mirror of
https://github.com/php/php-src.git
synced 2024-09-21 09:57:23 +00:00
Use runtime-cache to avoid hash lookups in BIND_GLOBAL instruction
This commit is contained in:
parent
c2decc6afc
commit
551ee4165b
@ -4586,7 +4586,8 @@ void zend_compile_global_var(zend_ast *ast TSRMLS_DC) /* {{{ */
|
||||
}
|
||||
|
||||
if (zend_try_compile_cv(&result, var_ast TSRMLS_CC) == SUCCESS) {
|
||||
zend_emit_op(NULL, ZEND_BIND_GLOBAL, &result, &name_node TSRMLS_CC);
|
||||
zend_op *opline = zend_emit_op(NULL, ZEND_BIND_GLOBAL, &result, &name_node TSRMLS_CC);
|
||||
zend_alloc_cache_slot(opline->op2.constant TSRMLS_CC);
|
||||
} else {
|
||||
zend_emit_op(&result, ZEND_FETCH_W, &name_node, NULL TSRMLS_CC);
|
||||
|
||||
|
@ -5891,19 +5891,46 @@ ZEND_VM_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST)
|
||||
zval *varname;
|
||||
zval *value;
|
||||
zval *variable_ptr;
|
||||
zend_string *name;
|
||||
Bucket *p;
|
||||
uint32_t idx;
|
||||
|
||||
SAVE_OPLINE();
|
||||
varname = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
name = Z_STR_P(varname);
|
||||
value = zend_hash_find(&EG(symbol_table).ht, name);
|
||||
if (value == NULL) {
|
||||
value = zend_hash_add_new(&EG(symbol_table).ht, name, &EG(uninitialized_zval));
|
||||
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;
|
||||
/* GLOBAL variable may be an INDIRECT pointer to CV */
|
||||
} else if (Z_TYPE_P(value) == IS_INDIRECT) {
|
||||
value = Z_INDIRECT_P(value);
|
||||
if (Z_TYPE_P(value) == IS_UNDEF) {
|
||||
ZVAL_NULL(value);
|
||||
if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) {
|
||||
value = Z_INDIRECT_P(value);
|
||||
if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36402,19 +36402,46 @@ static int ZEND_FASTCALL ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
|
||||
zval *varname;
|
||||
zval *value;
|
||||
zval *variable_ptr;
|
||||
zend_string *name;
|
||||
Bucket *p;
|
||||
uint32_t idx;
|
||||
|
||||
SAVE_OPLINE();
|
||||
varname = opline->op2.zv;
|
||||
name = Z_STR_P(varname);
|
||||
value = zend_hash_find(&EG(symbol_table).ht, name);
|
||||
if (value == NULL) {
|
||||
value = zend_hash_add_new(&EG(symbol_table).ht, name, &EG(uninitialized_zval));
|
||||
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;
|
||||
/* GLOBAL variable may be an INDIRECT pointer to CV */
|
||||
} else if (Z_TYPE_P(value) == IS_INDIRECT) {
|
||||
value = Z_INDIRECT_P(value);
|
||||
if (Z_TYPE_P(value) == IS_UNDEF) {
|
||||
ZVAL_NULL(value);
|
||||
if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) {
|
||||
value = Z_INDIRECT_P(value);
|
||||
if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
#define LITERAL_STATIC_PROPERTY 0x0700
|
||||
#define LITERAL_METHOD 0x0800
|
||||
#define LITERAL_PROPERTY 0x0900
|
||||
#define LITERAL_GLOBAL 0x0A00
|
||||
|
||||
#define LITERAL_EX_CLASS 0x4000
|
||||
#define LITERAL_EX_OBJ 0x2000
|
||||
@ -278,6 +279,9 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ZEND_BIND_GLOBAL:
|
||||
LITERAL_INFO(opline->op2.constant, LITERAL_GLOBAL, 0, 1, 1);
|
||||
break;
|
||||
default:
|
||||
if (ZEND_OP1_TYPE(opline) == IS_CONST) {
|
||||
LITERAL_INFO(opline->op1.constant, LITERAL_VALUE, 1, 0, 1);
|
||||
|
Loading…
Reference in New Issue
Block a user