Skip to content

Commit 57a3fbb

Browse files
committed
Fixed INIT_METHOD_CALL + IS_VAR + reference in tracing JIT
1 parent 43e58d3 commit 57a3fbb

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9092,6 +9092,7 @@ static int zend_jit_init_method_call(dasm_State **Dst,
90929092
| ZVAL_DEREF FCARG1a, op1_info
90939093
op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
90949094
} else {
9095+
/* Hack: Convert reference to regular value to simplify JIT code */
90959096
ZEND_ASSERT(Z_REG(op1_addr) == ZREG_FP);
90969097
| IF_NOT_ZVAL_TYPE op1_addr, IS_REFERENCE, >1
90979098
| LOAD_ZVAL_ADDR FCARG1a, op1_addr
@@ -14707,10 +14708,17 @@ static zend_bool zend_jit_fetch_reference(dasm_State **Dst, const zend_op *oplin
1470714708
if (add_ref_guard) {
1470814709
| IF_NOT_ZVAL_TYPE var_addr, IS_REFERENCE, &exit_addr
1470914710
}
14710-
| GET_ZVAL_PTR FCARG1a, var_addr
14711-
14712-
var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, offsetof(zend_reference, val));
14713-
*var_addr_ptr = var_addr;
14711+
if (opline->opcode == ZEND_INIT_METHOD_CALL && opline->op1_type == IS_VAR) {
14712+
/* Hack: Convert reference to regular value to simplify JIT code for INIT_METHOD_CALL */
14713+
if (Z_REG(var_addr) != ZREG_FCARG1a || Z_OFFSET(var_addr) != 0) {
14714+
| LOAD_ZVAL_ADDR FCARG1a, var_addr
14715+
}
14716+
| EXT_CALL zend_jit_unref_helper, r0
14717+
} else {
14718+
| GET_ZVAL_PTR FCARG1a, var_addr
14719+
var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, offsetof(zend_reference, val));
14720+
*var_addr_ptr = var_addr;
14721+
}
1471414722

1471514723
if (var_type != IS_UNKNOWN) {
1471614724
var_type &= ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT|IS_TRACE_PACKED);
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
JIT METHOD_CALL: 001
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=1M
8+
--SKIPIF--
9+
<?php require_once('skipif.inc'); ?>
10+
--FILE--
11+
<?php
12+
function &foo() {
13+
return A::$o;
14+
}
15+
class A {
16+
static $o = null;
17+
static function foo() {
18+
return foo()->bar();
19+
}
20+
static function loop() {
21+
for ($i = 0; $i < 10; $i++) {
22+
self::foo();
23+
}
24+
echo "ok\n";
25+
}
26+
}
27+
class B {
28+
function bar() {
29+
}
30+
}
31+
A::$o = new B;
32+
A::loop();
33+
?>
34+
--EXPECT--
35+
ok

0 commit comments

Comments
 (0)