mirror of
https://github.com/justinethier/cyclone.git
synced 2025-05-23 20:15:05 +02:00
Populate huge object heap
This commit is contained in:
parent
54f217fd4b
commit
f526eeb6f3
3 changed files with 35 additions and 18 deletions
43
gc.c
43
gc.c
|
@ -59,8 +59,8 @@ static int mark_stack_i = 0;
|
|||
static pthread_mutex_t heap_lock;
|
||||
|
||||
// Cached heap statistics
|
||||
static int cached_heap_free_sizes[3] = { 0, 0, 0 };
|
||||
static int cached_heap_total_sizes[3] = { 0, 0, 0 };
|
||||
static int cached_heap_free_sizes[4] = { 0, 0, 0, 0 };
|
||||
static int cached_heap_total_sizes[4] = { 0, 0, 0, 0 };
|
||||
|
||||
// Data for each individual mutator thread
|
||||
ck_array_t Cyc_mutators, old_mutators;
|
||||
|
@ -269,8 +269,8 @@ void gc_print_stats(gc_heap * h)
|
|||
}
|
||||
heap_is_empty = gc_is_heap_empty(h);
|
||||
fprintf(stderr,
|
||||
"Heap page size=%u, is empty=%d, used=%u, free=%u, free chunks=%u, min=%u, max=%u\n",
|
||||
h->size, heap_is_empty, h->size - free, free, free_chunks, free_min, free_max);
|
||||
"Heap type=%d, page size=%u, is empty=%d, used=%u, free=%u, free chunks=%u, min=%u, max=%u\n",
|
||||
h->type, h->size, heap_is_empty, h->size - free, free, free_chunks, free_min, free_max);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -432,11 +432,10 @@ int gc_grow_heap(gc_heap * h, int heap_type, size_t size, size_t chunk_size)
|
|||
gc_heap *h_last, *h_new;
|
||||
pthread_mutex_lock(&heap_lock);
|
||||
// Compute size of new heap page
|
||||
// experimental code for growing heap gradually using fibonnaci sequence.
|
||||
// but with boyer benchmarks there is more thrashing with this method,
|
||||
// so for now it is not used. If it is used again, the initial heaps will
|
||||
// need to start at a lower size (EG 1 MB).
|
||||
{
|
||||
if (heap_type == HEAP_HUGE) {
|
||||
new_size = size;
|
||||
} else {
|
||||
// Grow heap gradually using fibonnaci sequence.
|
||||
size_t prev_size = GROW_HEAP_BY_SIZE;
|
||||
new_size = 0;
|
||||
h_last = h;
|
||||
|
@ -527,6 +526,9 @@ void *gc_alloc(gc_heap_root * hrt, size_t size, char *obj, gc_thread_data * thd,
|
|||
} else if (size <= 64) {
|
||||
h = hrt->medium_obj_heap;
|
||||
heap_type = HEAP_MED;
|
||||
} else if (size >= MAX_STACK_OBJ) {
|
||||
h = hrt->huge_obj_heap;
|
||||
heap_type = HEAP_HUGE;
|
||||
} else {
|
||||
h = hrt->heap;
|
||||
heap_type = HEAP_REST;
|
||||
|
@ -661,10 +663,11 @@ size_t gc_sweep(gc_heap * h, int heap_type, size_t * sum_freed_ptr)
|
|||
//
|
||||
pthread_mutex_lock(&heap_lock);
|
||||
|
||||
// DEBUGGING:
|
||||
//fprintf(stderr, "\nBefore sweep -------------------------\n");
|
||||
//fprintf(stderr, "Heap %d diagnostics:\n", heap_type);
|
||||
//gc_print_stats(orig_heap_ptr);
|
||||
#if GC_DEBUG_SHOW_SWEEP_DIAG
|
||||
fprintf(stderr, "\nBefore sweep -------------------------\n");
|
||||
fprintf(stderr, "Heap %d diagnostics:\n", heap_type);
|
||||
gc_print_stats(orig_heap_ptr);
|
||||
#endif
|
||||
|
||||
for (; h; prev_h = h, h = h->next) { // All heaps
|
||||
#if GC_DEBUG_TRACE
|
||||
|
@ -765,6 +768,9 @@ size_t gc_sweep(gc_heap * h, int heap_type, size_t * sum_freed_ptr)
|
|||
}
|
||||
//h->free_size += heap_freed;
|
||||
cached_heap_free_sizes[heap_type] += heap_freed;
|
||||
// TODO: with huge heaps, this becomes more important. one of the huge
|
||||
// pages only has one object, so it is likely that the page
|
||||
// will become free at some point and could be reclaimed.
|
||||
// if (gc_is_heap_empty(h)){
|
||||
// unsigned int h_size = h->size;
|
||||
// gc_heap_free(h, prev_h);
|
||||
|
@ -775,10 +781,11 @@ size_t gc_sweep(gc_heap * h, int heap_type, size_t * sum_freed_ptr)
|
|||
heap_freed = 0;
|
||||
}
|
||||
|
||||
// DEBUGGING:
|
||||
//fprintf(stderr, "\nAfter sweep -------------------------\n");
|
||||
//fprintf(stderr, "Heap %d diagnostics:\n", heap_type);
|
||||
//gc_print_stats(orig_heap_ptr);
|
||||
#if GC_DEBUG_SHOW_SWEEP_DIAG
|
||||
fprintf(stderr, "\nAfter sweep -------------------------\n");
|
||||
fprintf(stderr, "Heap %d diagnostics:\n", heap_type);
|
||||
gc_print_stats(orig_heap_ptr);
|
||||
#endif
|
||||
|
||||
pthread_mutex_unlock(&heap_lock);
|
||||
if (sum_freed_ptr)
|
||||
|
@ -1340,7 +1347,9 @@ void gc_collector()
|
|||
max_freed = gc_sweep(gc_get_heap()->heap, HEAP_REST, &freed);
|
||||
max_freed = gc_sweep(gc_get_heap()->small_obj_heap, HEAP_SM, &freed);
|
||||
max_freed = gc_sweep(gc_get_heap()->medium_obj_heap, HEAP_MED, &freed);
|
||||
max_freed = gc_sweep(gc_get_heap()->huge_obj_heap, HEAP_HUGE, &freed);
|
||||
|
||||
// TODO: this loop only includes smallest 2 heaps, is that sufficient??
|
||||
for (heap_type = 0; heap_type < 2; heap_type++) {
|
||||
while (cached_heap_free_sizes[heap_type] <
|
||||
(cached_heap_total_sizes[heap_type] * GC_FREE_THRESHOLD)) {
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
// This is used as the first generation of the GC.
|
||||
#define STACK_SIZE 500000
|
||||
|
||||
// Do not allocate objects larger than this on the stack.
|
||||
#define MAX_STACK_OBJ (STACK_SIZE * 2)
|
||||
|
||||
// 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
|
||||
|
@ -50,6 +53,9 @@
|
|||
// Show diagnostic information for the GC when program terminates
|
||||
#define DEBUG_SHOW_DIAG 0
|
||||
|
||||
// Show diagnostic information before/after sweeping
|
||||
#define GC_DEBUG_SHOW_SWEEP_DIAG 1
|
||||
|
||||
// GC debugging flags
|
||||
#define GC_DEBUG_TRACE 0
|
||||
#define GC_DEBUG_VERBOSE 0
|
||||
|
@ -149,8 +155,8 @@ struct gc_thread_data_t {
|
|||
typedef enum {
|
||||
HEAP_SM = 0 // 32 byte objects (min gc_heap_align)
|
||||
, HEAP_MED // 64 byte objects (twice the min)
|
||||
, HEAP_HUGE // Huge objects, 1 per page
|
||||
, HEAP_REST // Everything else
|
||||
, HEAP_HUGE // Huge objects, 1 per page
|
||||
} gc_heap_type;
|
||||
|
||||
typedef struct gc_free_list_t gc_free_list;
|
||||
|
@ -175,6 +181,7 @@ typedef struct gc_heap_root_t gc_heap_root;
|
|||
struct gc_heap_root_t {
|
||||
gc_heap *small_obj_heap;
|
||||
gc_heap *medium_obj_heap;
|
||||
gc_heap *huge_obj_heap;
|
||||
gc_heap *heap;
|
||||
};
|
||||
|
||||
|
|
|
@ -190,6 +190,7 @@ void gc_init_heap(long heap_size)
|
|||
Cyc_heap->heap = gc_heap_create(HEAP_REST, initial_heap_size, 0, 0);
|
||||
Cyc_heap->small_obj_heap = gc_heap_create(HEAP_SM, initial_heap_size, 0, 0);
|
||||
Cyc_heap->medium_obj_heap = gc_heap_create(HEAP_MED, initial_heap_size, 0, 0);
|
||||
Cyc_heap->huge_obj_heap = gc_heap_create(HEAP_HUGE, 1024, 0, 0);
|
||||
|
||||
if (!ck_hs_init(&symbol_table,
|
||||
CK_HS_MODE_OBJECT | CK_HS_MODE_SPMC,
|
||||
|
|
Loading…
Add table
Reference in a new issue