Skip to content

Commit 3d12fc7

Browse files
committed
Small cleanups in hash implementation
* Drop unnecessary checks in non-inlined part of numeric key detection * Drop zend_hash_apply_deleter in favor of zend_hash_del_el. Also move block/unblock interruption macros in there.
1 parent ab0b15b commit 3d12fc7

File tree

1 file changed

+13
-47
lines changed

1 file changed

+13
-47
lines changed

Zend/zend_hash.c

Lines changed: 13 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,7 @@ ZEND_API int zend_hash_rehash(HashTable *ht)
614614

615615
static zend_always_inline void _zend_hash_del_el_ex(HashTable *ht, uint32_t idx, Bucket *p, Bucket *prev)
616616
{
617+
HANDLE_BLOCK_INTERRUPTIONS();
617618
if (!(ht->u.flags & HASH_FLAG_PACKED)) {
618619
if (prev) {
619620
Z_NEXT(prev->val) = Z_NEXT(p->val);
@@ -650,6 +651,7 @@ static zend_always_inline void _zend_hash_del_el_ex(HashTable *ht, uint32_t idx,
650651
} else {
651652
ZVAL_UNDEF(&p->val);
652653
}
654+
HANDLE_UNBLOCK_INTERRUPTIONS();
653655
}
654656

655657
static zend_always_inline void _zend_hash_del_el(HashTable *ht, uint32_t idx, Bucket *p)
@@ -697,9 +699,7 @@ ZEND_API int zend_hash_del(HashTable *ht, zend_string *key)
697699
p->key &&
698700
p->key->len == key->len &&
699701
memcmp(p->key->val, key->val, key->len) == 0)) {
700-
HANDLE_BLOCK_INTERRUPTIONS();
701702
_zend_hash_del_el_ex(ht, idx, p, prev);
702-
HANDLE_UNBLOCK_INTERRUPTIONS();
703703
return SUCCESS;
704704
}
705705
prev = p;
@@ -745,9 +745,7 @@ ZEND_API int zend_hash_del_ind(HashTable *ht, zend_string *key)
745745
ZVAL_UNDEF(data);
746746
}
747747
} else {
748-
HANDLE_BLOCK_INTERRUPTIONS();
749748
_zend_hash_del_el_ex(ht, idx, p, prev);
750-
HANDLE_UNBLOCK_INTERRUPTIONS();
751749
}
752750
return SUCCESS;
753751
}
@@ -793,9 +791,7 @@ ZEND_API int zend_hash_str_del(HashTable *ht, const char *str, size_t len)
793791
ZVAL_UNDEF(data);
794792
}
795793
} else {
796-
HANDLE_BLOCK_INTERRUPTIONS();
797794
_zend_hash_del_el_ex(ht, idx, p, prev);
798-
HANDLE_UNBLOCK_INTERRUPTIONS();
799795
}
800796
return SUCCESS;
801797
}
@@ -825,9 +821,7 @@ ZEND_API int zend_hash_str_del_ind(HashTable *ht, const char *str, size_t len)
825821
&& p->key
826822
&& (p->key->len == len)
827823
&& !memcmp(p->key->val, str, len)) {
828-
HANDLE_BLOCK_INTERRUPTIONS();
829824
_zend_hash_del_el_ex(ht, idx, p, prev);
830-
HANDLE_UNBLOCK_INTERRUPTIONS();
831825
return SUCCESS;
832826
}
833827
prev = p;
@@ -849,9 +843,7 @@ ZEND_API int zend_hash_index_del(HashTable *ht, zend_ulong h)
849843
if (h < ht->nNumUsed) {
850844
p = ht->arData + h;
851845
if (Z_TYPE(p->val) != IS_UNDEF) {
852-
HANDLE_BLOCK_INTERRUPTIONS();
853846
_zend_hash_del_el_ex(ht, h, p, NULL);
854-
HANDLE_UNBLOCK_INTERRUPTIONS();
855847
return SUCCESS;
856848
}
857849
}
@@ -863,9 +855,7 @@ ZEND_API int zend_hash_index_del(HashTable *ht, zend_ulong h)
863855
while (idx != INVALID_IDX) {
864856
p = ht->arData + idx;
865857
if ((p->h == h) && (p->key == NULL)) {
866-
HANDLE_BLOCK_INTERRUPTIONS();
867858
_zend_hash_del_el_ex(ht, idx, p, prev);
868-
HANDLE_UNBLOCK_INTERRUPTIONS();
869859
return SUCCESS;
870860
}
871861
prev = p;
@@ -1041,20 +1031,6 @@ ZEND_API void zend_symtable_clean(HashTable *ht)
10411031
}
10421032
}
10431033

