Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ext/opcache/ZendAccelerator.c
Original file line number Diff line number Diff line change
Expand Up @@ -1837,8 +1837,8 @@ static zend_persistent_script *opcache_compile_file(zend_file_handle *file_handl
zend_begin_record_errors();
}

orig_compiler_options = CG(compiler_options);
zend_try {
orig_compiler_options = CG(compiler_options);
CG(compiler_options) |= ZEND_COMPILE_HANDLE_OP_ARRAY;
CG(compiler_options) |= ZEND_COMPILE_DELAYED_BINDING;
CG(compiler_options) |= ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION;
Expand Down
13 changes: 13 additions & 0 deletions ext/opcache/jit/zend_jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1347,6 +1347,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
}

zend_jit_start(&ctx, op_array, ssa);
JIT_G(active_ctx) = &ctx;
if (JIT_G(opt_flags) & (ZEND_JIT_REG_ALLOC_LOCAL|ZEND_JIT_REG_ALLOC_GLOBAL)) {
checkpoint = zend_arena_checkpoint(CG(arena));
zend_jit_allocate_registers(&ctx, op_array, ssa);
Expand Down Expand Up @@ -1395,6 +1396,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
ssa->cfg.blocks[b].len == 1 &&
(ssa->cfg.blocks[b].flags & ZEND_BB_EXIT)) {
/* don't generate code for BB with single opcode */
JIT_G(active_ctx) = NULL;
zend_jit_free_ctx(&ctx);

if (JIT_G(opt_flags) & (ZEND_JIT_REG_ALLOC_LOCAL|ZEND_JIT_REG_ALLOC_GLOBAL)) {
Expand All @@ -1407,6 +1409,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
ssa->cfg.blocks[b].len == 1 &&
(ssa->cfg.blocks[b].flags & ZEND_BB_EXIT)) {
/* don't generate code for BB with single opcode */
JIT_G(active_ctx) = NULL;
zend_jit_free_ctx(&ctx);

if (JIT_G(opt_flags) & (ZEND_JIT_REG_ALLOC_LOCAL|ZEND_JIT_REG_ALLOC_GLOBAL)) {
Expand Down Expand Up @@ -2832,6 +2835,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
if (!handler) {
goto jit_failure;
}
JIT_G(active_ctx) = NULL;
zend_jit_free_ctx(&ctx);

if (JIT_G(opt_flags) & (ZEND_JIT_REG_ALLOC_LOCAL|ZEND_JIT_REG_ALLOC_GLOBAL)) {
Expand All @@ -2840,6 +2844,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
return SUCCESS;

jit_failure:
JIT_G(active_ctx) = NULL;
zend_jit_free_ctx(&ctx);
if (JIT_G(opt_flags) & (ZEND_JIT_REG_ALLOC_LOCAL|ZEND_JIT_REG_ALLOC_GLOBAL)) {
zend_arena_release(&CG(arena), checkpoint);
Expand Down Expand Up @@ -2998,6 +3003,10 @@ static int ZEND_FASTCALL zend_runtime_jit(void)
jit_extension->func_info.flags |= ZEND_FUNC_JITED;
} zend_catch {
do_bailout = true;
if (JIT_G(active_ctx)) {
zend_jit_free_ctx(JIT_G(active_ctx));
JIT_G(active_ctx) = NULL;
}
} zend_end_try();

zend_jit_protect();
Expand Down Expand Up @@ -3076,6 +3085,10 @@ void ZEND_FASTCALL zend_jit_hot_func(zend_execute_data *execute_data, const zend
jit_extension->func_info.flags |= ZEND_FUNC_JITED;
} zend_catch {
do_bailout = 1;
if (JIT_G(active_ctx)) {
zend_jit_free_ctx(JIT_G(active_ctx));
JIT_G(active_ctx) = NULL;
}
} zend_end_try();

zend_jit_protect();
Expand Down
2 changes: 2 additions & 0 deletions ext/opcache/jit/zend_jit.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
typedef struct _zend_jit_trace_rec zend_jit_trace_rec;
typedef struct _zend_jit_trace_stack_frame zend_jit_trace_stack_frame;
typedef struct _sym_node zend_sym_node;
typedef struct _zend_jit_ctx zend_jit_ctx;

extern bool zend_jit_startup_ok;

Expand Down Expand Up @@ -142,6 +143,7 @@ typedef struct _zend_jit_globals {
uint32_t bad_root_slot;

uint8_t *exit_counters;
zend_jit_ctx *active_ctx; /* non-NULL while zend_jit()/zend_jit_trace() owns a malloc'd IR buffer; outer zend_catch frees it on bailout */
} zend_jit_globals;

#ifdef ZTS
Expand Down
26 changes: 24 additions & 2 deletions ext/opcache/jit/zend_jit_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -4131,6 +4131,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
name = zend_jit_trace_name(op_array, opline->lineno);
zend_jit_trace_start(&ctx, op_array, ssa, name, ZEND_JIT_TRACE_NUM,
parent_trace ? &zend_jit_traces[parent_trace] : NULL, exit_num);
JIT_G(active_ctx) = &ctx;
ctx.trace = &zend_jit_traces[ZEND_JIT_TRACE_NUM];

/* Register allocation */
Expand Down Expand Up @@ -7324,6 +7325,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
}

jit_failure:
JIT_G(active_ctx) = NULL;
zend_jit_free_ctx(&ctx);

if (name) {
Expand All @@ -7333,6 +7335,10 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
jit_cleanup:;
} zend_catch {
do_bailout = 1;
if (JIT_G(active_ctx)) {
zend_jit_free_ctx(JIT_G(active_ctx));
JIT_G(active_ctx) = NULL;
}
} zend_end_try();

/* Clean up used op_arrays */
Expand Down Expand Up @@ -7394,6 +7400,7 @@ static const void *zend_jit_trace_exit_to_vm(uint32_t trace_num, uint32_t exit_n
zend_string_release(name);
return NULL;
}
JIT_G(active_ctx) = &ctx;

checkpoint = zend_arena_checkpoint(CG(arena));;

Expand Down Expand Up @@ -7430,6 +7437,7 @@ static const void *zend_jit_trace_exit_to_vm(uint32_t trace_num, uint32_t exit_n
handler = zend_jit_finish(&ctx);

jit_failure:
JIT_G(active_ctx) = NULL;
zend_jit_free_ctx(&ctx);
zend_string_release(name);
zend_arena_release(&CG(arena), checkpoint);
Expand All @@ -7453,6 +7461,7 @@ static zend_jit_trace_stop zend_jit_compile_root_trace(zend_jit_trace_rec *trace
} else if (ZEND_JIT_TRACE_NUM >= JIT_G(max_root_traces)) {
ret = ZEND_JIT_TRACE_STOP_TOO_MANY_TRACES;
} else {
orig_trigger = JIT_G(trigger);
zend_try {
SHM_UNPROTECT();
zend_jit_unprotect();
Expand Down Expand Up @@ -7481,7 +7490,6 @@ static zend_jit_trace_stop zend_jit_compile_root_trace(zend_jit_trace_rec *trace
t->consts_count = 0;
t->constants = NULL;

orig_trigger = JIT_G(trigger);
JIT_G(trigger) = ZEND_JIT_ON_HOT_TRACE;

handler = zend_jit_trace(trace_buffer, 0, 0);
Expand Down Expand Up @@ -7578,6 +7586,11 @@ static zend_jit_trace_stop zend_jit_compile_root_trace(zend_jit_trace_rec *trace
exit:;
} zend_catch {
do_bailout = 1;
JIT_G(trigger) = orig_trigger;
if (JIT_G(active_ctx)) {
zend_jit_free_ctx(JIT_G(active_ctx));
JIT_G(active_ctx) = NULL;
}
} zend_end_try();

zend_jit_protect();
Expand Down Expand Up @@ -8237,6 +8250,10 @@ static void zend_jit_blacklist_trace_exit(uint32_t trace_num, uint32_t exit_num)
zend_jit_traces[trace_num].exit_info[exit_num].flags |= ZEND_JIT_EXIT_BLACKLISTED;
} zend_catch {
do_bailout = 1;
if (JIT_G(active_ctx)) {
zend_jit_free_ctx(JIT_G(active_ctx));
JIT_G(active_ctx) = NULL;
}
} zend_end_try();

zend_jit_protect();
Expand Down Expand Up @@ -8293,6 +8310,7 @@ static zend_jit_trace_stop zend_jit_compile_side_trace(zend_jit_trace_rec *trace
} else if (zend_jit_traces[zend_jit_traces[parent_num].root].child_count >= JIT_G(max_side_traces)) {
ret = ZEND_JIT_TRACE_STOP_TOO_MANY_CHILDREN;
} else {
orig_trigger = JIT_G(trigger);
SHM_UNPROTECT();
zend_jit_unprotect();

Expand All @@ -8315,7 +8333,6 @@ static zend_jit_trace_stop zend_jit_compile_side_trace(zend_jit_trace_rec *trace
t->consts_count = 0;
t->constants = NULL;

orig_trigger = JIT_G(trigger);
JIT_G(trigger) = ZEND_JIT_ON_HOT_TRACE;

handler = zend_jit_trace(trace_buffer, parent_num, exit_num);
Expand Down Expand Up @@ -8418,6 +8435,11 @@ static zend_jit_trace_stop zend_jit_compile_side_trace(zend_jit_trace_rec *trace
exit:;
} zend_catch {
do_bailout = 1;
JIT_G(trigger) = orig_trigger;
if (JIT_G(active_ctx)) {
zend_jit_free_ctx(JIT_G(active_ctx));
JIT_G(active_ctx) = NULL;
}
} zend_end_try();

zend_jit_protect();
Expand Down
Loading