Skip to content

Commit ff3c402

Browse files
committed
More accurate reference-counter inference
1 parent b35255a commit ff3c402

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

ext/opcache/Optimizer/zend_inference.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3398,10 +3398,26 @@ static zend_always_inline int _zend_update_type_info(
33983398
case ZEND_FETCH_OBJ_UNSET:
33993399
case ZEND_FETCH_OBJ_FUNC_ARG:
34003400
if (ssa_op->result_def >= 0) {
3401-
tmp = zend_fetch_prop_type(script,
3402-
zend_fetch_prop_info(op_array, ssa, opline, ssa_op), &ce);
3401+
zend_property_info *prop_info = zend_fetch_prop_info(op_array, ssa, opline, ssa_op);
3402+
3403+
tmp = zend_fetch_prop_type(script, prop_info, &ce);
34033404
if (opline->result_type != IS_TMP_VAR) {
34043405
tmp |= MAY_BE_REF | MAY_BE_INDIRECT;
3406+
} else if (prop_info) {
3407+
/* FETCH_OBJ_R/IS for plain property increments reference counter,
3408+
so it can't be 1 */
3409+
tmp &= ~MAY_BE_RC1;
3410+
} else {
3411+
zend_class_entry *ce = NULL;
3412+
3413+
if (opline->op1_type == IS_UNUSED) {
3414+
ce = op_array->scope;
3415+
} else if (ssa_op->op1_use >= 0 && !ssa->var_info[ssa_op->op1_use].is_instanceof) {
3416+
ce = ssa->var_info[ssa_op->op1_use].ce;
3417+
}
3418+
if (ce && !ce->create_object && !ce->__get) {
3419+
tmp &= ~MAY_BE_RC1;
3420+
}
34053421
}
34063422
UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
34073423
if (ce) {
@@ -3419,6 +3435,8 @@ static zend_always_inline int _zend_update_type_info(
34193435
zend_fetch_static_prop_info(script, op_array, ssa, opline), &ce);
34203436
if (opline->result_type != IS_TMP_VAR) {
34213437
tmp |= MAY_BE_REF | MAY_BE_INDIRECT;
3438+
} else {
3439+
tmp &= ~MAY_BE_RC1;
34223440
}
34233441
UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
34243442
if (ce) {
@@ -3523,7 +3541,11 @@ static zend_always_inline int _zend_update_type_info(
35233541
if (ssa_op->result_def >= 0) {
35243542
tmp = MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF;
35253543
if (opline->result_type == IS_TMP_VAR) {
3526-
tmp |= MAY_BE_RC1 | MAY_BE_RCN;
3544+
if (opline->opcode == ZEND_FETCH_R || opline->opcode == ZEND_FETCH_IS) {
3545+
tmp |= MAY_BE_RCN;
3546+
} else {
3547+
tmp |= MAY_BE_RC1 | MAY_BE_RCN;
3548+
}
35273549
} else {
35283550
tmp |= MAY_BE_REF | MAY_BE_RC1 | MAY_BE_RCN;
35293551
switch (opline->opcode) {

0 commit comments

Comments
 (0)