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;
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;
#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;
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;
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)
}
}
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;
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) {