Skip to content

Commit 4337cc5

Browse files
committed
Improve ASSIGN_OBJ[_REF] RC inference
* ASSIGN_OBJ may only modify RC if it implements __set. * ASSIGN_OBJ_REF does not call __set, and thus may not modify RC.
1 parent ea3c541 commit 4337cc5

File tree

2 files changed

+18
-19
lines changed

2 files changed

+18
-19
lines changed

Zend/Optimizer/zend_inference.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3022,16 +3022,29 @@ static zend_always_inline zend_result _zend_update_type_info(
30223022
UPDATE_SSA_TYPE(tmp, ssa_op->op1_def);
30233023
}
30243024
break;
3025-
case ZEND_ASSIGN_OBJ:
3025+
case ZEND_ASSIGN_OBJ: {
3026+
const zend_property_info *prop_info = NULL;
30263027
if (opline->op1_type == IS_CV) {
3027-
tmp = (t1 & (MAY_BE_REF|MAY_BE_OBJECT))|MAY_BE_RC1|MAY_BE_RCN;
3028+
bool add_rc = false;
3029+
if (t1 & MAY_BE_OBJECT) {
3030+
prop_info = zend_fetch_prop_info(op_array, ssa, opline, ssa_op);
3031+
if (!prop_info) {
3032+
zend_class_entry *ce = ssa_var_info[ssa_op->op1_use].ce;
3033+
if (!ce || ce->__set || !(ce->ce_flags & ZEND_ACC_FINAL)) {
3034+
add_rc = true;
3035+
}
3036+
}
3037+
}
3038+
tmp = (t1 & (MAY_BE_REF|MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN))|(add_rc ? (MAY_BE_RC1|MAY_BE_RCN) : 0);
30283039
UPDATE_SSA_TYPE(tmp, ssa_op->op1_def);
30293040
COPY_SSA_OBJ_TYPE(ssa_op->op1_use, ssa_op->op1_def);
30303041
}
30313042
if (ssa_op->result_def >= 0) {
30323043
// TODO: If there is no __set we might do better
3033-
tmp = zend_fetch_prop_type(script,
3034-
zend_fetch_prop_info(op_array, ssa, opline, ssa_op), &ce);
3044+
if (!prop_info) {
3045+
prop_info = zend_fetch_prop_info(op_array, ssa, opline, ssa_op);
3046+
}
3047+
tmp = zend_fetch_prop_type(script, prop_info, &ce);
30353048
UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
30363049
if (ce) {
30373050
UPDATE_SSA_OBJ_TYPE(ce, 1, ssa_op->result_def);
@@ -3047,6 +3060,7 @@ static zend_always_inline zend_result _zend_update_type_info(
30473060
UPDATE_SSA_TYPE(tmp, ssa_op->op1_def);
30483061
}
30493062
break;
3063+
}
30503064
case ZEND_ASSIGN_STATIC_PROP:
30513065
if (ssa_op->result_def >= 0) {
30523066
tmp = MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_RC1 | MAY_BE_RCN;
@@ -3157,15 +3171,6 @@ static zend_always_inline zend_result _zend_update_type_info(
31573171
}
31583172
break;
31593173
case ZEND_ASSIGN_OBJ_REF:
3160-
if (opline->op1_type == IS_CV && ssa_op->op1_def >= 0) {
3161-
tmp = t1;
3162-
if (tmp & MAY_BE_OBJECT) {
3163-
tmp |= MAY_BE_RC1 | MAY_BE_RCN;
3164-
}
3165-
UPDATE_SSA_TYPE(tmp, ssa_op->op1_def);
3166-
COPY_SSA_OBJ_TYPE(ssa_op->op1_use, ssa_op->op1_def);
3167-
}
3168-
31693174
t2 = OP1_DATA_INFO();
31703175
if ((opline+1)->op1_type == IS_VAR && (opline->extended_value & ZEND_RETURNS_FUNCTION)) {
31713176
tmp = (MAY_BE_REF | MAY_BE_RCN | MAY_BE_RC1 | t2) & ~MAY_BE_UNDEF;

Zend/Optimizer/zend_ssa.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -607,12 +607,6 @@ static zend_always_inline int _zend_ssa_rename_op(const zend_op_array *op_array,
607607
}
608608
break;
609609
case ZEND_ASSIGN_OBJ_REF:
610-
if ((build_flags & ZEND_SSA_RC_INFERENCE) && opline->op1_type == IS_CV) {
611-
ssa_ops[k].op1_def = ssa_vars_count;
612-
var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
613-
ssa_vars_count++;
614-
//NEW_SSA_VAR(opline->op1.var)
615-
}
616610
next = opline + 1;
617611
if (next->op1_type & (IS_CV|IS_VAR|IS_TMP_VAR)) {
618612
ssa_ops[k + 1].op1_use = var[EX_VAR_TO_NUM(next->op1.var)];

0 commit comments

Comments
 (0)