]> granicus.if.org Git - php/commitdiff
JIT for SEND_FUNC_ARG
authorDmitry Stogov <dmitry@zend.com>
Thu, 19 Mar 2020 20:59:11 +0000 (23:59 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 19 Mar 2020 20:59:11 +0000 (23:59 +0300)
ext/opcache/jit/zend_jit.c
ext/opcache/jit/zend_jit_trace.c
ext/opcache/jit/zend_jit_x86.dasc

index 012b42b48c94280ce9f83755524e2b69e2de82ac..ce80ed8e81b27fa0a3e370b4d5e5443c9d5f249c 100644 (file)
@@ -2462,6 +2462,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                        case ZEND_SEND_VAR_EX:
                                        case ZEND_SEND_VAR_NO_REF:
                                        case ZEND_SEND_VAR_NO_REF_EX:
+                                       case ZEND_SEND_FUNC_ARG:
                                                if ((opline->opcode == ZEND_SEND_VAR_EX
                                                  || opline->opcode == ZEND_SEND_VAR_NO_REF_EX)
                                                 && opline->op2.num > MAX_ARG_FLAG_NUM) {
index ed4672d3fcd348c9faddabc236c44f0a2ced4a24..39857f2fe8075de32d9bdc34c794dfd8bc16eaf6 100644 (file)
@@ -1263,6 +1263,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
                                case ZEND_SEND_VAR_EX:
                                case ZEND_SEND_VAR_NO_REF:
                                case ZEND_SEND_VAR_NO_REF_EX:
+                               case ZEND_SEND_FUNC_ARG:
                                        if (tssa->ops[idx].op1_use >= 0 && op1_type != IS_UNKNOWN) {
                                                zend_ssa_var_info *info = &ssa_var_info[ssa_ops[idx].op1_use];
                                                if ((info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1 << op1_type)) {
@@ -1481,7 +1482,8 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
                                                ssa_var_info[v].type = MAY_BE_UNDEF;
                                        }
                                }
-                               if (i < op_array->num_args) {
+                               if (!(op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS)
+                                && i < op_array->num_args) {
                                        /* Propagate argument type */
                                        ssa_var_info[v].type &= frame->stack[i];
                                }
@@ -2202,6 +2204,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                        case ZEND_SEND_VAR_EX:
                                        case ZEND_SEND_VAR_NO_REF:
                                        case ZEND_SEND_VAR_NO_REF_EX:
+                                       case ZEND_SEND_FUNC_ARG:
                                                if ((opline->opcode == ZEND_SEND_VAR_EX
                                                  || opline->opcode == ZEND_SEND_VAR_NO_REF_EX)
                                                 && opline->op2.num > MAX_ARG_FLAG_NUM) {
@@ -2223,7 +2226,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                }
                                                if (frame->call
                                                 && frame->call->func->type == ZEND_USER_FUNCTION) {
-                                                       if (opline->opcode == ZEND_SEND_VAR_EX
+                                                       if ((opline->opcode == ZEND_SEND_VAR_EX
+                                                         || opline->opcode == ZEND_SEND_FUNC_ARG)
                                                         && ARG_SHOULD_BE_SENT_BY_REF(frame->call->func, opline->op2.num)) {
                                                                // TODO: this may require invalidation, if caller is changed ???
                                                                goto done;
index a9b0888ab1b00a1ce8ea299daf49654dd470e009..530949fc65af1cbae0dedf377cb16f8c5381a812 100644 (file)
@@ -8634,6 +8634,28 @@ static int zend_jit_send_var(dasm_State **Dst, const zend_op *opline, const zend
                                |       jmp >7
                        }
 
+                       |.code
+               }
+       } else if (opline->opcode == ZEND_SEND_FUNC_ARG) {
+               if (zend_jit_trigger == ZEND_JIT_ON_HOT_TRACE
+                && JIT_G(current_frame)
+                && JIT_G(current_frame)->call
+                && JIT_G(current_frame)->call->func) {
+                       if (ARG_SHOULD_BE_SENT_BY_REF(JIT_G(current_frame)->call->func, arg_num)) {
+                               if (!zend_jit_send_ref(Dst, opline, op_array, op1_info, 0)) {
+                                       return 0;
+                               }
+                               return 1;
+                       }
+               } else {
+                       |       test dword [RX + offsetof(zend_execute_data, This.u1.type_info)], ZEND_CALL_SEND_ARG_BY_REF
+                       |       jnz     >1
+                       |.cold_code
+                       |1:
+                       if (!zend_jit_send_ref(Dst, opline, op_array, op1_info, 1)) {
+                               return 0;
+                       }
+                       |       jmp >7
                        |.code
                }
        }
@@ -8677,7 +8699,7 @@ static int zend_jit_send_var(dasm_State **Dst, const zend_op *opline, const zend
                                return 0;
                        }
                }
-       } else if (op1_info & (MAY_BE_ANY|MAY_BE_REF)) {
+       } else {
                if (op1_info & MAY_BE_REF) {
                        if (opline->op1_type == IS_CV) {
                                zend_jit_addr val_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);