summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnatol Belski <ab@php.net>2015-01-14 12:29:50 +0100
committerAnatol Belski <ab@php.net>2015-01-14 12:32:23 +0100
commit8e3764e287ceb3c954dfd866dc72c9530907bef7 (patch)
tree9c068df73c14e74158f041a9358238285f6cb99f
parentade7a410403d7ec3fc1579bee3b890b1ce549eec (diff)
downloadphp-git-8e3764e287ceb3c954dfd866dc72c9530907bef7.tar.gz
fixed zend_hash_init() when the lzcnt instruction isn't supported
-rw-r--r--Zend/zend_hash.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index fd0d27fb07..e496e5898b 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -101,25 +101,24 @@ static const uint32_t uninitialized_bucket = {INVALID_IDX};
ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC)
{
+#if defined(ZEND_WIN32)
+ unsigned long index;
+#endif
/* Use big enough power of 2 */
-#if defined(PHP_WIN32) && !defined(__clang__)
- if (nSize <= 8) {
- ht->nTableSize = 8;
- } else if (nSize >= 0x80000000) {
- /* prevent overflow */
- ht->nTableSize = 0x80000000;
- } else {
- ht->nTableSize = 1U << __lzcnt(nSize);
- if (ht->nTableSize < nSize) {
- ht->nTableSize <<= 1;
- }
- }
-#else
/* size should be between 8 and 0x80000000 */
nSize = (nSize <= 8 ? 8 : (nSize >= 0x80000000 ? 0x80000000 : nSize));
-# if defined(__GNUC__)
+
+#if defined(ZEND_WIN32)
+ if (BitScanReverse(&index, nSize - 1)) {
+ ht->nTableSize = 0x2 << ((31 - index) ^ 0x1f);
+ } else {
+ /* nSize is ensured to be in the valid range, fall back to it
+ rather than using an undefined bis scan result. */
+ ht->nTableSize = nSize;
+ }
+#elif defined(__GNUC__)
ht->nTableSize = 0x2 << (__builtin_clz(nSize - 1) ^ 0x1f);
-# else
+#else
nSize -= 1;
nSize |= (nSize >> 1);
nSize |= (nSize >> 2);
@@ -127,7 +126,6 @@ ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestru
nSize |= (nSize >> 8);
nSize |= (nSize >> 16);
ht->nTableSize = nSize + 1;
-# endif
#endif
ht->nTableMask = 0;