Skip to content

Commit e900343

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

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
@@ -512,16 +512,27 @@ static int zend_jit_trace_record_fake_init_call_ex(zend_execute_data *call, zend
512512
&& (func->op_array.fn_flags & (ZEND_ACC_CLOSURE|ZEND_ACC_FAKE_CLOSURE))) {
513513
return -1;
514514
}
515-
if (func->type == ZEND_USER_FUNCTION
516-
&& (func->op_array.fn_flags & ZEND_ACC_CLOSURE)) {
515+
if (func->type == ZEND_USER_FUNCTION) {
517516
jit_extension =
518517
(zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(&func->op_array);
519-
if (UNEXPECTED(!jit_extension
520-
|| !(jit_extension->func_info.flags & ZEND_FUNC_JIT_ON_HOT_TRACE)
521-
|| (func->op_array.fn_flags & ZEND_ACC_FAKE_CLOSURE))) {
518+
if (func->op_array.fn_flags & ZEND_ACC_CLOSURE) {
519+
if (UNEXPECTED(!jit_extension
520+
|| !(jit_extension->func_info.flags & ZEND_FUNC_JIT_ON_HOT_TRACE)
521+
|| (func->op_array.fn_flags & ZEND_ACC_FAKE_CLOSURE))) {
522+
return -1;
523+
}
524+
func = (zend_function*)jit_extension->op_array;
525+
}
526+
// First not-skipped op
527+
zend_op *opline = func->op_array.opcodes;
528+
if (!(func->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) {
529+
while (opline->opcode == ZEND_RECV || opline->opcode == ZEND_RECV_INIT) {
530+
opline++;
531+
}
532+
}
533+
if (jit_extension && ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->trace_flags & ZEND_JIT_TRACE_BLACKLISTED) {
522534
return -1;
523535
}
524-
func = (zend_function*)jit_extension->op_array;
525536
}
526537
if (is_megamorphic == ZEND_JIT_EXIT_POLYMORPHISM
527538
/* TODO: use more accurate check ??? */
@@ -977,6 +988,11 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
977988
break;
978989
}
979990

991+
if (jit_extension && ZEND_OP_TRACE_INFO(opline, offset)->trace_flags & ZEND_JIT_TRACE_BLACKLISTED) {
992+
stop = ZEND_JIT_TRACE_STOP_BLACK_LIST;
993+
break;
994+
}
995+
980996
TRACE_RECORD(ZEND_JIT_TRACE_ENTER,
981997
EX(return_value) != NULL ? ZEND_JIT_TRACE_RETURN_VALUE_USED : 0,
982998
op_array);
@@ -1091,17 +1107,29 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
10911107
stop = ZEND_JIT_TRACE_STOP_BAD_FUNC;
10921108
break;
10931109
}
1094-
if (func->type == ZEND_USER_FUNCTION
1095-
&& (func->op_array.fn_flags & ZEND_ACC_CLOSURE)) {
1110+
if (func->type == ZEND_USER_FUNCTION) {
10961111
jit_extension =
10971112
(zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(&func->op_array);
1098-
if (UNEXPECTED(!jit_extension)
1099-
|| !(jit_extension->func_info.flags & ZEND_FUNC_JIT_ON_HOT_TRACE)
1100-
|| (func->op_array.fn_flags & ZEND_ACC_FAKE_CLOSURE)) {
1101-
stop = ZEND_JIT_TRACE_STOP_INTERPRETER;
1113+
if (func->op_array.fn_flags & ZEND_ACC_CLOSURE) {
1114+
if (UNEXPECTED(!jit_extension
1115+
|| !(jit_extension->func_info.flags & ZEND_FUNC_JIT_ON_HOT_TRACE)
1116+
|| (func->op_array.fn_flags & ZEND_ACC_FAKE_CLOSURE))) {
1117+
stop = ZEND_JIT_TRACE_STOP_INTERPRETER;
1118+
break;
1119+
}
1120+
func = (zend_function*)jit_extension->op_array;
1121+
}
1122+
// First not-skipped op
1123+
zend_op *opline = func->op_array.opcodes;
1124+
if (!(func->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) {
1125+
while (opline->opcode == ZEND_RECV || opline->opcode == ZEND_RECV_INIT) {
1126+
opline++;
1127+
}
1128+
}
1129+
if (jit_extension && ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->trace_flags & ZEND_JIT_TRACE_BLACKLISTED) {
1130+
stop = ZEND_JIT_TRACE_STOP_BLACK_LIST;
11021131
break;
11031132
}
1104-
func = (zend_function*)jit_extension->op_array;
11051133
}
11061134

11071135
#ifndef HAVE_GCC_GLOBAL_REGS

0 commit comments

Comments
 (0)