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 +
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;
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:
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) {
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;
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;
}
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);
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;
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;
level++;
} else {
/* Return from function */
+ prev_call = EX(call);
if (level == 0) {
if (is_toplevel) {
stop = ZEND_JIT_TRACE_STOP_TOPLEVEL;
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)) {
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 ??? */
}
}
+ 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