_(RECURSIVE_CALL, "recursive call") \
_(RECURSIVE_RET, "recursive return") \
_(RETURN, "return") \
- _(RETURN_HALT, "return from interpreter") \
_(INTERPRETER, "exit to VM interpreter") \
_(LINK, "link to another trace") \
/* compilation and linking successful */ \
_(COMPILED_LOOP, "compiled loop") \
_(TRAMPOLINE, "trampoline call") \
_(BAD_FUNC, "bad function call") \
- _(HALT, "exit from interpreter") \
_(COMPILER_ERROR, "JIT compilation error") \
/* no recoverable error (blacklist immediately) */ \
_(NO_SHM, "insufficient shared memory") \
typedef enum _zend_jit_trace_stop {
ZEND_JIT_TRACE_STOP(ZEND_JIT_TRACE_STOP_NAME)
+ ZEND_JIT_TRACE_HALT = 0x40
} zend_jit_trace_stop;
#define ZEND_JIT_TRACE_STOP_OK(ret) \
} else {
zend_jit_trace_return(&dasm_state, 0);
}
- } else if (p->stop == ZEND_JIT_TRACE_STOP_RETURN
- || p->stop == ZEND_JIT_TRACE_STOP_RETURN_HALT) {
+ } else if (p->stop == ZEND_JIT_TRACE_STOP_RETURN) {
zend_jit_trace_return(&dasm_state, 0);
} else {
// TODO: not implemented ???
}
}
} else if (p->stop == ZEND_JIT_TRACE_STOP_LINK
- || p->stop == ZEND_JIT_TRACE_STOP_RETURN_HALT
|| p->stop == ZEND_JIT_TRACE_STOP_INTERPRETER) {
if (opline
&& (opline->opcode == ZEND_DO_UCALL
ZEND_OP_TRACE_INFO(opline, offset)->trace_flags & ZEND_JIT_TRACE_START_MASK, 0);
JIT_G(tracing) = 0;
+ if (stop & ZEND_JIT_TRACE_HALT) {
+ ret = -1;
+ }
+ stop &= ~ZEND_JIT_TRACE_HALT;
+
if (UNEXPECTED(JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_BYTECODE)) {
zend_jit_dump_trace(trace_buffer, NULL);
}
if (ZEND_JIT_TRACE_STOP_OK(stop)) {
- if (stop == ZEND_JIT_TRACE_STOP_RETURN_HALT) {
- ret = -1;
- }
if (JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_STOP) {
if (stop == ZEND_JIT_TRACE_STOP_LINK) {
uint32_t idx = trace_buffer[1].last;
goto abort;
}
} else {
- if (stop == ZEND_JIT_TRACE_STOP_HALT) {
- ret = -1;
- }
abort:
if (JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_ABORT) {
fprintf(stderr, "---- TRACE %d abort (%s)\n",
stop = zend_jit_trace_execute(execute_data, EX(opline), trace_buffer, ZEND_JIT_TRACE_START_SIDE, is_megamorphic);
JIT_G(tracing) = 0;
+ if (stop & ZEND_JIT_TRACE_HALT) {
+ ret = -1;
+ }
+ stop &= ~ZEND_JIT_TRACE_HALT;
+
if (UNEXPECTED(JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_BYTECODE)) {
zend_jit_dump_trace(trace_buffer, NULL);
}
if (ZEND_JIT_TRACE_STOP_OK(stop)) {
- if (stop == ZEND_JIT_TRACE_STOP_RETURN_HALT) {
- ret = -1;
- }
if (JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_STOP) {
if (stop == ZEND_JIT_TRACE_STOP_LINK) {
uint32_t idx = trace_buffer[1].last;
goto abort;
}
} else {
- if (stop == ZEND_JIT_TRACE_STOP_HALT) {
- ret = -1;
- }
abort:
if (JIT_G(debug) & ZEND_JIT_DEBUG_TRACE_ABORT) {
fprintf(stderr, "---- TRACE %d abort (%s)\n",
#endif
const zend_op *orig_opline, *end_opline;
zend_jit_trace_stop stop = ZEND_JIT_TRACE_STOP_ERROR;
+ zend_jit_trace_stop halt = 0;
int level = 0;
int ret_level = 0;
int call_level;
#ifdef HAVE_GCC_GLOBAL_REGS
handler();
if (UNEXPECTED(opline == zend_jit_halt_op)) {
- stop = ZEND_JIT_TRACE_STOP_RETURN_HALT;
+ stop = ZEND_JIT_TRACE_STOP_RETURN;
+ opline = NULL;
+ halt = ZEND_JIT_TRACE_HALT;
break;
}
if (UNEXPECTED(execute_data != prev_execute_data)) {
rc = handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
if (rc != 0) {
if (rc < 0) {
- stop = ZEND_JIT_TRACE_STOP_RETURN_HALT;
+ stop = ZEND_JIT_TRACE_STOP_RETURN;
+ opline = NULL;
+ halt = ZEND_JIT_TRACE_HALT;
break;
} else if (execute_data == EG(current_execute_data)) {
/* return after interrupt handler */
TRACE_END(ZEND_JIT_TRACE_END, stop, end_opline);
#ifdef HAVE_GCC_GLOBAL_REGS
- if (stop != ZEND_JIT_TRACE_STOP_HALT
- && stop != ZEND_JIT_TRACE_STOP_RETURN_HALT) {
+ if (!halt) {
EX(opline) = opline;
}
#endif
opline = save_opline;
#endif
- return stop;
+ return stop | halt;
}
}
if (trace->op != ZEND_JIT_TRACE_END ||
(trace->stop != ZEND_JIT_TRACE_STOP_RETURN &&
- trace->stop != ZEND_JIT_TRACE_STOP_RETURN_HALT &&
trace->stop != ZEND_JIT_TRACE_STOP_INTERPRETER)) {
const zend_op *next_opline = trace->opline;