Skip to content

Commit 16b3b33

Browse files
committed
Check reference guard once
1 parent b9e3de0 commit 16b3b33

File tree

3 files changed

+55
-13
lines changed

3 files changed

+55
-13
lines changed

ext/opcache/Optimizer/zend_ssa.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ typedef struct _zend_ssa_var_info {
129129
unsigned int use_as_double : 1;
130130
unsigned int delayed_fetch_this : 1;
131131
unsigned int avoid_refcounting : 1;
132+
unsigned int guarded_reference : 1;
132133
} zend_ssa_var_info;
133134

134135
typedef struct _zend_ssa {

ext/opcache/jit/zend_jit_trace.c

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3499,9 +3499,14 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
34993499
op1_addr = OP1_REG_ADDR();
35003500
if (orig_op1_type != IS_UNKNOWN
35013501
&& (orig_op1_type & IS_TRACE_REFERENCE)) {
3502-
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 1)) {
3502+
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr,
3503+
!ssa->var_info[ssa_op->op1_use].guarded_reference, 1)) {
35033504
goto jit_failure;
35043505
}
3506+
if (opline->op1_type == IS_CV
3507+
&& !zend_jit_var_may_be_modified_indirectly(op_array, op_array_ssa, EX_VAR_TO_NUM(opline->op1.var))) {
3508+
ssa->var_info[ssa_op->op1_use].guarded_reference = 1;
3509+
}
35053510
} else {
35063511
CHECK_OP1_TRACE_TYPE();
35073512
}
@@ -3525,9 +3530,14 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
35253530
op1_addr = OP1_REG_ADDR();
35263531
if (orig_op1_type != IS_UNKNOWN
35273532
&& (orig_op1_type & IS_TRACE_REFERENCE)) {
3528-
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 1)) {
3533+
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr,
3534+
!ssa->var_info[ssa_op->op1_use].guarded_reference, 1)) {
35293535
goto jit_failure;
35303536
}
3537+
if (opline->op1_type == IS_CV
3538+
&& !zend_jit_var_may_be_modified_indirectly(op_array, op_array_ssa, EX_VAR_TO_NUM(opline->op1.var))) {
3539+
ssa->var_info[ssa_op->op1_use].guarded_reference = 1;
3540+
}
35313541
} else {
35323542
CHECK_OP1_TRACE_TYPE();
35333543
}
@@ -3568,9 +3578,14 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
35683578
op1_def_addr = OP1_DEF_REG_ADDR();
35693579
if (orig_op1_type != IS_UNKNOWN) {
35703580
if (orig_op1_type & IS_TRACE_REFERENCE) {
3571-
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 0)) {
3581+
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr,
3582+
!ssa->var_info[ssa_op->op1_use].guarded_reference, 0)) {
35723583
goto jit_failure;
35733584
}
3585+
if (opline->op1_type == IS_CV
3586+
&& !zend_jit_var_may_be_modified_indirectly(op_array, op_array_ssa, EX_VAR_TO_NUM(opline->op1.var))) {
3587+
ssa->var_info[ssa_op->op1_use].guarded_reference = 1;
3588+
}
35743589
if (!zend_jit_assign_to_typed_ref(&dasm_state, opline, opline->op2_type, op2_addr, 1)) {
35753590
goto jit_failure;
35763591
}
@@ -4009,9 +4024,14 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
40094024
op1_addr = OP1_REG_ADDR();
40104025
if (orig_op1_type != IS_UNKNOWN
40114026
&& (orig_op1_type & IS_TRACE_REFERENCE)) {
4012-
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 1)) {
4027+
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr,
4028+
!ssa->var_info[ssa_op->op1_use].guarded_reference, 1)) {
40134029
goto jit_failure;
40144030
}
4031+
if (opline->op1_type == IS_CV
4032+
&& !zend_jit_var_may_be_modified_indirectly(op_array, op_array_ssa, EX_VAR_TO_NUM(opline->op1.var))) {
4033+
ssa->var_info[ssa_op->op1_use].guarded_reference = 1;
4034+
}
40154035
} else {
40164036
CHECK_OP1_TRACE_TYPE();
40174037
}
@@ -4049,9 +4069,14 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
40494069
op1_addr = OP1_REG_ADDR();
40504070
if (orig_op1_type != IS_UNKNOWN
40514071
&& (orig_op1_type & IS_TRACE_REFERENCE)) {
4052-
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 1)) {
4072+
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr,
4073+
!ssa->var_info[ssa_op->op1_use].guarded_reference, 1)) {
40534074
goto jit_failure;
40544075
}
4076+
if (opline->op1_type == IS_CV
4077+
&& !zend_jit_var_may_be_modified_indirectly(op_array, op_array_ssa, EX_VAR_TO_NUM(opline->op1.var))) {
4078+
ssa->var_info[ssa_op->op1_use].guarded_reference = 1;
4079+
}
40554080
} else {
40564081
CHECK_OP1_TRACE_TYPE();
40574082
}
@@ -4091,9 +4116,14 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
40914116
op1_addr = OP1_REG_ADDR();
40924117
if (orig_op1_type != IS_UNKNOWN
40934118
&& (orig_op1_type & IS_TRACE_REFERENCE)) {
4094-
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 1)) {
4119+
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr,
4120+
!ssa->var_info[ssa_op->op1_use].guarded_reference, 1)) {
40954121
goto jit_failure;
40964122
}
4123+
if (opline->op1_type == IS_CV
4124+
&& !zend_jit_var_may_be_modified_indirectly(op_array, op_array_ssa, EX_VAR_TO_NUM(opline->op1.var))) {
4125+
ssa->var_info[ssa_op->op1_use].guarded_reference = 1;
4126+
}
40974127
} else {
40984128
CHECK_OP1_TRACE_TYPE();
40994129
}
@@ -4187,9 +4217,14 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
41874217
}
41884218
if (orig_op1_type != IS_UNKNOWN
41894219
&& (orig_op1_type & IS_TRACE_REFERENCE)) {
4190-
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 1)) {
4220+
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr,
4221+
!ssa->var_info[ssa_op->op1_use].guarded_reference, 1)) {
41914222
goto jit_failure;
41924223
}
4224+
if (opline->op1_type == IS_CV
4225+
&& !zend_jit_var_may_be_modified_indirectly(op_array, op_array_ssa, EX_VAR_TO_NUM(opline->op1.var))) {
4226+
ssa->var_info[ssa_op->op1_use].guarded_reference = 1;
4227+
}
41934228
} else {
41944229
CHECK_OP1_TRACE_TYPE();
41954230
}

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12477,18 +12477,24 @@ static zend_bool zend_jit_noref_guard(dasm_State **Dst, const zend_op *opline, z
1247712477
return 1;
1247812478
}
1247912479

