]> granicus.if.org Git - php/commitdiff
JIT for FETCH_CONSTANT
authorDmitry Stogov <dmitry@zend.com>
Wed, 2 Sep 2020 21:51:43 +0000 (00:51 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 2 Sep 2020 21:51:43 +0000 (00:51 +0300)
ext/opcache/jit/zend_jit.c
ext/opcache/jit/zend_jit_disasm_x86.c
ext/opcache/jit/zend_jit_internal.h
ext/opcache/jit/zend_jit_trace.c
ext/opcache/jit/zend_jit_vm_helpers.c
ext/opcache/jit/zend_jit_x86.dasc

index ea5bbfb33993a5f1be83e1f38114008691053285..56260c9105feedaa34f7ab43b4d0bfde45c1ef47 100644 (file)
@@ -2982,6 +2982,11 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
                                                        goto jit_failure;
                                                }
                                                goto done;
+                                       case ZEND_FETCH_CONSTANT:
+                                               if (!zend_jit_fetch_constant(&dasm_state, opline)) {
+                                                       goto jit_failure;
+                                               }
+                                               goto done;
                                        default:
                                                break;
                                }
index ce8eec6ebf2fe9c6dfc489225b09cd41527a606a..bd737fa669732549a91442ae8a08bdc2819dab5c 100644 (file)
@@ -459,6 +459,7 @@ static int zend_jit_disasm_init(void)
        REGISTER_HELPER(zend_runtime_jit);
        REGISTER_HELPER(zend_jit_hot_func);
        REGISTER_HELPER(zend_jit_check_constant);
+       REGISTER_HELPER(zend_jit_get_constant);
        REGISTER_HELPER(zend_jit_array_free);
        REGISTER_HELPER(zend_jit_zval_array_dup);
        REGISTER_HELPER(zend_jit_add_arrays_helper);
index 1f4b36cb62797e9ccdeedf5113ab57668268e235..bcbafad1479860d1a5146182e7099914c1d9ee35 100644 (file)
@@ -130,8 +130,8 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_counter_helper(ZEND_OPCODE_H
 void ZEND_FASTCALL zend_jit_copy_extra_args_helper(EXECUTE_DATA_D);
 zend_bool ZEND_FASTCALL zend_jit_deprecated_helper(OPLINE_D);
 
-void ZEND_FASTCALL zend_jit_get_constant(const zval *key, uint32_t flags);
-int  ZEND_FASTCALL zend_jit_check_constant(const zval *key);
+int ZEND_FASTCALL zend_jit_get_constant(const zval *key, uint32_t flags);
+int ZEND_FASTCALL zend_jit_check_constant(const zval *key);
 
 /* Tracer */
 #define zend_jit_opline_hash(opline) \
index 66183d97cd048a977dd9065aa83c7a9adfef4e66..7d3c7be1aa53d40d2c81d4dc5c842c30d606baa4 100644 (file)
@@ -4574,6 +4574,11 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
                                                        goto jit_failure;
                                                }
                                                goto done;
+                                       case ZEND_FETCH_CONSTANT:
+                                               if (!zend_jit_fetch_constant(&dasm_state, opline)) {
+                                                       goto jit_failure;
+                                               }
+                                               goto done;
                                        case ZEND_INIT_METHOD_CALL:
                                        case ZEND_INIT_DYNAMIC_CALL:
                                                if (!zend_jit_trace_handler(&dasm_state, op_array, opline, zend_may_throw(opline, ssa_op, op_array, ssa), p + 1)) {
index 729c64073d5e82b3d06cddc89b702fd4df5fde61..09a99811846f333f81f261e7ac4b9e9c7286bbd4 100644 (file)
@@ -278,9 +278,9 @@ static zend_always_inline int _zend_quick_get_constant(
        return SUCCESS;
 }
 
-void ZEND_FASTCALL zend_jit_get_constant(const zval *key, uint32_t flags)
+int ZEND_FASTCALL zend_jit_get_constant(const zval *key, uint32_t flags)
 {
-       _zend_quick_get_constant(key, flags, 0);
+       return _zend_quick_get_constant(key, flags, 0);
 }
 
 int ZEND_FASTCALL zend_jit_check_constant(const zval *key)
index f19777ab3c4a2c002ac3e9354d91c681946d8d8f..a863fed69e8854949c628c692f9025b6cea15e4d 100644 (file)
@@ -12651,15 +12651,50 @@ static int zend_jit_fe_fetch(dasm_State **Dst, const zend_op *opline, const zend
                } else {
                        |       // ZVAL_COPY(res, value);
                        |       ZVAL_COPY_VALUE var_addr, -1, val_addr, val_info, ZREG_R0, ZREG_FCARG1a
-                       if (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) {
-                               |       TRY_ADDREF op1_info, ah, FCARG1a
-                       }
+                       |       TRY_ADDREF val_info, ah, FCARG1a
                }
        }
 
        return 1;
 }
 
+static int zend_jit_fetch_constant(dasm_State **Dst, const zend_op *opline)
+{
+       zval *zv = RT_CONSTANT(opline, opline->op2) + 1;
+       zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
+       zend_jit_addr const_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
+
+       |       // c = CACHED_PTR(opline->extended_value);
+       |       mov FCARG1a, EX->run_time_cache
+       |       mov FCARG1a, aword [FCARG1a + opline->extended_value]
+       |       // if (c != NULL)
+       |       test FCARG1a, FCARG1a
+       |       jz >9
+       |       // if (!IS_SPECIAL_CACHE_VAL(c))
+       |       test FCARG1a, CACHE_SPECIAL
+       |       jnz >9
+       |       // ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); (no dup)
+       |       ZVAL_COPY_VALUE res_addr, MAY_BE_ANY, const_addr, MAY_BE_ANY, ZREG_R0, ZREG_FCARG2a
+       |       TRY_ADDREF MAY_BE_ANY, ah, FCARG2a
+       |8:
+
+       |.cold_code
+       |9:
+       |       // SAVE_OPLINE();
+       |       SAVE_VALID_OPLINE opline, r0
+       |       // zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num OPLINE_CC EXECUTE_DATA_CC);
+       |       LOAD_ADDR FCARG1a, zv
+       |       mov FCARG2a, opline->op1.num
+       |       EXT_CALL zend_jit_get_constant, r0
+       |       // ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+       |       test r0, r0
+       |       jz <8
+       |       jmp ->exception_handler
+       |.code
+
+       return 1;
+}
+
 static zend_bool zend_jit_noref_guard(dasm_State **Dst, const zend_op *opline, zend_jit_addr var_addr)
 {
        int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0);