summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/opcache/jit/zend_jit_internal.h2
-rw-r--r--ext/opcache/jit/zend_jit_trace.c24
-rw-r--r--ext/opcache/jit/zend_jit_vm_helpers.c16
-rw-r--r--ext/opcache/jit/zend_jit_x86.dasc4
4 files changed, 30 insertions, 16 deletions
diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h
index a385463029..c787bbf8b1 100644
--- a/ext/opcache/jit/zend_jit_internal.h
+++ b/ext/opcache/jit/zend_jit_internal.h
@@ -363,6 +363,7 @@ struct _zend_jit_trace_stack_frame {
zend_jit_trace_stack_frame *call;
zend_jit_trace_stack_frame *prev;
const zend_function *func;
+ uint32_t call_level;
uint32_t _info;
zend_jit_trace_stack stack[1];
};
@@ -384,6 +385,7 @@ struct _zend_jit_trace_stack_frame {
_frame->call = NULL; \
_frame->prev = NULL; \
_frame->func = (const zend_function*)_func; \
+ _frame->call_level = 0; \
_frame->_info = (((uint32_t)(num_args)) << TRACE_FRAME_SHIFT_NUM_ARGS) & TRACE_FRAME_MASK_NUM_ARGS; \
if (nested) { \
_frame->_info |= TRACE_FRAME_MASK_NESTED; \
diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c
index 7efe94517f..20696f5f5f 100644
--- a/ext/opcache/jit/zend_jit_trace.c
+++ b/ext/opcache/jit/zend_jit_trace.c
@@ -1614,8 +1614,12 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
v++;
}
if (return_value_info.type != 0) {
- if ((p+1)->op == ZEND_JIT_TRACE_VM) {
- const zend_op *opline = (p+1)->opline - 1;
+ zend_jit_trace_rec *q = p + 1;
+ while (q->op == ZEND_JIT_TRACE_INIT_CALL) {
+ q++;
+ }
+ if (q->op == ZEND_JIT_TRACE_VM) {
+ const zend_op *opline = q->opline - 1;
if (opline->result_type != IS_UNUSED) {
ssa_var_info[
p->first_ssa_var +
@@ -2429,7 +2433,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
const zend_op_array *op_array;
zend_ssa *ssa, *op_array_ssa;
zend_jit_trace_rec *p;
- int call_level = -1; // TODO: proper support for inlined functions ???
zend_jit_op_array_trace_extension *jit_extension;
int num_op_arrays = 0;
zend_jit_trace_info *t;
@@ -2671,8 +2674,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
p++;
}
-#if 0
- // TODO: call level calculation doesn't work for traces ???
switch (opline->opcode) {
case ZEND_INIT_FCALL:
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
case ZEND_INIT_STATIC_METHOD_CALL:
case ZEND_INIT_USER_CALL:
case ZEND_NEW:
- call_level++;
+ frame->call_level++;
}
-#endif
if (zend_jit_level >= ZEND_JIT_LEVEL_INLINE) {
switch (opline->opcode) {
@@ -3043,7 +3043,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
case ZEND_INIT_FCALL:
case ZEND_INIT_FCALL_BY_NAME:
case ZEND_INIT_NS_FCALL_BY_NAME:
- 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)) {
+ 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)) {
goto jit_failure;
}
goto done;
@@ -3128,7 +3128,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
case ZEND_DO_ICALL:
case ZEND_DO_FCALL_BY_NAME:
case ZEND_DO_FCALL:
- if (!zend_jit_do_fcall(&dasm_state, opline, op_array, op_array_ssa, call_level, -1, p + 1)) {
+ if (!zend_jit_do_fcall(&dasm_state, opline, op_array, op_array_ssa, frame->call_level, -1, p + 1)) {
goto jit_failure;
}
goto done;
@@ -3608,16 +3608,13 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
}
done:
-#if 0
- // TODO: call level calculation doesn't work for traces ???
switch (opline->opcode) {
case ZEND_DO_FCALL:
case ZEND_DO_ICALL:
case ZEND_DO_UCALL:
case ZEND_DO_FCALL_BY_NAME:
- call_level--;
+ frame->call_level--;
}
-#endif
if (ra) {
zend_jit_trace_clenup_stack(stack, opline, ssa_op, ssa, ra);
@@ -3946,6 +3943,7 @@ done:
if (!skip_guard && !zend_jit_init_fcall_guard(&dasm_state, NULL, p->func)) {
goto jit_failure;
}
+ frame->call_level++;
}
} else if (p->op == ZEND_JIT_TRACE_DO_ICALL) {
call = frame->call;
diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c
index b2faaeb1a0..7fcd14feca 100644
--- a/ext/opcache/jit/zend_jit_vm_helpers.c
+++ b/ext/opcache/jit/zend_jit_vm_helpers.c
@@ -696,6 +696,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
if (rc == 1) {
#endif
/* Enter into function */
+ prev_call = NULL;
if (level > ZEND_JIT_TRACE_MAX_CALL_DEPTH) {
stop = ZEND_JIT_TRACE_STOP_TOO_DEEP;
break;
@@ -726,6 +727,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
level++;
} else {
/* Return from function */
+ prev_call = EX(call);
if (level == 0) {
if (is_toplevel) {
stop = ZEND_JIT_TRACE_STOP_TOPLEVEL;
@@ -757,6 +759,10 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
unrolled_calls[ret_level] = &EX(func)->op_array;
ret_level++;
is_toplevel = EX(func)->op_array.function_name == NULL;
+
+ if (prev_call) {
+ idx = zend_jit_trace_record_fake_init_call(prev_call, trace_buffer, idx);
+ }
#endif
} else if (start & ZEND_JIT_TRACE_START_LOOP
&& !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,
offset = jit_extension->offset;
}
if (EX(call) != prev_call) {
- if (trace_buffer[idx-1].op != ZEND_JIT_TRACE_BACK
- && EX(call)
+ if (EX(call)
&& EX(call)->prev_execute_data == prev_call) {
if (EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
/* TODO: Can we continue recording ??? */
@@ -868,6 +873,13 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
}
}
+ if (stop == ZEND_JIT_TRACE_STOP_LINK) {
+ /* Shrink fake INIT_CALLs */
+ while (trace_buffer[idx-1].op == ZEND_JIT_TRACE_INIT_CALL && trace_buffer[idx-1].fake) {
+ idx--;
+ }
+ }
+
TRACE_END(ZEND_JIT_TRACE_END, stop, opline);
#ifdef HAVE_GCC_GLOBAL_REGS
diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc
index 60992a2128..9501e08375 100644
--- a/ext/opcache/jit/zend_jit_x86.dasc
+++ b/ext/opcache/jit/zend_jit_x86.dasc
@@ -9471,7 +9471,9 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const ze
const void *exit_addr;
zend_jit_trace_stack_frame *current_frame;
- trace++;
+ do {
+ trace++;
+ } while (trace->op == ZEND_JIT_TRACE_INIT_CALL);
ZEND_ASSERT(trace->op == ZEND_JIT_TRACE_VM || trace->op == ZEND_JIT_TRACE_END);
next_opline = trace->opline;
current_frame = JIT_G(current_frame);