Skip to content

Commit d384537

Browse files
committed
Move AVOID_REFCOUNTING type info flag into a separate bit
1 parent ecf4e70 commit d384537

File tree

5 files changed

+69
-27
lines changed

5 files changed

+69
-27
lines changed

ext/opcache/Optimizer/zend_inference.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
/* Bitmask for type inference (zend_ssa_var_info.type) */
2727
#include "zend_type_info.h"
2828

29-
#define AVOID_REFCOUNTING (1<<26) /* avoid reference counting */
3029
#define MAY_BE_CLASS_GUARD (1<<27) /* needs class guard */
3130
#define MAY_BE_GUARD (1<<28) /* needs type guard */
3231
#define MAY_BE_IN_REG (1<<29) /* value allocated in CPU register */

ext/opcache/Optimizer/zend_ssa.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ typedef struct _zend_ssa_var_info {
128128
unsigned int recursive : 1;
129129
unsigned int use_as_double : 1;
130130
unsigned int delayed_fetch_this : 1;
131+
unsigned int avoid_refcounting : 1;
131132
} zend_ssa_var_info;
132133

133134
typedef struct _zend_ssa {

ext/opcache/jit/zend_jit.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2817,7 +2817,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
28172817
break;
28182818
}
28192819
if (!zend_jit_fetch_dim_read(&dasm_state, opline, ssa, ssa_op,
2820-
OP1_INFO(), OP1_REG_ADDR(), OP2_INFO(), RES_INFO(), RES_REG_ADDR(),
2820+
OP1_INFO(), OP1_REG_ADDR(), 0,
2821+
OP2_INFO(), RES_INFO(), RES_REG_ADDR(),
28212822
zend_may_throw(opline, ssa_op, op_array, ssa))) {
28222823
goto jit_failure;
28232824
}
@@ -2846,7 +2847,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
28462847
target_label = target_label2 = (uint32_t)-1;
28472848
}
28482849
if (!zend_jit_isset_isempty_dim(&dasm_state, opline,
2849-
OP1_INFO(), OP1_REG_ADDR(), OP2_INFO(),
2850+
OP1_INFO(), OP1_REG_ADDR(), 0,
2851+
OP2_INFO(),
28502852
zend_may_throw(opline, ssa_op, op_array, ssa),
28512853
smart_branch_opcode, target_label, target_label2,
28522854
NULL)) {
@@ -2886,7 +2888,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
28862888
}
28872889
}
28882890
if (!zend_jit_fetch_obj(&dasm_state, opline, op_array, ssa, ssa_op,
2889-
op1_info, op1_addr, 0, ce, ce_is_instanceof, 0, NULL,
2891+
op1_info, op1_addr, 0, ce, ce_is_instanceof, 0, 0, NULL,
28902892
zend_may_throw(opline, ssa_op, op_array, ssa))) {
28912893
goto jit_failure;
28922894
}

