Skip to content

Commit f67986a

Browse files
committed
Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0: JIT: Fix memory leak
2 parents 0a5162b + 70f7e7d commit f67986a

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
@@ -6325,7 +6325,12 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
63256325
| LOAD_ZVAL_ADDR FCARG2x, op3_addr
63266326
| LOAD_ADDR CARG3, binary_op
63276327
| SET_EX_OPLINE opline, REG0
6328-
| EXT_CALL zend_jit_assign_op_to_typed_ref, REG0
6328+
if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR))
6329+
&& (op1_data_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
6330+
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, REG0
6331+
} else {
6332+
| EXT_CALL zend_jit_assign_op_to_typed_ref, REG0
6333+
}
63296334
| b >9
63306335
|.code
63316336
|1:
@@ -6446,7 +6451,12 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, uint32_t
64466451
| LOAD_ZVAL_ADDR FCARG2x, op2_addr
64476452
| LOAD_ADDR CARG3, binary_op
64486453
| SET_EX_OPLINE opline, REG0
6449-
| EXT_CALL zend_jit_assign_op_to_typed_ref, REG0
6454+
if ((opline->op2_type & (IS_TMP_VAR|IS_VAR))
6455+
&& (op2_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
6456+
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, REG0
6457+
} else {
6458+
| EXT_CALL zend_jit_assign_op_to_typed_ref, REG0
6459+
}
64506460
zend_jit_check_exception(Dst);
64516461
| b >9
64526462
|.code
@@ -13231,7 +13241,12 @@ static int zend_jit_assign_obj_op(dasm_State **Dst,
1323113241
| LOAD_ZVAL_ADDR FCARG2x, val_addr
1323213242
}
1323313243
| LOAD_ADDR CARG3, binary_op
13234-
| EXT_CALL zend_jit_assign_op_to_typed_ref, REG0
13244+
if ((opline->op2_type & (IS_TMP_VAR|IS_VAR))
13245+
&& (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
13246+
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, REG0
13247+
} else {
13248+
| EXT_CALL zend_jit_assign_op_to_typed_ref, REG0
13249+
}
1323513250
| b >9
1323613251
|.code
1323713252

@@ -13292,7 +13307,12 @@ static int zend_jit_assign_obj_op(dasm_State **Dst,
1329213307
| SET_EX_OPLINE opline, REG0
1329313308
}
1329413309
| LOAD_ADDR CARG3, binary_op
13295-
| EXT_CALL zend_jit_assign_op_to_typed_ref, REG0
13310+
if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR))
13311+
&& (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
13312+
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, REG0
13313+
} else {
13314+
| EXT_CALL zend_jit_assign_op_to_typed_ref, REG0
13315+
}
1329613316
| b >9
1329713317
|.code
1329813318
|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
@@ -2321,6 +2321,20 @@ static void ZEND_FASTCALL zend_jit_assign_op_to_typed_ref(zend_reference *ref, z
23212321
}
23222322
}
23232323

2324+
static void ZEND_FASTCALL zend_jit_assign_op_to_typed_ref_tmp(zend_reference *ref, zval *val, binary_op_type binary_op)
2325+
{
2326+
zval z_copy;
2327+
2328+
binary_op(&z_copy, &ref->val, val);
2329+
if (EXPECTED(zend_verify_ref_assignable_zval(ref, &z_copy, ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data))))) {
2330+
zval_ptr_dtor(&ref->val);
2331+
ZVAL_COPY_VALUE(&ref->val, &z_copy);
2332+
} else {
2333+
zval_ptr_dtor(&z_copy);
2334+
}
2335+
zval_ptr_dtor_nogc(val);
2336+
}
2337+
23242338
static void ZEND_FASTCALL zend_jit_only_vars_by_reference(zval *arg)
23252339
{
23262340
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
@@ -6863,7 +6863,12 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
68636863
| PUSH_ADDR binary_op, r0
68646864
|.endif
68656865
| SET_EX_OPLINE opline, r0
6866-
| EXT_CALL zend_jit_assign_op_to_typed_ref, r0
6866+
if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR))
6867+
&& (op1_data_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
6868+
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, r0
6869+
} else {
6870+
| EXT_CALL zend_jit_assign_op_to_typed_ref, r0
6871+
}
68676872
|.if not(X64)
68686873
| add r4, 12
68696874
|.endif
@@ -7001,7 +7006,12 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, uint32_t
70017006
| PUSH_ADDR binary_op, r0
70027007
|.endif
70037008
| SET_EX_OPLINE opline, r0
7004-
| EXT_CALL zend_jit_assign_op_to_typed_ref, r0
7009+
if ((opline->op2_type & (IS_TMP_VAR|IS_VAR))
7010+
&& (op2_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
7011+
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, r0
7012+
} else {
7013+
| EXT_CALL zend_jit_assign_op_to_typed_ref, r0
7014+
}
70057015
|.if not(X64)
70067016
| add r4, 12
70077017
|.endif
@@ -14006,7 +14016,12 @@ static int zend_jit_assign_obj_op(dasm_State **Dst,
1400614016
| sub r4, 12
1400714017
| PUSH_ADDR binary_op, r0
1400814018
|.endif
14009-
| EXT_CALL zend_jit_assign_op_to_typed_ref, r0
14019+
if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR))
14020+
&& (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
14021+
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, r0
14022+
} else {
14023+
| EXT_CALL zend_jit_assign_op_to_typed_ref, r0
14024+
}
1401014025
|.if not(X64)
1401114026
| add r4, 12
1401214027
|.endif
@@ -14085,7 +14100,12 @@ static int zend_jit_assign_obj_op(dasm_State **Dst,
1408514100
| sub r4, 12
1408614101
| PUSH_ADDR binary_op, r0
1408714102
|.endif
14088-
| EXT_CALL zend_jit_assign_op_to_typed_ref, r0
14103+
if (((opline+1)->op1_type & (IS_TMP_VAR|IS_VAR))
14104+
&& (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) {
14105+
| EXT_CALL zend_jit_assign_op_to_typed_ref_tmp, r0
14106+
} else {
14107+
| EXT_CALL zend_jit_assign_op_to_typed_ref, r0
14108+
}
1408914109
|.if not(X64)
1409014110
| add r4, 12
1409114111
|.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)