From 391051ba7bdc6e9f33dbcb13dda513b6996bf129 Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Sun, 13 Nov 2016 16:54:57 -0500 Subject: [PATCH] GC performance improvements - Increase page size - Cache last page that had an allocation, and start from that page next time, if possible. This speeds up allocation on large heaps because we can avoid searching through the whole heap each time. --- gc.c | 10 ++++++++++ include/cyclone/types.h | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/gc.c b/gc.c index 9ddf0d8b..7e2d5ea3 100644 --- a/gc.c +++ b/gc.c @@ -223,6 +223,8 @@ gc_heap *gc_heap_create(int heap_type, size_t size, size_t max_size, h->type = heap_type; h->size = size; h->newly_created = 1; + h->next_free = h; + h->last_alloc_size = 0; //h->free_size = size; cached_heap_total_sizes[heap_type] += size; cached_heap_free_sizes[heap_type] += size; @@ -526,8 +528,12 @@ int gc_grow_heap(gc_heap * h, int heap_type, size_t size, size_t chunk_size) void *gc_try_alloc(gc_heap * h, int heap_type, size_t size, char *obj, gc_thread_data * thd) { + gc_heap *h_passed = h; gc_free_list *f1, *f2, *f3; pthread_mutex_lock(&heap_lock); + if (size <= h->last_alloc_size) { + h = h->next_free; + } for (; h; h = h->next) { // All heaps // TODO: chunk size (ignoring for now) @@ -550,6 +556,8 @@ void *gc_try_alloc(gc_heap * h, int heap_type, size_t size, char *obj, cached_heap_free_sizes[heap_type] -= gc_allocated_bytes(obj, NULL, NULL); } + h_passed->next_free = h; + h_passed->last_alloc_size = size; pthread_mutex_unlock(&heap_lock); return f2; } @@ -721,6 +729,8 @@ size_t gc_sweep(gc_heap * h, int heap_type, size_t * sum_freed_ptr) // how much time is even spent sweeping // pthread_mutex_lock(&heap_lock); + h->next_free = h; + h->last_alloc_size = 0; #if GC_DEBUG_SHOW_SWEEP_DIAG fprintf(stderr, "\nBefore sweep -------------------------\n"); diff --git a/include/cyclone/types.h b/include/cyclone/types.h index 397123f6..2381f0ea 100644 --- a/include/cyclone/types.h +++ b/include/cyclone/types.h @@ -34,7 +34,7 @@ // Parameters for size of a "page" on the heap (the second generation GC), in bytes. #define GROW_HEAP_BY_SIZE (2 * 1024 * 1024) // Grow first page by adding this amount to it #define INITIAL_HEAP_SIZE (3 * 1024 * 1024) // Size of the first page -#define HEAP_SIZE (16 * 1024 * 1024) // Normal size of a page +#define HEAP_SIZE (32 * 1024 * 1024) // Normal size of a page ///////////////////////////// // Major GC tuning parameters @@ -191,6 +191,9 @@ struct gc_heap_t { unsigned int chunk_size; // 0 for any size, other and heap will only alloc chunks of that size unsigned int max_size; unsigned int newly_created; + // + gc_heap *next_free; + unsigned int last_alloc_size; //unsigned int free_size; gc_free_list *free_list; gc_heap *next; // TBD, linked list is not very efficient, but easy to work with as a start