Skip to content

Commit 91d7e87

Browse files
committed
Fixed nested init fcall guards.
1 parent b03fd37 commit 91d7e87

File tree

4 files changed

+27
-14
lines changed

4 files changed

+27
-14
lines changed

ext/opcache/jit/zend_jit_internal.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,15 @@ typedef enum _zend_jit_trace_op {
256256
#define ZEND_JIT_TRACE_MAX_SSA_VAR 0x7ffffe
257257
#define ZEND_JIT_TRACE_SSA_VAR_SHIFT 9
258258

259+
#define ZEND_JIT_TRACE_FAKE_LEVEL_MASK 0xffff0000
260+
#define ZEND_JIT_TRACE_FAKE_LEVEL_SHIFT 16
261+
262+
#define ZEND_JIT_TRACE_FAKE_LEVEL(info) \
263+
(((info) & ZEND_JIT_TRACE_FAKE_LEVEL_MASK) >> ZEND_JIT_TRACE_FAKE_LEVEL_SHIFT)
264+
265+
#define ZEND_JIT_TRACE_FAKE_INFO(level) \
266+
(((level) << ZEND_JIT_TRACE_FAKE_LEVEL_SHIFT) | ZEND_JIT_TRACE_FAKE_INIT_CALL)
267+
259268
#define ZEND_JIT_TRACE_SET_FIRST_SSA_VAR(_info, var) do { \
260269
_info |= (var << ZEND_JIT_TRACE_SSA_VAR_SHIFT); \
261270
} while (0)

ext/opcache/jit/zend_jit_trace.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4506,7 +4506,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
45064506
goto jit_failure;
45074507
}
45084508
if ((p+1)->op == ZEND_JIT_TRACE_INIT_CALL && (p+1)->func) {
4509-
if (!zend_jit_init_fcall_guard(&dasm_state, (p+1)->func, opline+1)) {
4509+
if (!zend_jit_init_fcall_guard(&dasm_state, 0, (p+1)->func, opline+1)) {
45104510
goto jit_failure;
45114511
}
45124512
}
@@ -4518,7 +4518,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
45184518
if ((opline->op1_type != IS_CONST
45194519
|| opline->op2_type != IS_CONST)
45204520
&& (p+1)->op == ZEND_JIT_TRACE_INIT_CALL && (p+1)->func) {
4521-
if (!zend_jit_init_fcall_guard(&dasm_state, (p+1)->func, opline+1)) {
4521+
if (!zend_jit_init_fcall_guard(&dasm_state, 0, (p+1)->func, opline+1)) {
45224522
goto jit_failure;
45234523
}
45244524
}
@@ -4529,7 +4529,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
45294529
}
45304530
if (opline->op2_type != IS_CONST
45314531
&& (p+1)->op == ZEND_JIT_TRACE_INIT_CALL && (p+1)->func) {
4532-
if (!zend_jit_init_fcall_guard(&dasm_state, (p+1)->func, opline+1)) {
4532+
if (!zend_jit_init_fcall_guard(&dasm_state, 0, (p+1)->func, opline+1)) {
45334533
goto jit_failure;
45344534
}
45354535
}
@@ -4541,7 +4541,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
45414541
if (opline->op1_type != IS_CONST
45424542
&& (p+1)->op == ZEND_JIT_TRACE_INIT_CALL && (p+1)->func) {
45434543
SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->result.var), IS_OBJECT);
4544-
if (!zend_jit_init_fcall_guard(&dasm_state, (p+1)->func, opline+1)) {
4544+
if (!zend_jit_init_fcall_guard(&dasm_state, 0, (p+1)->func, opline+1)) {
45454545
goto jit_failure;
45464546
}
45474547
}
@@ -4946,7 +4946,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
49464946
opline = q->opline;
49474947
ZEND_ASSERT(opline != NULL);
49484948
}
4949-
if (!zend_jit_init_fcall_guard(&dasm_state, p->func, opline)) {
4949+
if (!zend_jit_init_fcall_guard(&dasm_state,
4950+
ZEND_JIT_TRACE_FAKE_LEVEL(p->info), p->func, opline)) {
49504951
goto jit_failure;
49514952
}
49524953
}

ext/opcache/jit/zend_jit_vm_helpers.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ static int zend_jit_trace_bad_loop_exit(const zend_op *opline)
467467
return 0;
468468
}
469469

