Use ZEND_FAST_CONCAT instead of ZEND_CONCAT for CONST operands.

This commit is contained in:
Dmitry Stogov 2017-12-29 13:54:18 +03:00
parent f010423335
commit 5c8f8f8fce
5 changed files with 13 additions and 69 deletions

View 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);

View 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;

View 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,

View File

@ -232,7 +232,7 @@ static uint32_t zend_vm_opcodes_flags[199] = {
0x00000707,
0x00000707,
0x00000707,
0x00000707,
0x40000707,
0x80000707,
0x80000707,
0x80000707,

View 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);