ext/opcache/jit/zend_jit_trace.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2895,6 +2895,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
28952895
zend_class_entry *ce;
28962896
zend_bool ce_is_instanceof;
28972897
zend_bool delayed_fetch_this = 0;
2898+
zend_bool avoid_refcounting = 0;
28982899
uint32_t i;
28992900
zend_jit_trace_stack_frame *frame, *top, *call;
29002901
zend_jit_trace_stack *stack;
@@ -4011,7 +4012,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
40114012
CHECK_OP2_TRACE_TYPE();
40124013
res_info = RES_INFO();
40134014
if (!zend_jit_fetch_dim_read(&dasm_state, opline, ssa, ssa_op,
4014-
op1_info, op1_addr, op2_info, res_info, RES_REG_ADDR(),
4015+
op1_info, op1_addr, ssa->var_info[ssa_op->op1_use].avoid_refcounting,
4016+
op2_info, res_info, RES_REG_ADDR(),
40154017
(
40164018
(op1_info & MAY_BE_ANY) != MAY_BE_ARRAY ||
40174019
(op2_info & (MAY_BE_ANY - (MAY_BE_LONG|MAY_BE_STRING))) != 0 ||
@@ -4052,7 +4054,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
40524054
if (ra) {
40534055
zend_jit_trace_clenup_stack(stack, opline, ssa_op, ssa, ra);
40544056
}
4055-
if (op1_info & AVOID_REFCOUNTING) {
4057+
if (ssa->var_info[ssa_op->op1_use].avoid_refcounting) {
40564058
/* Temporary reset ZREG_ZVAL_TRY_ADDREF */
40574059
zend_jit_trace_stack *stack = JIT_G(current_frame)->stack;
40584060
uint32_t old_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->op1.var));
@@ -4073,7 +4075,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
40734075
exit_addr = NULL;
40744076
}
40754077
if (!zend_jit_isset_isempty_dim(&dasm_state, opline,
4076-
op1_info, op1_addr, op2_info,
4078+
op1_info, op1_addr, ssa->var_info[ssa_op->op1_use].avoid_refcounting,
4079+
op2_info,
40774080
zend_may_throw_ex(opline, ssa_op, op_array, ssa, op1_info, op2_info),
40784081
smart_branch_opcode, -1, -1,
40794082
exit_addr)) {
@@ -4092,6 +4095,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
40924095
case ZEND_FETCH_OBJ_IS:
40934096
case ZEND_FETCH_OBJ_W:
40944097
delayed_fetch_this = 0;
4098+
avoid_refcounting = 0;
40954099
if (opline->op2_type != IS_CONST
40964100
|| Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING
40974101
|| Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') {
@@ -4140,11 +4144,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
41404144
}
41414145
if (ssa_op->op1_use >= 0) {
41424146
delayed_fetch_this = ssa->var_info[ssa_op->op1_use].delayed_fetch_this;
4147+
avoid_refcounting = ssa->var_info[ssa_op->op1_use].avoid_refcounting;
41434148
}
41444149
}
41454150
if (!zend_jit_fetch_obj(&dasm_state, opline, op_array, ssa, ssa_op,
41464151
op1_info, op1_addr, op1_indirect, ce, ce_is_instanceof,
4147-
delayed_fetch_this, op1_ce,
4152+
delayed_fetch_this, avoid_refcounting, op1_ce,
41484153
zend_may_throw_ex(opline, ssa_op, op_array, ssa, op1_info, MAY_BE_STRING))) {
41494154
goto jit_failure;
41504155
}
@@ -4353,7 +4358,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
43534358
if (opline->opcode == ZEND_FETCH_THIS
43544359
&& delayed_fetch_this) {
43554360
SET_STACK_REG(stack, EX_VAR_TO_NUM(opline->result.var), ZREG_THIS);
4356-
} else if (ssa->var_info[ssa_op->result_def].type & AVOID_REFCOUNTING) {
4361+
} else if (ssa->var_info[ssa_op->result_def].avoid_refcounting) {
43574362
SET_STACK_REG(stack, EX_VAR_TO_NUM(opline->result.var), ZREG_ZVAL_TRY_ADDREF);
43584363
} else if (ra && ra[ssa_op->result_def]) {
43594364
SET_STACK_REG(stack, EX_VAR_TO_NUM(opline->result.var), ra[ssa_op->result_def]->reg);

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10479,12 +10479,23 @@ static zend_bool zend_jit_may_avoid_refcounting(const zend_op *opline)
1047910479
return 0;
1048010480
}
1048110481

10482-
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)
10482+
static int zend_jit_fetch_dim_read(dasm_State **Dst,
10483+
const zend_op *opline,
10484+
zend_ssa *ssa,
10485+
const zend_ssa_op *ssa_op,
10486+
uint32_t op1_info,
10487+
zend_jit_addr op1_addr,
10488+
zend_bool op1_avoid_refcounting,
10489+
uint32_t op2_info,
10490+
uint32_t res_info,
10491+
zend_jit_addr res_addr,
10492+
int may_throw)
1048310493
{
1048410494
zend_jit_addr orig_op1_addr, op2_addr;
1048510495
const void *exit_addr = NULL;
1048610496
const void *not_found_exit_addr = NULL;
1048710497
const void *res_exit_addr = NULL;
10498+
zend_bool result_avoid_refcounting = 0;
1048810499

1048910500
orig_op1_addr = OP1_ADDR();
1049010501
op2_addr = OP2_ADDR();
@@ -10498,7 +10509,7 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, zend
1049810509
}
1049910510
}
1050010511

