Reduce HT_MAX_SIZE to account for the max load factor of 0.5#10242
Merged
arnaud-lb merged 3 commits intophp:PHP-8.1from Jan 13, 2023
Merged
Reduce HT_MAX_SIZE to account for the max load factor of 0.5#10242arnaud-lb merged 3 commits intophp:PHP-8.1from
arnaud-lb merged 3 commits intophp:PHP-8.1from
Conversation
zend_hash allocates a hash table twice as big as nTableSize (HT_HASH_SIZE(HT_SIZE_TO_MASK(nTableSize)) == nTableSize*2), so HT_MAX_SIZE must be half the max table size or less.
Girgias
approved these changes
Jan 7, 2023
Member
Girgias
left a comment
There was a problem hiding this comment.
Looks sensible to me.
Maybe just expand the comment on why the MAX_SIZE was chosen in the header file?
arnaud-lb
commented
Jan 7, 2023
Comment on lines
-431
to
+438
| (((size_t)(uint32_t)-(int32_t)(nTableMask)) * sizeof(uint32_t)) | ||
| (((size_t)-(uint32_t)(nTableMask)) * sizeof(uint32_t)) |
Member
Author
There was a problem hiding this comment.
(int32_t)(nTableMask) is implementation defined when nTableMask has its max value (uint32_t)INT32_MAX+1.
I think that the (int32_t) cast is not necessary here, and that -(uint32_t)(nTableMask) gives the same result without being implementation defined.
arnaud-lb
commented
Jan 7, 2023
| */ | ||
| #if SIZEOF_SIZE_T == 4 | ||
| # define HT_MAX_SIZE 0x04000000 /* small enough to avoid overflow checks */ | ||
| # define HT_MAX_SIZE 0x02000000 |
Member
Author
There was a problem hiding this comment.
This is SSIZE_MAX/(sizeof(Bucket)+2*sizeof(uint32_t)) (0x3ffffff) rounded down to the closest power of two
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
zend_hash allocates a hash table twice as big as nTableSize:
HT_HASH_SIZE(HT_SIZE_TO_MASK(nTableSize)) == nTableSize*2, so HT_MAX_SIZE must be half the max table size or less.This fixes #10240:
In HT_HASH_RESET, HT_HASH_SIZE((ht)->nTableMask) evaluates to 0, leading to the assertion failure.
0is indeed an invalid value for nTableMask, given how the hash table offsets are computed:This relies on nTableMask having at least the highest bit set, so that interpreting (hash | nTableMask) as signed gives an offset in the range
]-(~(nTableMask)+1)...0].ht->arDatapoints to the end of the hash table.hashis always > 0, so the range is actually]-(~(nTableMask)+1)...-1].HT_SIZE_TO_MASK multiples nSize by 2 to ensure a load factor of 0.5.
Given that, I think that HT_MAX_SIZE should be (2**31 / 2) : 0x40000000.