Skip to content

Commit 5d6bc25

Browse files
committed
Reset Bucket->key of deleted HastTable elemets to NULL.
This allows elimination of some Z_ISUNDEF(Bucket->val) checks.
1 parent 3c73225 commit 5d6bc25

File tree

6 files changed

+152
-191
lines changed

6 files changed

+152
-191
lines changed

Zend/zend_hash.c

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,9 +1404,6 @@ static zend_always_inline void _zend_hash_del_el_ex(HashTable *ht, uint32_t idx,
14041404
} while (ht->nNumUsed > 0 && (UNEXPECTED(Z_TYPE(ht->arData[ht->nNumUsed-1].val) == IS_UNDEF)));
14051405
ht->nInternalPointer = MIN(ht->nInternalPointer, ht->nNumUsed);
14061406
}
1407-
if (p->key) {
1408-
zend_string_release(p->key);
1409-
}
14101407
if (ht->pDestructor) {
14111408
zval tmp;
14121409
ZVAL_COPY_VALUE(&tmp, &p->val);
@@ -1435,6 +1432,10 @@ static zend_always_inline void _zend_hash_del_el(HashTable *ht, uint32_t idx, Bu
14351432
}
14361433

14371434
_zend_hash_del_el_ex(ht, idx, p, prev);
1435+
if (p->key) {
1436+
zend_string_release(p->key);
1437+
p->key = NULL;
1438+
}
14381439
}
14391440

14401441
ZEND_API void ZEND_FASTCALL zend_hash_packed_del_val(HashTable *ht, zval *zv)
@@ -1476,6 +1477,8 @@ ZEND_API zend_result ZEND_FASTCALL zend_hash_del(HashTable *ht, zend_string *key
14761477
p->key &&
14771478
zend_string_equal_content(p->key, key))) {
14781479
_zend_hash_del_el_ex(ht, idx, p, prev);
1480+
zend_string_release(p->key);
1481+
p->key = NULL;
14791482
return SUCCESS;
14801483
}
14811484
prev = p;
@@ -1523,6 +1526,8 @@ ZEND_API zend_result ZEND_FASTCALL zend_hash_del_ind(HashTable *ht, zend_string
15231526
}
15241527
} else {
15251528
_zend_hash_del_el_ex(ht, idx, p, prev);
1529+
zend_string_release(p->key);
1530+
p->key = NULL;
15261531
}
15271532
return SUCCESS;
15281533
}
@@ -1567,6 +1572,8 @@ ZEND_API zend_result ZEND_FASTCALL zend_hash_str_del_ind(HashTable *ht, const ch
15671572
}
15681573
} else {
15691574
_zend_hash_del_el_ex(ht, idx, p, prev);
1575+
zend_string_release(p->key);
1576+
p->key = NULL;
15701577
}
15711578
return SUCCESS;
15721579
}
@@ -1598,6 +1605,8 @@ ZEND_API zend_result ZEND_FASTCALL zend_hash_str_del(HashTable *ht, const char *
15981605
&& (ZSTR_LEN(p->key) == len)
15991606
&& !memcmp(ZSTR_VAL(p->key), str, len)) {
16001607
_zend_hash_del_el_ex(ht, idx, p, prev);
1608+
zend_string_release(p->key);
1609+
p->key = NULL;
16011610
return SUCCESS;
16021611
}
16031612
prev = p;
@@ -1698,7 +1707,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
16981707
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) {
16991708
ht->pDestructor(&p->val);
17001709
if (EXPECTED(p->key)) {
1701-
zend_string_release(p->key);
1710+
zend_string_release(p->key);
17021711
}
17031712
}
17041713
} while (++p != end);
@@ -1708,10 +1717,8 @@ ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
17081717
} else {
17091718
if (!HT_HAS_STATIC_KEYS_ONLY(ht)) {
17101719
do {
1711-
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) {
1712-
if (EXPECTED(p->key)) {
1713-
zend_string_release(p->key);
1714-
}
1720+
if (EXPECTED(p->key)) {
1721+
zend_string_release(p->key);
17151722
}
17161723
} while (++p != end);
17171724
}
@@ -1846,21 +1853,11 @@ ZEND_API void ZEND_FASTCALL zend_hash_clean(HashTable *ht)
18461853
}
18471854
} else {
18481855
if (!HT_HAS_STATIC_KEYS_ONLY(ht)) {
1849-
if (HT_IS_WITHOUT_HOLES(ht)) {
1850-
do {
1851-
if (EXPECTED(p->key)) {
1852-
zend_string_release(p->key);
1853-
}
1854-
} while (++p != end);
1855-
} else {
1856-
do {
1857-
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) {
1858-
if (EXPECTED(p->key)) {
1859-
zend_string_release(p->key);
1860-
}
1861-
}
1862-
} while (++p != end);
1863-
}
1856+
do {
1857+
if (EXPECTED(p->key)) {
1858+
zend_string_release(p->key);
1859+
}
1860+
} while (++p != end);
18641861
}
18651862
}
18661863
HT_HASH_RESET(ht);