10501-
if (op1_info & AVOID_REFCOUNTING) {
10512+
if (op1_avoid_refcounting) {
1050210513
SET_STACK_REG(JIT_G(current_frame)->stack,
1050310514
EX_VAR_TO_NUM(opline->op1.var), ZREG_NONE);
1050410515
}
@@ -10512,7 +10523,7 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, zend
1051210523
int32_t exit_point;
1051310524

1051410525
if ((opline->op1_type & (IS_VAR|IS_TMP_VAR))
10515-
&& !(op1_info & AVOID_REFCOUNTING)) {
10526+
&& !op1_avoid_refcounting) {
1051610527
flags |= ZEND_JIT_EXIT_FREE_OP1;
1051710528
}
1051810529
if ((opline->op2_type & (IS_VAR|IS_TMP_VAR))
@@ -10524,8 +10535,8 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, zend
1052410535
&& (ssa_op+1)->op1_use == ssa_op->result_def
1052510536
&& !(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF) - (MAY_BE_STRING|MAY_BE_LONG)))
1052610537
&& zend_jit_may_avoid_refcounting(opline+1)) {
10527-
res_info |= AVOID_REFCOUNTING;
10528-
ssa->var_info[ssa_op->result_def].type |= AVOID_REFCOUNTING;
10538+
result_avoid_refcounting = 1;
10539+
ssa->var_info[ssa_op->result_def].avoid_refcounting = 1;
1052910540
}
1053010541

