From f8cf7152a9410f86566109c33a4ed182b37228fc Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 16 Feb 2021 14:11:47 +0300 Subject: Microoptimization of STRLEN and IN_ARRAY opcodes (based on https://github.com/php/php-src/pull/4981) --- Zend/zend_vm_def.h | 58 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 10 deletions(-) (limited to 'Zend/zend_vm_def.h') diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index a0b222fa2b..eb2245d3c1 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8290,7 +8290,9 @@ ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMPVAR|CV, ANY) value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); - FREE_OP1(); + if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(value); + } ZEND_VM_NEXT_OPCODE(); } else { bool strict; @@ -8901,33 +8903,69 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(189, ZEND_IN_ARRAY, CONST|TMP|VAR|CV, CONST, NUM HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); zval *result; - SAVE_OPLINE(); - op1 = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R); + op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { result = zend_hash_find_ex(ht, Z_STR_P(op1), OP1_TYPE == IS_CONST); - } else if (opline->extended_value) { + if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + ZEND_VM_SMART_BRANCH(result, 0); + } + + if (opline->extended_value) { if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - } else { - result = NULL; + ZEND_VM_SMART_BRANCH(result, 0); + } + SAVE_OPLINE(); + if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), 0); + FREE_OP1(); + ZEND_VM_SMART_BRANCH(result, 0); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + result = zend_hash_index_find(ht, Z_LVAL_P(op1)); + FREE_OP1(); + ZEND_VM_SMART_BRANCH(result, 0); + } + } else if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } } else if (Z_TYPE_P(op1) <= IS_FALSE) { + if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } result = zend_hash_find_ex(ht, ZSTR_EMPTY_ALLOC(), 1); + ZEND_VM_SMART_BRANCH(result, 0); } else { zend_string *key; zval key_tmp, *val; - result = NULL; + if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), 0); + FREE_OP1(); + ZEND_VM_SMART_BRANCH(result, 0); + } + } + + SAVE_OPLINE(); ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { ZVAL_STR(&key_tmp, key); if (zend_compare(op1, &key_tmp) == 0) { - result = val; - break; + FREE_OP1(); + ZEND_VM_SMART_BRANCH(1, 1); } } ZEND_HASH_FOREACH_END(); } FREE_OP1(); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_SMART_BRANCH(0, 1); } ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMPVAR|CV, UNUSED) -- cgit v1.2.1