From: Dmitry Stogov Date: Wed, 10 Jun 2020 05:10:27 +0000 (+0300) Subject: Setup RETURN counters for nested frames X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c1887974ccbf00f4c5a4950480eb53cf75c153a0;p=php Setup RETURN counters for nested frames --- diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h index 7666737ab4..1624bd816d 100644 --- a/ext/opcache/jit/zend_jit_internal.h +++ b/ext/opcache/jit/zend_jit_internal.h @@ -359,6 +359,7 @@ struct _zend_jit_trace_stack_frame { zend_jit_trace_stack_frame *call; zend_jit_trace_stack_frame *prev; const zend_function *func; + const zend_op *call_opline; uint32_t call_level; uint32_t _info; zend_jit_trace_stack stack[1]; @@ -382,6 +383,7 @@ struct _zend_jit_trace_stack_frame { _frame->call = NULL; \ _frame->prev = NULL; \ _frame->func = (const zend_function*)_func; \ + _frame->call_opline = NULL; \ _frame->call_level = 0; \ _frame->_info = (((uint32_t)(num_args)) << TRACE_FRAME_SHIFT_NUM_ARGS) & TRACE_FRAME_MASK_NUM_ARGS; \ _frame->_info |= _flags; \ diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index a4028c926f..7f32a02c4a 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -4023,20 +4023,24 @@ done: call = frame->call; assert(call && &call->func->op_array == p->op_array); - /* Check if SEND_UNPACK/SEND_ARRAY may cause enter at different opline */ - if ((opline->opcode == ZEND_DO_UCALL - || opline->opcode == ZEND_DO_FCALL_BY_NAME - || opline->opcode == ZEND_DO_FCALL) - && opline > op_array->opcodes - && ((opline-1)->opcode == ZEND_SEND_ARRAY - || (opline-1)->opcode == ZEND_SEND_UNPACK) - && p->op_array->num_args - && (p->op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0 - && ((p+1)->op == ZEND_JIT_TRACE_VM - || (p+1)->op == ZEND_JIT_TRACE_END) - && TRACE_FRAME_NUM_ARGS(call) < p->op_array->num_args - && !zend_jit_trace_opline_guard(&dasm_state, (p+1)->opline)) { - goto jit_failure; + if (opline->opcode == ZEND_DO_UCALL + || opline->opcode == ZEND_DO_FCALL_BY_NAME + || opline->opcode == ZEND_DO_FCALL) { + + frame->call_opline = opline; + + /* Check if SEND_UNPACK/SEND_ARRAY may cause enter at different opline */ + if (opline > op_array->opcodes + && ((opline-1)->opcode == ZEND_SEND_ARRAY + || (opline-1)->opcode == ZEND_SEND_UNPACK) + && p->op_array->num_args + && (p->op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0 + && ((p+1)->op == ZEND_JIT_TRACE_VM + || (p+1)->op == ZEND_JIT_TRACE_END) + && TRACE_FRAME_NUM_ARGS(call) < p->op_array->num_args + && !zend_jit_trace_opline_guard(&dasm_state, (p+1)->opline)) { + goto jit_failure; + } } if ((p+1)->op == ZEND_JIT_TRACE_END) { @@ -4288,6 +4292,19 @@ done: || opline->opcode == ZEND_DO_FCALL_BY_NAME) { zend_jit_trace_setup_ret_counter(opline, jit_extension->offset); } + if (JIT_G(current_frame) + && JIT_G(current_frame)->prev) { + frame = JIT_G(current_frame)->prev; + do { + if (frame->call_opline) { + op_array = &frame->func->op_array; + jit_extension = + (zend_jit_op_array_trace_extension*)ZEND_FUNC_INFO(op_array); + zend_jit_trace_setup_ret_counter(frame->call_opline, jit_extension->offset); + } + frame = frame->prev; + } while (frame); + } } }