]> granicus.if.org Git - php/commitdiff
Optimize zend_new_array() for special case, when size <= HT_MIN_SIZE
authorDmitry Stogov <dmitry@zend.com>
Wed, 30 May 2018 22:17:55 +0000 (01:17 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 30 May 2018 22:17:55 +0000 (01:17 +0300)
Zend/zend_hash.c
Zend/zend_hash.h

index b97cfb2ba43bcfbab3424bdf391f68d13191aa08..8cb666a708915220964c380da81cc564161a3ab0 100644 (file)
@@ -92,8 +92,8 @@ static zend_always_inline uint32_t zend_hash_check_size(uint32_t nSize)
 
        /* Use big enough power of 2 */
        /* size should be between HT_MIN_SIZE and HT_MAX_SIZE */
-       if (nSize < HT_MIN_SIZE) {
-               nSize = HT_MIN_SIZE;
+       if (nSize <= HT_MIN_SIZE) {
+               return HT_MIN_SIZE;
        } else if (UNEXPECTED(nSize >= HT_MAX_SIZE)) {
                zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", nSize, sizeof(Bucket), sizeof(Bucket));
        }
@@ -214,6 +214,13 @@ ZEND_API void ZEND_FASTCALL _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_
        _zend_hash_init_int(ht, nSize, pDestructor, persistent);
 }
 
+ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_0(ZEND_FILE_LINE_D)
+{
+       HashTable *ht = emalloc(sizeof(HashTable));
+       _zend_hash_init_int(ht, HT_MIN_SIZE, ZVAL_PTR_DTOR, 0);
+       return ht;
+}
+
 ZEND_API HashTable* ZEND_FASTCALL _zend_new_array(uint32_t nSize ZEND_FILE_LINE_DC)
 {
        HashTable *ht = emalloc(sizeof(HashTable));
index 220bccbb76211250a5f09826b898b9e421ee7cfe..f2399ca93737b52dfe8c4d7e2242a14445f48322 100644 (file)
@@ -289,9 +289,23 @@ ZEND_API zval* ZEND_FASTCALL zend_hash_minmax(const HashTable *ht, compare_func_
 
 ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht);
 
-#define zend_new_array(size) \
+#if !ZEND_DEBUG && defined(HAVE_BUILTIN_CONSTANT_P)
+# define zend_new_array(size) \
+       (__builtin_constant_p(size) ? \
+               ((((uint32_t)(size)) <= HT_MIN_SIZE) ? \
+                       _zend_new_array_0(ZEND_FILE_LINE_C) \
+               : \
+                       _zend_new_array((size) ZEND_FILE_LINE_CC) \
+               ) \
+       : \
+               _zend_new_array((size) ZEND_FILE_LINE_CC) \
+       )
+#else
+# define zend_new_array(size) \
        _zend_new_array(size ZEND_FILE_LINE_CC)
+#endif
 
+ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_0(ZEND_FILE_LINE_D);
 ZEND_API HashTable* ZEND_FASTCALL _zend_new_array(uint32_t size ZEND_FILE_LINE_DC);
 ZEND_API uint32_t zend_array_count(HashTable *ht);
 ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source);