Skip to content

Commit 5ede541

Browse files
committed
Fix GH-17868: Cannot allocate memory with tracing JIT on 8.4.4
The generated code tries to initialize the run time cache for even internal closures, but it should only initialize the run time cache for user closures. We fix this by adding a check for the function type. If `func` is known, then we can check the type at code generation time. Closes GH-17869.
1 parent ca75ebf commit 5ede541

File tree

2 files changed

+17
-7
lines changed

2 files changed

+17
-7
lines changed

NEWS

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ PHP NEWS
5757
FETCH_OBJ_R breaks JIT). (Dmitry, nielsdos)
5858
. Fixed bug GH-17715 (Null pointer deref in observer API when calling
5959
cases() method on preloaded enum). (Bob)
60+
. Fixed bug GH-17868 (Cannot allocate memory with tracing JIT on 8.4.4).
61+
(nielsdos)
6062

6163
- PDO_SQLite:
6264
. Fixed GH-17837 ()::getColumnMeta() on unexecuted statement segfaults).

ext/opcache/jit/zend_jit_ir.c

+15-7
Original file line numberDiff line numberDiff line change
@@ -8676,6 +8676,7 @@ static int zend_jit_push_call_frame(zend_jit_ctx *jit, const zend_op *opline, co
86768676
ir_STORE(jit_CALL(rx, This), IR_NULL);
86778677
} else {
86788678
ir_ref object_or_called_scope, call_info, call_info2, object, if_cond;
8679+
ir_ref if_cond_user = IR_UNUSED;
86798680

86808681
if (opline->op2_type == IS_CV) {
86818682
// JIT: GC_ADDREF(closure);
@@ -8713,15 +8714,22 @@ static int zend_jit_push_call_frame(zend_jit_ctx *jit, const zend_op *opline, co
87138714
// JIT: Z_PTR(call->This) = object_or_called_scope;
87148715
ir_STORE(jit_CALL(rx, This.value.ptr), object_or_called_scope);
87158716

8716-
// JIT: if (closure->func.op_array.run_time_cache__ptr)
8717-
if_cond = ir_IF(ir_LOAD_A(ir_ADD_OFFSET(func_ref, offsetof(zend_closure, func.op_array.run_time_cache__ptr))));
8718-
ir_IF_FALSE(if_cond);
8717+
if (!func) {
8718+
// JIT: if (closure->func.common.type & ZEND_USER_FUNCTION)
8719+
ir_ref type = ir_LOAD_U8(ir_ADD_OFFSET(func_ref, offsetof(zend_closure, func.type)));
8720+
if_cond_user = ir_IF(ir_AND_U8(type, ir_CONST_U8(ZEND_USER_FUNCTION)));
8721+
ir_IF_TRUE(if_cond_user);
8722+
}
87198723

8720-
// JIT: zend_jit_init_func_run_time_cache_helper(closure->func);
8721-
ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_init_func_run_time_cache_helper),
8722-
ir_ADD_OFFSET(func_ref, offsetof(zend_closure, func)));
8724+
if (!func || func->common.type == ZEND_USER_FUNCTION) {
8725+
// JIT: zend_jit_init_func_run_time_cache_helper(closure->func);
8726+
ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_init_func_run_time_cache_helper),
8727+
ir_ADD_OFFSET(func_ref, offsetof(zend_closure, func)));
8728+
}
87238729

8724-
ir_MERGE_WITH_EMPTY_TRUE(if_cond);
8730+
if (!func) {
8731+
ir_MERGE_WITH_EMPTY_FALSE(if_cond_user);
8732+
}
87258733
}
87268734

87278735
// JIT: ZEND_CALL_NUM_ARGS(call) = num_args;

0 commit comments

Comments
 (0)