]> granicus.if.org Git - php/commitdiff
Avoid refcounting when return CV (similar to optimization in VM).
authorDmitry Stogov <dmitry@zend.com>
Thu, 15 Oct 2020 12:27:00 +0000 (15:27 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 15 Oct 2020 12:27:00 +0000 (15:27 +0300)
ext/opcache/jit/zend_jit_trace.c
ext/opcache/jit/zend_jit_x86.dasc

index 31d12437283a7a08a14e737a7f6c111b1708c67b..a6d27caece02923e60100e48fcef1dd9cc7c6db0 100644 (file)
@@ -4494,16 +4494,19 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                                uint32_t info;
                                                                zend_uchar type;
 
+                                                               info = zend_ssa_cv_info(op_array, op_array_ssa, j);
+                                                               type = STACK_TYPE(stack, j);
+                                                               info = zend_jit_trace_type_to_info_ex(type, info);
                                                                if (opline->op1_type == IS_CV
                                                                 && EX_VAR_TO_NUM(opline->op1.var) == j
                                                                 && !(op1_info & MAY_BE_REF)
-                                                                && JIT_G(current_frame)
-                                                                && TRACE_FRAME_IS_RETURN_VALUE_USED(JIT_G(current_frame))) {
-                                                                       continue;
+                                                                && JIT_G(current_frame)) {
+                                                                       if (TRACE_FRAME_IS_RETURN_VALUE_USED(JIT_G(current_frame))) {
+                                                                               continue;
+                                                                       } else if ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) != MAY_BE_OBJECT) {
+                                                                               info |= MAY_BE_NULL;
+                                                                       }
                                                                }
-                                                               info = zend_ssa_cv_info(op_array, op_array_ssa, j);
-                                                               type = STACK_TYPE(stack, j);
-                                                               info = zend_jit_trace_type_to_info_ex(type, info);
                                                                if (info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) {
                                                                        if (!left_frame) {
                                                                                left_frame = 1;
index 9918bf365f527e240ecef5784c4ed9b3809e2419..72f5bcd0a06aeabc3f267e8bea1e9da2542aaaf3 100644 (file)
@@ -11387,8 +11387,17 @@ static int zend_jit_return(dasm_State **Dst, const zend_op *opline, const zend_o
                }
                |       ZVAL_COPY_VALUE ret_addr, MAY_BE_ANY, op1_addr, op1_info, ZREG_R0, ZREG_R2
                if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || (op1_info & MAY_BE_REF) || (return_value_used != 1)) {
-                       |       // TODO: JIT: if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) ZVAL_NULL(retval_ptr); ???
-                       |       TRY_ADDREF op1_info, ah, r2
+                       if (op1_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
+                               if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE
+                                && !(op1_info & MAY_BE_REF)
+                                && op_array->function_name
+                                && (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) != MAY_BE_OBJECT) {
+                                       |       // if (EXPECTED(!(EX_CALL_INFO() & ZEND_CALL_CODE))) ZVAL_NULL(retval_ptr);
+                                       |       SET_ZVAL_TYPE_INFO op1_addr, IS_NULL
+                               } else {
+                                       |       TRY_ADDREF op1_info, ah, r2
+                               }
+                       }
                }
        } else {
                if (op1_info & MAY_BE_REF) {