1053110542
if (!(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF) - (MAY_BE_STRING|MAY_BE_LONG)))) {
@@ -10722,7 +10733,7 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, zend
1072210733
| SET_ZVAL_TYPE_INFO res_addr, type
1072310734
} else {
1072410735
| SET_ZVAL_TYPE_INFO res_addr, edx
10725-
if (!(res_info & AVOID_REFCOUNTING)) {
10736+
if (!result_avoid_refcounting) {
1072610737
| TRY_ADDREF res_info, dh, r1
1072710738
}
1072810739
}
@@ -10751,7 +10762,7 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, zend
1075110762
#endif
1075210763

1075310764
| FREE_OP opline->op2_type, opline->op2, op2_info, 0, opline
10754-
if (!(op1_info & AVOID_REFCOUNTING)) {
10765+
if (!op1_avoid_refcounting) {
1075510766
| FREE_OP opline->op1_type, opline->op1, op1_info, 0, opline
1075610767
}
1075710768

@@ -10764,7 +10775,17 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, zend
1076410775
return 1;
1076510776
}
1076610777

10767-
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)
10778+
static int zend_jit_isset_isempty_dim(dasm_State **Dst,
10779+
const zend_op *opline,
10780+
uint32_t op1_info,
10781+
zend_jit_addr op1_addr,
10782+
zend_bool op1_avoid_refcounting,
10783+
uint32_t op2_info,
10784+
int may_throw,
10785+
zend_uchar smart_branch_opcode,
10786+
uint32_t target_label,
10787+
uint32_t target_label2,
10788+
const void *exit_addr)
1076810789
{
1076910790
zend_jit_addr op2_addr, res_addr;
1077010791

@@ -10791,7 +10812,7 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst, const zend_op *opline, u
1079110812
if (exit_addr
1079210813
&& !(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_ARRAY))
1079310814
&& !may_throw
10794-
&& (!(opline->op1_type & (IS_TMP_VAR|IS_VAR)) || (op1_info & AVOID_REFCOUNTING))
10815+
&& (!(opline->op1_type & (IS_TMP_VAR|IS_VAR)) || op1_avoid_refcounting)
1079510816
&& (!(opline->op2_type & (IS_TMP_VAR|IS_VAR)) || !(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_LONG)))) {
1079610817
if (smart_branch_opcode == ZEND_JMPNZ) {
1079710818
found_exit_addr = exit_addr;
@@ -10859,7 +10880,7 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst, const zend_op *opline, u
1085910880

1086010881
|8:
1086110882
| FREE_OP opline->op2_type, opline->op2, op2_info, 0, opline
10862-
if (!(op1_info & AVOID_REFCOUNTING)) {
10883+
if (!op1_avoid_refcounting) {
1086310884
| FREE_OP opline->op1_type, opline->op1, op1_info, 0, opline
1086410885
}
1086510886
if (may_throw) {
@@ -10895,7 +10916,7 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst, const zend_op *opline, u
1089510916

1089610917
|9: // not found
1089710918
| FREE_OP opline->op2_type, opline->op2, op2_info, 0, opline
10898-
if (!(op1_info & AVOID_REFCOUNTING)) {
10919+
if (!op1_avoid_refcounting) {
1089910920
| FREE_OP opline->op1_type, opline->op1, op1_info, 0, opline
1090010921
}
1090110922
if (may_throw) {
@@ -11320,7 +11341,20 @@ static int zend_jit_class_guard(dasm_State **Dst, const zend_op *opline, zend_cl
1132011341
return 1;
1132111342
}
1132211343

11323-
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)
11344+
static int zend_jit_fetch_obj(dasm_State **Dst,
11345+
const zend_op *opline,
11346+
const zend_op_array *op_array,
11347+
zend_ssa *ssa,
11348+
const zend_ssa_op *ssa_op,
11349+
uint32_t op1_info,
11350+
zend_jit_addr op1_addr,
11351+
zend_bool op1_indirect,
11352+
zend_class_entry *ce,
11353+
zend_bool ce_is_instanceof,
11354+
zend_bool use_this,
11355+
zend_bool op1_avoid_refcounting,
11356+
zend_class_entry *trace_ce,
11357+
int may_throw)
1132411358
{
1132511359
zval *member;
1132611360
zend_property_info *prop_info;
@@ -11494,7 +11528,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zen
1149411528
}
1149511529
}
1149611530
}
11497-
if (op1_info & AVOID_REFCOUNTING) {
11531+
if (op1_avoid_refcounting) {
1149811532
SET_STACK_REG(JIT_G(current_frame)->stack,
1149911533
EX_VAR_TO_NUM(opline->op1.var), ZREG_NONE);
1150011534
}
@@ -11506,6 +11540,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zen
1150611540
| SET_ZVAL_TYPE_INFO res_addr, IS_INDIRECT
1150711541
} else {
1150811542
uint32_t res_info = RES_INFO();
11543+
zend_bool result_avoid_refcounting = 0;
1150911544

1151011545
if ((res_info & MAY_BE_GUARD) && JIT_G(current_frame) && prop_info) {
1151111546
uint32_t flags = 0;
@@ -11518,7 +11553,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zen
1151811553

1151911554
if ((opline->op1_type & (IS_VAR|IS_TMP_VAR))
1152011555
&& !use_this
11521-
&& !(op1_info & AVOID_REFCOUNTING)) {
11556+
&& !op1_avoid_refcounting) {
1152211557
flags = ZEND_JIT_EXIT_FREE_OP1;
1152311558
}
1152411559

@@ -11528,8 +11563,8 @@ static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zen
1152811563
&& (res_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))
1152911564
&& (ssa_op+1)->op1_use == ssa_op->result_def
1153011565
&& zend_jit_may_avoid_refcounting(opline+1)) {
11531-
res_info |= AVOID_REFCOUNTING;
11532-
ssa->var_info[ssa_op->result_def].type |= AVOID_REFCOUNTING;
11566+
result_avoid_refcounting = 1;
11567+
ssa->var_info[ssa_op->result_def].avoid_refcounting = 1;
1153311568
}
1153411569

1153511570
old_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->result.var));
@@ -11564,7 +11599,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zen
1156411599
| SET_ZVAL_TYPE_INFO res_addr, type
1156511600
} else {
1156611601
| SET_ZVAL_TYPE_INFO res_addr, edx
11567-
if (!(res_info & AVOID_REFCOUNTING)) {
11602+
if (!result_avoid_refcounting) {
1156811603
| TRY_ADDREF res_info, dh, r1
1156911604
}
1157011605
}
@@ -11652,7 +11687,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst, const zend_op *opline, const zen
1165211687
| SAVE_VALID_OPLINE opline, r0
1165311688
| EXT_CALL zend_jit_extract_helper, r0
1165411689
|1:
11655-
} else if (!(op1_info & AVOID_REFCOUNTING)) {
11690+
} else if (!op1_avoid_refcounting) {
1165611691
| FREE_OP opline->op1_type, opline->op1, op1_info, 1, opline
1165711692
}
1165811693
}

0 commit comments

Comments
 (0)