dmitry Mon, 04 Oct 2010 15:50:47 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=304031
Log: Bug #51155 (Unreasonable non-emalloc allocations of memory) Bug: http://bugs.php.net/51155 (Assigned) Unreasonable non-emalloc allocations of memory Changed paths: U php/php-src/trunk/Zend/zend_alloc.c Modified: php/php-src/trunk/Zend/zend_alloc.c =================================================================== --- php/php-src/trunk/Zend/zend_alloc.c 2010-10-04 15:33:09 UTC (rev 304030) +++ php/php-src/trunk/Zend/zend_alloc.c 2010-10-04 15:50:47 UTC (rev 304031) @@ -435,6 +435,7 @@ 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 @@ 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 @@ #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 @@ 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 @@ 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 @@ } } 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 @@ 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) {
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php