mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Made run_time_cache to keep "offset" to dynamic properties Buckets (instead of index).
This commit is contained in:
parent
8f804a2128
commit
59a7944bc6
5 changed files with 286 additions and 288 deletions
|
@ -1883,7 +1883,7 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c
|
|||
}
|
||||
if (prop_op_type == IS_CONST &&
|
||||
EXPECTED(Z_OBJCE_P(container) == CACHED_PTR_EX(cache_slot))) {
|
||||
uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR_EX(cache_slot + 1);
|
||||
intptr_t prop_offset = (intptr_t)CACHED_PTR_EX(cache_slot + 1);
|
||||
zend_object *zobj = Z_OBJ_P(container);
|
||||
zval *retval;
|
||||
|
||||
|
|
|
@ -286,7 +286,7 @@ static zend_always_inline zend_bool is_derived_class(zend_class_entry *child_cla
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_always_inline uint32_t zend_get_property_offset(zend_class_entry *ce, zend_string *member, int silent, void **cache_slot) /* {{{ */
|
||||
static zend_always_inline intptr_t zend_get_property_offset(zend_class_entry *ce, zend_string *member, int silent, void **cache_slot) /* {{{ */
|
||||
{
|
||||
zval *zv;
|
||||
zend_property_info *property_info = NULL;
|
||||
|
@ -294,7 +294,7 @@ static zend_always_inline uint32_t zend_get_property_offset(zend_class_entry *ce
|
|||
zend_class_entry *scope;
|
||||
|
||||
if (cache_slot && EXPECTED(ce == CACHED_PTR_EX(cache_slot))) {
|
||||
return (uint32_t)(intptr_t)CACHED_PTR_EX(cache_slot + 1);
|
||||
return (intptr_t)CACHED_PTR_EX(cache_slot + 1);
|
||||
}
|
||||
|
||||
if (UNEXPECTED(ZSTR_VAL(member)[0] == '\0' && ZSTR_LEN(member) != 0)) {
|
||||
|
@ -352,7 +352,7 @@ static zend_always_inline uint32_t zend_get_property_offset(zend_class_entry *ce
|
|||
} else if (UNEXPECTED(property_info == NULL)) {
|
||||
exit_dynamic:
|
||||
if (cache_slot) {
|
||||
CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, (void*)(intptr_t)ZEND_DYNAMIC_PROPERTY_OFFSET);
|
||||
CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
|
||||
}
|
||||
return ZEND_DYNAMIC_PROPERTY_OFFSET;
|
||||
} else if (UNEXPECTED(property_info == ZEND_WRONG_PROPERTY_INFO)) {
|
||||
|
@ -544,7 +544,7 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_
|
|||
zend_object *zobj;
|
||||
zval tmp_member;
|
||||
zval *retval;
|
||||
uint32_t property_offset;
|
||||
intptr_t property_offset;
|
||||
|
||||
zobj = Z_OBJ_P(object);
|
||||
|
||||
|
@ -570,10 +570,10 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_
|
|||
} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(property_offset))) {
|
||||
if (EXPECTED(zobj->properties != NULL)) {
|
||||
if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(property_offset)) {
|
||||
uint32_t idx = ZEND_DECODE_DYN_PROP_OFFSET(property_offset);
|
||||
intptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(property_offset);
|
||||
|
||||
if (EXPECTED(idx < zobj->properties->nNumUsed)) {
|
||||
Bucket *p = zobj->properties->arData + idx;
|
||||
if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
|
||||
Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
|
||||
|
||||
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
|
||||
(EXPECTED(p->key == Z_STR_P(member)) ||
|
||||
|
@ -585,14 +585,13 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_
|
|||
goto exit;
|
||||
}
|
||||
}
|
||||
CACHE_PTR_EX(cache_slot + 1, (void*)(uintptr_t)ZEND_DYNAMIC_PROPERTY_OFFSET);
|
||||
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
|
||||
}
|
||||
retval = zend_hash_find(zobj->properties, Z_STR_P(member));
|
||||
if (EXPECTED(retval)) {
|
||||
if (cache_slot) {
|
||||
uint32_t idx = ((char*)retval - (char*)zobj->properties->arData) / sizeof(Bucket);
|
||||
/* Store "hash slot index" + 2 (NULL is a mark of uninitialized cache slot) */
|
||||
CACHE_PTR_EX(cache_slot + 1, (void*)(uintptr_t)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
|
||||
intptr_t idx = (char*)retval - (char*)zobj->properties->arData;
|
||||
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
|
||||
}
|
||||
goto exit;
|
||||
}
|
||||
|
@ -673,7 +672,7 @@ ZEND_API void zend_std_write_property(zval *object, zval *member, zval *value, v
|
|||
zend_object *zobj;
|
||||
zval tmp_member;
|
||||
zval *variable_ptr;
|
||||
uint32_t property_offset;
|
||||
intptr_t property_offset;
|
||||
|
||||
zobj = Z_OBJ_P(object);
|
||||
|
||||
|
@ -851,7 +850,7 @@ static zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int type,
|
|||
zend_object *zobj;
|
||||
zend_string *name;
|
||||
zval *retval = NULL;
|
||||
uint32_t property_offset;
|
||||
intptr_t property_offset;
|
||||
|
||||
zobj = Z_OBJ_P(object);
|
||||
if (EXPECTED(Z_TYPE_P(member) == IS_STRING)) {
|
||||
|
@ -922,7 +921,7 @@ static void zend_std_unset_property(zval *object, zval *member, void **cache_slo
|
|||
{
|
||||
zend_object *zobj;
|
||||
zval tmp_member;
|
||||
uint32_t property_offset;
|
||||
intptr_t property_offset;
|
||||
|
||||
zobj = Z_OBJ_P(object);
|
||||
|
||||
|
@ -1497,7 +1496,7 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists,
|
|||
int result;
|
||||
zval *value = NULL;
|
||||
zval tmp_member;
|
||||
uint32_t property_offset;
|
||||
intptr_t property_offset;
|
||||
|
||||
zobj = Z_OBJ_P(object);
|
||||
|
||||
|
@ -1518,10 +1517,10 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists,
|
|||
} else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(property_offset))) {
|
||||
if (EXPECTED(zobj->properties != NULL)) {
|
||||
if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(property_offset)) {
|
||||
uint32_t idx = ZEND_DECODE_DYN_PROP_OFFSET(property_offset);
|
||||
intptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(property_offset);
|
||||
|
||||
if (EXPECTED(idx < zobj->properties->nNumUsed)) {
|
||||
Bucket *p = zobj->properties->arData + idx;
|
||||
if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
|
||||
Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
|
||||
|
||||
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
|
||||
(EXPECTED(p->key == Z_STR_P(member)) ||
|
||||
|
@ -1533,14 +1532,13 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists,
|
|||
goto found;
|
||||
}
|
||||
}
|
||||
CACHE_PTR_EX(cache_slot + 1, (void*)(uintptr_t)ZEND_DYNAMIC_PROPERTY_OFFSET);
|
||||
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
|
||||
}
|
||||
value = zend_hash_find(zobj->properties, Z_STR_P(member));
|
||||
if (value) {
|
||||
if (cache_slot) {
|
||||
uint32_t idx = ((char*)value - (char*)zobj->properties->arData) / sizeof(Bucket);
|
||||
/* Store "hash slot index" + 2 (NULL is a mark of uninitialized cache slot) */
|
||||
CACHE_PTR_EX(cache_slot + 1, (void*)(uintptr_t)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
|
||||
intptr_t idx = (char*)value - (char*)zobj->properties->arData;
|
||||
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
|
||||
}
|
||||
found:
|
||||
switch (has_set_exists) {
|
||||
|
|
|
@ -25,17 +25,17 @@
|
|||
struct _zend_property_info;
|
||||
|
||||
#define ZEND_WRONG_PROPERTY_INFO \
|
||||
((struct _zend_property_info*)((zend_intptr_t)-1))
|
||||
((struct _zend_property_info*)((intptr_t)-1))
|
||||
|
||||
#define ZEND_DYNAMIC_PROPERTY_OFFSET ((uint32_t)(-1))
|
||||
#define ZEND_DYNAMIC_PROPERTY_OFFSET ((intptr_t)(-1))
|
||||
|
||||
#define IS_VALID_PROPERTY_OFFSET(offset) ((int32_t)(offset) > 0)
|
||||
#define IS_WRONG_PROPERTY_OFFSET(offset) ((int32_t)(offset) == 0)
|
||||
#define IS_DYNAMIC_PROPERTY_OFFSET(offset) ((int32_t)(offset) < 0)
|
||||
#define IS_VALID_PROPERTY_OFFSET(offset) ((intptr_t)(offset) > 0)
|
||||
#define IS_WRONG_PROPERTY_OFFSET(offset) ((intptr_t)(offset) == 0)
|
||||
#define IS_DYNAMIC_PROPERTY_OFFSET(offset) ((intptr_t)(offset) < 0)
|
||||
|
||||
#define IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(offset) (offset == ZEND_DYNAMIC_PROPERTY_OFFSET)
|
||||
#define ZEND_DECODE_DYN_PROP_OFFSET(offset) ((uint32_t)(-(int32_t)(offset) - 2))
|
||||
#define ZEND_ENCODE_DYN_PROP_OFFSET(idx) ((uint32_t)(-(idx + 2)))
|
||||
#define ZEND_DECODE_DYN_PROP_OFFSET(offset) (-(intptr_t)(offset) - 2)
|
||||
#define ZEND_ENCODE_DYN_PROP_OFFSET(offset) (-((intptr_t)(offset) + 2))
|
||||
|
||||
|
||||
/* The following rule applies to read_property() and read_dimension() implementations:
|
||||
|
|
|
@ -1792,7 +1792,7 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR
|
|||
cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset));
|
||||
|
||||
if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
|
||||
uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR_EX(cache_slot + 1);
|
||||
intptr_t prop_offset = (intptr_t)CACHED_PTR_EX(cache_slot + 1);
|
||||
|
||||
if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
|
||||
retval = OBJ_PROP(zobj, prop_offset);
|
||||
|
@ -1802,10 +1802,10 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR
|
|||
}
|
||||
} else if (EXPECTED(zobj->properties != NULL)) {
|
||||
if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
|
||||
uint32_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
|
||||
intptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
|
||||
|
||||
if (EXPECTED(idx < zobj->properties->nNumUsed)) {
|
||||
Bucket *p = zobj->properties->arData + idx;
|
||||
if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
|
||||
Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
|
||||
|
||||
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
|
||||
(EXPECTED(p->key == Z_STR_P(offset)) ||
|
||||
|
@ -1817,12 +1817,12 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR
|
|||
break;
|
||||
}
|
||||
}
|
||||
CACHE_PTR_EX(cache_slot + 1, (void*)(uintptr_t)ZEND_DYNAMIC_PROPERTY_OFFSET);
|
||||
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
|
||||
}
|
||||
retval = zend_hash_find(zobj->properties, Z_STR_P(offset));
|
||||
if (EXPECTED(retval)) {
|
||||
uint32_t idx = ((char*)retval - (char*)zobj->properties->arData) / sizeof(Bucket);
|
||||
CACHE_PTR_EX(cache_slot + 1, (void*)(uintptr_t)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
|
||||
intptr_t idx = (char*)retval - (char*)zobj->properties->arData;
|
||||
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
|
||||
ZVAL_COPY_UNREF(EX_VAR(opline->result.var), retval);
|
||||
break;
|
||||
}
|
||||
|
@ -1937,7 +1937,7 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR
|
|||
cache_slot = CACHE_ADDR(Z_CACHE_SLOT_P(offset));
|
||||
|
||||
if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) {
|
||||
uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR_EX(cache_slot + 1);
|
||||
intptr_t prop_offset = (intptr_t)CACHED_PTR_EX(cache_slot + 1);
|
||||
|
||||
if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
|
||||
retval = OBJ_PROP(zobj, prop_offset);
|
||||
|
@ -1947,10 +1947,10 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR
|
|||
}
|
||||
} else if (EXPECTED(zobj->properties != NULL)) {
|
||||
if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) {
|
||||
uint32_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
|
||||
intptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset);
|
||||
|
||||
if (EXPECTED(idx < zobj->properties->nNumUsed)) {
|
||||
Bucket *p = zobj->properties->arData + idx;
|
||||
if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
|
||||
Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
|
||||
|
||||
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
|
||||
(EXPECTED(p->key == Z_STR_P(offset)) ||
|
||||
|
@ -1962,12 +1962,12 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR
|
|||
break;
|
||||
}
|
||||
}
|
||||
CACHE_PTR_EX(cache_slot + 1, (void*)(uintptr_t)ZEND_DYNAMIC_PROPERTY_OFFSET);
|
||||
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET);
|
||||
}
|
||||
retval = zend_hash_find(zobj->properties, Z_STR_P(offset));
|
||||
if (EXPECTED(retval)) {
|
||||
uint32_t idx = ((char*)retval - (char*)zobj->properties->arData) / sizeof(Bucket);
|
||||
CACHE_PTR_EX(cache_slot + 1, (void*)(uintptr_t)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
|
||||
intptr_t idx = (char*)retval - (char*)zobj->properties->arData;
|
||||
CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx));
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), retval);
|
||||
break;
|
||||
}
|
||||
|
@ -2126,7 +2126,7 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, SPEC(
|
|||
|
||||
if (OP2_TYPE == IS_CONST &&
|
||||
EXPECTED(Z_OBJCE_P(object) == CACHED_PTR(Z_CACHE_SLOT_P(property)))) {
|
||||
uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*));
|
||||
intptr_t prop_offset = (intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(property) + sizeof(void*));
|
||||
zend_object *zobj = Z_OBJ_P(object);
|
||||
zval *property_val;
|
||||
|
||||
|
@ -7568,7 +7568,7 @@ ZEND_VM_HOT_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST)
|
|||
zval *varname;
|
||||
zval *value;
|
||||
zval *variable_ptr;
|
||||
uint32_t idx;
|
||||
intptr_t idx;
|
||||
zend_reference *ref;
|
||||
|
||||
ZEND_VM_REPEATABLE_OPCODE
|
||||
|
@ -7576,9 +7576,9 @@ ZEND_VM_HOT_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST)
|
|||
varname = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
/* 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).nNumUsed)) {
|
||||
Bucket *p = EG(symbol_table).arData + idx;
|
||||
idx = (intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)) - 1;
|
||||
if (EXPECTED(idx < EG(symbol_table).nNumUsed * sizeof(Bucket))) {
|
||||
Bucket *p = (Bucket*)((char*)EG(symbol_table).arData + idx);
|
||||
|
||||
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
|
||||
(EXPECTED(p->key == Z_STR_P(varname)) ||
|
||||
|
@ -7587,7 +7587,7 @@ ZEND_VM_HOT_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST)
|
|||
EXPECTED(ZSTR_LEN(p->key) == Z_STRLEN_P(varname)) &&
|
||||
EXPECTED(memcmp(ZSTR_VAL(p->key), Z_STRVAL_P(varname), Z_STRLEN_P(varname)) == 0)))) {
|
||||
|
||||
value = &EG(symbol_table).arData[idx].val;
|
||||
value = (zval*)p; /* value = &p->val; */
|
||||
ZEND_VM_C_GOTO(check_indirect);
|
||||
}
|
||||
}
|
||||
|
@ -7595,13 +7595,13 @@ ZEND_VM_HOT_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST)
|
|||
value = zend_hash_find(&EG(symbol_table), Z_STR_P(varname));
|
||||
if (UNEXPECTED(value == NULL)) {
|
||||
value = zend_hash_add_new(&EG(symbol_table), Z_STR_P(varname), &EG(uninitialized_zval));
|
||||
idx = ((char*)value - (char*)EG(symbol_table).arData) / sizeof(Bucket);
|
||||
idx = (char*)value - (char*)EG(symbol_table).arData;
|
||||
/* 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));
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(idx + 1));
|
||||
} else {
|
||||
idx = ((char*)value - (char*)EG(symbol_table).arData) / sizeof(Bucket);
|
||||
idx = (char*)value - (char*)EG(symbol_table).arData;
|
||||
/* 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));
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(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)) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue