Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Zend/zend_execute_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ void init_executor(void) /* {{{ */

EG(ht_iterators_count) = sizeof(EG(ht_iterators_slots)) / sizeof(HashTableIterator);
EG(ht_iterators_used) = 0;
EG(ht_iterators_free_hint) = 0;
EG(ht_iterators) = EG(ht_iterators_slots);
memset(EG(ht_iterators), 0, sizeof(EG(ht_iterators_slots)));

Expand Down
1 change: 1 addition & 0 deletions Zend/zend_globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ struct _zend_executor_globals {

uint32_t ht_iterators_count; /* number of allocated slots */
uint32_t ht_iterators_used; /* number of used slots */
uint32_t ht_iterators_free_hint; /* no free slot below this one */
HashTableIterator *ht_iterators;
HashTableIterator ht_iterators_slots[16];

Expand Down
17 changes: 11 additions & 6 deletions Zend/zend_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -689,25 +689,26 @@ static void zend_hash_remove_iterator_copies(uint32_t idx) {

ZEND_API uint32_t ZEND_FASTCALL zend_hash_iterator_add(HashTable *ht, HashPosition pos)
{
HashTableIterator *iter = EG(ht_iterators);
HashTableIterator *end = iter + EG(ht_iterators_count);
uint32_t idx;
/* Slots below the hint are in use, start looking for a free one from there */
uint32_t idx = EG(ht_iterators_free_hint);
HashTableIterator *iter;

if (EXPECTED(!HT_ITERATORS_OVERFLOW(ht))) {
HT_INC_ITERATORS_COUNT(ht);
}
while (iter != end) {
while (idx < EG(ht_iterators_count)) {
iter = EG(ht_iterators) + idx;
if (iter->ht == NULL) {
iter->ht = ht;
iter->pos = pos;
idx = iter - EG(ht_iterators);
iter->next_copy = idx;
EG(ht_iterators_free_hint) = idx + 1;
if (idx + 1 > EG(ht_iterators_used)) {
EG(ht_iterators_used) = idx + 1;
}
return idx;
}
iter++;
idx++;
}
if (EG(ht_iterators) == EG(ht_iterators_slots)) {
EG(ht_iterators) = emalloc(sizeof(HashTableIterator) * (EG(ht_iterators_count) + 8));
Expand All @@ -723,6 +724,7 @@ ZEND_API uint32_t ZEND_FASTCALL zend_hash_iterator_add(HashTable *ht, HashPositi
idx = iter - EG(ht_iterators);
iter->next_copy = idx;
EG(ht_iterators_used) = idx + 1;
EG(ht_iterators_free_hint) = idx + 1;
return idx;
}

Expand Down Expand Up @@ -818,6 +820,9 @@ ZEND_API void ZEND_FASTCALL zend_hash_iterator_del(uint32_t idx)
HT_DEC_ITERATORS_COUNT(iter->ht);
}
iter->ht = NULL;
if (idx < EG(ht_iterators_free_hint)) {
EG(ht_iterators_free_hint) = idx;
}

if (UNEXPECTED(iter->next_copy != idx)) {
zend_hash_remove_iterator_copies(idx);
Expand Down
Loading