diff --git a/.github/actions/test-macos/action.yml b/.github/actions/test-macos/action.yml index 029ca2edb966d..017cef9f74c36 100644 --- a/.github/actions/test-macos/action.yml +++ b/.github/actions/test-macos/action.yml @@ -21,7 +21,6 @@ runs: export STACK_LIMIT_DEFAULTS_CHECK=1 sapi/cli/php run-tests.php -P -q ${{ inputs.runTestsParameters }} \ -d opcache.jit=${{ inputs.jitType }} \ - -d opcache.protect_memory=1 \ -d opcache.jit_buffer_size=64M \ -j$(($(sysctl -n hw.ncpu) - 1)) \ -g FAIL,BORK,LEAK,XLEAK \ diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 52a323c581488..5c431903cf438 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -76,9 +76,6 @@ jobs: - debug: false zts: false asan: false - - debug: true - zts: true - asan: true name: "LINUX_X64_${{ matrix.debug && 'DEBUG' || 'RELEASE' }}_${{ matrix.zts && 'ZTS' || 'NTS' }}${{ matrix.asan && '_ASAN' || '' }}" runs-on: ubuntu-22.04 steps: @@ -145,7 +142,7 @@ jobs: - name: Verify generated files are up to date if: ${{ !matrix.asan }} uses: ./.github/actions/verify-generated-files - MACOS_DEBUG_NTS: + MACOS_DEBUG_ZTS: if: github.repository_owner == 'php' || github.event_name == 'pull_request' strategy: fail-fast: false @@ -155,7 +152,7 @@ jobs: arch: X64 - os: 14 arch: ARM64 - name: MACOS_${{ matrix.arch }}_DEBUG_NTS + name: MACOS_${{ matrix.arch }}_DEBUG_ZTS runs-on: macos-${{ matrix.os }} steps: - name: git checkout @@ -170,7 +167,7 @@ jobs: - name: ./configure uses: ./.github/actions/configure-macos with: - configurationParameters: --enable-debug --disable-zts + configurationParameters: --enable-debug --enable-zts - name: make run: |- export PATH="$(brew --prefix)/opt/bison/bin:$PATH" @@ -187,130 +184,3 @@ jobs: -d opcache.enable_cli=1 - name: Verify generated files are up to date uses: ./.github/actions/verify-generated-files - WINDOWS: - if: github.repository_owner == 'php' || github.event_name == 'pull_request' - name: WINDOWS_X64_ZTS - runs-on: windows-2019 - env: - PHP_BUILD_CACHE_BASE_DIR: C:\build-cache - PHP_BUILD_OBJ_DIR: C:\obj - PHP_BUILD_CACHE_SDK_DIR: C:\build-cache\sdk - PHP_BUILD_SDK_BRANCH: php_downloads_server_migration_v1 - PHP_BUILD_CRT: vs16 - PLATFORM: x64 - THREAD_SAFE: "1" - INTRINSICS: AVX2 - PARALLEL: -j2 - OPCACHE: "1" - steps: - - name: git config - run: git config --global core.autocrlf false && git config --global core.eol lf - - name: git checkout - uses: actions/checkout@v4 - - name: Setup - uses: ./.github/actions/setup-windows - - name: Build - run: .github/scripts/windows/build.bat - - name: Test - run: .github/scripts/windows/test.bat - BENCHMARKING: - name: BENCHMARKING - if: github.repository_owner == 'php' || github.event_name == 'pull_request' - runs-on: ubuntu-22.04 - steps: - - name: git checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: apt - run: | - set -x - sudo apt-get update - sudo apt-get install \ - bison \ - libgmp-dev \ - libonig-dev \ - libsqlite3-dev \ - openssl \ - re2c \ - valgrind - - name: ccache - uses: hendrikmuhs/ccache-action@v1.2 - with: - key: "${{github.job}}-${{hashFiles('main/php_version.h')}}" - append-timestamp: false - - name: ./configure - run: | - set -x - ./buildconf --force - ./configure \ - --disable-debug \ - --enable-mbstring \ - --enable-opcache \ - --enable-option-checking=fatal \ - --enable-sockets \ - --enable-werror \ - --prefix=/usr \ - --with-config-file-scan-dir=/etc/php.d \ - --with-gmp \ - --with-mysqli=mysqlnd \ - --with-openssl \ - --with-pdo-sqlite \ - --with-valgrind - - name: make - run: make -j$(/usr/bin/nproc) >/dev/null - - name: make install - run: | - set -x - sudo make install - sudo mkdir -p /etc/php.d - sudo chmod 777 /etc/php.d - echo mysqli.default_socket=/var/run/mysqld/mysqld.sock > /etc/php.d/mysqli.ini - echo zend_extension=opcache.so >> /etc/php.d/opcache.ini - echo opcache.enable=1 >> /etc/php.d/opcache.ini - echo opcache.enable_cli=1 >> /etc/php.d/opcache.ini - - name: Setup - run: | - git config --global user.name "Benchmark" - git config --global user.email "benchmark@php.net" - sudo service mysql start - mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS wordpress" - mysql -uroot -proot -e "CREATE USER 'wordpress'@'localhost' IDENTIFIED BY 'wordpress'; FLUSH PRIVILEGES;" - mysql -uroot -proot -e "GRANT ALL PRIVILEGES ON *.* TO 'wordpress'@'localhost' WITH GRANT OPTION;" - - name: git checkout benchmarking-data - uses: actions/checkout@v4 - with: - repository: php/benchmarking-data - ssh-key: ${{ secrets.BENCHMARKING_DATA_DEPLOY_KEY }} - path: benchmark/repos/data - - name: Benchmark - run: php benchmark/benchmark.php true - - name: Store result - if: github.event_name == 'push' - run: | - set -x - cd benchmark/repos/data - git pull --autostash - if [ -e ".git/MERGE_HEAD" ]; then - echo "Merging, can't proceed" - exit 1 - fi - git add . - if git diff --cached --quiet; then - exit 0 - fi - git commit -m "Add result for ${{ github.repository }}@${{ github.sha }}" - git push - - name: Show diff - if: github.event_name == 'pull_request' - run: |- - set -x - php benchmark/generate_diff.php \ - ${{ github.sha }} \ - $(git merge-base ${{ github.event.pull_request.base.sha }} ${{ github.sha }}) \ - > $GITHUB_STEP_SUMMARY - - uses: actions/upload-artifact@v4 - with: - name: profiles - path: ${{ github.workspace }}/benchmark/profiles - retention-days: 30 diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 294ed1db8eaf7..a078d1d7618c6 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -3191,18 +3191,21 @@ ZEND_EXT_API void zend_jit_unprotect(void) { #ifdef HAVE_MPROTECT if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) { - int opts = PROT_READ | PROT_WRITE; -#ifdef ZTS #ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP if (zend_write_protect) { pthread_jit_write_protect_np(0); + return; } #endif +#if !defined(ZTS) || !defined(__APPLE__) || !defined(__aarch64__) + int opts = PROT_READ | PROT_WRITE; +#ifdef ZTS opts |= PROT_EXEC; #endif if (mprotect(dasm_buf, dasm_size, opts) != 0) { fprintf(stderr, "mprotect() failed [%d] %s\n", errno, strerror(errno)); } +#endif } #elif _WIN32 if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) { @@ -3229,11 +3232,14 @@ ZEND_EXT_API void zend_jit_protect(void) #ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP if (zend_write_protect) { pthread_jit_write_protect_np(1); + return; } #endif +#if !defined(ZTS) || !defined(__APPLE__) || !defined(__aarch64__) if (mprotect(dasm_buf, dasm_size, PROT_READ | PROT_EXEC) != 0) { fprintf(stderr, "mprotect() failed [%d] %s\n", errno, strerror(errno)); } +#endif } #elif _WIN32 if (!(JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP))) { @@ -3463,12 +3469,15 @@ ZEND_EXT_API void zend_jit_startup(void *buf, size_t size, bool reattached) dasm_size = size; dasm_ptr = dasm_end = (void*)(((char*)dasm_buf) + size - sizeof(*dasm_ptr) * 2); + do { #ifdef HAVE_MPROTECT #ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP if (zend_write_protect) { pthread_jit_write_protect_np(1); + break; } #endif +#if !defined(ZTS) || !defined(__APPLE__) || !defined(__aarch64__) if (JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP)) { if (mprotect(dasm_buf, dasm_size, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) { fprintf(stderr, "mprotect() failed [%d] %s\n", errno, strerror(errno)); @@ -3478,6 +3487,7 @@ ZEND_EXT_API void zend_jit_startup(void *buf, size_t size, bool reattached) fprintf(stderr, "mprotect() failed [%d] %s\n", errno, strerror(errno)); } } +#endif #elif _WIN32 if (JIT_G(debug) & (ZEND_JIT_DEBUG_GDB|ZEND_JIT_DEBUG_PERF_DUMP)) { DWORD old; @@ -3499,6 +3509,7 @@ ZEND_EXT_API void zend_jit_startup(void *buf, size_t size, bool reattached) } } #endif + } while (0); if (!reattached) { zend_jit_unprotect(); diff --git a/ext/opcache/shared_alloc_mmap.c b/ext/opcache/shared_alloc_mmap.c index d5e4612bc104e..9b15743a863da 100644 --- a/ext/opcache/shared_alloc_mmap.c +++ b/ext/opcache/shared_alloc_mmap.c @@ -48,6 +48,10 @@ # define MAP_HUGETLB MAP_ALIGNED_SUPER #endif +#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP +#include +#endif + #if (defined(__linux__) || defined(__FreeBSD__)) && (defined(__x86_64__) || defined (__aarch64__)) && !defined(__SANITIZE_ADDRESS__) static void *find_prefered_mmap_base(size_t requested_size) { @@ -180,6 +184,7 @@ static int create_segments(size_t requested_size, zend_shared_segment ***shared_ { zend_shared_segment *shared_segment; int flags = PROT_READ | PROT_WRITE, fd = -1; + int mmap_flags = MAP_SHARED | MAP_ANONYMOUS; void *p; #if defined(HAVE_PROCCTL) && defined(PROC_WXMAP_CTL) int enable_wxmap = PROC_WX_MAPPINGS_PERMIT; @@ -198,7 +203,17 @@ static int create_segments(size_t requested_size, zend_shared_segment ***shared_ flags |= PROT_MAX(PROT_READ | PROT_WRITE | PROT_EXEC); #endif #ifdef MAP_JIT - flags |= MAP_JIT; +# ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP + if (pthread_jit_write_protect_supported_np()) { + mmap_flags |= MAP_JIT; + } else { +#if defined(ZTS) && defined(__APPLE__) && defined(__aarch64__) + flags |= PROT_EXEC; +#endif + } +# else + mmap_flags |= MAP_JIT; +# endif #endif #if (defined(__linux__) || defined(__FreeBSD__)) && (defined(__x86_64__) || defined (__aarch64__)) && !defined(__SANITIZE_ADDRESS__) void *hint = find_prefered_mmap_base(requested_size); @@ -206,13 +221,13 @@ static int create_segments(size_t requested_size, zend_shared_segment ***shared_ # ifdef MAP_HUGETLB size_t huge_page_size = 2 * 1024 * 1024; if (requested_size >= huge_page_size && requested_size % huge_page_size == 0) { - p = mmap(hint, requested_size, flags, MAP_SHARED|MAP_ANONYMOUS|MAP_HUGETLB|MAP_FIXED, -1, 0); + p = mmap(hint, requested_size, flags, mmap_flags|MAP_HUGETLB|MAP_FIXED, -1, 0); if (p != MAP_FAILED) { goto success; } } #endif - p = mmap(hint, requested_size, flags, MAP_SHARED|MAP_ANONYMOUS|MAP_FIXED, -1, 0); + p = mmap(hint, requested_size, flags, mmap_flags|MAP_FIXED, -1, 0); if (p != MAP_FAILED) { goto success; } @@ -236,34 +251,34 @@ static int create_segments(size_t requested_size, zend_shared_segment ***shared_ /* to got HUGE PAGES in low 32-bit address we have to reserve address space and then remap it using MAP_HUGETLB */ - p = mmap(NULL, requested_size, flags, MAP_SHARED|MAP_ANONYMOUS|MAP_32BIT, fd, 0); + p = mmap(NULL, requested_size, flags, mmap_flags|MAP_32BIT, fd, 0); if (p != MAP_FAILED) { munmap(p, requested_size); p = (void*)(ZEND_MM_ALIGNED_SIZE_EX((ptrdiff_t)p, huge_page_size)); - p = mmap(p, requested_size, flags, MAP_SHARED|MAP_ANONYMOUS|MAP_32BIT|MAP_HUGETLB|MAP_FIXED, -1, 0); + p = mmap(p, requested_size, flags, mmap_flags|MAP_32BIT|MAP_HUGETLB|MAP_FIXED, -1, 0); if (p != MAP_FAILED) { goto success; } else { - p = mmap(NULL, requested_size, flags, MAP_SHARED|MAP_ANONYMOUS|MAP_32BIT, fd, 0); + p = mmap(NULL, requested_size, flags, mmap_flags|MAP_32BIT, fd, 0); if (p != MAP_FAILED) { goto success; } } } # endif - p = mmap(0, requested_size, flags, MAP_SHARED|MAP_ANONYMOUS|MAP_HUGETLB, fd, 0); + p = mmap(0, requested_size, flags, mmap_flags|MAP_HUGETLB, fd, 0); if (p != MAP_FAILED) { goto success; } } #elif defined(PREFER_MAP_32BIT) && defined(__x86_64__) && defined(MAP_32BIT) - p = mmap(NULL, requested_size, flags, MAP_SHARED|MAP_ANONYMOUS|MAP_32BIT, fd, 0); + p = mmap(NULL, requested_size, flags, mmap_flags|MAP_32BIT, fd, 0); if (p != MAP_FAILED) { goto success; } #endif - p = mmap(0, requested_size, flags, MAP_SHARED|MAP_ANONYMOUS, fd, 0); + p = mmap(0, requested_size, flags, mmap_flags, fd, 0); if (p == MAP_FAILED) { *error_in = "mmap"; return ALLOC_FAILURE;