Zend/zend_object_handlers.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -619,11 +619,10 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
619619
if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
620620
Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
621621

622-
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
623-
(EXPECTED(p->key == name) ||
624-
(EXPECTED(p->h == ZSTR_H(name)) &&
625-
EXPECTED(p->key != NULL) &&
626-
EXPECTED(zend_string_equal_content(p->key, name))))) {
622+
if (EXPECTED(p->key == name) ||
623+
(EXPECTED(p->h == ZSTR_H(name)) &&
624+
EXPECTED(p->key != NULL) &&
625+
EXPECTED(zend_string_equal_content(p->key, name)))) {
627626
retval = &p->val;
628627
goto exit;
629628
}
@@ -1754,11 +1753,10 @@ ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has
17541753
if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
17551754
Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
17561755

1757-
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
1758-
(EXPECTED(p->key == name) ||
1759-
(EXPECTED(p->h == ZSTR_H(name)) &&
1760-
EXPECTED(p->key != NULL) &&
1761-
EXPECTED(zend_string_equal_content(p->key, name))))) {
1756+
if (EXPECTED(p->key == name) ||
1757+
(EXPECTED(p->h == ZSTR_H(name)) &&
1758+
EXPECTED(p->key != NULL) &&
1759+
EXPECTED(zend_string_equal_content(p->key, name)))) {
17621760
value = &p->val;
17631761
goto found;
17641762
}

Zend/zend_vm_def.h

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,11 +2083,10 @@ ZEND_VM_C_LABEL(fetch_obj_r_fast_copy):
20832083
if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
20842084
Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
20852085

2086-
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
2087-
(EXPECTED(p->key == name) ||
2088-
(EXPECTED(p->h == ZSTR_H(name)) &&
2089-
EXPECTED(p->key != NULL) &&
2090-
EXPECTED(zend_string_equal_content(p->key, name))))) {
2086+
if (EXPECTED(p->key == name) ||
2087+
(EXPECTED(p->h == ZSTR_H(name)) &&
2088+
EXPECTED(p->key != NULL) &&
2089+
EXPECTED(zend_string_equal_content(p->key, name)))) {
20912090
retval = &p->val;
20922091
if (!ZEND_VM_SPEC || (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) != 0) {
20932092
ZEND_VM_C_GOTO(fetch_obj_r_copy);
@@ -2248,11 +2247,10 @@ ZEND_VM_C_LABEL(fetch_obj_is_fast_copy):
22482247
if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) {
22492248
Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx);
22502249

2251-
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
2252-
(EXPECTED(p->key == name) ||
2253-
(EXPECTED(p->h == ZSTR_H(name)) &&
2254-
EXPECTED(p->key != NULL) &&
2255-
EXPECTED(zend_string_equal_content(p->key, name))))) {
2250+
if (EXPECTED(p->key == name) ||
2251+
(EXPECTED(p->h == ZSTR_H(name)) &&
2252+
EXPECTED(p->key != NULL) &&
2253+
EXPECTED(zend_string_equal_content(p->key, name)))) {
22562254
retval = &p->val;
22572255
if (!ZEND_VM_SPEC || (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) != 0) {
22582256
ZEND_VM_C_GOTO(fetch_obj_is_copy);
@@ -8370,11 +8368,10 @@ ZEND_VM_HOT_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST, CACHE_SLOT)
83708368
if (EXPECTED(idx < EG(symbol_table).nNumUsed * sizeof(Bucket))) {
83718369
Bucket *p = (Bucket*)((char*)EG(symbol_table).arData + idx);
83728370

8373-
if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
8374-
(EXPECTED(p->key == varname) ||
8375-
(EXPECTED(p->h == ZSTR_H(varname)) &&
8376-
EXPECTED(p->key != NULL) &&
8377-
EXPECTED(zend_string_equal_content(p->key, varname))))) {
8371+
if (EXPECTED(p->key == varname) ||
8372+
(EXPECTED(p->h == ZSTR_H(varname)) &&
8373+
EXPECTED(p->key != NULL) &&
8374+
EXPECTED(zend_string_equal_content(p->key, varname)))) {
83788375

83798376
value = (zval*)p; /* value = &p->val; */
83808377
ZEND_VM_C_GOTO(check_indirect);

0 commit comments

Comments
 (0)