12480-
static zend_bool zend_jit_fetch_reference(dasm_State **Dst, const zend_op *opline, uint8_t var_type, uint32_t *var_info_ptr, zend_jit_addr *var_addr_ptr, zend_bool add_type_guard)
12480+
static zend_bool zend_jit_fetch_reference(dasm_State **Dst, const zend_op *opline, uint8_t var_type, uint32_t *var_info_ptr, zend_jit_addr *var_addr_ptr, zend_bool add_ref_guard, zend_bool add_type_guard)
1248112481
{
1248212482
zend_jit_addr var_addr = *var_addr_ptr;
1248312483
uint32_t var_info = *var_info_ptr;
12484-
int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0);
12485-
const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
12484+
const void *exit_addr = NULL;
1248612485

12487-
if (!exit_addr) {
12488-
return 0;
12486+
if (add_ref_guard || add_type_guard) {
12487+
int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0);
12488+
12489+
exit_addr = zend_jit_trace_get_exit_addr(exit_point);
12490+
if (!exit_addr) {
12491+
return 0;
12492+
}
1248912493
}
1249012494

12491-
| IF_NOT_ZVAL_TYPE var_addr, IS_REFERENCE, &exit_addr
12495+
if (add_ref_guard) {
12496+
| IF_NOT_ZVAL_TYPE var_addr, IS_REFERENCE, &exit_addr
12497+
}
1249212498
| GET_ZVAL_PTR FCARG1a, var_addr
1249312499

1249412500
var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, offsetof(zend_reference, val));

0 commit comments

Comments
 (0)