]> granicus.if.org Git - php/commitdiff
Added specialized code for small arrays
authorDmitry Stogov <dmitry@zend.com>
Thu, 20 Dec 2018 14:55:01 +0000 (17:55 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 20 Dec 2018 14:55:01 +0000 (17:55 +0300)
Zend/zend_hash.c

index 686f97cba510de39f24ff83cc485aa66e5e0523f..11ab0156ab00bb5094f781642667f6ceab16dd71 100644 (file)
@@ -119,53 +119,67 @@ static zend_always_inline uint32_t zend_hash_check_size(uint32_t nSize)
 
 static zend_always_inline void zend_hash_real_init_packed_ex(HashTable *ht)
 {
-       HT_SET_DATA_ADDR(ht, pemalloc(HT_SIZE_EX(ht->nTableSize, HT_MIN_MASK), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT));
+       void *data;
+
+       if (UNEXPECTED(GC_FLAGS(ht) & IS_ARRAY_PERSISTENT)) {
+               data = pemalloc(HT_SIZE_EX(ht->nTableSize, HT_MIN_MASK), 1);
+       } else if (EXPECTED(ht->nTableSize == HT_MIN_SIZE)) {
+               data = emalloc(HT_SIZE_EX(HT_MIN_SIZE, HT_MIN_MASK));
+       } else {
+               data = emalloc(HT_SIZE_EX(ht->nTableSize, HT_MIN_MASK));
+       }
+       HT_SET_DATA_ADDR(ht, data);
        HT_FLAGS(ht) |= HASH_FLAG_INITIALIZED | HASH_FLAG_PACKED;
        HT_HASH_RESET_PACKED(ht);
 }
 
 static zend_always_inline void zend_hash_real_init_mixed_ex(HashTable *ht)
 {
+       void *data;
        uint32_t nSize = ht->nTableSize;
 
-       if (EXPECTED(nSize == HT_MIN_SIZE)) {
+       if (UNEXPECTED(GC_FLAGS(ht) & IS_ARRAY_PERSISTENT)) {
+               data = pemalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)), 1);
+       } else if (EXPECTED(nSize == HT_MIN_SIZE)) {
+               data = emalloc(HT_SIZE_EX(HT_MIN_SIZE, HT_SIZE_TO_MASK(HT_MIN_SIZE)));
                ht->nTableMask = HT_SIZE_TO_MASK(HT_MIN_SIZE);
-               HT_SET_DATA_ADDR(ht, pemalloc(HT_SIZE_EX(HT_MIN_SIZE, HT_SIZE_TO_MASK(HT_MIN_SIZE)), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT));
+               HT_SET_DATA_ADDR(ht, data);
                HT_FLAGS(ht) |= HASH_FLAG_INITIALIZED;
-               do {
-                       Bucket *arData = ht->arData;
 #ifdef __SSE2__
+               do {
                        __m128i xmm0 = _mm_setzero_si128();
                        xmm0 = _mm_cmpeq_epi8(xmm0, xmm0);
-                       _mm_storeu_si128((__m128i*)&HT_HASH_EX(arData, -16), xmm0);
-                       _mm_storeu_si128((__m128i*)&HT_HASH_EX(arData, -12), xmm0);
-                       _mm_storeu_si128((__m128i*)&HT_HASH_EX(arData, -8), xmm0);
-                       _mm_storeu_si128((__m128i*)&HT_HASH_EX(arData, -4), xmm0);
+                       _mm_storeu_si128((__m128i*)&HT_HASH_EX(data,  0), xmm0);
+                       _mm_storeu_si128((__m128i*)&HT_HASH_EX(data,  4), xmm0);
+                       _mm_storeu_si128((__m128i*)&HT_HASH_EX(data,  8), xmm0);
+                       _mm_storeu_si128((__m128i*)&HT_HASH_EX(data, 12), xmm0);
+               } while (0);
 #else
-                       HT_HASH_EX(arData, -16) = -1;
-                       HT_HASH_EX(arData, -15) = -1;
-                       HT_HASH_EX(arData, -14) = -1;
-                       HT_HASH_EX(arData, -13) = -1;
-                       HT_HASH_EX(arData, -12) = -1;
-                       HT_HASH_EX(arData, -11) = -1;
-                       HT_HASH_EX(arData, -10) = -1;
-                       HT_HASH_EX(arData, -9) = -1;
-                       HT_HASH_EX(arData, -8) = -1;
-                       HT_HASH_EX(arData, -7) = -1;
-                       HT_HASH_EX(arData, -6) = -1;
-                       HT_HASH_EX(arData, -5) = -1;
-                       HT_HASH_EX(arData, -4) = -1;
-                       HT_HASH_EX(arData, -3) = -1;
-                       HT_HASH_EX(arData, -2) = -1;
-                       HT_HASH_EX(arData, -1) = -1;
+               HT_HASH_EX(data,  0) = -1;
+               HT_HASH_EX(data,  1) = -1;
+               HT_HASH_EX(data,  2) = -1;
+               HT_HASH_EX(data,  3) = -1;
+               HT_HASH_EX(data,  4) = -1;
+               HT_HASH_EX(data,  5) = -1;
+               HT_HASH_EX(data,  6) = -1;
+               HT_HASH_EX(data,  7) = -1;
+               HT_HASH_EX(data,  8) = -1;
+               HT_HASH_EX(data,  9) = -1;
+               HT_HASH_EX(data, 10) = -1;
+               HT_HASH_EX(data, 11) = -1;
+               HT_HASH_EX(data, 12) = -1;
+               HT_HASH_EX(data, 13) = -1;
+               HT_HASH_EX(data, 14) = -1;
+               HT_HASH_EX(data, 15) = -1;
 #endif
-               } while (0);
+               return;
        } else {
-               ht->nTableMask = HT_SIZE_TO_MASK(nSize);
-               HT_SET_DATA_ADDR(ht, pemalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT));
-               HT_FLAGS(ht) |= HASH_FLAG_INITIALIZED;
-               HT_HASH_RESET(ht);
+               data = emalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)));
        }
+       ht->nTableMask = HT_SIZE_TO_MASK(nSize);
+       HT_SET_DATA_ADDR(ht, data);
+       HT_FLAGS(ht) |= HASH_FLAG_INITIALIZED;
+       HT_HASH_RESET(ht);
 }
 
 static zend_always_inline void zend_hash_real_init_ex(HashTable *ht, int packed)