@@ -149,6 +149,22 @@ static size_t _real_page_size = ZEND_MM_PAGE_SIZE;
149149# define ZEND_MM_HEAP_PROTECTION 1 /* protect heap against corruptions */
150150#endif
151151
152+ #if ZEND_MM_HEAP_PROTECTION
153+ /* Define ZEND_MM_MIN_USEABLE_BIN_SIZE to the size of two pointers */
154+ # if UINTPTR_MAX == UINT64_MAX
155+ # define ZEND_MM_MIN_USEABLE_BIN_SIZE 16
156+ # elif UINTPTR_MAX == UINT32_MAX
157+ # define ZEND_MM_MIN_USEABLE_BIN_SIZE 8
158+ # else
159+ # error
160+ # endif
161+ # if ZEND_MM_MIN_USEABLE_BIN_SIZE < ZEND_MM_MIN_SMALL_SIZE
162+ # error
163+ # endif
164+ #else /* ZEND_MM_HEAP_PROTECTION */
165+ # define ZEND_MM_MIN_USEABLE_BIN_SIZE ZEND_MM_MIN_SMALL_SIZE
166+ #endif /* ZEND_MM_HEAP_PROTECTION */
167+
152168#ifndef ZEND_MM_CHECK
153169# define ZEND_MM_CHECK (condition , message ) do { \
154170 if (UNEXPECTED(!(condition))) { \
@@ -1336,7 +1352,7 @@ static zend_always_inline zend_mm_free_slot* zend_mm_decode_free_slot(zend_mm_he
13361352
13371353static zend_always_inline void zend_mm_set_next_free_slot (zend_mm_heap * heap , uint32_t bin_num , zend_mm_free_slot * slot , zend_mm_free_slot * next )
13381354{
1339- ZEND_ASSERT (bin_data_size [bin_num ] >= ZEND_MM_MIN_SMALL_SIZE );
1355+ ZEND_ASSERT (bin_data_size [bin_num ] >= ZEND_MM_MIN_USEABLE_BIN_SIZE );
13401356
13411357 slot -> next_free_slot = next ;
13421358 ZEND_MM_FREE_SLOT_PTR_SHADOW (slot , bin_num ) = zend_mm_encode_free_slot (heap , next );
@@ -1419,7 +1435,7 @@ static zend_never_inline void *zend_mm_alloc_small_slow(zend_mm_heap *heap, uint
14191435
14201436static zend_always_inline void * zend_mm_alloc_small (zend_mm_heap * heap , int bin_num ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC )
14211437{
1422- ZEND_ASSERT (bin_data_size [bin_num ] >= ZEND_MM_MIN_SMALL_SIZE );
1438+ ZEND_ASSERT (bin_data_size [bin_num ] >= ZEND_MM_MIN_USEABLE_BIN_SIZE );
14231439
14241440#if ZEND_MM_STAT
14251441 do {
@@ -1441,7 +1457,7 @@ static zend_always_inline void *zend_mm_alloc_small(zend_mm_heap *heap, int bin_
14411457
14421458static zend_always_inline void zend_mm_free_small (zend_mm_heap * heap , void * ptr , int bin_num )
14431459{
1444- ZEND_ASSERT (bin_data_size [bin_num ] >= ZEND_MM_MIN_SMALL_SIZE );
1460+ ZEND_ASSERT (bin_data_size [bin_num ] >= ZEND_MM_MIN_USEABLE_BIN_SIZE );
14451461
14461462 zend_mm_free_slot * p ;
14471463
@@ -1493,8 +1509,8 @@ static zend_always_inline void *zend_mm_alloc_heap(zend_mm_heap *heap, size_t si
14931509{
14941510 void * ptr ;
14951511#if ZEND_MM_HEAP_PROTECTION
1496- if (size < ZEND_MM_MIN_SMALL_SIZE ) {
1497- size = ZEND_MM_MIN_SMALL_SIZE ;
1512+ if (size < ZEND_MM_MIN_USEABLE_BIN_SIZE ) {
1513+ size = ZEND_MM_MIN_USEABLE_BIN_SIZE ;
14981514 }
14991515#endif /* ZEND_MM_HEAP_PROTECTION */
15001516#if ZEND_DEBUG
@@ -1719,8 +1735,8 @@ static zend_always_inline void *zend_mm_realloc_heap(zend_mm_heap *heap, void *p
17191735 int page_num = (int )(page_offset / ZEND_MM_PAGE_SIZE );
17201736 zend_mm_page_info info = chunk -> map [page_num ];
17211737#if ZEND_MM_HEAP_PROTECTION
1722- if (size < ZEND_MM_MIN_SMALL_SIZE ) {
1723- size = ZEND_MM_MIN_SMALL_SIZE ;
1738+ if (size < ZEND_MM_MIN_USEABLE_BIN_SIZE ) {
1739+ size = ZEND_MM_MIN_USEABLE_BIN_SIZE ;
17241740 }
17251741#endif /* ZEND_MM_HEAP_PROTECTION */
17261742#if ZEND_DEBUG
@@ -2759,14 +2775,16 @@ ZEND_API bool is_zend_ptr(const void *ptr)
27592775# define ZEND_MM_CUSTOM_DEALLOCATOR (ptr )
27602776#endif
27612777
2762- # define _ZEND_BIN_ALLOCATOR (_num , _size , _elements , _pages , x , y ) \
2778+ # define _ZEND_BIN_ALLOCATOR (_num , _size , _elements , _pages , _min_size , y ) \
27632779 ZEND_API void* ZEND_FASTCALL _emalloc_ ## _size(void) { \
2764- ZEND_ASSERT(_size >= ZEND_MM_MIN_SMALL_SIZE); \
27652780 ZEND_MM_CUSTOM_ALLOCATOR(_size); \
2781+ if (_size < _min_size) { \
2782+ return _emalloc_ ## _min_size(); \
2783+ } \
27662784 return zend_mm_alloc_small(AG(mm_heap), _num ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); \
27672785 }
27682786
2769- ZEND_MM_BINS_INFO (_ZEND_BIN_ALLOCATOR , x , y )
2787+ ZEND_MM_BINS_INFO (_ZEND_BIN_ALLOCATOR , ZEND_MM_MIN_USEABLE_BIN_SIZE , y )
27702788
27712789ZEND_API void * ZEND_FASTCALL _emalloc_large (size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC )
27722790{
@@ -2781,10 +2799,13 @@ ZEND_API void* ZEND_FASTCALL _emalloc_huge(size_t size)
27812799}
27822800
27832801#if ZEND_DEBUG
2784- # define _ZEND_BIN_FREE (_num , _size , _elements , _pages , x , y ) \
2802+ # define _ZEND_BIN_FREE (_num , _size , _elements , _pages , _min_size , y ) \
27852803 ZEND_API void ZEND_FASTCALL _efree_ ## _size(void *ptr) { \
2786- ZEND_ASSERT(_size >= ZEND_MM_MIN_SMALL_SIZE); \
27872804 ZEND_MM_CUSTOM_DEALLOCATOR(ptr); \
2805+ if (_size < _min_size) { \
2806+ _efree_ ## _min_size(ptr); \
2807+ return; \
2808+ } \
27882809 { \
27892810 size_t page_offset = ZEND_MM_ALIGNED_OFFSET(ptr, ZEND_MM_CHUNK_SIZE); \
27902811 zend_mm_chunk *chunk = (zend_mm_chunk*)ZEND_MM_ALIGNED_BASE(ptr, ZEND_MM_CHUNK_SIZE); \
@@ -2796,10 +2817,13 @@ ZEND_API void* ZEND_FASTCALL _emalloc_huge(size_t size)
27962817 } \
27972818 }
27982819#else
2799- # define _ZEND_BIN_FREE (_num , _size , _elements , _pages , x , y ) \
2820+ # define _ZEND_BIN_FREE (_num , _size , _elements , _pages , _min_size , y ) \
28002821 ZEND_API void ZEND_FASTCALL _efree_ ## _size(void *ptr) { \
2801- ZEND_ASSERT(_size >= ZEND_MM_MIN_SMALL_SIZE); \
28022822 ZEND_MM_CUSTOM_DEALLOCATOR(ptr); \
2823+ if (_size < _min_size) { \
2824+ _efree_ ## _min_size(ptr); \
2825+ return; \
2826+ } \
28032827 { \
28042828 zend_mm_chunk *chunk = (zend_mm_chunk*)ZEND_MM_ALIGNED_BASE(ptr, ZEND_MM_CHUNK_SIZE); \
28052829 ZEND_MM_CHECK(chunk->heap == AG(mm_heap), "zend_mm_heap corrupted"); \
@@ -2808,7 +2832,7 @@ ZEND_API void* ZEND_FASTCALL _emalloc_huge(size_t size)
28082832 }
28092833#endif
28102834
2811- ZEND_MM_BINS_INFO (_ZEND_BIN_FREE , x , y )
2835+ ZEND_MM_BINS_INFO (_ZEND_BIN_FREE , ZEND_MM_MIN_USEABLE_BIN_SIZE , y )
28122836
28132837ZEND_API void ZEND_FASTCALL _efree_large (void * ptr , size_t size )
28142838{
0 commit comments