Skip to content

Commit

Permalink
Always load EX(opline) into the current frame in JIT when observers a…
Browse files Browse the repository at this point in the history
…re enabled

Fixes php#13772.
  • Loading branch information
bwoebi committed Apr 8, 2024
1 parent a86256c commit 1330e49
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 2 deletions.
7 changes: 6 additions & 1 deletion ext/opcache/jit/zend_jit_arm64.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -9449,7 +9449,12 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
}

if (ZEND_OBSERVER_ENABLED) {
| SAVE_IP
if (trace && (trace->op != ZEND_JIT_TRACE_END || trace->stop != ZEND_JIT_TRACE_STOP_INTERPRETER)) {
ZEND_ASSERT(trace[1].op == ZEND_JIT_TRACE_VM || trace[1].op == ZEND_JIT_TRACE_END);
| SET_EX_OPLINE trace[1].opline, REG0
} else {
| SAVE_IP
}
| mov FCARG1x, FP
| EXT_CALL zend_observer_fcall_begin, REG0
}
Expand Down
7 changes: 6 additions & 1 deletion ext/opcache/jit/zend_jit_x86.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -10187,7 +10187,12 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
}

if (ZEND_OBSERVER_ENABLED) {
| SAVE_IP
if (trace && (trace->op != ZEND_JIT_TRACE_END || trace->stop != ZEND_JIT_TRACE_STOP_INTERPRETER)) {
ZEND_ASSERT(trace[1].op == ZEND_JIT_TRACE_VM || trace[1].op == ZEND_JIT_TRACE_END);
| SET_EX_OPLINE trace[1].opline, r0
} else {
| SAVE_IP
}
| mov FCARG1a, FP
| EXT_CALL zend_observer_fcall_begin, r0
}
Expand Down
26 changes: 26 additions & 0 deletions ext/opcache/tests/jit/gh13772.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--TEST--
EX(opline) is correctly set for nested JIT user code calls
--EXTENSIONS--
opcache
zend_test
--INI--
opcache.enable=1
opcache.enable_cli=1
zend_test.observer.enabled=1
zend_test.observer.observe_all=1
zend_test.observer.show_output=0
--FILE--
<?php

function Ack($m, $n) {
if ($m == 0) return $n+1;
if ($n == 0) return Ack($m-1, 1);
return Ack($m - 1, Ack($m, ($n - 1)));
}

var_dump(Ack(3, 3));

?>
--EXPECT--
int(61)

10 changes: 10 additions & 0 deletions ext/zend_test/observer.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,16 @@ static void observer_show_opcode(zend_execute_data *execute_data)
php_printf("%*s<!-- opcode: '%s' -->\n", 2 * ZT_G(observer_nesting_depth), "", zend_get_opcode_name(EX(opline)->opcode));
}

static inline void assert_observer_opline(zend_execute_data *execute_data) {
ZEND_ASSERT(!ZEND_USER_CODE(EX(func)->type) ||
(EX(opline) >= EX(func)->op_array.opcodes && EX(opline) < EX(func)->op_array.opcodes + EX(func)->op_array.last) ||
(EX(opline) >= EG(exception_op) && EX(opline) < EG(exception_op) + 3));
}

static void observer_begin(zend_execute_data *execute_data)
{
assert_observer_opline(execute_data);

if (!ZT_G(observer_show_output)) {
return;
}
Expand Down Expand Up @@ -112,6 +120,8 @@ static void get_retval_info(zval *retval, smart_str *buf)

static void observer_end(zend_execute_data *execute_data, zval *retval)
{
assert_observer_opline(execute_data);

if (!ZT_G(observer_show_output)) {
return;
}
Expand Down

0 comments on commit 1330e49

Please sign in to comment.