Skip to content

Commit

Permalink
Tracing JIT support for include() and generators
Browse files Browse the repository at this point in the history
  • Loading branch information
dstogov committed Jun 29, 2020
1 parent 1ca2fd2 commit 24a8065
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 11 deletions.
3 changes: 3 additions & 0 deletions Zend/zend_generators.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,9 +742,11 @@ ZEND_API void zend_generator_resume(zend_generator *orig_generator) /* {{{ */
{
/* Backup executor globals */
zend_execute_data *original_execute_data = EG(current_execute_data);
uint32_t original_jit_trace_num = EG(jit_trace_num);

/* Set executor globals */
EG(current_execute_data) = generator->execute_data;
EG(jit_trace_num) = 0;

/* We want the backtrace to look as if the generator function was
* called from whatever method we are current running (e.g. next()).
Expand Down Expand Up @@ -777,6 +779,7 @@ ZEND_API void zend_generator_resume(zend_generator *orig_generator) /* {{{ */

/* Restore executor globals */
EG(current_execute_data) = original_execute_data;
EG(jit_trace_num) = original_jit_trace_num;

/* If an exception was thrown in the generator we have to internally
* rethrow it in the parent scope.
Expand Down
1 change: 0 additions & 1 deletion ext/opcache/Optimizer/zend_inference.c
Original file line number Diff line number Diff line change
Expand Up @@ -3511,7 +3511,6 @@ static zend_always_inline int _zend_update_type_info(
}
break;
case ZEND_CATCH:
case ZEND_INCLUDE_OR_EVAL:
/* Forbidden opcodes */
ZEND_UNREACHABLE();
break;
Expand Down
14 changes: 7 additions & 7 deletions ext/opcache/jit/zend_jit_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -4456,10 +4456,16 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
}
}
} 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->opcode == ZEND_DO_UCALL
|| opline->opcode == ZEND_DO_FCALL
|| opline->opcode == ZEND_DO_FCALL_BY_NAME) {
|| opline->opcode == ZEND_DO_FCALL_BY_NAME
|| opline->opcode == ZEND_GENERATOR_CREATE
|| opline->opcode == ZEND_GENERATOR_RETURN
|| opline->opcode == ZEND_YIELD
|| opline->opcode == ZEND_YIELD_FROM
|| opline->opcode == ZEND_INCLUDE_OR_EVAL) {
zend_jit_trace_setup_ret_counter(opline, jit_extension->offset);
}
if (JIT_G(current_frame)
Expand Down Expand Up @@ -5499,12 +5505,6 @@ static zend_always_inline uint8_t zend_jit_trace_supported(const zend_op *opline
case ZEND_CATCH:
case ZEND_FAST_CALL:
case ZEND_FAST_RET:
case ZEND_GENERATOR_CREATE:
case ZEND_GENERATOR_RETURN:
case ZEND_EXIT:
case ZEND_YIELD:
case ZEND_YIELD_FROM:
case ZEND_INCLUDE_OR_EVAL:
return ZEND_JIT_TRACE_UNSUPPORTED;
default:
return ZEND_JIT_TRACE_SUPPORTED;
Expand Down
6 changes: 5 additions & 1 deletion ext/opcache/jit/zend_jit_vm_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,9 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
if (EX(call)->func->type == ZEND_INTERNAL_FUNCTION) {
TRACE_RECORD(ZEND_JIT_TRACE_DO_ICALL, 0, EX(call)->func);
}
} else if (opline->opcode == ZEND_INCLUDE_OR_EVAL) {
stop = ZEND_JIT_TRACE_STOP_INTERPRETER;
break;
}

handler = (zend_vm_opcode_handler_t)ZEND_OP_TRACE_INFO(opline, offset)->call_handler;
Expand Down Expand Up @@ -975,7 +978,8 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
TRACE_END(ZEND_JIT_TRACE_END, stop, end_opline);

#ifdef HAVE_GCC_GLOBAL_REGS
if (stop != ZEND_JIT_TRACE_STOP_HALT) {
if (stop != ZEND_JIT_TRACE_STOP_HALT
&& stop != ZEND_JIT_TRACE_STOP_RETURN_HALT) {
EX(opline) = opline;
}
#endif
Expand Down
16 changes: 14 additions & 2 deletions ext/opcache/jit/zend_jit_x86.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -3183,7 +3183,10 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra

if (zend_jit_trace_may_exit(op_array, opline)) {
// TODO: try to avoid this check ???
if (opline->opcode == ZEND_RETURN || opline->opcode == ZEND_RETURN_BY_REF) {
if (opline->opcode == ZEND_RETURN ||
opline->opcode == ZEND_RETURN_BY_REF ||
opline->opcode == ZEND_GENERATOR_CREATE) {

if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
| cmp IP, zend_jit_halt_op
| je ->trace_halt
Expand All @@ -3194,8 +3197,17 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra
| test eax, eax
| jl ->trace_halt
}
} else if (opline->opcode == ZEND_EXIT ||
opline->opcode == ZEND_GENERATOR_RETURN ||
opline->opcode == ZEND_YIELD ||
opline->opcode == ZEND_YIELD_FROM) {
| jmp ->trace_halt
}
if (trace->op != ZEND_JIT_TRACE_END || trace->stop != ZEND_JIT_TRACE_STOP_RETURN) {
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;
const zend_op *exit_opline = NULL;
uint32_t exit_point;
Expand Down

0 comments on commit 24a8065

Please sign in to comment.