]> granicus.if.org Git - php/commitdiff
JIT for ECHO and variable string operands
authorDmitry Stogov <dmitry@zend.com>
Thu, 19 Mar 2020 22:01:33 +0000 (01:01 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 19 Mar 2020 22:01:33 +0000 (01:01 +0300)
ext/opcache/jit/zend_jit.c
ext/opcache/jit/zend_jit_trace.c
ext/opcache/jit/zend_jit_x86.dasc

index ce80ed8e81b27fa0a3e370b4d5e5443c9d5f249c..d64b8282d52b11e3782d676454a91e38b523beba 100644 (file)
@@ -2795,11 +2795,11 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                }
                                                goto done;
                                        case ZEND_ECHO:
-                                               if (opline->op1_type != IS_CONST
-                                                || Z_TYPE_P(RT_CONSTANT(opline, opline->op1)) != IS_STRING) {
+                                               op1_info = OP1_INFO();
+                                               if ((op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) != MAY_BE_STRING) {
                                                        break;
                                                }
-                                               if (!zend_jit_echo(&dasm_state, opline, op_array)) {
+                                               if (!zend_jit_echo(&dasm_state, opline, op_array, op1_info)) {
                                                        goto jit_failure;
                                                }
                                                goto done;
index 39857f2fe8075de32d9bdc34c794dfd8bc16eaf6..9c8489b7180c5553898b085627116c547ee1df06 100644 (file)
@@ -1242,6 +1242,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
                                case ZEND_JMPZNZ:
                                case ZEND_JMPZ_EX:
                                case ZEND_JMPNZ_EX:
+                               case ZEND_ECHO:
                                        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)) {
@@ -2624,11 +2625,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                }
                                                goto done;
                                        case ZEND_ECHO:
-                                               if (opline->op1_type != IS_CONST
-                                                || Z_TYPE_P(RT_CONSTANT(opline, opline->op1)) != IS_STRING) {
+                                               op1_info = OP1_INFO();
+                                               CHECK_OP1_TRACE_TYPE();
+                                               if ((op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) != MAY_BE_STRING) {
                                                        break;
                                                }
-                                               if (!zend_jit_echo(&dasm_state, opline, op_array)) {
+                                               if (!zend_jit_echo(&dasm_state, opline, op_array, op1_info)) {
                                                        goto jit_failure;
                                                }
                                                goto done;
index 530949fc65af1cbae0dedf377cb16f8c5381a812..e6128bec63a68168a890e2550b4d43868d7529c0 100644 (file)
@@ -10459,31 +10459,57 @@ static int zend_jit_free(dasm_State **Dst, const zend_op *opline, const zend_op_
        return 1;
 }
 
-static int zend_jit_echo(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array)
+static int zend_jit_echo(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, uint32_t op1_info)
 {
        zval *zv;
        size_t len;
 
-       ZEND_ASSERT(opline->op1_type == IS_CONST);
-       zv = RT_CONSTANT(opline, opline->op1);
-       ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING);
-       len = Z_STRLEN_P(zv);
+       if (opline->op1_type == IS_CONST) {
+               zv = RT_CONSTANT(opline, opline->op1);
+               ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING);
+               len = Z_STRLEN_P(zv);
 
-       if (len > 0) {
-               const char *str = Z_STRVAL_P(zv);
+               if (len > 0) {
+                       const char *str = Z_STRVAL_P(zv);
+
+                       |       SAVE_VALID_OPLINE opline, r0
+                       |.if X64
+                               |       LOAD_ADDR CARG1, str
+                               |       LOAD_ADDR CARG2, len
+                               |       EXT_CALL zend_write, r0
+                       |.else
+                               |       sub r4, 8
+                               |       push len
+                               |       push str
+                               |       EXT_CALL zend_write, r0
+                               |       add r4, 16
+                       |.endif
+                       if (!zend_jit_check_exception(Dst)) {
+                               return 0;
+                       }
+               }
+       } else {
+               zend_jit_addr op1_addr = OP1_ADDR();
+
+               ZEND_ASSERT((op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_STRING);
 
                |       SAVE_VALID_OPLINE opline, r0
+               |       GET_ZVAL_PTR r0, op1_addr
                |.if X64
-                       |       LOAD_ADDR CARG1, str
-                       |       LOAD_ADDR CARG2, len
-                       |       EXT_CALL zend_write, r0
+               |       lea CARG1, aword [r0 + offsetof(zend_string, val)]
+               |       mov CARG2, aword [r0 + offsetof(zend_string, len)]
+               |       EXT_CALL zend_write, r0
                |.else
-                       |       sub r4, 8
-                       |       push len
-                       |       push str
-                       |       EXT_CALL zend_write, r0
-                       |       add r4, 16
+               |       sub r4, 8
+               |       push aword [r0 + offsetof(zend_string, len)]
+               |       add r0, offsetof(zend_string, val)
+               |       push r0
+               |       EXT_CALL zend_write, r0
+               |       add r4, 16
                |.endif
+               if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
+                       |       ZVAL_PTR_DTOR op1_addr, op1_info, 0, 0, opline
+               }
                if (!zend_jit_check_exception(Dst)) {
                        return 0;
                }