Skip to content

Commit 739eb43

Browse files
committed
Tracing JIT support for preloaded scripts
1 parent 82f0d3c commit 739eb43

File tree

3 files changed

+146
-21
lines changed

3 files changed

+146
-21
lines changed

ext/opcache/ZendAccelerator.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4487,7 +4487,6 @@ static int accel_preload(const char *config, zend_bool in_child)
44874487
} zend_end_try();
44884488

44894489
PG(open_basedir) = orig_open_basedir;
4490-
CG(compiler_options) = orig_compiler_options;
44914490
accelerator_orig_compile_file = preload_orig_compile_file;
44924491
ZCG(enabled) = 1;
44934492

@@ -4726,6 +4725,7 @@ static int accel_preload(const char *config, zend_bool in_child)
47264725
}
47274726

47284727
finish:
4728+
CG(compiler_options) = orig_compiler_options;
47294729
zend_hash_destroy(preload_scripts);
47304730
efree(preload_scripts);
47314731
preload_scripts = NULL;

ext/opcache/jit/zend_jit.c

Lines changed: 125 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3626,9 +3626,55 @@ void ZEND_FASTCALL zend_jit_hot_func(zend_execute_data *execute_data, const zend
36263626
/* JIT-ed code is going to be called by VM */
36273627
}
36283628

