]> granicus.if.org Git - php/commitdiff
Setup RETURN counters for nested frames
authorDmitry Stogov <dmitry@zend.com>
Wed, 10 Jun 2020 05:10:27 +0000 (08:10 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 10 Jun 2020 05:10:27 +0000 (08:10 +0300)
ext/opcache/jit/zend_jit_internal.h
ext/opcache/jit/zend_jit_trace.c

index 7666737ab4a5118b86f453f55dbff3397e2bb0cb..1624bd816da046c26c4ca8b21be259e7e4dc6d32 100644 (file)
@@ -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; \
index a4028c926f8413dd92dc77873d6acc52ef1aa87e..7f32a02c4ac81a688b976039e4b6554b58b7ab3c 100644 (file)
@@ -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);
+                       }
                }
        }