Skip to content

Commit 5783e61

Browse files
committed
Improve trace selection (avoid blacklisting of trace that may be linked).
1 parent 2556967 commit 5783e61

File tree

1 file changed

+29
-45
lines changed

1 file changed

+29
-45
lines changed

ext/opcache/jit/zend_jit_vm_helpers.c

Lines changed: 29 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -416,57 +416,20 @@ static int zend_jit_trace_has_recursive_ret(zend_execute_data *ex, const zend_op
416416
return 0;
417417
}
418418

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)
420420
{
421421
const zend_op **cache_opline = JIT_G(bad_root_cache_opline);
422422
uint8_t *cache_count = JIT_G(bad_root_cache_count);
423423
uint8_t *cache_stop = JIT_G(bad_root_cache_stop);
424424
uint32_t i;
425425

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;
454428
}
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-
465429
for (i = 0; i < ZEND_JIT_TRACE_BAD_ROOT_SLOTS; i++) {
466430
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];
470433
}
471434
break;
472435
}
@@ -590,6 +553,8 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
590553
int idx, count;
591554
uint8_t trace_flags, op1_type, op2_type, op3_type;
592555
zend_class_entry *ce1, *ce2;
556+
const zend_op *link_to_enter_opline = NULL;
557+
int backtrack_link_to_enter = -1;
593558
int backtrack_recursion = -1;
594559
int backtrack_ret_recursion = -1;
595560
int backtrack_ret_recursion_level = 0;
@@ -877,7 +842,8 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
877842
idx = ret;
878843
}
879844
} 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) {
881847
/* Fail to try close the loop.
882848
If this doesn't work terminate it. */
883849
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,
966932
if (trace_flags & ZEND_JIT_TRACE_START_LOOP) {
967933
if ((start & ZEND_JIT_TRACE_START_LOOP) != 0
968934
&& 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) {
970937
/* Fail to try close outer loop through side exit.
971938
If this doesn't work just link. */
972939
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,
981948
stop = ZEND_JIT_TRACE_STOP_LINK;
982949
break;
983950
}
951+
if (backtrack_link_to_enter < 0) {
952+
backtrack_link_to_enter = idx;
953+
link_to_enter_opline = opline;
954+
}
984955
} else {
985956
stop = ZEND_JIT_TRACE_STOP_LINK;
986957
break;
@@ -990,13 +961,18 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
990961
break;
991962
} else if (trace_flags & ZEND_JIT_TRACE_START_LOOP) {
992963
if (start != ZEND_JIT_TRACE_START_SIDE) {
964+
uint8_t bad_stop;
965+
993966
if (opline == orig_opline && level + ret_level == 0) {
994967
stop = ZEND_JIT_TRACE_STOP_LOOP;
995968
break;
996969
}
997970
/* Fail to try creating a trace for inner loop first.
998971
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) {
1000976
stop = ZEND_JIT_TRACE_STOP_INNER_LOOP;
1001977
break;
1002978
}
@@ -1026,6 +1002,14 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
10261002
ret_level = backtrack_ret_recursion_level;
10271003
stop = ZEND_JIT_TRACE_STOP_RECURSIVE_RET;
10281004
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+
}
10291013
}
10301014
}
10311015

0 commit comments

Comments
 (0)