From 5c8f8f8fce5736e0bdcdcb0efff3094f89181407 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 29 Dec 2017 13:54:18 +0300 Subject: [PATCH] Use ZEND_FAST_CONCAT instead of ZEND_CONCAT for CONST operands. --- Zend/zend_compile.c | 3 ++ Zend/zend_vm_def.h | 2 +- Zend/zend_vm_execute.h | 69 +------------------------- Zend/zend_vm_opcodes.c | 2 +- ext/opcache/Optimizer/zend_optimizer.c | 6 +++ 5 files changed, 13 insertions(+), 69 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index ff69e2ebb4..02721085b3 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -7096,6 +7096,9 @@ void zend_compile_binary_op(znode *result, zend_ast *ast) /* {{{ */ if (right_node.op_type == IS_CONST) { convert_to_string(&right_node.u.constant); } + if (left_node.op_type == IS_CONST && right_node.op_type == IS_CONST) { + opcode = ZEND_FAST_CONCAT; + } } zend_emit_op_tmp(result, opcode, &left_node, &right_node); } while (0); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 171c009c59..fb02154c51 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -282,7 +282,7 @@ ZEND_VM_HANDLER(166, ZEND_POW, CONST|TMPVAR|CV, CONST|TMPVAR|CV) ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(NO_CONST_CONST)) { USE_OPLINE zend_free_op free_op1, free_op2; diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 312e9e99e8..6fafff95b7 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -4426,68 +4426,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POW_SPEC_CONST_CONST_HANDLER(Z ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *op1, *op2; - - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - - if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - - if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - - } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - } - - } else if (IS_CONST != IS_CONST && IS_CONST != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - - - } - ZEND_VM_NEXT_OPCODE(); - } else { - SAVE_OPLINE(); - - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R); - } - concat_function(EX_VAR(opline->result.var), op1, op2); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } -} - static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -53107,7 +53045,7 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_SR_SPEC_CV_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_SR_SPEC_CV_CV_LABEL, - (void*)&&ZEND_CONCAT_SPEC_CONST_CONST_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_CONCAT_SPEC_CONST_TMPVAR_LABEL, (void*)&&ZEND_CONCAT_SPEC_CONST_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -58178,9 +58116,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) HYBRID_CASE(ZEND_POW_SPEC_CONST_CONST): ZEND_POW_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); - HYBRID_CASE(ZEND_CONCAT_SPEC_CONST_CONST): - ZEND_CONCAT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - HYBRID_BREAK(); HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_CONST_CONST): ZEND_IS_IDENTICAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); HYBRID_BREAK(); @@ -61999,7 +61934,7 @@ void zend_init_opcodes_handlers(void) ZEND_SR_SPEC_CV_TMPVAR_HANDLER, ZEND_NULL_HANDLER, ZEND_SR_SPEC_CV_CV_HANDLER, - ZEND_CONCAT_SPEC_CONST_CONST_HANDLER, + ZEND_NULL_HANDLER, ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER, ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER, ZEND_NULL_HANDLER, diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 38cd265d42..ffc2c152da 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -232,7 +232,7 @@ static uint32_t zend_vm_opcodes_flags[199] = { 0x00000707, 0x00000707, 0x00000707, - 0x00000707, + 0x40000707, 0x80000707, 0x80000707, 0x80000707, diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index bd859eaee6..0c9eac1d78 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -319,6 +319,9 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array, case ZEND_FETCH_UNSET: case ZEND_FETCH_FUNC_ARG: TO_STRING_NOWARN(val); + if (opline->opcode == ZEND_CONCAT && opline->op2_type == IS_CONST) { + opline->opcode == ZEND_FAST_CONCAT; + } /* break missing intentionally */ default: opline->op1.constant = zend_optimizer_add_literal(op_array, val); @@ -468,6 +471,9 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array, case ZEND_CONCAT: case ZEND_FAST_CONCAT: TO_STRING_NOWARN(val); + if (opline->opcode == ZEND_CONCAT && opline->op1_type == IS_CONST) { + opline->opcode == ZEND_FAST_CONCAT; + } /* break missing intentionally */ default: opline->op2.constant = zend_optimizer_add_literal(op_array, val); -- 2.50.1