Skip to content

Commit 65934d3

Browse files
committed
Improved tracing JIT for nested calls
1 parent 0e0c608 commit 65934d3

File tree

4 files changed

+30
-16
lines changed

4 files changed

+30
-16
lines changed

ext/opcache/jit/zend_jit_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ struct _zend_jit_trace_stack_frame {
363363
zend_jit_trace_stack_frame *call;
364364
zend_jit_trace_stack_frame *prev;
365365
const zend_function *func;
366+
uint32_t call_level;
366367
uint32_t _info;
367368
zend_jit_trace_stack stack[1];
368369
};
@@ -384,6 +385,7 @@ struct _zend_jit_trace_stack_frame {
384385
_frame->call = NULL; \
385386
_frame->prev = NULL; \
386387
_frame->func = (const zend_function*)_func; \
388+
_frame->call_level = 0; \
387389
_frame->_info = (((uint32_t)(num_args)) << TRACE_FRAME_SHIFT_NUM_ARGS) & TRACE_FRAME_MASK_NUM_ARGS; \
388390
if (nested) { \
389391
_frame->_info |= TRACE_FRAME_MASK_NESTED; \

ext/opcache/jit/zend_jit_trace.c

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,8 +1614,12 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
16141614
v++;
16151615
}
16161616
if (return_value_info.type != 0) {
1617-
if ((p+1)->op == ZEND_JIT_TRACE_VM) {
1618-
const zend_op *opline = (p+1)->opline - 1;
1617+
zend_jit_trace_rec *q = p + 1;
1618+
while (q->op == ZEND_JIT_TRACE_INIT_CALL) {
1619+
q++;
1620+
}
1621+
if (q->op == ZEND_JIT_TRACE_VM) {
1622+
const zend_op *opline = q->opline - 1;
16191623
if (opline->result_type != IS_UNUSED) {
16201624
ssa_var_info[
16211625
p->first_ssa_var +
@@ -2429,7 +2433,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
24292433
const zend_op_array *op_array;
24302434
zend_ssa *ssa, *op_array_ssa;
24312435
zend_jit_trace_rec *p;
2432-
int call_level = -1; // TODO: proper support for inlined functions ???
24332436
zend_jit_op_array_trace_extension *jit_extension;
24342437
int num_op_arrays = 0;
24352438
zend_jit_trace_info *t;
@@ -2671,8 +2674,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
26712674
p++;
26722675
}
26732676

2674-
#if 0
2675-
// TODO: call level calculation doesn't work for traces ???
26762677
switch (opline->opcode) {
26772678
case ZEND_INIT_FCALL:
26782679
case ZEND_INIT_FCALL_BY_NAME:
@@ -2682,9 +2683,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
26822683
case ZEND_INIT_STATIC_METHOD_CALL:
26832684
case ZEND_INIT_USER_CALL:
26842685
case ZEND_NEW:
2685-
call_level++;
2686+
frame->call_level++;
26862687
}
2687-
#endif
26882688

26892689
if (zend_jit_level >= ZEND_JIT_LEVEL_INLINE) {
26902690
switch (opline->opcode) {
@@ -3043,7 +3043,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
30433043
case ZEND_INIT_FCALL:
30443044
case ZEND_INIT_FCALL_BY_NAME:
30453045
case ZEND_INIT_NS_FCALL_BY_NAME:
3046-
if (!zend_jit_init_fcall(&dasm_state, opline, op_array_ssa->cfg.map ? op_array_ssa->cfg.map[opline - op_array->opcodes] : -1, op_array, op_array_ssa, call_level, p + 1)) {
3046+
if (!zend_jit_init_fcall(&dasm_state, opline, op_array_ssa->cfg.map ? op_array_ssa->cfg.map[opline - op_array->opcodes] : -1, op_array, op_array_ssa, frame->call_level, p + 1)) {
30473047
goto jit_failure;
30483048
}
30493049
goto done;
@@ -3128,7 +3128,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
31283128
case ZEND_DO_ICALL:
31293129
case ZEND_DO_FCALL_BY_NAME:
31303130
case ZEND_DO_FCALL:
3131-
if (!zend_jit_do_fcall(&dasm_state, opline, op_array, op_array_ssa, call_level, -1, p + 1)) {
3131+
if (!zend_jit_do_fcall(&dasm_state, opline, op_array, op_array_ssa, frame->call_level, -1, p + 1)) {
31323132
goto jit_failure;
31333133
}
31343134
goto done;
@@ -3608,16 +3608,13 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
36083608
}
36093609

36103610
done:
3611-
#if 0
3612-
// TODO: call level calculation doesn't work for traces ???
36133611
switch (opline->opcode) {
36143612
case ZEND_DO_FCALL:
36153613
case ZEND_DO_ICALL:
36163614
case ZEND_DO_UCALL:
36173615
case ZEND_DO_FCALL_BY_NAME:
3618-
call_level--;
3616+
frame->call_level--;
36193617
}
3620-
#endif
36213618

36223619
if (ra) {
36233620
zend_jit_trace_clenup_stack(stack, opline, ssa_op, ssa, ra);
@@ -3946,6 +3943,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
39463943
if (!skip_guard && !zend_jit_init_fcall_guard(&dasm_state, NULL, p->func)) {
39473944
goto jit_failure;
39483945
}
3946+
frame->call_level++;
39493947
}
39503948
} else if (p->op == ZEND_JIT_TRACE_DO_ICALL) {
39513949
call = frame->call;

ext/opcache/jit/zend_jit_vm_helpers.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
696696
if (rc == 1) {
697697
#endif
698698
/* Enter into function */
699+
prev_call = NULL;
699700
if (level > ZEND_JIT_TRACE_MAX_CALL_DEPTH) {
700701
stop = ZEND_JIT_TRACE_STOP_TOO_DEEP;
701702
break;
@@ -726,6 +727,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
726727
level++;
727728
} else {
728729
/* Return from function */
730+
prev_call = EX(call);
729731
if (level == 0) {
730732
if (is_toplevel) {
731733
stop = ZEND_JIT_TRACE_STOP_TOPLEVEL;
@@ -757,6 +759,10 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
757759
unrolled_calls[ret_level] = &EX(func)->op_array;
758760
ret_level++;
759761
is_toplevel = EX(func)->op_array.function_name == NULL;
762+
763+
if (prev_call) {
764+
idx = zend_jit_trace_record_fake_init_call(prev_call, trace_buffer, idx);
765+
}
760766
#endif
761767
} else if (start & ZEND_JIT_TRACE_START_LOOP
762768
&& !zend_jit_trace_bad_loop_exit(orig_opline)) {
@@ -785,8 +791,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
785791
offset = jit_extension->offset;
786792
}
787793
if (EX(call) != prev_call) {
788-
if (trace_buffer[idx-1].op != ZEND_JIT_TRACE_BACK
789-
&& EX(call)
794+
if (EX(call)
790795
&& EX(call)->prev_execute_data == prev_call) {
791796
if (EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
792797
/* TODO: Can we continue recording ??? */
@@ -868,6 +873,13 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
868873
}
869874
}
870875

876+
if (stop == ZEND_JIT_TRACE_STOP_LINK) {
877+
/* Shrink fake INIT_CALLs */
878+
while (trace_buffer[idx-1].op == ZEND_JIT_TRACE_INIT_CALL && trace_buffer[idx-1].fake) {
879+
idx--;
880+
}
881+
}
882+
871883
TRACE_END(ZEND_JIT_TRACE_END, stop, opline);
872884

873885
#ifdef HAVE_GCC_GLOBAL_REGS

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9471,7 +9471,9 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const ze
94719471
const void *exit_addr;
94729472
zend_jit_trace_stack_frame *current_frame;
94739473

9474-
trace++;
9474+
do {
9475+
trace++;
9476+
} while (trace->op == ZEND_JIT_TRACE_INIT_CALL);
94759477
ZEND_ASSERT(trace->op == ZEND_JIT_TRACE_VM || trace->op == ZEND_JIT_TRACE_END);
94769478
next_opline = trace->opline;
94779479
current_frame = JIT_G(current_frame);

0 commit comments

Comments
 (0)