]> granicus.if.org Git - php/commitdiff
Fixed tracing JIT support for ZEND_RETURN_BY_REF in CALL VM
authorDmitry Stogov <dmitry@zend.com>
Wed, 27 May 2020 15:04:16 +0000 (18:04 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 27 May 2020 15:04:16 +0000 (18:04 +0300)
ext/opcache/jit/zend_jit.c
ext/opcache/jit/zend_jit_trace.c
ext/opcache/jit/zend_jit_x86.dasc

index 81429086d8d2959e4c982c8d92dfbba5ba0c5d3b..70102e58fe8c6f0f257bdae7a414b90ca3a401d2 100644 (file)
@@ -111,7 +111,7 @@ static int zend_may_overflow(const zend_op *opline, const zend_op_array *op_arra
 static void ZEND_FASTCALL zend_runtime_jit(void);
 
 static int zend_jit_trace_op_len(const zend_op *opline);
-static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op *opline, zend_jit_trace_rec *trace);
+static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op *opline);
 static uint32_t zend_jit_trace_get_exit_point(const zend_op *from_opline, const zend_op *to_opline, zend_jit_trace_rec *trace, uint32_t flags);
 static const void *zend_jit_trace_get_exit_addr(uint32_t n);
 static void zend_jit_trace_add_code(const void *start, uint32_t size);
index 138f4cbb2c0b2957f2c6f18e2bf71f63b608f686..699103b634ea35f34cb4d8f5b37ebb71b1e4e3e7 100644 (file)
@@ -240,7 +240,7 @@ static zend_string *zend_jit_trace_name(const zend_op_array *op_array, uint32_t
        return buf.s;
 }
 
-static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op *opline, zend_jit_trace_rec *trace)
+static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op *opline)
 {
        switch (opline->opcode) {
                case ZEND_IS_IDENTICAL:
index db194b9e03dfb04c7e1f9a8ef1a0d88c9b4b1881..c625f683828479aa51d056fc3daddb20042db6c0 100644 (file)
@@ -3148,8 +3148,14 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra
                zend_jit_check_exception(Dst);
        }
 
-       if (!GCC_GLOBAL_REGS) {
+       while (trace->op != ZEND_JIT_TRACE_VM && trace->op != ZEND_JIT_TRACE_END) {
+               trace++;
+       }
+
+       if (!GCC_GLOBAL_REGS
+        && (trace->op != ZEND_JIT_TRACE_END || trace->stop != ZEND_JIT_TRACE_STOP_RETURN)) {
                if (opline->opcode == ZEND_RETURN ||
+                   opline->opcode == ZEND_RETURN_BY_REF ||
                    opline->opcode == ZEND_DO_UCALL ||
                    opline->opcode == ZEND_DO_FCALL_BY_NAME ||
                    opline->opcode == ZEND_DO_FCALL) {
@@ -3157,9 +3163,9 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra
                }
        }
 
-       if (zend_jit_trace_may_exit(op_array, opline, trace)) {
+       if (zend_jit_trace_may_exit(op_array, opline)) {
                // TODO: try to avoid this check ???
-               if (opline->opcode == ZEND_RETURN) {
+               if (opline->opcode == ZEND_RETURN || opline->opcode == ZEND_RETURN_BY_REF) {
                        if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
                                |       cmp IP, zend_jit_halt_op
                                |       je ->trace_halt
@@ -3171,9 +3177,6 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra
                                |       jl ->trace_halt
                        }
                }
-               while (trace->op != ZEND_JIT_TRACE_VM && trace->op != ZEND_JIT_TRACE_END) {
-                       trace++;
-               }
                if (trace->op != ZEND_JIT_TRACE_END || trace->stop != ZEND_JIT_TRACE_STOP_RETURN) {
                        const zend_op *next_opline = trace->opline;
                        const zend_op *exit_opline = NULL;
@@ -3221,25 +3224,6 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra
                        |       CMP_IP next_opline
                        |       jne &exit_addr
                }
-       } else {
-               while (trace->op != ZEND_JIT_TRACE_VM && trace->op != ZEND_JIT_TRACE_END) {
-                       trace++;
-               }
-               // TODO: remove this ???
-               if (opline->opcode == ZEND_RETURN
-                && trace->op == ZEND_JIT_TRACE_END
-                && trace->stop == ZEND_JIT_TRACE_STOP_RETURN) {
-                       if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
-                               |       cmp IP, zend_jit_halt_op
-                               |       je ->trace_halt
-                       } else if (GCC_GLOBAL_REGS) {
-                               |       test IP, IP
-                               |       je ->trace_halt
-                       } else {
-                               |       test eax, eax
-                               |       jl ->trace_halt
-                       }
-               }
        }
 
        last_valid_opline = trace->opline;