Skip to content

Commit

Permalink
Fix phpGH-17868: Cannot allocate memory with tracing JIT on 8.4.4
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nielsdos committed Feb 20, 2025
1 parent 04a33a1 commit 0df4547
Showing 1 changed file with 23 additions and 8 deletions.
31 changes: 23 additions & 8 deletions ext/opcache/jit/zend_jit_ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -8675,7 +8675,9 @@ static int zend_jit_push_call_frame(zend_jit_ctx *jit, const zend_op *opline, co
// JIT: Z_CE(call->This) = called_scope;
ir_STORE(jit_CALL(rx, This), IR_NULL);
} else {
ir_ref object_or_called_scope, call_info, call_info2, object, if_cond;
ir_ref object_or_called_scope, call_info, call_info2, object;
ir_ref if_cond = IR_UNUSED;
ir_ref if_cond_user = IR_UNUSED;

if (opline->op2_type == IS_CV) {
// JIT: GC_ADDREF(closure);
Expand Down Expand Up @@ -8713,15 +8715,28 @@ static int zend_jit_push_call_frame(zend_jit_ctx *jit, const zend_op *opline, co
// JIT: Z_PTR(call->This) = object_or_called_scope;
ir_STORE(jit_CALL(rx, This.value.ptr), object_or_called_scope);

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

if (!func || func->common.type == ZEND_USER_FUNCTION) {
// JIT: if (closure->func.op_array.run_time_cache__ptr)
if_cond = ir_IF(ir_LOAD_A(ir_ADD_OFFSET(func_ref, offsetof(zend_closure, func.op_array.run_time_cache__ptr))));
ir_IF_FALSE(if_cond);

// JIT: zend_jit_init_func_run_time_cache_helper(closure->func);
ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_init_func_run_time_cache_helper),
ir_ADD_OFFSET(func_ref, offsetof(zend_closure, func)));

// JIT: zend_jit_init_func_run_time_cache_helper(closure->func);
ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_init_func_run_time_cache_helper),
ir_ADD_OFFSET(func_ref, offsetof(zend_closure, func)));
ir_MERGE_WITH_EMPTY_TRUE(if_cond);
}

ir_MERGE_WITH_EMPTY_TRUE(if_cond);
if (!func) {
ir_MERGE_WITH_EMPTY_FALSE(if_cond_user);
}
}

// JIT: ZEND_CALL_NUM_ARGS(call) = num_args;
Expand Down

0 comments on commit 0df4547

Please # to comment.