break;
}
if (!zend_jit_fetch_dim_read(&dasm_state, opline, ssa, ssa_op,
- OP1_INFO(), OP1_REG_ADDR(), OP2_INFO(), RES_INFO(), RES_REG_ADDR(),
+ OP1_INFO(), OP1_REG_ADDR(), 0,
+ OP2_INFO(), RES_INFO(), RES_REG_ADDR(),
zend_may_throw(opline, ssa_op, op_array, ssa))) {
goto jit_failure;
}
target_label = target_label2 = (uint32_t)-1;
}
if (!zend_jit_isset_isempty_dim(&dasm_state, opline,
- OP1_INFO(), OP1_REG_ADDR(), OP2_INFO(),
+ OP1_INFO(), OP1_REG_ADDR(), 0,
+ OP2_INFO(),
zend_may_throw(opline, ssa_op, op_array, ssa),
smart_branch_opcode, target_label, target_label2,
NULL)) {
}
}
if (!zend_jit_fetch_obj(&dasm_state, opline, op_array, ssa, ssa_op,
- op1_info, op1_addr, 0, ce, ce_is_instanceof, 0, NULL,
+ op1_info, op1_addr, 0, ce, ce_is_instanceof, 0, 0, NULL,
zend_may_throw(opline, ssa_op, op_array, ssa))) {
goto jit_failure;
}
zend_class_entry *ce;
zend_bool ce_is_instanceof;
zend_bool delayed_fetch_this = 0;
+ zend_bool avoid_refcounting = 0;
uint32_t i;
zend_jit_trace_stack_frame *frame, *top, *call;
zend_jit_trace_stack *stack;
CHECK_OP2_TRACE_TYPE();
res_info = RES_INFO();
if (!zend_jit_fetch_dim_read(&dasm_state, opline, ssa, ssa_op,
- op1_info, op1_addr, op2_info, res_info, RES_REG_ADDR(),
+ op1_info, op1_addr, ssa->var_info[ssa_op->op1_use].avoid_refcounting,
+ op2_info, res_info, RES_REG_ADDR(),
(
(op1_info & MAY_BE_ANY) != MAY_BE_ARRAY ||
(op2_info & (MAY_BE_ANY - (MAY_BE_LONG|MAY_BE_STRING))) != 0 ||
if (ra) {
zend_jit_trace_clenup_stack(stack, opline, ssa_op, ssa, ra);
}
- if (op1_info & AVOID_REFCOUNTING) {
+ if (ssa->var_info[ssa_op->op1_use].avoid_refcounting) {
/* Temporary reset ZREG_ZVAL_TRY_ADDREF */
zend_jit_trace_stack *stack = JIT_G(current_frame)->stack;
uint32_t old_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->op1.var));
exit_addr = NULL;
}
if (!zend_jit_isset_isempty_dim(&dasm_state, opline,
- op1_info, op1_addr, op2_info,
+ op1_info, op1_addr, ssa->var_info[ssa_op->op1_use].avoid_refcounting,
+ op2_info,
zend_may_throw_ex(opline, ssa_op, op_array, ssa, op1_info, op2_info),
smart_branch_opcode, -1, -1,
exit_addr)) {
case ZEND_FETCH_OBJ_IS:
case ZEND_FETCH_OBJ_W:
delayed_fetch_this = 0;
+ avoid_refcounting = 0;
if (opline->op2_type != IS_CONST
|| Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING
|| Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') {
}
if (ssa_op->op1_use >= 0) {
delayed_fetch_this = ssa->var_info[ssa_op->op1_use].delayed_fetch_this;
+ avoid_refcounting = ssa->var_info[ssa_op->op1_use].avoid_refcounting;
}
}
if (!zend_jit_fetch_obj(&dasm_state, opline, op_array, ssa, ssa_op,
op1_info, op1_addr, op1_indirect, ce, ce_is_instanceof,
- delayed_fetch_this, op1_ce,
+ delayed_fetch_this, avoid_refcounting, op1_ce,
zend_may_throw_ex(opline, ssa_op, op_array, ssa, op1_info, MAY_BE_STRING))) {
goto jit_failure;
}
if (opline->opcode == ZEND_FETCH_THIS
&& delayed_fetch_this) {
SET_STACK_REG(stack, EX_VAR_TO_NUM(opline->result.var), ZREG_THIS);
- } else if (ssa->var_info[ssa_op->result_def].type & AVOID_REFCOUNTING) {
+ } else if (ssa->var_info[ssa_op->result_def].avoid_refcounting) {
SET_STACK_REG(stack, EX_VAR_TO_NUM(opline->result.var), ZREG_ZVAL_TRY_ADDREF);
} else if (ra && ra[ssa_op->result_def]) {
SET_STACK_REG(stack, EX_VAR_TO_NUM(opline->result.var), ra[ssa_op->result_def]->reg);
return 0;
}
-static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, zend_ssa *ssa, const zend_ssa_op *ssa_op, uint32_t op1_info, zend_jit_addr op1_addr, uint32_t op2_info, uint32_t res_info, zend_jit_addr res_addr, int may_throw)
+static int zend_jit_fetch_dim_read(dasm_State **Dst,
+ const zend_op *opline,
+ zend_ssa *ssa,
+ const zend_ssa_op *ssa_op,
+ uint32_t op1_info,
+ zend_jit_addr op1_addr,
+ zend_bool op1_avoid_refcounting,
+ uint32_t op2_info,
+ uint32_t res_info,
+ zend_jit_addr res_addr,
+ int may_throw)
{
zend_jit_addr orig_op1_addr, op2_addr;
const void *exit_addr = NULL;
const void *not_found_exit_addr = NULL;
const void *res_exit_addr = NULL;
+ zend_bool result_avoid_refcounting = 0;
orig_op1_addr = OP1_ADDR();
op2_addr = OP2_ADDR();
}
}
- if (op1_info & AVOID_REFCOUNTING) {
+ if (op1_avoid_refcounting) {
SET_STACK_REG(JIT_G(current_frame)->stack,
EX_VAR_TO_NUM(opline->op1.var), ZREG_NONE);
}
int32_t exit_point;
if ((opline->op1_type & (IS_VAR|IS_TMP_VAR))
- && !(op1_info & AVOID_REFCOUNTING)) {
+ && !op1_avoid_refcounting) {
flags |= ZEND_JIT_EXIT_FREE_OP1;
}
if ((opline->op2_type & (IS_VAR|IS_TMP_VAR))
&& (ssa_op+1)->op1_use == ssa_op->result_def
&& !(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF) - (MAY_BE_STRING|MAY_BE_LONG)))
&& zend_jit_may_avoid_refcounting(opline+1)) {
- res_info |= AVOID_REFCOUNTING;
- ssa->var_info[ssa_op->result_def].type |= AVOID_REFCOUNTING;
+ result_avoid_refcounting = 1;
+ ssa->var_info[ssa_op->result_def].avoid_refcounting = 1;
}
if (!(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF) - (MAY_BE_STRING|MAY_BE_LONG)))) {
| SET_ZVAL_TYPE_INFO res_addr, type
} else {
| SET_ZVAL_TYPE_INFO res_addr, edx
- if (!(res_info & AVOID_REFCOUNTING)) {
+ if (!result_avoid_refcounting) {
| TRY_ADDREF res_info, dh, r1
}
}
#endif
| FREE_OP opline->op2_type, opline->op2, op2_info, 0, opline
- if (!(op1_info & AVOID_REFCOUNTING)) {
+ if (!op1_avoid_refcounting) {
| FREE_OP opline->op1_type, opline->op1, op1_info, 0, opline
}
return 1;
}
-static int zend_jit_isset_isempty_dim(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, zend_jit_addr op1_addr, uint32_t op2_info, int may_throw, zend_uchar smart_branch_opcode, uint32_t target_label, uint32_t target_label2, const void *exit_addr)
+static int zend_jit_isset_isempty_dim(dasm_State **Dst,
+ const zend_op *opline,
+ uint32_t op1_info,
+ zend_jit_addr op1_addr,
+ zend_bool op1_avoid_refcounting,
+ uint32_t op2_info,
+ int may_throw,
+ zend_uchar smart_branch_opcode,
+ uint32_t target_label,
+ uint32_t target_label2,
+ const void *exit_addr)
{
zend_jit_addr op2_addr, res_addr;
if (exit_addr
&& !(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_ARRAY))
&& !may_throw
- && (!(opline->op1_type & (IS_TMP_VAR|IS_VAR)) || (op1_info & AVOID_REFCOUNTING))
+ && (!(opline->op1_type & (IS_TMP_VAR|IS_VAR)) || op1_avoid_refcounting)
&& (!(opline->op2_type & (IS_TMP_VAR|IS_VAR)) || !(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_LONG)))) {
if (smart_branch_opcode == ZEND_JMPNZ) {
found_exit_addr = exit_addr;
|8:
| FREE_OP opline->op2_type, opline->op2, op2_info, 0, opline
- if (!(op1_info & AVOID_REFCOUNTING)) {
+ if (!op1_avoid_refcounting) {
| FREE_OP opline->op1_type, opline->op1, op1_info, 0, opline
}
if (may_throw) {
|9: // not found
| FREE_OP opline->op2_type, opline->op2, op2_info, 0, opline
- if (!(op1_info & AVOID_REFCOUNTING)) {
+ if (!op1_avoid_refcounting) {
| FREE_OP opline->op1_type, opline->op1, op1_info, 0, opline
}
if (may_throw) {
return 1;
}
-static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, zend_ssa *ssa, const zend_ssa_op *ssa_op, uint32_t op1_info, zend_jit_addr op1_addr, zend_bool op1_indirect, zend_class_entry *ce, zend_bool ce_is_instanceof, zend_bool use_this, zend_class_entry *trace_ce, int may_throw)
+static int zend_jit_fetch_obj(dasm_State **Dst,
+ const zend_op *opline,
+ const zend_op_array *op_array,
+ zend_ssa *ssa,
+ const zend_ssa_op *ssa_op,
+ uint32_t op1_info,
+ zend_jit_addr op1_addr,
+ zend_bool op1_indirect,
+ zend_class_entry *ce,
+ zend_bool ce_is_instanceof,
+ zend_bool use_this,
+ zend_bool op1_avoid_refcounting,
+ zend_class_entry *trace_ce,
+ int may_throw)
{
zval *member;
zend_property_info *prop_info;
}
}
}
- if (op1_info & AVOID_REFCOUNTING) {
+ if (op1_avoid_refcounting) {
SET_STACK_REG(JIT_G(current_frame)->stack,
EX_VAR_TO_NUM(opline->op1.var), ZREG_NONE);
}
| SET_ZVAL_TYPE_INFO res_addr, IS_INDIRECT
} else {
uint32_t res_info = RES_INFO();
+ zend_bool result_avoid_refcounting = 0;
if ((res_info & MAY_BE_GUARD) && JIT_G(current_frame) && prop_info) {
uint32_t flags = 0;
if ((opline->op1_type & (IS_VAR|IS_TMP_VAR))
&& !use_this
- && !(op1_info & AVOID_REFCOUNTING)) {
+ && !op1_avoid_refcounting) {
flags = ZEND_JIT_EXIT_FREE_OP1;
}
&& (res_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))
&& (ssa_op+1)->op1_use == ssa_op->result_def
&& zend_jit_may_avoid_refcounting(opline+1)) {
- res_info |= AVOID_REFCOUNTING;
- ssa->var_info[ssa_op->result_def].type |= AVOID_REFCOUNTING;
+ result_avoid_refcounting = 1;
+ ssa->var_info[ssa_op->result_def].avoid_refcounting = 1;
}
old_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->result.var));
| SET_ZVAL_TYPE_INFO res_addr, type
} else {
| SET_ZVAL_TYPE_INFO res_addr, edx
- if (!(res_info & AVOID_REFCOUNTING)) {
+ if (!result_avoid_refcounting) {
| TRY_ADDREF res_info, dh, r1
}
}
| SAVE_VALID_OPLINE opline, r0
| EXT_CALL zend_jit_extract_helper, r0
|1:
- } else if (!(op1_info & AVOID_REFCOUNTING)) {
+ } else if (!op1_avoid_refcounting) {
| FREE_OP opline->op1_type, opline->op1, op1_info, 1, opline
}
}