@@ -416,57 +416,20 @@ static int zend_jit_trace_has_recursive_ret(zend_execute_data *ex, const zend_op
416
416
return 0 ;
417
417
}
418
418
419
- static int zend_jit_trace_bad_inner_loop (const zend_op * opline )
419
+ static uint8_t zend_jit_trace_bad_stop_event (const zend_op * opline , int count )
420
420
{
421
421
const zend_op * * cache_opline = JIT_G (bad_root_cache_opline );
422
422
uint8_t * cache_count = JIT_G (bad_root_cache_count );
423
423
uint8_t * cache_stop = JIT_G (bad_root_cache_stop );
424
424
uint32_t i ;
425
425
426
- for (i = 0 ; i < ZEND_JIT_TRACE_BAD_ROOT_SLOTS ; i ++ ) {
427
- if (cache_opline [i ] == opline ) {
428
- if ((cache_stop [i ] == ZEND_JIT_TRACE_STOP_INNER_LOOP
429
- || cache_stop [i ] == ZEND_JIT_TRACE_STOP_LOOP_EXIT )
430
- && cache_count [i ] > JIT_G (blacklist_root_trace ) / 2 ) {
431
- return 1 ;
432
- }
433
- break ;
434
- }
435
- }
436
- return 0 ;
437
- }
438
-
439
- static int zend_jit_trace_bad_compiled_loop (const zend_op * opline )
440
- {
441
- const zend_op * * cache_opline = JIT_G (bad_root_cache_opline );
442
- uint8_t * cache_count = JIT_G (bad_root_cache_count );
443
- uint8_t * cache_stop = JIT_G (bad_root_cache_stop );
444
- uint32_t i ;
445
-
446
- for (i = 0 ; i < ZEND_JIT_TRACE_BAD_ROOT_SLOTS ; i ++ ) {
447
- if (cache_opline [i ] == opline ) {
448
- if (cache_stop [i ] == ZEND_JIT_TRACE_STOP_COMPILED_LOOP
449
- && cache_count [i ] >= JIT_G (blacklist_root_trace ) - 1 ) {
450
- return 1 ;
451
- }
452
- break ;
453
- }
426
+ if (count < 0 ) {
427
+ count = 0 ;
454
428
}
455
- return 0 ;
456
- }
457
-
458
- static int zend_jit_trace_bad_loop_exit (const zend_op * opline )
459
- {
460
- const zend_op * * cache_opline = JIT_G (bad_root_cache_opline );
461
- uint8_t * cache_count = JIT_G (bad_root_cache_count );
462
- uint8_t * cache_stop = JIT_G (bad_root_cache_stop );
463
- uint32_t i ;
464
-
465
429
for (i = 0 ; i < ZEND_JIT_TRACE_BAD_ROOT_SLOTS ; i ++ ) {
466
430
if (cache_opline [i ] == opline ) {
467
- if (cache_stop [i ] == ZEND_JIT_TRACE_STOP_LOOP_EXIT
468
- && cache_count [i ] >= JIT_G (blacklist_root_trace ) - 1 ) {
469
- return 1 ;
431
+ if (cache_count [i ] >= count ) {
432
+ return cache_stop [i ];
470
433
}
471
434
break ;
472
435
}
@@ -590,6 +553,8 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
590
553
int idx , count ;
591
554
uint8_t trace_flags , op1_type , op2_type , op3_type ;
592
555
zend_class_entry * ce1 , * ce2 ;
556
+ const zend_op * link_to_enter_opline = NULL ;
557
+ int backtrack_link_to_enter = -1 ;
593
558
int backtrack_recursion = -1 ;
594
559
int backtrack_ret_recursion = -1 ;
595
560
int backtrack_ret_recursion_level = 0 ;
@@ -877,7 +842,8 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
877
842
idx = ret ;
878
843
}
879
844
} else if (start & ZEND_JIT_TRACE_START_LOOP
880
- && !zend_jit_trace_bad_loop_exit (orig_opline )) {
845
+ && zend_jit_trace_bad_stop_event (orig_opline , JIT_G (blacklist_root_trace ) - 1 ) !=
846
+ ZEND_JIT_TRACE_STOP_LOOP_EXIT ) {
881
847
/* Fail to try close the loop.
882
848
If this doesn't work terminate it. */
883
849
stop = ZEND_JIT_TRACE_STOP_LOOP_EXIT ;
@@ -966,7 +932,8 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
966
932
if (trace_flags & ZEND_JIT_TRACE_START_LOOP ) {
967
933
if ((start & ZEND_JIT_TRACE_START_LOOP ) != 0
968
934
&& level + ret_level == 0
969
- && !zend_jit_trace_bad_compiled_loop (orig_opline )) {
935
+ && zend_jit_trace_bad_stop_event (orig_opline , JIT_G (blacklist_root_trace ) - 1 ) !=
936
+ ZEND_JIT_TRACE_STOP_COMPILED_LOOP ) {
970
937
/* Fail to try close outer loop through side exit.
971
938
If this doesn't work just link. */
972
939
stop = ZEND_JIT_TRACE_STOP_COMPILED_LOOP ;
@@ -981,6 +948,10 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
981
948
stop = ZEND_JIT_TRACE_STOP_LINK ;
982
949
break ;
983
950
}
951
+ if (backtrack_link_to_enter < 0 ) {
952
+ backtrack_link_to_enter = idx ;
953
+ link_to_enter_opline = opline ;
954
+ }
984
955
} else {
985
956
stop = ZEND_JIT_TRACE_STOP_LINK ;
986
957
break ;
@@ -990,13 +961,18 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
990
961
break ;
991
962
} else if (trace_flags & ZEND_JIT_TRACE_START_LOOP ) {
992
963
if (start != ZEND_JIT_TRACE_START_SIDE ) {
964
+ uint8_t bad_stop ;
965
+
993
966
if (opline == orig_opline && level + ret_level == 0 ) {
994
967
stop = ZEND_JIT_TRACE_STOP_LOOP ;
995
968
break ;
996
969
}
997
970
/* Fail to try creating a trace for inner loop first.
998
971
If this doesn't work try unroling loop. */
999
- if (!zend_jit_trace_bad_inner_loop (opline )) {
972
+ bad_stop = zend_jit_trace_bad_stop_event (opline ,
973
+ JIT_G (blacklist_root_trace ) / 2 );
974
+ if (bad_stop != ZEND_JIT_TRACE_STOP_INNER_LOOP
975
+ && bad_stop != ZEND_JIT_TRACE_STOP_LOOP_EXIT ) {
1000
976
stop = ZEND_JIT_TRACE_STOP_INNER_LOOP ;
1001
977
break ;
1002
978
}
@@ -1026,6 +1002,14 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
1026
1002
ret_level = backtrack_ret_recursion_level ;
1027
1003
stop = ZEND_JIT_TRACE_STOP_RECURSIVE_RET ;
1028
1004
end_opline = orig_opline ;
1005
+ } else if (backtrack_link_to_enter > 0 ) {
1006
+ if (stop == ZEND_JIT_TRACE_STOP_DEEP_RECURSION
1007
+ && zend_jit_trace_bad_stop_event (orig_opline , JIT_G (blacklist_root_trace ) / 2 ) ==
1008
+ ZEND_JIT_TRACE_STOP_DEEP_RECURSION ) {
1009
+ idx = backtrack_link_to_enter ;
1010
+ stop = ZEND_JIT_TRACE_STOP_LINK ;
1011
+ end_opline = link_to_enter_opline ;
1012
+ }
1029
1013
}
1030
1014
}
1031
1015
0 commit comments