From e45dbba5602b7bbd8c97b4aa3bae6b00602a8110 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 24 Nov 2014 15:46:34 +0300 Subject: [PATCH] Micro optimization --- Zend/zend_vm_def.h | 59 +++++++++++++++++++++--------------------- Zend/zend_vm_execute.h | 59 +++++++++++++++++++++--------------------- 2 files changed, 58 insertions(+), 60 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 78ef315ec7..cd748b73f0 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -5907,23 +5907,39 @@ ZEND_VM_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST) zval *varname; zval *value; zval *variable_ptr; - Bucket *p; uint32_t idx; SAVE_OPLINE(); varname = GET_OP2_ZVAL_PTR(BP_VAR_R); - idx = (uint32_t)(uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)); - /* index 0 can't be cached (NULL is a mark of uninitialized cache slot) */ - p = EG(symbol_table).ht.arData + idx; - if (EXPECTED(idx > 0) && - EXPECTED(idx < EG(symbol_table).ht.nNumUsed) && - EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && - (EXPECTED(p->key == Z_STR_P(varname)) || - (EXPECTED(p->h == Z_STR_P(varname)->h) && - EXPECTED(p->key != NULL) && - EXPECTED(p->key->len == Z_STRLEN_P(varname)) && - EXPECTED(memcmp(p->key->val, Z_STRVAL_P(varname), Z_STRLEN_P(varname)) == 0)))) { - value = &EG(symbol_table).ht.arData[idx].val; + + /* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ + idx = (uint32_t)(uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)) - 1; + if (EXPECTED(idx < EG(symbol_table).ht.nNumUsed)) { + Bucket *p = EG(symbol_table).ht.arData + idx; + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(varname)) || + (EXPECTED(p->h == Z_STR_P(varname)->h) && + EXPECTED(p->key != NULL) && + EXPECTED(p->key->len == Z_STRLEN_P(varname)) && + EXPECTED(memcmp(p->key->val, Z_STRVAL_P(varname), Z_STRLEN_P(varname)) == 0)))) { + + value = &EG(symbol_table).ht.arData[idx].val; + ZEND_VM_C_GOTO(check_indirect); + } + } + + value = zend_hash_find(&EG(symbol_table).ht, Z_STR_P(varname)); + if (UNEXPECTED(value == NULL)) { + value = zend_hash_add_new(&EG(symbol_table).ht, Z_STR_P(varname), &EG(uninitialized_zval)); + idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); + /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ + CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1)); + } else { + idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); + /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ + CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1)); +ZEND_VM_C_LABEL(check_indirect): /* GLOBAL variable may be an INDIRECT pointer to CV */ if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { value = Z_INDIRECT_P(value); @@ -5931,23 +5947,6 @@ ZEND_VM_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST) ZVAL_NULL(value); } } - } else { - value = zend_hash_find(&EG(symbol_table).ht, Z_STR_P(varname)); - if (UNEXPECTED(value == NULL)) { - value = zend_hash_add_new(&EG(symbol_table).ht, Z_STR_P(varname), &EG(uninitialized_zval)); - idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); - CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)idx); - } else { - idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); - CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)idx); - /* GLOBAL variable may be an INDIRECT pointer to CV */ - if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { - value = Z_INDIRECT_P(value); - if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - ZVAL_NULL(value); - } - } - } } variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 074dbc2965..a1f7a3ffc2 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -37393,23 +37393,39 @@ static int ZEND_FASTCALL ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN zval *varname; zval *value; zval *variable_ptr; - Bucket *p; uint32_t idx; SAVE_OPLINE(); varname = opline->op2.zv; - idx = (uint32_t)(uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)); - /* index 0 can't be cached (NULL is a mark of uninitialized cache slot) */ - p = EG(symbol_table).ht.arData + idx; - if (EXPECTED(idx > 0) && - EXPECTED(idx < EG(symbol_table).ht.nNumUsed) && - EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && - (EXPECTED(p->key == Z_STR_P(varname)) || - (EXPECTED(p->h == Z_STR_P(varname)->h) && - EXPECTED(p->key != NULL) && - EXPECTED(p->key->len == Z_STRLEN_P(varname)) && - EXPECTED(memcmp(p->key->val, Z_STRVAL_P(varname), Z_STRLEN_P(varname)) == 0)))) { - value = &EG(symbol_table).ht.arData[idx].val; + + /* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ + idx = (uint32_t)(uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)) - 1; + if (EXPECTED(idx < EG(symbol_table).ht.nNumUsed)) { + Bucket *p = EG(symbol_table).ht.arData + idx; + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(varname)) || + (EXPECTED(p->h == Z_STR_P(varname)->h) && + EXPECTED(p->key != NULL) && + EXPECTED(p->key->len == Z_STRLEN_P(varname)) && + EXPECTED(memcmp(p->key->val, Z_STRVAL_P(varname), Z_STRLEN_P(varname)) == 0)))) { + + value = &EG(symbol_table).ht.arData[idx].val; + goto check_indirect; + } + } + + value = zend_hash_find(&EG(symbol_table).ht, Z_STR_P(varname)); + if (UNEXPECTED(value == NULL)) { + value = zend_hash_add_new(&EG(symbol_table).ht, Z_STR_P(varname), &EG(uninitialized_zval)); + idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); + /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ + CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1)); + } else { + idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); + /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ + CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1)); +check_indirect: /* GLOBAL variable may be an INDIRECT pointer to CV */ if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { value = Z_INDIRECT_P(value); @@ -37417,23 +37433,6 @@ static int ZEND_FASTCALL ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN ZVAL_NULL(value); } } - } else { - value = zend_hash_find(&EG(symbol_table).ht, Z_STR_P(varname)); - if (UNEXPECTED(value == NULL)) { - value = zend_hash_add_new(&EG(symbol_table).ht, Z_STR_P(varname), &EG(uninitialized_zval)); - idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); - CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)idx); - } else { - idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); - CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)idx); - /* GLOBAL variable may be an INDIRECT pointer to CV */ - if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { - value = Z_INDIRECT_P(value); - if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - ZVAL_NULL(value); - } - } - } } variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); -- 2.40.0