From: Dmitry Stogov Date: Mon, 21 Sep 2020 21:47:23 +0000 (+0300) Subject: Fixed INIT_METHOD_CALL + IS_VAR + reference in tracing JIT X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=57a3fbb1e143c0f8431bb5246308b9b581b99c52;p=php Fixed INIT_METHOD_CALL + IS_VAR + reference in tracing JIT --- diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 7630badc7d..deed2c402e 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -9092,6 +9092,7 @@ static int zend_jit_init_method_call(dasm_State **Dst, | ZVAL_DEREF FCARG1a, op1_info op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0); } else { + /* Hack: Convert reference to regular value to simplify JIT code */ ZEND_ASSERT(Z_REG(op1_addr) == ZREG_FP); | IF_NOT_ZVAL_TYPE op1_addr, IS_REFERENCE, >1 | LOAD_ZVAL_ADDR FCARG1a, op1_addr @@ -14707,10 +14708,17 @@ static zend_bool zend_jit_fetch_reference(dasm_State **Dst, const zend_op *oplin if (add_ref_guard) { | IF_NOT_ZVAL_TYPE var_addr, IS_REFERENCE, &exit_addr } - | GET_ZVAL_PTR FCARG1a, var_addr - - var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, offsetof(zend_reference, val)); - *var_addr_ptr = var_addr; + if (opline->opcode == ZEND_INIT_METHOD_CALL && opline->op1_type == IS_VAR) { + /* Hack: Convert reference to regular value to simplify JIT code for INIT_METHOD_CALL */ + if (Z_REG(var_addr) != ZREG_FCARG1a || Z_OFFSET(var_addr) != 0) { + | LOAD_ZVAL_ADDR FCARG1a, var_addr + } + | EXT_CALL zend_jit_unref_helper, r0 + } else { + | GET_ZVAL_PTR FCARG1a, var_addr + var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, offsetof(zend_reference, val)); + *var_addr_ptr = var_addr; + } if (var_type != IS_UNKNOWN) { var_type &= ~(IS_TRACE_REFERENCE|IS_TRACE_INDIRECT|IS_TRACE_PACKED); diff --git a/ext/opcache/tests/jit/method_call_001.phpt b/ext/opcache/tests/jit/method_call_001.phpt new file mode 100644 index 0000000000..2d96d359e0 --- /dev/null +++ b/ext/opcache/tests/jit/method_call_001.phpt @@ -0,0 +1,35 @@ +--TEST-- +JIT METHOD_CALL: 001 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--SKIPIF-- + +--FILE-- +bar(); + } + static function loop() { + for ($i = 0; $i < 10; $i++) { + self::foo(); + } + echo "ok\n"; + } +} +class B { + function bar() { + } +} +A::$o = new B; +A::loop(); +?> +--EXPECT-- +ok