Skip to content

Commit 6021e72

Browse files
committed
Tracinf JIT: Prevnt generation code for instruction that with cyclic dependency
e.g. $a[] += $a is compiled into ASSIGN_DIM_OP+OP_DATA, where OP_DATA.op1_use depends on ASSIGN_DIM_OP.op1_def
1 parent 6974372 commit 6021e72

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

ext/opcache/jit/zend_jit_trace.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,6 +1520,11 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
15201520
/* break missing intentionally */
15211521
case ZEND_ASSIGN_DIM:
15221522
if (opline->op1_type == IS_CV) {
1523+
if ((opline+1)->op1_type == IS_CV
1524+
&& (opline+1)->op1.var == opline->op1.var) {
1525+
/* skip $a[x] = $a; */
1526+
break;
1527+
}
15231528
ADD_OP1_DATA_TRACE_GUARD();
15241529
ADD_OP2_TRACE_GUARD();
15251530
ADD_OP1_TRACE_GUARD();
@@ -1553,6 +1558,12 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
15531558
break;
15541559
}
15551560
if (opline->opcode == ZEND_ASSIGN_OBJ_OP) {
1561+
if (opline->op1_type == IS_CV
1562+
&& (opline+1)->op1_type == IS_CV
1563+
&& (opline+1)->op1.var == opline->op1.var) {
1564+
/* skip $a->prop += $a; */
1565+
break;
1566+
}
15561567
ADD_OP1_DATA_TRACE_GUARD();
15571568
}
15581569
ADD_OP1_TRACE_GUARD();
@@ -4219,6 +4230,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
42194230
opline->extended_value, MAY_BE_ANY, OP1_DATA_INFO())) {
42204231
break;
42214232
}
4233+
if (opline->op1_type == IS_CV
4234+
&& (opline+1)->op1_type == IS_CV
4235+
&& (opline+1)->op1.var == opline->op1.var) {
4236+
/* skip $a[x] += $a; */
4237+
break;
4238+
}
42224239
op1_info = OP1_INFO();
42234240
op1_addr = OP1_REG_ADDR();
42244241
if (opline->op1_type == IS_VAR) {
@@ -4336,6 +4353,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
43364353
|| Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') {
43374354
break;
43384355
}
4356+
if (opline->op1_type == IS_CV
4357+
&& (opline+1)->op1_type == IS_CV
4358+
&& (opline+1)->op1.var == opline->op1.var) {
4359+
/* skip $a->prop += $a; */
4360+
break;
4361+
}
43394362
if (!zend_jit_supported_binary_op(
43404363
opline->extended_value, MAY_BE_ANY, OP1_DATA_INFO())) {
43414364
break;
@@ -4480,6 +4503,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
44804503
case ZEND_ASSIGN_DIM:
44814504
op1_info = OP1_INFO();
44824505
op1_addr = OP1_REG_ADDR();
4506+
if (opline->op1_type == IS_CV
4507+
&& (opline+1)->op1_type == IS_CV
4508+
&& (opline+1)->op1.var == opline->op1.var) {
4509+
/* skip $a[x] = $a; */
4510+
break;
4511+
}
44834512
if (opline->op1_type == IS_VAR) {
44844513
if (orig_op1_type != IS_UNKNOWN
44854514
&& (orig_op1_type & IS_TRACE_INDIRECT)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
JIT ASSIGN_DIM_OP: Cyclic dependency
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=1M
8+
--FILE--
9+
<?php
10+
$a = null;
11+
$a[] .= $a;
12+
var_dump($a);
13+
?>
14+
--EXPECTF--
15+
Warning: Array to string conversion in %sassign_dim_op_004.php on line 3
16+
array(1) {
17+
[0]=>
18+
string(5) "Array"
19+
}
20+

0 commit comments

Comments
 (0)