Skip to content

Commit 8ffa0e9

Browse files
author
wxue1
committed
Link to the compiled function to improve performance
When JIT is recording, backtrack the trace if encountering a compiled inline function and link to this function later. This reduces the runtime compilation overhead and duplicated JITTed code. Smaller code size has better cache efficiency, which brings 1.7% performance gain in our benchmark on x86. Signed-off-by: Wang, Xue <[email protected]> Signed-off-by: Yang, Lin A <[email protected]> Signed-off-by: Su, Tao <[email protected]>
1 parent 05c46b7 commit 8ffa0e9

File tree

3 files changed

+19
-0
lines changed

3 files changed

+19
-0
lines changed

ext/opcache/jit/zend_jit.h

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ typedef struct _zend_jit_globals {
116116
zend_long max_recursive_returns; /* max number of recursive inlined return unrolls */
117117
zend_long max_polymorphic_calls; /* max number of inlined polymorphic calls */
118118
zend_long max_trace_length; /* max length of a single trace */
119+
zend_long jit_trace_inline_func_limit; /* max length of inlined function in a trace */
119120

120121
zend_sym_node *symbols; /* symbols for disassembler */
121122

ext/opcache/jit/zend_jit_vm_helpers.c

+16
Original file line numberDiff line numberDiff line change
@@ -562,10 +562,14 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
562562
uint8_t trace_flags, op1_type, op2_type, op3_type;
563563
zend_class_entry *ce1, *ce2;
564564
const zend_op *link_to_enter_opline = NULL;
565+
/* Remember the first opline of inline function*/
566+
const zend_op *link_to_inline_func_opline = NULL;
565567
int backtrack_link_to_enter = -1;
566568
int backtrack_recursion = -1;
567569
int backtrack_ret_recursion = -1;
568570
int backtrack_ret_recursion_level = 0;
571+
/* Remember the index of inline function opline in the trace buffer */
572+
int backtrack_link_to_inline_func = -1;
569573
int loop_unroll_limit = 0;
570574
int last_loop = -1;
571575
int last_loop_level = -1;
@@ -922,6 +926,13 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
922926
} else if (count >= JIT_G(max_recursive_calls)) {
923927
stop = ZEND_JIT_TRACE_STOP_DEEP_RECURSION;
924928
break;
929+
/* If the inline function is JITTed, backtrack this trace. */
930+
} else if ( idx > JIT_G(jit_trace_inline_func_limit) && \
931+
backtrack_link_to_inline_func < 0 && \
932+
(ZEND_OP_TRACE_INFO(opline, offset)->trace_flags & ZEND_JIT_TRACE_JITED)) {
933+
backtrack_link_to_inline_func = idx;
934+
link_to_inline_func_opline = opline;
935+
break;
925936
}
926937

927938
unrolled_calls[ret_level + level] = &EX(func)->op_array;
@@ -1156,6 +1167,11 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
11561167
ret_level = backtrack_ret_recursion_level;
11571168
stop = ZEND_JIT_TRACE_STOP_RECURSIVE_RET;
11581169
end_opline = orig_opline;
1170+
} else if (backtrack_link_to_inline_func > 0) {
1171+
/* Reset the index and stop flag to link to the compiled inline function. */
1172+
idx = backtrack_link_to_inline_func;
1173+
stop = ZEND_JIT_TRACE_STOP_LINK;
1174+
end_opline = link_to_inline_func_opline;
11591175
} else if (backtrack_link_to_enter > 0) {
11601176
if (stop == ZEND_JIT_TRACE_STOP_DEEP_RECURSION
11611177
&& zend_jit_trace_bad_stop_event(orig_opline, JIT_G(blacklist_root_trace) / 2) ==

ext/opcache/zend_accelerator_module.c

+2
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,7 @@ ZEND_INI_BEGIN()
336336
STD_PHP_INI_ENTRY("opcache.jit_max_recursive_returns" , "2", PHP_INI_ALL, OnUpdateUnrollR, max_recursive_returns, zend_jit_globals, jit_globals)
337337
STD_PHP_INI_ENTRY("opcache.jit_max_polymorphic_calls" , "2", PHP_INI_ALL, OnUpdateLong, max_polymorphic_calls, zend_jit_globals, jit_globals)
338338
STD_PHP_INI_ENTRY("opcache.jit_max_trace_length" , "1024", PHP_INI_ALL, OnUpdateMaxTraceLength, max_trace_length, zend_jit_globals, jit_globals)
339+
STD_PHP_INI_ENTRY("opcache.jit_trace_inline_func_limit" , "16", PHP_INI_ALL, OnUpdateLong, jit_trace_inline_func_limit, zend_jit_globals, jit_globals)
339340
#endif
340341
ZEND_INI_END()
341342

@@ -851,6 +852,7 @@ ZEND_FUNCTION(opcache_get_configuration)
851852
add_assoc_long(&directives, "opcache.jit_max_side_traces", JIT_G(max_side_traces));
852853
add_assoc_long(&directives, "opcache.jit_prof_threshold", JIT_G(prof_threshold));
853854
add_assoc_long(&directives, "opcache.jit_max_trace_length", JIT_G(max_trace_length));
855+
add_assoc_long(&directives, "opcache.jit_trace_inline_func_limit", JIT_G(jit_trace_inline_func_limit));
854856
#endif
855857

856858
add_assoc_zval(return_value, "directives", &directives);

0 commit comments

Comments
 (0)