3629+
static void zend_jit_setup_hot_counters_ex(zend_op_array *op_array, zend_cfg *cfg)
3630+
{
3631+
if (JIT_G(hot_func)) {
3632+
zend_op *opline = op_array->opcodes;
3633+
3634+
if (!(op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) {
3635+
while (opline->opcode == ZEND_RECV || opline->opcode == ZEND_RECV_INIT) {
3636+
opline++;
3637+
}
3638+
}
3639+
3640+
opline->handler = (const void*)zend_jit_func_hot_counter_handler;
3641+
}
3642+
3643+
if (JIT_G(hot_loop)) {
3644+
uint32_t i;
3645+
3646+
for (i = 0; i < cfg->blocks_count; i++) {
3647+
if ((cfg->blocks[i].flags & ZEND_BB_REACHABLE) &&
3648+
(cfg->blocks[i].flags & ZEND_BB_LOOP_HEADER)) {
3649+
op_array->opcodes[cfg->blocks[i].start].handler =
3650+
(const void*)zend_jit_loop_hot_counter_handler;
3651+
}
3652+
}
3653+
}
3654+
}
3655+
3656+
static int zend_jit_restart_hot_counters(zend_op_array *op_array)
3657+
{
3658+
zend_jit_op_array_hot_extension *jit_extension;
3659+
zend_cfg cfg;
3660+
uint32_t i;
3661+
3662+
jit_extension = (zend_jit_op_array_hot_extension*)ZEND_FUNC_INFO(op_array);
3663+
for (i = 0; i < op_array->last; i++) {
3664+
op_array->opcodes[i].handler = jit_extension->orig_handlers[i];
3665+
}
3666+
3667+
if (zend_jit_build_cfg(op_array, &cfg) != SUCCESS) {
3668+
return FAILURE;
3669+
}
3670+
3671+
zend_jit_setup_hot_counters_ex(op_array, &cfg);
3672+
3673+
return SUCCESS;
3674+
}
3675+
36293676
static int zend_jit_setup_hot_counters(zend_op_array *op_array)
36303677
{
3631-
zend_op *opline = op_array->opcodes;
36323678
zend_jit_op_array_hot_extension *jit_extension;
36333679
zend_cfg cfg;
36343680
uint32_t i;
@@ -3649,25 +3695,7 @@ static int zend_jit_setup_hot_counters(zend_op_array *op_array)
36493695
}
36503696
ZEND_SET_FUNC_INFO(op_array, (void*)jit_extension);
36513697

3652-
if (JIT_G(hot_func)) {
3653-
if (!(op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) {
3654-
while (opline->opcode == ZEND_RECV || opline->opcode == ZEND_RECV_INIT) {
3655-
opline++;
3656-
}
3657-
}
3658-
3659-
opline->handler = (const void*)zend_jit_func_hot_counter_handler;
3660-
}
3661-
3662-
if (JIT_G(hot_loop)) {
3663-
for (i = 0; i < cfg.blocks_count; i++) {
3664-
if ((cfg.blocks[i].flags & ZEND_BB_REACHABLE) &&
3665-
(cfg.blocks[i].flags & ZEND_BB_LOOP_HEADER)) {
3666-
op_array->opcodes[cfg.blocks[i].start].handler =
3667-
(const void*)zend_jit_loop_hot_counter_handler;
3668-
}
3669-
}
3670-
}
3698+
zend_jit_setup_hot_counters_ex(op_array, &cfg);
36713699

36723700
zend_shared_alloc_register_xlat_entry(op_array->opcodes, jit_extension);
36733701

@@ -3686,6 +3714,12 @@ ZEND_EXT_API int zend_jit_op_array(zend_op_array *op_array, zend_script *script)
36863714
zend_jit_op_array_extension *jit_extension;
36873715
zend_op *opline = op_array->opcodes;
36883716

3717+
if (CG(compiler_options) & ZEND_COMPILE_PRELOAD) {
3718+
ZEND_SET_FUNC_INFO(op_array, NULL);
3719+
zend_error(E_WARNING, "Preloading is incompatible with first-exec and profile triggered JIT");
3720+
return SUCCESS;
3721+
}
3722+
36893723
/* Set run-time JIT handler */
36903724
ZEND_ASSERT(zend_jit_runtime_jit_handler != NULL);
36913725
if (!(op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) {
@@ -3706,6 +3740,12 @@ ZEND_EXT_API int zend_jit_op_array(zend_op_array *op_array, zend_script *script)
37063740
zend_jit_op_array_extension *jit_extension;
37073741
zend_op *opline = op_array->opcodes;
37083742

3743+
if (CG(compiler_options) & ZEND_COMPILE_PRELOAD) {
3744+
ZEND_SET_FUNC_INFO(op_array, NULL);
3745+
zend_error(E_WARNING, "Preloading is incompatible with first-exec and profile triggered JIT");
3746+
return SUCCESS;
3747+
}
3748+
37093749
ZEND_ASSERT(zend_jit_profile_jit_handler != NULL);
37103750
if (op_array->function_name) {
37113751
if (!(op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) {
@@ -4265,6 +4305,59 @@ ZEND_EXT_API void zend_jit_deactivate(void)
42654305
}
42664306
}
42674307

4308+
static void zend_jit_restart_preloaded_op_array(zend_op_array *op_array)
4309+
{
4310+
zend_func_info *func_info = ZEND_FUNC_INFO(op_array);
4311+
4312+
if (!func_info) {
4313+
return;
4314+
}
4315+
4316+
if (func_info->flags & ZEND_FUNC_JIT_ON_HOT_TRACE) {
4317+
zend_jit_restart_hot_trace_counters(op_array);
4318+
} else if (func_info->flags & ZEND_FUNC_JIT_ON_HOT_COUNTERS) {
4319+
zend_jit_restart_hot_counters(op_array);
4320+
#if 0
4321+
// TODO: We have to restore handlers for some inner basic-blocks, but we didn't store them ???
4322+
} else if (func_info->flags & (ZEND_FUNC_JIT_ON_FIRST_EXEC|ZEND_FUNC_JIT_ON_PROF_REQUEST)) {
4323+
zend_op *opline = op_array->opcodes;
4324+
zend_jit_op_array_extension *jit_extension =
4325+
(zend_jit_op_array_extension*)func_info;
4326+
4327+
if (!(op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) {
4328+
while (opline->opcode == ZEND_RECV || opline->opcode == ZEND_RECV_INIT) {
4329+
opline++;
4330+
}
4331+
}
4332+
if (func_info->flags & ZEND_FUNC_JIT_ON_FIRST_EXEC) {
4333+
opline->handler = (const void*)zend_jit_runtime_jit_handler;
4334+
} else {
4335+
opline->handler = (const void*)zend_jit_profile_jit_handler;
4336+
}
4337+
#endif
4338+
}
4339+
}
4340+
4341+
static void zend_jit_restart_preloaded_script(zend_persistent_script *script)
4342+
{
4343+
zend_class_entry *ce;
4344+
zend_op_array *op_array;
4345+
4346+
zend_jit_restart_preloaded_op_array(&script->script.main_op_array);
4347+
4348+
ZEND_HASH_FOREACH_PTR(&script->script.function_table, op_array) {
4349+
zend_jit_restart_preloaded_op_array(op_array);
4350+
} ZEND_HASH_FOREACH_END();
4351+
4352+
ZEND_HASH_FOREACH_PTR(&script->script.class_table, ce) {
4353+
ZEND_HASH_FOREACH_PTR(&ce->function_table, op_array) {
4354+
if (op_array->type == ZEND_USER_FUNCTION) {
4355+
zend_jit_restart_preloaded_op_array(op_array);
4356+
}
4357+
} ZEND_HASH_FOREACH_END();
4358+
} ZEND_HASH_FOREACH_END();
4359+
}
4360+
42684361
ZEND_EXT_API void zend_jit_restart(void)
42694362
{
42704363
if (dasm_buf) {
@@ -4275,6 +4368,18 @@ ZEND_EXT_API void zend_jit_restart(void)
42754368

42764369
zend_jit_trace_restart();
42774370

4371+
if (ZCSG(preload_script)) {
4372+
zend_jit_restart_preloaded_script(ZCSG(preload_script));
4373+
if (ZCSG(saved_scripts)) {
4374+
zend_persistent_script **p = ZCSG(saved_scripts);
4375+
4376+
while (*p) {
4377+
zend_jit_restart_preloaded_script(*p);
4378+
p++;
4379+
}
4380+
}
4381+
}
4382+
42784383
zend_jit_protect();
42794384
}
42804385
}

ext/opcache/jit/zend_jit_trace.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6833,6 +6833,26 @@ static zend_always_inline uint8_t zend_jit_trace_supported(const zend_op *opline
68336833
}
68346834
}
68356835

6836+
static int zend_jit_restart_hot_trace_counters(zend_op_array *op_array)
6837+
{
6838+
zend_jit_op_array_trace_extension *jit_extension;
6839+
uint32_t i;
6840+
6841+
jit_extension = (zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(op_array);
6842+
for (i = 0; i < op_array->last; i++) {
6843+
jit_extension->trace_info[i].trace_flags &=
6844+
ZEND_JIT_TRACE_START_LOOP | ZEND_JIT_TRACE_START_ENTER | ZEND_JIT_TRACE_UNSUPPORTED;
6845+
if (jit_extension->trace_info[i].trace_flags == ZEND_JIT_TRACE_START_LOOP) {
6846+
op_array->opcodes[i].handler = (const void*)zend_jit_loop_trace_counter_handler;
6847+
} else if (jit_extension->trace_info[i].trace_flags == ZEND_JIT_TRACE_START_ENTER) {
6848+
op_array->opcodes[i].handler = (const void*)zend_jit_func_trace_counter_handler;
6849+
} else {
6850+
op_array->opcodes[i].handler = jit_extension->trace_info[i].orig_handler;
6851+
}
6852+
}
6853+
return SUCCESS;
6854+
}
6855+
68366856
static int zend_jit_setup_hot_trace_counters(zend_op_array *op_array)
68376857
{
68386858
zend_op *opline;

0 commit comments

Comments
 (0)