mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-18 21:29:19 +02:00
tweaks for fixed-size heaps, fix issue #632
This commit is contained in:
parent
90b0336048
commit
83e82f55a7
4 changed files with 56 additions and 9 deletions
51
gc.c
51
gc.c
|
@ -37,12 +37,14 @@ static sexp_heap sexp_heap_last (sexp_heap h) {
|
|||
return h;
|
||||
}
|
||||
|
||||
#if !SEXP_USE_FIXED_CHUNK_SIZE_HEAPS
|
||||
static size_t sexp_heap_total_size (sexp_heap h) {
|
||||
size_t total_size = 0;
|
||||
for (; h; h=h->next)
|
||||
total_size += h->size;
|
||||
return total_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ! SEXP_USE_GLOBAL_HEAP
|
||||
#if SEXP_USE_DEBUG_GC
|
||||
|
@ -571,26 +573,38 @@ int sexp_grow_heap (sexp ctx, size_t size, size_t chunk_size) {
|
|||
#if SEXP_USE_FIXED_CHUNK_SIZE_HEAPS
|
||||
for (tmp=sexp_context_heap(ctx); tmp; tmp=tmp->next)
|
||||
if (tmp->chunk_size == size) {
|
||||
while (tmp->next && tmp->next->chunk_size == size)
|
||||
tmp = tmp->next;
|
||||
h = tmp;
|
||||
chunk_size = size;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
cur_size = h->size;
|
||||
new_size = sexp_heap_align(((cur_size > size) ? cur_size : size) * 2);
|
||||
new_size = (size_t) ceil(SEXP_GROW_HEAP_FACTOR * (double) (sexp_heap_align(((cur_size > size) ? cur_size : size))));
|
||||
tmp = sexp_make_heap(new_size, h->max_size, chunk_size);
|
||||
if (tmp) tmp->next = h->next;
|
||||
h->next = tmp;
|
||||
if (tmp) {
|
||||
tmp->next = h->next;
|
||||
h->next = tmp;
|
||||
}
|
||||
return (h->next != NULL);
|
||||
}
|
||||
|
||||
void* sexp_try_alloc (sexp ctx, size_t size) {
|
||||
sexp_free_list ls1, ls2, ls3;
|
||||
sexp_heap h;
|
||||
#if SEXP_USE_FIXED_CHUNK_SIZE_HEAPS
|
||||
int found_fixed = 0;
|
||||
#endif
|
||||
for (h=sexp_context_heap(ctx); h; h=h->next) {
|
||||
#if SEXP_USE_FIXED_CHUNK_SIZE_HEAPS
|
||||
if (h->chunk_size && h->chunk_size != size)
|
||||
continue;
|
||||
if (h->chunk_size) {
|
||||
if (h->chunk_size != size)
|
||||
continue;
|
||||
found_fixed = 1;
|
||||
} else if (found_fixed) { /* don't use a non-fixed heap */
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
for (ls1=h->free_list, ls2=ls1->next; ls2; ls1=ls2, ls2=ls2->next) {
|
||||
if (ls2->size >= size) {
|
||||
|
@ -617,9 +631,30 @@ void* sexp_try_alloc (sexp ctx, size_t size) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if SEXP_USE_FIXED_CHUNK_SIZE_HEAPS
|
||||
int sexp_find_fixed_chunk_heap_usage(sexp ctx, size_t size, size_t* sum_freed, size_t* total_size) {
|
||||
sexp_heap h;
|
||||
sexp_free_list ls;
|
||||
size_t avail=0, total=0;
|
||||
for (h=sexp_context_heap(ctx); h; h=h->next) {
|
||||
if (h->chunk_size == size || !h->chunk_size) {
|
||||
for (; h && (h->chunk_size == size || !h->chunk_size); h=h->next) {
|
||||
total += h->size;
|
||||
for (ls=h->free_list; ls; ls=ls->next)
|
||||
avail += ls->size;
|
||||
}
|
||||
*sum_freed = avail;
|
||||
*total_size = total;
|
||||
return h && h->chunk_size > 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void* sexp_alloc (sexp ctx, size_t size) {
|
||||
void *res;
|
||||
size_t max_freed, sum_freed, total_size;
|
||||
size_t max_freed, sum_freed, total_size=0;
|
||||
sexp_heap h = sexp_context_heap(ctx);
|
||||
#if SEXP_USE_TRACK_ALLOC_SIZES
|
||||
size_t size_bucket;
|
||||
|
@ -637,7 +672,11 @@ void* sexp_alloc (sexp ctx, size_t size) {
|
|||
res = sexp_try_alloc(ctx, size);
|
||||
if (! res) {
|
||||
max_freed = sexp_unbox_fixnum(sexp_gc(ctx, &sum_freed));
|
||||
#if SEXP_USE_FIXED_CHUNK_SIZE_HEAPS
|
||||
sexp_find_fixed_chunk_heap_usage(ctx, size, &sum_freed, &total_size);
|
||||
#else
|
||||
total_size = sexp_heap_total_size(sexp_context_heap(ctx));
|
||||
#endif
|
||||
if (((max_freed < size)
|
||||
|| ((total_size > sum_freed)
|
||||
&& (total_size - sum_freed) > (total_size*SEXP_GROW_HEAP_RATIO)))
|
||||
|
|
|
@ -273,6 +273,11 @@
|
|||
#define SEXP_GROW_HEAP_RATIO 0.75
|
||||
#endif
|
||||
|
||||
/* how much to expand the heap size by */
|
||||
#ifndef SEXP_GROW_HEAP_FACTOR
|
||||
#define SEXP_GROW_HEAP_FACTOR 2 /* 1.6180339887498948482 */
|
||||
#endif
|
||||
|
||||
/* the default number of opcodes to run each thread for */
|
||||
#ifndef SEXP_DEFAULT_QUANTUM
|
||||
#define SEXP_DEFAULT_QUANTUM 500
|
||||
|
|
|
@ -546,8 +546,9 @@ struct sexp_struct {
|
|||
#endif
|
||||
char tailp, tracep, timeoutp, waitp, errorp;
|
||||
sexp_uint_t last_fp;
|
||||
sexp_uint_t gc_count;
|
||||
#if SEXP_USE_TIME_GC
|
||||
sexp_uint_t gc_count, gc_usecs;
|
||||
sexp_uint_t gc_usecs;
|
||||
#endif
|
||||
#if SEXP_USE_TRACK_ALLOC_TIMES
|
||||
sexp_uint_t alloc_count, alloc_usecs;
|
||||
|
@ -1311,8 +1312,8 @@ enum sexp_uniform_vector_type {
|
|||
#define sexp_context_dk(x) (sexp_field(x, context, SEXP_CONTEXT, dk))
|
||||
#define sexp_context_params(x) (sexp_field(x, context, SEXP_CONTEXT, params))
|
||||
#define sexp_context_last_fp(x) (sexp_field(x, context, SEXP_CONTEXT, last_fp))
|
||||
#if SEXP_USE_TIME_GC
|
||||
#define sexp_context_gc_count(x) (sexp_field(x, context, SEXP_CONTEXT, gc_count))
|
||||
#if SEXP_USE_TIME_GC
|
||||
#define sexp_context_gc_usecs(x) (sexp_field(x, context, SEXP_CONTEXT, gc_usecs))
|
||||
#else
|
||||
#define sexp_context_gc_count(x) 0
|
||||
|
|
4
sexp.c
4
sexp.c
|
@ -606,7 +606,9 @@ sexp sexp_bootstrap_context (sexp_uint_t size, sexp_uint_t max_size) {
|
|||
sexp_heap heap;
|
||||
struct sexp_struct dummy_ctx;
|
||||
if (size < SEXP_MINIMUM_HEAP_SIZE) size = SEXP_INITIAL_HEAP_SIZE;
|
||||
heap = sexp_make_heap(sexp_heap_align(size), sexp_heap_align(max_size), 0);
|
||||
size = sexp_heap_align(size);
|
||||
max_size = sexp_heap_align(max_size);
|
||||
heap = sexp_make_heap(size, max_size, 0);
|
||||
if (!heap) return 0;
|
||||
sexp_pointer_tag(&dummy_ctx) = SEXP_CONTEXT;
|
||||
sexp_context_saves(&dummy_ctx) = NULL;
|
||||
|
|
Loading…
Add table
Reference in a new issue