diff --git a/NEWS b/NEWS index ae3a252c762..98b0f62f0da 100644 --- a/NEWS +++ b/NEWS @@ -21,6 +21,8 @@ PHP NEWS . Fixed segfault in function JIT due to NAN to bool warning. (Girgias) . Fixed bug GH-19984 (Double-free of EG(errors)/persistent_script->warnings on persist of already persisted file). (ilutov, Arnaud) + . Fixed bug GH-19889 (race condition in zend_runtime_jit(), + zend_jit_hot_func()). (Arnaud) - SOAP: . Fixed bug GH-19773 (SIGSEGV due to uninitialized soap_globals->lang_en). diff --git a/Zend/Optimizer/zend_func_info.h b/Zend/Optimizer/zend_func_info.h index b53683bdf5e..db00d843ee1 100644 --- a/Zend/Optimizer/zend_func_info.h +++ b/Zend/Optimizer/zend_func_info.h @@ -39,7 +39,7 @@ #define ZEND_FUNC_JIT_ON_PROF_REQUEST (1<<14) /* used by JIT */ #define ZEND_FUNC_JIT_ON_HOT_COUNTERS (1<<15) /* used by JIT */ #define ZEND_FUNC_JIT_ON_HOT_TRACE (1<<16) /* used by JIT */ - +#define ZEND_FUNC_JITED (1<<17) /* used by JIT */ typedef struct _zend_func_info zend_func_info; typedef struct _zend_call_info zend_call_info; diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 30f49fb73f6..00888b8b640 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -3098,8 +3098,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_runtime_jit(Z bool do_bailout = 0; zend_shared_alloc_lock(); + jit_extension = (zend_jit_op_array_extension*)ZEND_FUNC_INFO(op_array); - if (ZEND_FUNC_INFO(op_array)) { + if (jit_extension && !(jit_extension->func_info.flags & ZEND_FUNC_JITED)) { SHM_UNPROTECT(); zend_jit_unprotect(); @@ -3111,11 +3112,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_runtime_jit(Z opline++; } } - jit_extension = (zend_jit_op_array_extension*)ZEND_FUNC_INFO(op_array); ((zend_op*)opline)->handler = jit_extension->orig_handler; /* perform real JIT for this function */ zend_real_jit_func(op_array, NULL, NULL, ZEND_JIT_ON_FIRST_EXEC); + + jit_extension->func_info.flags |= ZEND_FUNC_JITED; } zend_catch { do_bailout = true; } zend_end_try(); @@ -3182,7 +3184,7 @@ void ZEND_FASTCALL zend_jit_hot_func(zend_execute_data *execute_data, const zend zend_shared_alloc_lock(); jit_extension = (zend_jit_op_array_hot_extension*)ZEND_FUNC_INFO(op_array); - if (jit_extension) { + if (jit_extension && !(jit_extension->func_info.flags & ZEND_FUNC_JITED)) { SHM_UNPROTECT(); zend_jit_unprotect(); @@ -3195,6 +3197,8 @@ void ZEND_FASTCALL zend_jit_hot_func(zend_execute_data *execute_data, const zend /* perform real JIT for this function */ zend_real_jit_func(op_array, NULL, opline, ZEND_JIT_ON_HOT_COUNTERS); + + jit_extension->func_info.flags |= ZEND_FUNC_JITED; } zend_catch { do_bailout = 1; } zend_end_try();