mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4: Fix GH-21267: JIT infinite loop on FETCH_OBJ_R with IS_UNDEF property (#21368)
This commit is contained in:
@@ -7949,7 +7949,7 @@ static int zend_jit_defined(zend_jit_ctx *jit, const zend_op *opline, uint8_t sm
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int zend_jit_escape_if_undef(zend_jit_ctx *jit, int var, uint32_t flags, const zend_op *opline, int8_t reg)
|
||||
static int zend_jit_escape_if_undef(zend_jit_ctx *jit, int var, uint32_t flags, const zend_op *opline, const zend_op_array *op_array, int8_t reg)
|
||||
{
|
||||
zend_jit_addr reg_addr = ZEND_ADDR_REF_ZVAL(zend_jit_deopt_rload(jit, IR_ADDR, reg));
|
||||
ir_ref if_def = ir_IF(jit_Z_TYPE(jit, reg_addr));
|
||||
@@ -7972,7 +7972,20 @@ static int zend_jit_escape_if_undef(zend_jit_ctx *jit, int var, uint32_t flags,
|
||||
}
|
||||
|
||||
jit_LOAD_IP_ADDR(jit, opline - 1);
|
||||
ir_IJMP(jit_STUB_ADDR(jit, jit_stub_trace_escape));
|
||||
|
||||
/* We can't use trace_escape() because opcode handler may be overridden by JIT */
|
||||
zend_jit_op_array_trace_extension *jit_extension =
|
||||
(zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(op_array);
|
||||
size_t offset = jit_extension->offset;
|
||||
ir_ref ref = ir_CONST_ADDR(ZEND_OP_TRACE_INFO((opline - 1), offset)->orig_handler);
|
||||
if (GCC_GLOBAL_REGS) {
|
||||
ir_TAILCALL(IR_VOID, ref);
|
||||
} else {
|
||||
#if defined(IR_TARGET_X86)
|
||||
ref = ir_CAST_FC_FUNC(ref);
|
||||
#endif
|
||||
ir_TAILCALL_1(IR_I32, ref, jit_FP(jit));
|
||||
}
|
||||
|
||||
ir_IF_TRUE(if_def);
|
||||
|
||||
|
||||
@@ -3634,7 +3634,7 @@ static int zend_jit_trace_deoptimization(
|
||||
|
||||
ZEND_ASSERT(STACK_FLAGS(parent_stack, check2) == ZREG_ZVAL_COPY);
|
||||
ZEND_ASSERT(reg != ZREG_NONE);
|
||||
if (!zend_jit_escape_if_undef(jit, check2, flags, opline, reg)) {
|
||||
if (!zend_jit_escape_if_undef(jit, check2, flags, opline, exit_info->op_array, reg)) {
|
||||
return 0;
|
||||
}
|
||||
if (!zend_jit_restore_zval(jit, EX_NUM_TO_VAR(check2), reg)) {
|
||||
|
||||
35
ext/opcache/tests/jit/gh21267.phpt
Normal file
35
ext/opcache/tests/jit/gh21267.phpt
Normal file
@@ -0,0 +1,35 @@
|
||||
--TEST--
|
||||
GH-21267 (JIT infinite loop on FETCH_OBJ_R with IS_UNDEF property in polymorphic context)
|
||||
--INI--
|
||||
opcache.enable=1
|
||||
opcache.enable_cli=1
|
||||
opcache.jit=tracing
|
||||
opcache.jit_buffer_size=64M
|
||||
opcache.jit_hot_loop=0
|
||||
opcache.jit_hot_func=2
|
||||
opcache.jit_hot_return=0
|
||||
opcache.jit_hot_side_exit=1
|
||||
--FILE--
|
||||
<?php
|
||||
class C {
|
||||
public $x = true;
|
||||
public function __get($name) { return null; }
|
||||
public function getX() { return $this->x; }
|
||||
}
|
||||
|
||||
$o1 = new C;
|
||||
$o2 = new C;
|
||||
$o2->x = false;
|
||||
$o3 = new C;
|
||||
unset($o3->x);
|
||||
$a = [$o1, $o2, $o3];
|
||||
|
||||
for ($i = 0; $i < 8; $i++) {
|
||||
$m = $a[$i % 3];
|
||||
$m->getX();
|
||||
$m->getX();
|
||||
}
|
||||
?>
|
||||
OK
|
||||
--EXPECT--
|
||||
OK
|
||||
36
ext/opcache/tests/jit/gh21267_blacklist.phpt
Normal file
36
ext/opcache/tests/jit/gh21267_blacklist.phpt
Normal file
@@ -0,0 +1,36 @@
|
||||
--TEST--
|
||||
GH-21267 (JIT infinite loop on FETCH_OBJ_R with IS_UNDEF via blacklisted trace exit)
|
||||
--INI--
|
||||
opcache.enable=1
|
||||
opcache.enable_cli=1
|
||||
opcache.jit=tracing
|
||||
opcache.jit_buffer_size=64M
|
||||
opcache.jit_hot_loop=0
|
||||
opcache.jit_hot_func=2
|
||||
opcache.jit_hot_return=0
|
||||
opcache.jit_hot_side_exit=1
|
||||
opcache.jit_max_side_traces=0
|
||||
--FILE--
|
||||
<?php
|
||||
class C {
|
||||
public $x = true;
|
||||
public function __get($name) { return null; }
|
||||
public function getX() { return $this->x; }
|
||||
}
|
||||
|
||||
$o1 = new C;
|
||||
$o2 = new C;
|
||||
$o2->x = false;
|
||||
$o3 = new C;
|
||||
unset($o3->x);
|
||||
$a = [$o1, $o2, $o3];
|
||||
|
||||
for ($i = 0; $i < 8; $i++) {
|
||||
$m = $a[$i % 3];
|
||||
$m->getX();
|
||||
$m->getX();
|
||||
}
|
||||
?>
|
||||
OK
|
||||
--EXPECT--
|
||||
OK
|
||||
Reference in New Issue
Block a user