Skip to content

Commit 3830855

Browse files
committed
Tracing JIT support for PHP references in ASSIGN instruction
1 parent 5aa649c commit 3830855

File tree

2 files changed

+44
-9
lines changed

2 files changed

+44
-9
lines changed

ext/opcache/jit/zend_jit_trace.c

+25-7
Original file line numberDiff line numberDiff line change
@@ -3156,7 +3156,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
31563156
op1_addr = OP1_REG_ADDR();
31573157
if (orig_op1_type != IS_UNKNOWN
31583158
&& (orig_op1_type & IS_TRACE_REFERENCE)) {
3159-
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr)) {
3159+
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 1)) {
31603160
goto jit_failure;
31613161
}
31623162
} else {
@@ -3182,7 +3182,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
31823182
op1_addr = OP1_REG_ADDR();
31833183
if (orig_op1_type != IS_UNKNOWN
31843184
&& (orig_op1_type & IS_TRACE_REFERENCE)) {
3185-
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr)) {
3185+
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 1)) {
31863186
goto jit_failure;
31873187
}
31883188
} else {
@@ -3221,10 +3221,28 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
32213221
CHECK_OP2_TRACE_TYPE();
32223222
op1_info = OP1_INFO();
32233223
op1_def_info = OP1_DEF_INFO();
3224-
USE_OP1_TRACE_TYPE();
3224+
op1_addr = OP1_REG_ADDR();
3225+
op1_def_addr = OP1_DEF_REG_ADDR();
3226+
if (orig_op1_type != IS_UNKNOWN
3227+
&& (orig_op1_type & IS_TRACE_REFERENCE)) {
3228+
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 0)) {
3229+
goto jit_failure;
3230+
}
3231+
op1_def_addr = op1_addr;
3232+
} else {
3233+
USE_OP1_TRACE_TYPE();
3234+
if (orig_op1_type != IS_UNKNOWN
3235+
&& (op1_info & MAY_BE_REF)) {
3236+
if (!zend_jit_noref_guard(&dasm_state, opline, op1_addr)) {
3237+
goto jit_failure;
3238+
}
3239+
op1_info &= ~MAY_BE_REF;
3240+
op1_def_info &= ~MAY_BE_REF;
3241+
}
3242+
}
32253243
if (!zend_jit_assign(&dasm_state, opline, op_array,
3226-
op1_info, OP1_REG_ADDR(),
3227-
op1_def_info, OP1_DEF_REG_ADDR(),
3244+
op1_info, op1_addr,
3245+
op1_def_info, op1_def_addr,
32283246
op2_info, op2_addr, op2_def_addr,
32293247
res_info, res_addr,
32303248
zend_may_throw(opline, ssa_op, op_array, ssa))) {
@@ -3616,7 +3634,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
36163634
op1_addr = OP1_REG_ADDR();
36173635
if (orig_op1_type != IS_UNKNOWN
36183636
&& (orig_op1_type & IS_TRACE_REFERENCE)) {
3619-
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr)) {
3637+
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 1)) {
36203638
goto jit_failure;
36213639
}
36223640
} else {
@@ -3649,7 +3667,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
36493667
op1_addr = OP1_REG_ADDR();
36503668
if (orig_op1_type != IS_UNKNOWN
36513669
&& (orig_op1_type & IS_TRACE_REFERENCE)) {
3652-
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr)) {
3670+
if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 1)) {
36533671
goto jit_failure;
36543672
}
36553673
} else {

ext/opcache/jit/zend_jit_x86.dasc

+19-2
Original file line numberDiff line numberDiff line change
@@ -11350,7 +11350,20 @@ static zend_bool zend_jit_verify_return_type(dasm_State **Dst, const zend_op *op
1135011350
return 1;
1135111351
}
1135211352

11353-
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)
11353+
static zend_bool zend_jit_noref_guard(dasm_State **Dst, const zend_op *opline, zend_jit_addr var_addr)
11354+
{
11355+
int32_t exit_point = zend_jit_trace_get_exit_point(opline, opline, NULL, 0);
11356+
const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
11357+
11358+
if (!exit_addr) {
11359+
return 0;
11360+
}
11361+
| IF_ZVAL_TYPE var_addr, IS_REFERENCE, &exit_addr
11362+
11363+
return 1;
11364+
}
11365+
11366+
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)
1135411367
{
1135511368
zend_jit_addr var_addr = *var_addr_ptr;
1135611369
uint32_t var_info = *var_info_ptr;
@@ -11369,7 +11382,8 @@ static zend_bool zend_jit_fetch_reference(dasm_State **Dst, const zend_op *oplin
1136911382
*var_addr_ptr = var_addr;
1137011383

1137111384
var_type &= ~IS_TRACE_REFERENCE;
11372-
if (var_type != IS_UNKNOWN
11385+
if (add_type_guard
11386+
&& var_type != IS_UNKNOWN
1137311387
&& (var_info & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1 << var_type)) {
1137411388
| IF_NOT_Z_TYPE FCARG1a, var_type, &exit_addr
1137511389

@@ -11382,6 +11396,9 @@ static zend_bool zend_jit_fetch_reference(dasm_State **Dst, const zend_op *oplin
1138211396
var_info = MAY_BE_ARRAY | (var_info & (MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF|MAY_BE_ARRAY_KEY_ANY|MAY_BE_RC1|MAY_BE_RCN));
1138311397
}
1138411398

11399+
*var_info_ptr = var_info;
11400+
} else {
11401+
var_info &= ~MAY_BE_REF;
1138511402
*var_info_ptr = var_info;
1138611403
}
1138711404

0 commit comments

Comments
 (0)