mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix race condition in zend_runtime_jit(), zend_jit_hot_func()
zend_runtime_jit() prevents concurrent compilation with zend_shared_alloc_lock(), but this doesn't prevent blocked threads from trying to compile the function again after they acquire the lock. In the case of GH-19889, one of the function entries is compiled with zend_jit_handler(), which fails when the op handler has already been replaced by a JIT'ed handler. Fix by marking compiled functions with a new flag ZEND_FUNC_JITED, and skipping compilation of marked functions. The same fix is applied to zend_jit_hot_func(). Fixes GH-19889 Closes GH-19971
This commit is contained in:
2
NEWS
2
NEWS
@@ -44,6 +44,8 @@ PHP NEWS
|
||||
. Fixed bug GH-19669 (assertion failure in zend_jit_trace_type_to_info_ex).
|
||||
(Arnaud)
|
||||
. Fixed bug GH-19831 (function JIT may not deref property value). (Arnaud)
|
||||
. Fixed bug GH-19889 (race condition in zend_runtime_jit(),
|
||||
zend_jit_hot_func()). (Arnaud)
|
||||
|
||||
- Phar:
|
||||
. Fix memory leak and invalid continuation after tar header writing fails.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -2945,8 +2945,9 @@ static int ZEND_FASTCALL zend_runtime_jit(void)
|
||||
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();
|
||||
@@ -2958,11 +2959,12 @@ static int ZEND_FASTCALL zend_runtime_jit(void)
|
||||
opline++;
|
||||
}
|
||||
}
|
||||
jit_extension = (zend_jit_op_array_extension*)ZEND_FUNC_INFO(op_array);
|
||||
opline->handler = jit_extension->orig_handler;
|
||||
((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();
|
||||
@@ -3024,7 +3026,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();
|
||||
|
||||
@@ -3039,6 +3041,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();
|
||||
|
||||
Reference in New Issue
Block a user