470-
static int zend_jit_trace_record_fake_init_call_ex(zend_execute_data *call, zend_jit_trace_rec *trace_buffer, int idx, zend_bool is_megamorphic, uint32_t *megamorphic, uint32_t level, uint32_t *call_level)
470+
static int zend_jit_trace_record_fake_init_call_ex(zend_execute_data *call, zend_jit_trace_rec *trace_buffer, int idx, zend_bool is_megamorphic, uint32_t *megamorphic, uint32_t level, uint32_t init_level, uint32_t *call_level)
471471
{
472472
zend_jit_trace_stop stop ZEND_ATTRIBUTE_UNUSED = ZEND_JIT_TRACE_STOP_ERROR;
473473

@@ -476,7 +476,7 @@ static int zend_jit_trace_record_fake_init_call_ex(zend_execute_data *call, zend
476476
zend_jit_op_array_trace_extension *jit_extension;
477477

478478
if (call->prev_execute_data) {
479-
idx = zend_jit_trace_record_fake_init_call_ex(call->prev_execute_data, trace_buffer, idx, is_megamorphic, megamorphic, level, call_level);
479+
idx = zend_jit_trace_record_fake_init_call_ex(call->prev_execute_data, trace_buffer, idx, is_megamorphic, megamorphic, level, init_level + 1, call_level);
480480
if (idx < 0) {
481481
return idx;
482482
}
@@ -510,7 +510,7 @@ static int zend_jit_trace_record_fake_init_call_ex(zend_execute_data *call, zend
510510
*megamorphic &= ~(1 << (level + *call_level));
511511
}
512512
(*call_level)++;
513-
TRACE_RECORD(ZEND_JIT_TRACE_INIT_CALL, ZEND_JIT_TRACE_FAKE_INIT_CALL, func);
513+
TRACE_RECORD(ZEND_JIT_TRACE_INIT_CALL, ZEND_JIT_TRACE_FAKE_INFO(init_level), func);
514514
} while (0);
515515
return idx;
516516
}
@@ -519,7 +519,7 @@ static int zend_jit_trace_record_fake_init_call(zend_execute_data *call, zend_ji
519519
{
520520
uint32_t call_level = 0;
521521

522-
return zend_jit_trace_record_fake_init_call_ex(call, trace_buffer, idx, is_megamorphic, megamorphic, level, &call_level);
522+
return zend_jit_trace_record_fake_init_call_ex(call, trace_buffer, idx, is_megamorphic, megamorphic, level, 0, &call_level);
523523
}
524524

525525
static int zend_jit_trace_call_level(const zend_execute_data *call)

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8474,7 +8474,7 @@ static int zend_jit_needs_call_chain(zend_call_info *call_info, uint32_t b, cons
84748474
}
84758475
}
84768476

8477-
static int zend_jit_init_fcall_guard(dasm_State **Dst, const zend_function *func, const zend_op *to_opline)
8477+
static int zend_jit_init_fcall_guard(dasm_State **Dst, uint32_t level, const zend_function *func, const zend_op *to_opline)
84788478
{
84798479
int32_t exit_point;
84808480
const void *exit_addr;
@@ -8500,14 +8500,19 @@ static int zend_jit_init_fcall_guard(dasm_State **Dst, const zend_function *func
85008500
return 0;
85018501
}
85028502

8503+
| // call = EX(call);
8504+
| mov r1, EX->call
8505+
while (level > 0) {
8506+
| mov r1, EX:r1->prev_execute_data
8507+
level--;
8508+
}
8509+
85038510
if (func->type == ZEND_USER_FUNCTION &&
85048511
(!(func->common.fn_flags & ZEND_ACC_IMMUTABLE) ||
85058512
(func->common.fn_flags & ZEND_ACC_CLOSURE) ||
85068513
!func->common.function_name)) {
85078514
const zend_op *opcodes = func->op_array.opcodes;
85088515

8509-
| // call = EX(call);
8510-
| mov r1, EX->call
85118516
| mov r1, aword EX:r1->func
85128517
| .if X64
85138518
|| if (!IS_SIGNED_32BIT(opcodes)) {
@@ -8521,8 +8526,6 @@ static int zend_jit_init_fcall_guard(dasm_State **Dst, const zend_function *func
85218526
| .endif
85228527
| jne &exit_addr
85238528
} else {
8524-
| // call = EX(call);
8525-
| mov r1, EX->call
85268529
| .if X64
85278530
|| if (!IS_SIGNED_32BIT(func)) {
85288531
| mov64 r0, ((ptrdiff_t)func)

0 commit comments

Comments
 (0)