Skip to content

Commit 8e00da3

Browse files
committed
Merge branch 'PHP-8.1'
* PHP-8.1: JIT: Fix memory leak
2 parents de7e23a + f67986a commit 8e00da3

File tree

5 files changed

+94
-8
lines changed

5 files changed

+94
-8
lines changed

ext/opcache/jit/zend_jit_arm64.dasc

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6320,7 +6320,12 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
63206320
| LOAD_ZVAL_ADDR FCARG2x, op3_addr
63216321
| LOAD_ADDR CARG3, binary_op
63226322
| SET_EX_OPLINE opline, REG0
6323-
| EXT_CALL zend_jit_assign_op_to_typed_ref, REG0
6323+
if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR))
6324+
&& (op1_data_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
6325+
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, REG0
6326+
} else {
6327+
| EXT_CALL zend_jit_assign_op_to_typed_ref, REG0
6328+
}
63246329
| b >9
63256330
|.code
63266331
|1:
@@ -6441,7 +6446,12 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, uint32_t
64416446
| LOAD_ZVAL_ADDR FCARG2x, op2_addr
64426447
| LOAD_ADDR CARG3, binary_op
64436448
| SET_EX_OPLINE opline, REG0
6444-
| EXT_CALL zend_jit_assign_op_to_typed_ref, REG0
6449+
if ((opline->op2_type & (IS_TMP_VAR|IS_VAR))
6450+
&& (op2_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
6451+
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, REG0
6452+
} else {
6453+
| EXT_CALL zend_jit_assign_op_to_typed_ref, REG0
6454+
}
64456455
zend_jit_check_exception(Dst);
64466456
| b >9
64476457
|.code
@@ -13088,7 +13098,12 @@ static int zend_jit_assign_obj_op(dasm_State **Dst,
1308813098
| LOAD_ZVAL_ADDR FCARG2x, val_addr
1308913099
}
1309013100
| LOAD_ADDR CARG3, binary_op
13091-
| EXT_CALL zend_jit_assign_op_to_typed_ref, REG0
13101+
if ((opline->op2_type & (IS_TMP_VAR|IS_VAR))
13102+
&& (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
13103+
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, REG0
13104+
} else {
13105+
| EXT_CALL zend_jit_assign_op_to_typed_ref, REG0
13106+
}
1309213107
| b >9
1309313108
|.code
1309413109

@@ -13149,7 +13164,12 @@ static int zend_jit_assign_obj_op(dasm_State **Dst,
1314913164
| SET_EX_OPLINE opline, REG0
1315013165
}
1315113166
| LOAD_ADDR CARG3, binary_op
13152-
| EXT_CALL zend_jit_assign_op_to_typed_ref, REG0
13167+
if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR))
13168+
&& (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
13169+
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, REG0
13170+
} else {
13171+
| EXT_CALL zend_jit_assign_op_to_typed_ref, REG0
13172+
}
1315313173
| b >9
1315413174
|.code
1315513175
|2:

ext/opcache/jit/zend_jit_disasm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@ static int zend_jit_disasm_init(void)
664664
REGISTER_HELPER(zend_jit_post_inc_typed_ref);
665665
REGISTER_HELPER(zend_jit_post_dec_typed_ref);
666666
REGISTER_HELPER(zend_jit_assign_op_to_typed_ref);
667+
REGISTER_HELPER(zend_jit_assign_op_to_typed_ref_tmp);
667668
REGISTER_HELPER(zend_jit_only_vars_by_reference);
668669
REGISTER_HELPER(zend_jit_invalid_array_access);
669670
REGISTER_HELPER(zend_jit_invalid_property_read);

ext/opcache/jit/zend_jit_helpers.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2316,6 +2316,20 @@ static void ZEND_FASTCALL zend_jit_assign_op_to_typed_ref(zend_reference *ref, z
23162316
}
23172317
}
23182318

2319+
static void ZEND_FASTCALL zend_jit_assign_op_to_typed_ref_tmp(zend_reference *ref, zval *val, binary_op_type binary_op)
2320+
{
2321+
zval z_copy;
2322+
2323+
binary_op(&z_copy, &ref->val, val);
2324+
if (EXPECTED(zend_verify_ref_assignable_zval(ref, &z_copy, ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data))))) {
2325+
zval_ptr_dtor(&ref->val);
2326+
ZVAL_COPY_VALUE(&ref->val, &z_copy);
2327+
} else {
2328+
zval_ptr_dtor(&z_copy);
2329+
}
2330+
zval_ptr_dtor_nogc(val);
2331+
}
2332+
23192333
static void ZEND_FASTCALL zend_jit_only_vars_by_reference(zval *arg)
23202334
{
23212335
ZVAL_NEW_REF(arg, arg);

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6858,7 +6858,12 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
68586858
| PUSH_ADDR binary_op, r0
68596859
|.endif
68606860
| SET_EX_OPLINE opline, r0
6861-
| EXT_CALL zend_jit_assign_op_to_typed_ref, r0
6861+
if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR))
6862+
&& (op1_data_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
6863+
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, r0
6864+
} else {
6865+
| EXT_CALL zend_jit_assign_op_to_typed_ref, r0
6866+
}
68626867
|.if not(X64)
68636868
| add r4, 12
68646869
|.endif
@@ -6996,7 +7001,12 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, uint32_t
69967001
| PUSH_ADDR binary_op, r0
69977002
|.endif
69987003
| SET_EX_OPLINE opline, r0
6999-
| EXT_CALL zend_jit_assign_op_to_typed_ref, r0
7004+
if ((opline->op2_type & (IS_TMP_VAR|IS_VAR))
7005+
&& (op2_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
7006+
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, r0
7007+
} else {
7008+
| EXT_CALL zend_jit_assign_op_to_typed_ref, r0
7009+
}
70007010
|.if not(X64)
70017011
| add r4, 12
70027012
|.endif
@@ -13863,7 +13873,12 @@ static int zend_jit_assign_obj_op(dasm_State **Dst,
1386313873
| sub r4, 12
1386413874
| PUSH_ADDR binary_op, r0
1386513875
|.endif
13866-
| EXT_CALL zend_jit_assign_op_to_typed_ref, r0
13876+
if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR))
13877+
&& (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
13878+
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, r0
13879+
} else {
13880+
| EXT_CALL zend_jit_assign_op_to_typed_ref, r0
13881+
}
1386713882
|.if not(X64)
1386813883
| add r4, 12
1386913884
|.endif
@@ -13942,7 +13957,12 @@ static int zend_jit_assign_obj_op(dasm_State **Dst,
1394213957
| sub r4, 12
1394313958
| PUSH_ADDR binary_op, r0
1394413959
|.endif
13945-
| EXT_CALL zend_jit_assign_op_to_typed_ref, r0
13960+
if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR))
13961+
&& (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
13962+
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, r0
13963+
} else {
13964+
| EXT_CALL zend_jit_assign_op_to_typed_ref, r0
13965+
}
1394613966
|.if not(X64)
1394713967
| add r4, 12
1394813968
|.endif
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
JIT ASSIGN_OBJ_OP: memory leak
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+
class A {
11+
public string $prop = "222";
12+
}
13+
14+
class B {
15+
public function __toString() {
16+
global $a;
17+
$a->prop .= $a->prop . "leak";
18+
return "test";
19+
}
20+
}
21+
22+
$a = new A;
23+
$prop = &$a->prop;
24+
$a->prop = new B;
25+
var_dump($a);
26+
?>
27+
--EXPECT--
28+
object(A)#1 (1) {
29+
["prop"]=>
30+
&string(4) "test"
31+
}

0 commit comments

Comments
 (0)