Skip to content

Commit d4fdaa6

Browse files
committed
Add check for blacklisted traces when calling functions
Signed-off-by: Bob Weinand <[email protected]>
1 parent e0a40f4 commit d4fdaa6

File tree

1 file changed

+41
-13
lines changed

1 file changed

+41
-13
lines changed

ext/opcache/jit/zend_jit_vm_helpers.c

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -521,16 +521,27 @@ static int zend_jit_trace_record_fake_init_call_ex(zend_execute_data *call, zend
521521
&& (func->op_array.fn_flags & (ZEND_ACC_CLOSURE|ZEND_ACC_FAKE_CLOSURE))) {
522522
return -1;
523523
}
524-
if (func->type == ZEND_USER_FUNCTION
525-
&& (func->op_array.fn_flags & ZEND_ACC_CLOSURE)) {
524+
if (func->type == ZEND_USER_FUNCTION) {
526525
jit_extension =
527526
(zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(&func->op_array);
528-
if (UNEXPECTED(!jit_extension
529-
|| !(jit_extension->func_info.flags & ZEND_FUNC_JIT_ON_HOT_TRACE)
530-
|| (func->op_array.fn_flags & ZEND_ACC_FAKE_CLOSURE))) {
527+
if (func->op_array.fn_flags & ZEND_ACC_CLOSURE) {
528+
if (UNEXPECTED(!jit_extension
529+
|| !(jit_extension->func_info.flags & ZEND_FUNC_JIT_ON_HOT_TRACE)
530+
|| (func->op_array.fn_flags & ZEND_ACC_FAKE_CLOSURE))) {
531+
return -1;
532+
}
533+
func = (zend_function*)jit_extension->op_array;
534+
}
535+
// First not-skipped op
536+
zend_op *opline = func->op_array.opcodes;
537+
if (!(func->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) {
538+
while (opline->opcode == ZEND_RECV || opline->opcode == ZEND_RECV_INIT) {
539+
opline++;
540+
}
541+
}
542+
if (jit_extension && ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->trace_flags & ZEND_JIT_TRACE_BLACKLISTED) {
531543
return -1;
532544
}
533-
func = (zend_function*)jit_extension->op_array;
534545
}
535546
if (is_megamorphic == ZEND_JIT_EXIT_POLYMORPHISM
536547
/* TODO: use more accurate check ??? */
@@ -986,6 +997,11 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
986997
break;
987998
}
988999

1000+
if (jit_extension && ZEND_OP_TRACE_INFO(opline, offset)->trace_flags & ZEND_JIT_TRACE_BLACKLISTED) {
1001+
stop = ZEND_JIT_TRACE_STOP_BLACK_LIST;
1002+
break;
1003+
}
1004+
9891005
TRACE_RECORD(ZEND_JIT_TRACE_ENTER,
9901006
EX(return_value) != NULL ? ZEND_JIT_TRACE_RETURN_VALUE_USED : 0,
9911007
op_array);
@@ -1100,17 +1116,29 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
11001116
stop = ZEND_JIT_TRACE_STOP_BAD_FUNC;
11011117
break;
11021118
}
1103-
if (func->type == ZEND_USER_FUNCTION
1104-
&& (func->op_array.fn_flags & ZEND_ACC_CLOSURE)) {
1119+
if (func->type == ZEND_USER_FUNCTION) {
11051120
jit_extension =
11061121
(zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(&func->op_array);
1107-
if (UNEXPECTED(!jit_extension)
1108-
|| !(jit_extension->func_info.flags & ZEND_FUNC_JIT_ON_HOT_TRACE)
1109-
|| (func->op_array.fn_flags & ZEND_ACC_FAKE_CLOSURE)) {
1110-
stop = ZEND_JIT_TRACE_STOP_INTERPRETER;
1122+
if (func->op_array.fn_flags & ZEND_ACC_CLOSURE) {
1123+
if (UNEXPECTED(!jit_extension
1124+
|| !(jit_extension->func_info.flags & ZEND_FUNC_JIT_ON_HOT_TRACE)
1125+
|| (func->op_array.fn_flags & ZEND_ACC_FAKE_CLOSURE))) {
1126+
stop = ZEND_JIT_TRACE_STOP_INTERPRETER;
1127+
break;
1128+
}
1129+
func = (zend_function*)jit_extension->op_array;
1130+
}
1131+
// First not-skipped op
1132+
zend_op *opline = func->op_array.opcodes;
1133+
if (!(func->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) {
1134+
while (opline->opcode == ZEND_RECV || opline->opcode == ZEND_RECV_INIT) {
1135+
opline++;
1136+
}
1137+
}
1138+
if (jit_extension && ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->trace_flags & ZEND_JIT_TRACE_BLACKLISTED) {
1139+
stop = ZEND_JIT_TRACE_STOP_BLACK_LIST;
11111140
break;
11121141
}
1113-
func = (zend_function*)jit_extension->op_array;
11141142
}
11151143

11161144
#ifndef HAVE_GCC_GLOBAL_REGS

0 commit comments

Comments
 (0)