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

Reply via email to