From 3830855a651e98ad5aa01fad03730289a12f0284 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 17 Jun 2020 12:24:51 +0300 Subject: [PATCH] Tracing JIT support for PHP references in ASSIGN instruction --- ext/opcache/jit/zend_jit_trace.c | 32 ++++++++++++++++++++++++------- ext/opcache/jit/zend_jit_x86.dasc | 21 ++++++++++++++++++-- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index a39486a289..33e0cd714c 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -3156,7 +3156,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par op1_addr = OP1_REG_ADDR(); if (orig_op1_type != IS_UNKNOWN && (orig_op1_type & IS_TRACE_REFERENCE)) { - if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr)) { + if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 1)) { goto jit_failure; } } else { @@ -3182,7 +3182,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par op1_addr = OP1_REG_ADDR(); if (orig_op1_type != IS_UNKNOWN && (orig_op1_type & IS_TRACE_REFERENCE)) { - if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr)) { + if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 1)) { goto jit_failure; } } else { @@ -3221,10 +3221,28 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par CHECK_OP2_TRACE_TYPE(); op1_info = OP1_INFO(); op1_def_info = OP1_DEF_INFO(); - USE_OP1_TRACE_TYPE(); + op1_addr = OP1_REG_ADDR(); + op1_def_addr = OP1_DEF_REG_ADDR(); + if (orig_op1_type != IS_UNKNOWN + && (orig_op1_type & IS_TRACE_REFERENCE)) { + if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 0)) { + goto jit_failure; + } + op1_def_addr = op1_addr; + } else { + USE_OP1_TRACE_TYPE(); + if (orig_op1_type != IS_UNKNOWN + && (op1_info & MAY_BE_REF)) { + if (!zend_jit_noref_guard(&dasm_state, opline, op1_addr)) { + goto jit_failure; + } + op1_info &= ~MAY_BE_REF; + op1_def_info &= ~MAY_BE_REF; + } + } if (!zend_jit_assign(&dasm_state, opline, op_array, - op1_info, OP1_REG_ADDR(), - op1_def_info, OP1_DEF_REG_ADDR(), + op1_info, op1_addr, + op1_def_info, op1_def_addr, op2_info, op2_addr, op2_def_addr, res_info, res_addr, zend_may_throw(opline, ssa_op, op_array, ssa))) { @@ -3616,7 +3634,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par op1_addr = OP1_REG_ADDR(); if (orig_op1_type != IS_UNKNOWN && (orig_op1_type & IS_TRACE_REFERENCE)) { - if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr)) { + if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 1)) { goto jit_failure; } } else { @@ -3649,7 +3667,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par op1_addr = OP1_REG_ADDR(); if (orig_op1_type != IS_UNKNOWN && (orig_op1_type & IS_TRACE_REFERENCE)) { - if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr)) { + if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 1)) { goto jit_failure; } } else { diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 5e3e88e920..6c7eb92563 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -11350,7 +11350,20 @@ static zend_bool zend_jit_verify_return_type(dasm_State **Dst, const zend_op *op return 1; } -static zend_bool zend_jit_fetch_reference(dasm_State **Dst, const zend_op *opline, uint8_t var_type, uint32_t *var_info_ptr, zend_jit_addr *var_addr_ptr) +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, opline, NULL, 0); + const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); + + if (!exit_addr) { + return 0; + } + | IF_ZVAL_TYPE var_addr, IS_REFERENCE, &exit_addr + + return 1; +} + +static zend_bool zend_jit_fetch_reference(dasm_State **Dst, const zend_op *opline, uint8_t var_type, uint32_t *var_info_ptr, zend_jit_addr *var_addr_ptr, zend_bool add_type_guard) { zend_jit_addr var_addr = *var_addr_ptr; uint32_t var_info = *var_info_ptr; @@ -11369,7 +11382,8 @@ static zend_bool zend_jit_fetch_reference(dasm_State **Dst, const zend_op *oplin *var_addr_ptr = var_addr; var_type &= ~IS_TRACE_REFERENCE; - if (var_type != IS_UNKNOWN + if (add_type_guard + && var_type != IS_UNKNOWN && (var_info & (MAY_BE_ANY|MAY_BE_UNDEF)) != (1 << var_type)) { | IF_NOT_Z_TYPE FCARG1a, var_type, &exit_addr @@ -11382,6 +11396,9 @@ static zend_bool zend_jit_fetch_reference(dasm_State **Dst, const zend_op *oplin var_info = MAY_BE_ARRAY | (var_info & (MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_OF_REF|MAY_BE_ARRAY_KEY_ANY|MAY_BE_RC1|MAY_BE_RCN)); } + *var_info_ptr = var_info; + } else { + var_info &= ~MAY_BE_REF; *var_info_ptr = var_info; } -- 2.40.0