Skip to content

Commit 05afc37

Browse files
committed
JIT: Fix escape_if_undef on PHP-8.4 CALL VM
Two issues in zend_jit_escape_if_undef. Register orig_handler as IR_FUNC_ADDR (was tripping the FUNC_ADDR assertion in side-trace compile); replace ir_TAILCALL_1 with ir_CALL_1 + ir_RETURN(1) so execute_ex reloads execute_data after the deopt on CALL VM. Fixes GH-21368 Closes GH-22028
1 parent ef589ce commit 05afc37

2 files changed

Lines changed: 39 additions & 5 deletions

File tree

ext/opcache/jit/zend_jit_ir.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8096,14 +8096,12 @@ static int zend_jit_escape_if_undef(zend_jit_ctx *jit, int var, uint32_t flags,
80968096
zend_jit_op_array_trace_extension *jit_extension =
80978097
(zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(op_array);
80988098
size_t offset = jit_extension->offset;
8099-
ir_ref ref = ir_CONST_ADDR(ZEND_OP_TRACE_INFO((opline - 1), offset)->orig_handler);
8099+
ir_ref ref = ir_CONST_FC_FUNC(ZEND_OP_TRACE_INFO((opline - 1), offset)->orig_handler);
81008100
if (GCC_GLOBAL_REGS) {
81018101
ir_TAILCALL(IR_VOID, ref);
81028102
} else {
8103-
#if defined(IR_TARGET_X86)
8104-
ref = ir_CAST_FC_FUNC(ref);
8105-
#endif
8106-
ir_TAILCALL_1(IR_I32, ref, jit_FP(jit));
8103+
ir_CALL_1(IR_I32, ref, jit_FP(jit));
8104+
ir_RETURN(ir_CONST_I32(1));
81078105
}
81088106

81098107
ir_IF_TRUE(if_def);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
GH-21368 (JIT escape_if_undef SEGV on CALL VM with aggressive trace counters)
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.jit_buffer_size=64M
7+
opcache.jit=tracing
8+
opcache.protect_memory=1
9+
opcache.jit_hot_loop=1
10+
opcache.jit_hot_func=1
11+
opcache.jit_hot_return=1
12+
opcache.jit_hot_side_exit=1
13+
--FILE--
14+
<?php
15+
class C {
16+
public $x = true;
17+
public function __get($name) { return null; }
18+
public function getX() { return $this->x; }
19+
}
20+
21+
$o1 = new C;
22+
$o2 = new C;
23+
$o2->x = false;
24+
$o3 = new C;
25+
unset($o3->x);
26+
$a = [$o1, $o2, $o3];
27+
28+
for ($i = 0; $i < 8; $i++) {
29+
$m = $a[$i % 3];
30+
$m->getX();
31+
$m->getX();
32+
}
33+
?>
34+
OK
35+
--EXPECT--
36+
OK

0 commit comments

Comments
 (0)