mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Bug #51155 (Unreasonable non-emalloc allocations of memory)
This commit is contained in:
parent
026da7d4a0
commit
656f1fb271
1 changed files with 47 additions and 19 deletions
|
@ -435,6 +435,7 @@ struct _zend_mm_heap {
|
|||
zend_mm_free_block *free_buckets[ZEND_MM_NUM_BUCKETS*2];
|
||||
zend_mm_free_block *large_free_buckets[ZEND_MM_NUM_BUCKETS];
|
||||
zend_mm_free_block *rest_buckets[2];
|
||||
int rest_count;
|
||||
#if ZEND_MM_CACHE_STAT
|
||||
struct {
|
||||
int count;
|
||||
|
@ -455,6 +456,10 @@ struct _zend_mm_heap {
|
|||
sizeof(zend_mm_free_block*) * 2 - \
|
||||
sizeof(zend_mm_small_free_block))
|
||||
|
||||
#define ZEND_MM_REST_BLOCK ((zend_mm_free_block*)(zend_uintptr_t)(1))
|
||||
|
||||
#define ZEND_MM_MAX_REST_BLOCKS 16
|
||||
|
||||
#if ZEND_MM_COOKIES
|
||||
|
||||
static unsigned int _zend_mm_cookie = 0;
|
||||
|
@ -711,23 +716,6 @@ static inline unsigned int zend_mm_low_bit(size_t _size)
|
|||
#endif
|
||||
}
|
||||
|
||||
static inline void zend_mm_add_to_rest_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
|
||||
{
|
||||
zend_mm_free_block *prev, *next;
|
||||
|
||||
ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_FREED);
|
||||
|
||||
if (!ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block))) {
|
||||
mm_block->parent = NULL;
|
||||
}
|
||||
|
||||
prev = heap->rest_buckets[0];
|
||||
next = prev->next_free_block;
|
||||
mm_block->prev_free_block = prev;
|
||||
mm_block->next_free_block = next;
|
||||
prev->next_free_block = next->prev_free_block = mm_block;
|
||||
}
|
||||
|
||||
static inline void zend_mm_add_to_free_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
|
||||
{
|
||||
size_t size;
|
||||
|
@ -854,12 +842,45 @@ subst_block:
|
|||
heap->free_bitmap &= ~(ZEND_MM_LONG_CONST(1) << index);
|
||||
}
|
||||
}
|
||||
} else if (UNEXPECTED(mm_block->parent == ZEND_MM_REST_BLOCK)) {
|
||||
heap->rest_count--;
|
||||
} else if (UNEXPECTED(mm_block->parent != NULL)) {
|
||||
goto subst_block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void zend_mm_add_to_rest_list(zend_mm_heap *heap, zend_mm_free_block *mm_block)
|
||||
{
|
||||
zend_mm_free_block *prev, *next;
|
||||
|
||||
while (heap->rest_count >= ZEND_MM_MAX_REST_BLOCKS) {
|
||||
zend_mm_free_block *p = heap->rest_buckets[1];
|
||||
|
||||
if (!ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(p))) {
|
||||
heap->rest_count--;
|
||||
}
|
||||
prev = p->prev_free_block;
|
||||
next = p->next_free_block;
|
||||
prev->next_free_block = next;
|
||||
next->prev_free_block = prev;
|
||||
zend_mm_add_to_free_list(heap, p);
|
||||
}
|
||||
|
||||
if (!ZEND_MM_SMALL_SIZE(ZEND_MM_FREE_BLOCK_SIZE(mm_block))) {
|
||||
mm_block->parent = ZEND_MM_REST_BLOCK;
|
||||
heap->rest_count++;
|
||||
}
|
||||
|
||||
ZEND_MM_SET_MAGIC(mm_block, MEM_BLOCK_FREED);
|
||||
|
||||
prev = heap->rest_buckets[0];
|
||||
next = prev->next_free_block;
|
||||
mm_block->prev_free_block = prev;
|
||||
mm_block->next_free_block = next;
|
||||
prev->next_free_block = next->prev_free_block = mm_block;
|
||||
}
|
||||
|
||||
static inline void zend_mm_init(zend_mm_heap *heap)
|
||||
{
|
||||
zend_mm_free_block* p;
|
||||
|
@ -884,6 +905,7 @@ static inline void zend_mm_init(zend_mm_heap *heap)
|
|||
heap->large_free_buckets[i] = NULL;
|
||||
}
|
||||
heap->rest_buckets[0] = heap->rest_buckets[1] = ZEND_MM_REST_BUCKET(heap);
|
||||
heap->rest_count = 0;
|
||||
}
|
||||
|
||||
static void zend_mm_del_segment(zend_mm_heap *heap, zend_mm_segment *segment)
|
||||
|
@ -1116,6 +1138,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_mem_handlers *handlers,
|
|||
}
|
||||
}
|
||||
mm_heap->rest_buckets[0] = mm_heap->rest_buckets[1] = ZEND_MM_REST_BUCKET(mm_heap);
|
||||
mm_heap->rest_count = 0;
|
||||
|
||||
free(heap);
|
||||
heap = mm_heap;
|
||||
|
@ -1674,8 +1697,13 @@ ZEND_API void zend_mm_shutdown(zend_mm_heap *heap, int full_shutdown, int silent
|
|||
storage->handlers->compact(storage);
|
||||
}
|
||||
zend_mm_init(heap);
|
||||
heap->real_size = 0;
|
||||
heap->real_peak = 0;
|
||||
if (heap->segments_list) {
|
||||
heap->real_size = heap->segments_list->size;
|
||||
heap->real_peak = heap->segments_list->size;
|
||||
} else {
|
||||
heap->real_size = 0;
|
||||
heap->real_peak = 0;
|
||||
}
|
||||
heap->size = 0;
|
||||
heap->peak = 0;
|
||||
if (heap->segments_list) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue