@@ -562,10 +562,16 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
562
562
uint8_t trace_flags , op1_type , op2_type , op3_type ;
563
563
zend_class_entry * ce1 , * ce2 ;
564
564
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 ;
565
567
int backtrack_link_to_enter = -1 ;
566
568
int backtrack_recursion = -1 ;
567
569
int backtrack_ret_recursion = -1 ;
568
570
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 ;
573
+ int backtrack_link_to_inline_func_next = -1 ;
574
+ bool link_to_inline_func_flag = false;
569
575
int loop_unroll_limit = 0 ;
570
576
int last_loop = -1 ;
571
577
int last_loop_level = -1 ;
@@ -908,6 +914,23 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
908
914
} else if (count >= JIT_G (max_recursive_calls )) {
909
915
stop = ZEND_JIT_TRACE_STOP_DEEP_RECURSION ;
910
916
break ;
917
+ } else if (backtrack_link_to_inline_func < 0 && backtrack_link_to_inline_func_next < 0 ) {
918
+ // && ZEND_OP_TRACE_INFO(opline, offset)->trace_flags & ZEND_JIT_TRACE_JITED
919
+ /* enter a compiled inline function, remember the idx */
920
+ backtrack_link_to_inline_func = idx ;
921
+ link_to_inline_func_opline = opline ;
922
+ } else if (backtrack_link_to_inline_func > 0 && backtrack_link_to_inline_func_next < 0 ) {
923
+ /* enter a function the second time */
924
+ backtrack_link_to_inline_func_next = idx ;
925
+ if (idx - backtrack_link_to_inline_func > JIT_G (jit_trace_inline_func_limit )) {
926
+ link_to_inline_func_flag = true;
927
+ break ;
928
+ } else {
929
+ /* the inline function is not too long */
930
+ backtrack_link_to_inline_func = backtrack_link_to_inline_func_next ;
931
+ link_to_inline_func_opline = opline ;
932
+ backtrack_link_to_inline_func_next = -1 ;
933
+ }
911
934
}
912
935
913
936
unrolled_calls [ret_level + level ] = & EX (func )-> op_array ;
@@ -925,6 +948,9 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
925
948
if (ret_level > ZEND_JIT_TRACE_MAX_RET_DEPTH ) {
926
949
stop = ZEND_JIT_TRACE_STOP_TOO_DEEP_RET ;
927
950
break ;
951
+ } else if (idx - backtrack_link_to_inline_func > JIT_G (jit_trace_inline_func_limit )) {
952
+ link_to_inline_func_flag = true;
953
+ break ;
928
954
}
929
955
TRACE_RECORD (ZEND_JIT_TRACE_BACK , 0 , op_array );
930
956
count = zend_jit_trace_recursive_ret_count (& EX (func )-> op_array , unrolled_calls , ret_level );
@@ -975,6 +1001,10 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
975
1001
if (level < last_loop_level ) {
976
1002
last_loop_opline = NULL ;
977
1003
}
1004
+ if (idx - backtrack_link_to_inline_func > JIT_G (jit_trace_inline_func_limit )) {
1005
+ link_to_inline_func_flag = true;
1006
+ break ;
1007
+ }
978
1008
TRACE_RECORD (ZEND_JIT_TRACE_BACK , 0 , op_array );
979
1009
}
980
1010
}
@@ -1142,6 +1172,11 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
1142
1172
ret_level = backtrack_ret_recursion_level ;
1143
1173
stop = ZEND_JIT_TRACE_STOP_RECURSIVE_RET ;
1144
1174
end_opline = orig_opline ;
1175
+ } else if (backtrack_link_to_inline_func > 0 && link_to_inline_func_flag == true) {
1176
+ /* Reset the index and stop flag to link to the long inline function. */
1177
+ idx = backtrack_link_to_inline_func ;
1178
+ stop = ZEND_JIT_TRACE_STOP_BACKTRACK_INLINE ;
1179
+ end_opline = link_to_inline_func_opline ;
1145
1180
} else if (backtrack_link_to_enter > 0 ) {
1146
1181
if (stop == ZEND_JIT_TRACE_STOP_DEEP_RECURSION
1147
1182
&& zend_jit_trace_bad_stop_event (orig_opline , JIT_G (blacklist_root_trace ) / 2 ) ==
0 commit comments