Browse Source

CONCAT/FAST_CONCAT micro-optimization

pull/2946/head
Dmitry Stogov 9 years ago
parent
commit
6a2738c713
  1. 108
      Zend/zend_vm_def.h
  2. 924
      Zend/zend_vm_execute.h

108
Zend/zend_vm_def.h

@ -297,38 +297,36 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
zend_string *op2_str = Z_STR_P(op2);
zend_string *str;
do {
if (OP1_TYPE != IS_CONST) {
if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
FREE_OP1();
break;
}
}
if (OP2_TYPE != IS_CONST) {
if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
FREE_OP1();
break;
}
if (OP1_TYPE != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
if (OP2_TYPE == IS_CONST || OP2_TYPE == IS_CV) {
ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
} else {
ZVAL_STR(EX_VAR(opline->result.var), op2_str);
}
if (OP1_TYPE != IS_CONST && OP1_TYPE != 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);
break;
FREE_OP1();
} else if (OP2_TYPE != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_CV) {
ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_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);
ZVAL_STR(EX_VAR(opline->result.var), op1_str);
}
FREE_OP2();
} else if (OP1_TYPE != IS_CONST && OP1_TYPE != 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);
FREE_OP2();
} 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);
FREE_OP1();
} while (0);
FREE_OP2();
FREE_OP2();
}
ZEND_VM_NEXT_OPCODE();
} else {
SAVE_OPLINE();
@ -2734,38 +2732,36 @@ ZEND_VM_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
zend_string *op2_str = Z_STR_P(op2);
zend_string *str;
do {
if (OP1_TYPE != IS_CONST) {
if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
FREE_OP1();
break;
}
}
if (OP2_TYPE != IS_CONST) {
if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str);
FREE_OP1();
break;
}
if (OP1_TYPE != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) {
if (OP2_TYPE == IS_CONST || OP2_TYPE == IS_CV) {
ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str);
} else {
ZVAL_STR(EX_VAR(opline->result.var), op2_str);
}
if (OP1_TYPE != IS_CONST && OP1_TYPE != 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);
break;
FREE_OP1();
} else if (OP2_TYPE != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) {
if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_CV) {
ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_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);
ZVAL_STR(EX_VAR(opline->result.var), op1_str);
}
FREE_OP2();
} else if (OP1_TYPE != IS_CONST && OP1_TYPE != 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);
FREE_OP2();
} 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);
FREE_OP1();
} while (0);
FREE_OP2();
FREE_OP2();
}
ZEND_VM_NEXT_OPCODE();
}

924
Zend/zend_vm_execute.h
File diff suppressed because it is too large
View File

Loading…
Cancel
Save