Skip to content

JIT_G(enabled) not set correctly on other threads #16851

Closed
@dktapps

Description

@dktapps

Description

Disclaimer: I encountered this issue using a threading extension. Well aware this may not be the best source of truth on issues like this, especially due to the difficulty of reproducing.

With the following INI:

opcache.jit=tracing
opcache.jit_buffer_size=0

the following happens:

  • INI is loaded on the main thread and sets JIT_G(enabled) = 1 and JIT_G(on) = 1
  • accel_post_startup() is called during process init, and overrides thread-locals here to force-disable JIT:
    JIT_G(enabled) = false;
    JIT_G(on) = false;
  • dasm_buf is therefore null because zend_jit_startup() wasn't called due to jit_buffer_size=0:
    if (JIT_G(enabled)) {
    if (JIT_G(buffer_size) == 0) {
    JIT_G(enabled) = false;
    JIT_G(on) = false;
    } else if (!ZSMMG(reserved)) {
    zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Could not enable JIT: could not use reserved buffer!");
    } else {
    zend_jit_startup(ZSMMG(reserved), jit_size, reattached);
    }
    }
    &
    dasm_buf = buf;
  • when a second thread is started, INI is loaded again, setting JIT_G(enabled) = 1 and JIT_G(on) = 1, but this time accel_post_startup() does not override these settings
  • finally, the following calls fail on Windows with errors like VirtualProtect() failed [87] The parameter is incorrect during zend_accel_persist_script() because dasm_buf is NULL - this is because JIT_G(on) = 1 although it was supposed to be forcibly disabled:
    if (JIT_G(on) && for_shm) {
    zend_jit_unprotect();
    }
    &
    if (JIT_G(on) && for_shm) {
    if (JIT_G(opt_level) >= ZEND_JIT_LEVEL_OPT_SCRIPT) {
    zend_jit_script(&script->script);
    }
    zend_jit_protect();
    }

Proposed solution

  • JIT_G(enabled) needs to become a true global
  • zend_jit_config() needs to respect the existing value of JIT_G(enabled) (or its replacement true global) instead of overwriting it like it currently does
  • JIT_G(enabled) (or its replacement true global) should be set to true in accel_post_startup() after zend_jit_startup() returns a success code

PHP Version

8.1, 8.2, 8.3, 8.4, master

Operating System

Windows

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions