Skip to content

Commit 83bbf4b

Browse files
committed
Merge branch 'PHP-8.4'
* PHP-8.4: Improve JIT TRACE coverage (#16171)
2 parents d7bdf90 + ddc4915 commit 83bbf4b

File tree

3 files changed

+55
-6
lines changed

3 files changed

+55
-6
lines changed

ext/opcache/jit/zend_jit_internal.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,12 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_ret_trace_helper(ZEND_OPCODE_HAND
647647
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_trace_helper(ZEND_OPCODE_HANDLER_ARGS);
648648

649649
int ZEND_FASTCALL zend_jit_trace_hot_root(zend_execute_data *execute_data, const zend_op *opline);
650-
zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *execute_data, const zend_op *opline, zend_jit_trace_rec *trace_buffer, uint8_t start, uint32_t is_megamorphc);
650+
zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *execute_data,
651+
const zend_op *opline,
652+
zend_jit_trace_rec *trace_buffer,
653+
uint8_t start,
654+
uint32_t is_megamorphc,
655+
int ret_depth);
651656

652657
static zend_always_inline const zend_op* zend_jit_trace_get_exit_opline(zend_jit_trace_rec *trace, const zend_op *opline, bool *exit_if_true)
653658
{

ext/opcache/jit/zend_jit_trace.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8066,7 +8066,7 @@ int ZEND_FASTCALL zend_jit_trace_hot_root(zend_execute_data *execute_data, const
80668066

80678067
JIT_G(tracing) = 1;
80688068
stop = zend_jit_trace_execute(execute_data, opline, trace_buffer,
8069-
ZEND_OP_TRACE_INFO(opline, offset)->trace_flags & ZEND_JIT_TRACE_START_MASK, 0);
8069+
ZEND_OP_TRACE_INFO(opline, offset)->trace_flags & ZEND_JIT_TRACE_START_MASK, 0, 0);
80708070
JIT_G(tracing) = 0;
80718071

80728072
if (stop & ZEND_JIT_TRACE_HALT) {
@@ -8390,6 +8390,8 @@ int ZEND_FASTCALL zend_jit_trace_hot_side(zend_execute_data *execute_data, uint3
83908390
zend_jit_trace_rec trace_buffer[ZEND_JIT_TRACE_MAX_LENGTH];
83918391
uint32_t is_megamorphic = 0;
83928392
uint32_t polymorphism = 0;
8393+
uint32_t root;
8394+
int ret_depth = 0;
83938395

83948396
trace_num = ZEND_JIT_TRACE_NUM;
83958397

@@ -8414,7 +8416,8 @@ int ZEND_FASTCALL zend_jit_trace_hot_side(zend_execute_data *execute_data, uint3
84148416
goto abort;
84158417
}
84168418

8417-
if (zend_jit_traces[zend_jit_traces[parent_num].root].child_count >= JIT_G(max_side_traces)) {
8419+
root = zend_jit_traces[parent_num].root;
8420+
if (zend_jit_traces[root].child_count >= JIT_G(max_side_traces)) {
84188421
stop = ZEND_JIT_TRACE_STOP_TOO_MANY_CHILDREN;
84198422
goto abort;
84208423
}
@@ -8434,8 +8437,29 @@ int ZEND_FASTCALL zend_jit_trace_hot_side(zend_execute_data *execute_data, uint3
84348437
}
84358438
}
84368439

8440+
/* Check if this is a side trace of a root LOOP trace */
8441+
if ((zend_jit_traces[root].flags & ZEND_JIT_TRACE_LOOP)
8442+
&& zend_jit_traces[root].op_array != &EX(func)->op_array) {
8443+
const zend_op_array *op_array = zend_jit_traces[root].op_array;
8444+
const zend_op *opline = zend_jit_traces[root].opline;
8445+
zend_jit_op_array_trace_extension *jit_extension =
8446+
(zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(op_array);
8447+
8448+
if (jit_extension->trace_info[opline - op_array->opcodes].trace_flags & ZEND_JIT_TRACE_START_LOOP) {
8449+
zend_execute_data *ex = execute_data;
8450+
int n = 0;
8451+
do {
8452+
ex = ex->prev_execute_data;
8453+
n++;
8454+
} while (ex && zend_jit_traces[root].op_array != &ex->func->op_array);
8455+
if (ex && n <= ZEND_JIT_TRACE_MAX_RET_DEPTH) {
8456+
ret_depth = n;
8457+
}
8458+
}
8459+
}
8460+
84378461
JIT_G(tracing) = 1;
8438-
stop = zend_jit_trace_execute(execute_data, EX(opline), trace_buffer, ZEND_JIT_TRACE_START_SIDE, is_megamorphic);
8462+
stop = zend_jit_trace_execute(execute_data, EX(opline), trace_buffer, ZEND_JIT_TRACE_START_SIDE, is_megamorphic, ret_depth);
84398463
JIT_G(tracing) = 0;
84408464

84418465
if (stop & ZEND_JIT_TRACE_HALT) {

ext/opcache/jit/zend_jit_vm_helpers.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ static int zend_jit_trace_subtrace(zend_jit_trace_rec *trace_buffer, int start,
575575
* +--------+----------+----------+----------++----------+----------+----------+
576576
* | RETURN |INNER_LOOP| | rec-ret || LINK | | LINK |
577577
* +--------+----------+----------+----------++----------+----------+----------+
578-
* | SIDE | unroll | | return || LINK | LINK | LINK |
578+
* | SIDE | unroll | | side-ret || LINK | LINK | LINK |
579579
* +--------+----------+----------+----------++----------+----------+----------+
580580
*
581581
* loop: LOOP if "cycle" and level == 0, otherwise INNER_LOOP
@@ -586,10 +586,16 @@ static int zend_jit_trace_subtrace(zend_jit_trace_rec *trace_buffer, int start,
586586
* loop-ret: LOOP_EXIT if level == 0, otherwise continue (wait for loop)
587587
* return: RETURN if level == 0
588588
* rec_ret: RECURSIVE_RET if "cycle" and ret_level > N, otherwise continue
589+
* side_ret: RETURN if level == 0 && ret_level == ret_depth, otherwise continue
589590
*
590591
*/
591592

592-
zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, const zend_op *op, zend_jit_trace_rec *trace_buffer, uint8_t start, uint32_t is_megamorphic)
593+
zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
594+
const zend_op *op,
595+
zend_jit_trace_rec *trace_buffer,
596+
uint8_t start,
597+
uint32_t is_megamorphic,
598+
int ret_depth)
593599

594600
{
595601
#ifdef HAVE_GCC_GLOBAL_REGS
@@ -1060,6 +1066,20 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
10601066
ZEND_JIT_TRACE_STOP_RECURSION_EXIT) {
10611067
stop = ZEND_JIT_TRACE_STOP_RECURSION_EXIT;
10621068
break;
1069+
} else if ((start & ZEND_JIT_TRACE_START_SIDE)
1070+
&& ret_level < ret_depth) {
1071+
TRACE_RECORD(ZEND_JIT_TRACE_BACK, 0, op_array);
1072+
ret_level++;
1073+
last_loop_opline = NULL;
1074+
1075+
if (prev_call) {
1076+
int ret = zend_jit_trace_record_fake_init_call(prev_call, trace_buffer, idx, 0);
1077+
if (ret < 0) {
1078+
stop = ZEND_JIT_TRACE_STOP_BAD_FUNC;
1079+
break;
1080+
}
1081+
idx = ret;
1082+
}
10631083
} else {
10641084
stop = ZEND_JIT_TRACE_STOP_RETURN;
10651085
break;

0 commit comments

Comments
 (0)