Skip to content

Commit 11946e9

Browse files
author
wxue1
committed
Stop JIT hot spot counting
When max_root_trace is reached, JIT in tracing mode will not compile any new code for root trace and side trace, but counting hot code is still going on. This patch stops counting as soon as possible by replacing counter handler with original handler, which increases 1.5% performance. Signed-off-by: Wang, Xue <xue1.wang@intel.com>
1 parent b0c658f commit 11946e9

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

ext/opcache/jit/zend_jit_trace.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7125,6 +7125,74 @@ static zend_jit_trace_stop zend_jit_compile_root_trace(zend_jit_trace_rec *trace
71257125
return ret;
71267126
}
71277127

7128+
/* Set counting handler back to original VM handler. */
7129+
static void zend_jit_stop_hot_trace_counters(zend_op_array *op_array)
7130+
{
7131+
zend_jit_op_array_trace_extension *jit_extension;
7132+
uint32_t i;
7133+
7134+
jit_extension = (zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(op_array);
7135+
zend_shared_alloc_lock();
7136+
SHM_UNPROTECT();
7137+
for (i = 0; i < op_array->last; i++) {
7138+
/* Opline with Jit-ed code handler is skipped. */
7139+
if (jit_extension->trace_info[i].trace_flags &
7140+
(ZEND_JIT_TRACE_JITED|ZEND_JIT_TRACE_BLACKLISTED)) {
7141+
continue;
7142+
}
7143+
if (jit_extension->trace_info[i].trace_flags &
7144+
(ZEND_JIT_TRACE_START_LOOP | ZEND_JIT_TRACE_START_ENTER | ZEND_JIT_TRACE_START_RETURN)) {
7145+
op_array->opcodes[i].handler = jit_extension->trace_info[i].orig_handler;
7146+
}
7147+
}
7148+
SHM_PROTECT();
7149+
zend_shared_alloc_unlock();
7150+
}
7151+
7152+
/* Get the tracing op_array. */
7153+
static void zend_jit_stop_persistent_op_array(zend_op_array *op_array) {
7154+
zend_func_info *func_info = ZEND_FUNC_INFO(op_array);
7155+
if (!func_info) {
7156+
return;
7157+
}
7158+
if (func_info->flags & ZEND_FUNC_JIT_ON_HOT_TRACE) {
7159+
zend_jit_stop_hot_trace_counters(op_array);
7160+
}
7161+
}
7162+
7163+
/* Get all op_arrays with counter handler. */
7164+
static void zend_jit_stop_persistent_script(zend_persistent_script *script) {
7165+
zend_class_entry *ce;
7166+
zend_op_array *op_array;
7167+
7168+
zend_jit_stop_persistent_op_array(&script->script.main_op_array);
7169+
7170+
ZEND_HASH_FOREACH_PTR(&script->script.function_table, op_array) {
7171+
zend_jit_stop_persistent_op_array(op_array);
7172+
} ZEND_HASH_FOREACH_END();
7173+
7174+
ZEND_HASH_FOREACH_PTR(&script->script.class_table, ce) {
7175+
ZEND_HASH_FOREACH_PTR(&ce->function_table, op_array) {
7176+
if (op_array->type == ZEND_USER_FUNCTION) {
7177+
zend_jit_stop_persistent_op_array(op_array);
7178+
}
7179+
} ZEND_HASH_FOREACH_END();
7180+
} ZEND_HASH_FOREACH_END();
7181+
}
7182+
7183+
/* Get all scripts which are accelerated by JIT */
7184+
static void zend_jit_stop_counter_handlers() {
7185+
for (uint32_t i = 0; i < ZCSG(hash).max_num_entries; i++) {
7186+
zend_accel_hash_entry *cache_entry;
7187+
for (cache_entry = ZCSG(hash).hash_table[i]; cache_entry; cache_entry = cache_entry->next) {
7188+
zend_persistent_script *script;
7189+
if (cache_entry->indirect) continue;
7190+
script = (zend_persistent_script *)cache_entry->data;
7191+
zend_jit_stop_persistent_script(script);
7192+
}
7193+
}
7194+
}
7195+
71287196
static void zend_jit_blacklist_root_trace(const zend_op *opline, size_t offset)
71297197
{
71307198
zend_shared_alloc_lock();
@@ -7505,6 +7573,7 @@ int ZEND_FASTCALL zend_jit_trace_hot_root(zend_execute_data *execute_data, const
75057573

75067574
if (ZEND_JIT_TRACE_NUM >= JIT_G(max_root_traces)) {
75077575
stop = ZEND_JIT_TRACE_STOP_TOO_MANY_TRACES;
7576+
zend_jit_stop_counter_handlers();
75087577
goto abort;
75097578
}
75107579

0 commit comments

Comments
 (0)