From: Dmitry Stogov Date: Thu, 19 Mar 2020 20:59:11 +0000 (+0300) Subject: JIT for SEND_FUNC_ARG X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=282265bccdd0f61fea1d6ed976a5927db713e1e5;p=php JIT for SEND_FUNC_ARG --- diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 012b42b48c..ce80ed8e81 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -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) { diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index ed4672d3fc..39857f2fe8 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -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; diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index a9b0888ab1..530949fc65 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -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);