summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2020-07-06 15:53:28 +0300
committerDmitry Stogov <dmitry@zend.com>2020-07-06 15:53:28 +0300
commitb35255ad21a4e441f2304d944014c0649e37d712 (patch)
tree45649f9d04f9e8e82841c4789d57d00433ef7d88
parent48eb635a0f07000909f6f0c81850ef3fdea74ad7 (diff)
downloadphp-git-b35255ad21a4e441f2304d944014c0649e37d712.tar.gz
More accurate reference-counter inference
-rw-r--r--ext/opcache/Optimizer/zend_inference.c10
-rw-r--r--ext/opcache/jit/zend_jit_x86.dasc9
2 files changed, 13 insertions, 6 deletions
diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c
index e131a3ee58..0f79e92a9f 100644
--- a/ext/opcache/Optimizer/zend_inference.c
+++ b/ext/opcache/Optimizer/zend_inference.c
@@ -1972,15 +1972,15 @@ uint32_t zend_array_element_type(uint32_t t1, int write, int insert)
if (tmp & MAY_BE_ARRAY) {
tmp |= MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
}
- if (t1 & MAY_BE_ARRAY_OF_REF) {
+ if (tmp & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
if (!write) {
/* can't be REF because of ZVAL_COPY_DEREF() usage */
- tmp |= MAY_BE_RC1 | MAY_BE_RCN;
- } else {
+ tmp |= MAY_BE_RCN;
+ } else if (t1 & MAY_BE_ARRAY_OF_REF) {
tmp |= MAY_BE_REF | MAY_BE_RC1 | MAY_BE_RCN;
+ } else {
+ tmp |= MAY_BE_RC1 | MAY_BE_RCN;
}
- } else if (tmp & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
- tmp |= MAY_BE_RC1 | MAY_BE_RCN;
}
}
if (write) {
diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc
index e6be17a3c9..feabefba4d 100644
--- a/ext/opcache/jit/zend_jit_x86.dasc
+++ b/ext/opcache/jit/zend_jit_x86.dasc
@@ -5567,6 +5567,9 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, const ze
if (op1_info & (MAY_BE_ARRAY_OF_REF|MAY_BE_OBJECT)) {
var_info |= MAY_BE_REF;
}
+ if (var_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
+ var_info |= MAY_BE_RC1;
+ }
| // value = zend_assign_to_variable(variable_ptr, value, OP_DATA_TYPE);
if (!zend_jit_assign_to_variable(Dst, opline, op_array, var_addr, var_info, -1, (opline+1)->op1_type, (opline+1)->op1, op3_addr, val_info, res_addr, 0)) {
return 0;
@@ -5777,6 +5780,9 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, const
if (op1_info & (MAY_BE_ARRAY_OF_REF|MAY_BE_OBJECT)) {
var_info |= MAY_BE_REF;
}
+ if (var_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
+ var_info |= MAY_BE_RC1;
+ }
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_RW, op1_info, op2_info, 8, 8, NULL, NULL)) {
return 0;
@@ -11126,7 +11132,8 @@ static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zen
|9: // END
if (opline->op1_type != IS_UNUSED && !use_this && !op1_indirect) {
if (opline->op1_type == IS_VAR
- && opline->opcode == ZEND_FETCH_OBJ_W) {
+ && opline->opcode == ZEND_FETCH_OBJ_W
+ && (op1_info & MAY_BE_RC1)) {
zend_jit_addr orig_op1_addr = OP1_ADDR();
| IF_NOT_ZVAL_REFCOUNTED orig_op1_addr, >1