Skip to content

Commit cb3579d

Browse files
authored
Fix zend_jit_trace_find_init_fcall_op() (#23449)
zend_jit_trace_find_init_fcall_op() tries to find the INIT_FCALL opline corresponding to a ZEND_JIT_TRACE_INIT_CALL record, but it fails to do so in the ZEND_JIT_TRACE_FAKE_INIT_CALL case, for nested calls. The first loop is supposed to find the first opline after the sequence of ZEND_JIT_TRACE_INIT_CALL record, but it mistakenly decrements 'p' after initially incrementing it. As a result 'p' eventually points to an invalid record. It works for non-nested calls because the 'p->op == ZEND_JIT_TRACE_VM' condition is true on the first iteration in that case. This can not lead to a crash or miscompilations, but this results in lost optimization opportunities.
1 parent 48d2b45 commit cb3579d

1 file changed

Lines changed: 5 additions & 1 deletion

File tree

ext/opcache/jit/zend_jit_trace.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,9 @@ static const zend_op *zend_jit_trace_find_init_fcall_op(zend_jit_trace_rec *p, c
11671167
const zend_op *opline = NULL;
11681168
int call_level = 0;
11691169

1170+
/* Scan trace buffer forward to find the first recorded opline after
1171+
* the sequence of ZEND_JIT_TRACE_INIT_CALL, and keep track of the
1172+
* call level. */
11701173
p++;
11711174
while (1) {
11721175
if (p->op == ZEND_JIT_TRACE_VM) {
@@ -1178,8 +1181,9 @@ static const zend_op *zend_jit_trace_find_init_fcall_op(zend_jit_trace_rec *p, c
11781181
} else {
11791182
return NULL;
11801183
}
1181-
p--;
1184+
p++;
11821185
}
1186+
/* Scan oplines backward to find the init fcall op */
11831187
if (opline) {
11841188
while (opline > op_array->opcodes) {
11851189
opline--;

0 commit comments

Comments
 (0)