]> granicus.if.org Git - php/commitdiff
Use ZEND_FAST_CONCAT instead of ZEND_CONCAT for CONST operands.
authorDmitry Stogov <dmitry@zend.com>
Fri, 29 Dec 2017 10:54:18 +0000 (13:54 +0300)
committerDmitry Stogov <dmitry@zend.com>
Fri, 29 Dec 2017 10:54:18 +0000 (13:54 +0300)
Zend/zend_compile.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_opcodes.c
ext/opcache/Optimizer/zend_optimizer.c

index ff69e2ebb4aabb6c3eb118e31cec305b4d7038ca..02721085b33918f8deee576aded42396f262ed90 100644 (file)
@@ -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);
index 171c009c593f3030ba2e18b5badbbd2dbb3f7df5..fb02154c51d0486348a60327356c291d41aa558c 100644 (file)
@@ -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;
index 312e9e99e8cc7895278a62197f06988ae9c45aae..6fafff95b73b6e4f5f25914ed32a1b5d8670e481 100644 (file)
@@ -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,
index 38cd265d42689a7dab8fa675b9e05a924697272a..ffc2c152dab66621afa53dae6fb0473623ccaad4 100644 (file)
@@ -232,7 +232,7 @@ static uint32_t zend_vm_opcodes_flags[199] = {
        0x00000707,
        0x00000707,
        0x00000707,
-       0x00000707,
+       0x40000707,
        0x80000707,
        0x80000707,
        0x80000707,
index bd859eaee6159de40380be3d052b54ba7e0d4f3f..0c9eac1d78e5b341ea165dc81e4973a86a8c1821 100644 (file)
@@ -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);