1044-
/* This function is used by the various apply() functions.
1045-
* It deletes the passed bucket, and returns the address of the
1046-
* next bucket. The hash *may* be altered during that time, the
1047-
* returned value will still be valid.
1048-
*/
1049-
static void zend_hash_apply_deleter(HashTable *ht, uint32_t idx, Bucket *p)
1050-
{
1051-
1052-
HANDLE_BLOCK_INTERRUPTIONS();
1053-
_zend_hash_del_el(ht, idx, p);
1054-
HANDLE_UNBLOCK_INTERRUPTIONS();
1055-
}
1056-
1057-
10581034
ZEND_API void zend_hash_graceful_destroy(HashTable *ht)
10591035
{
10601036
uint32_t idx;
@@ -1065,7 +1041,7 @@ ZEND_API void zend_hash_graceful_destroy(HashTable *ht)
10651041
for (idx = 0; idx < ht->nNumUsed; idx++) {
10661042
p = ht->arData + idx;
10671043
if (Z_TYPE(p->val) == IS_UNDEF) continue;
1068-
zend_hash_apply_deleter(ht, idx, p);
1044+
_zend_hash_del_el(ht, idx, p);
10691045
}
10701046
if (ht->nTableMask) {
10711047
pefree(ht->arData, ht->u.flags & HASH_FLAG_PERSISTENT);
@@ -1086,7 +1062,7 @@ ZEND_API void zend_hash_graceful_reverse_destroy(HashTable *ht)
10861062
idx--;
10871063
p = ht->arData + idx;
10881064
if (Z_TYPE(p->val) == IS_UNDEF) continue;
1089-
zend_hash_apply_deleter(ht, idx, p);
1065+
_zend_hash_del_el(ht, idx, p);
10901066
}
10911067

10921068
if (ht->nTableMask) {
@@ -1121,7 +1097,7 @@ ZEND_API void zend_hash_apply(HashTable *ht, apply_func_t apply_func)
11211097
result = apply_func(&p->val);
11221098

11231099
if (result & ZEND_HASH_APPLY_REMOVE) {
1124-
zend_hash_apply_deleter(ht, idx, p);
1100+
_zend_hash_del_el(ht, idx, p);
11251101
}
11261102
if (result & ZEND_HASH_APPLY_STOP) {
11271103
break;
@@ -1147,7 +1123,7 @@ ZEND_API void zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t appl
11471123
result = apply_func(&p->val, argument);
11481124

11491125
if (result & ZEND_HASH_APPLY_REMOVE) {
1150-
zend_hash_apply_deleter(ht, idx, p);
1126+
_zend_hash_del_el(ht, idx, p);
11511127
}
11521128
if (result & ZEND_HASH_APPLY_STOP) {
11531129
break;
@@ -1179,7 +1155,7 @@ ZEND_API void zend_hash_apply_with_arguments(HashTable *ht, apply_func_args_t ap
11791155
result = apply_func(&p->val, num_args, args, &hash_key);
11801156

11811157
if (result & ZEND_HASH_APPLY_REMOVE) {
1182-
zend_hash_apply_deleter(ht, idx, p);
1158+
_zend_hash_del_el(ht, idx, p);
11831159
}
11841160
if (result & ZEND_HASH_APPLY_STOP) {
11851161
va_end(args);
@@ -1210,7 +1186,7 @@ ZEND_API void zend_hash_reverse_apply(HashTable *ht, apply_func_t apply_func)
12101186
result = apply_func(&p->val);
12111187

12121188
if (result & ZEND_HASH_APPLY_REMOVE) {
1213-
zend_hash_apply_deleter(ht, idx, p);
1189+
_zend_hash_del_el(ht, idx, p);
12141190
}
12151191
if (result & ZEND_HASH_APPLY_STOP) {
12161192
break;
@@ -1932,25 +1908,15 @@ ZEND_API zval *zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint
19321908
ZEND_API int _zend_handle_numeric_str_ex(const char *key, size_t length, zend_ulong *idx)
19331909
{
19341910
register const char *tmp = key;
1935-
const char *end;
19361911

1937-
if (*tmp > '9') {
1938-
return 0;
1939-
} else if (*tmp < '0') {
1940-
if (*tmp != '-') {
1941-
return 0;
1942-
}
1912+
const char *end = key + length;
1913+
ZEND_ASSERT(*end == '\0');
1914+
1915+
if (*tmp == '-') {
19431916
tmp++;
1944-
if (*tmp > '9' || *tmp < '0') {
1945-
return 0;
1946-
}
19471917
}
19481918

1949-
/* possibly a numeric index */
1950-
end = key + length;
1951-
1952-
if ((*end != '\0') /* not a null terminated string */
1953-
|| (*tmp == '0' && length > 1) /* numbers with leading zeros */
1919+
if ((*tmp == '0' && length > 1) /* numbers with leading zeros */
19541920
|| (end - tmp > MAX_LENGTH_OF_LONG - 1) /* number too long */
19551921
|| (SIZEOF_ZEND_LONG == 4 &&
19561922
end - tmp == MAX_LENGTH_OF_LONG - 1 &&

0 commit comments

Comments
 (0)