mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-19 05:39:18 +02:00
Adding fixed-size heaps as an experimental compile-time option.
This commit is contained in:
parent
b3bc13443b
commit
24a880ad28
4 changed files with 30 additions and 11 deletions
23
gc.c
23
gc.c
|
@ -467,7 +467,7 @@ sexp sexp_gc (sexp ctx, size_t *sum_freed) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
sexp_heap sexp_make_heap (size_t size, size_t max_size) {
|
sexp_heap sexp_make_heap (size_t size, size_t max_size, size_t chunk_size) {
|
||||||
sexp_free_list free, next;
|
sexp_free_list free, next;
|
||||||
sexp_heap h;
|
sexp_heap h;
|
||||||
#if SEXP_USE_MMAP_GC
|
#if SEXP_USE_MMAP_GC
|
||||||
|
@ -479,6 +479,7 @@ sexp_heap sexp_make_heap (size_t size, size_t max_size) {
|
||||||
if (! h) return NULL;
|
if (! h) return NULL;
|
||||||
h->size = size;
|
h->size = size;
|
||||||
h->max_size = max_size;
|
h->max_size = max_size;
|
||||||
|
h->chunk_size = chunk_size;
|
||||||
h->data = (char*) sexp_heap_align(sizeof(h->data)+(sexp_uint_t)&(h->data));
|
h->data = (char*) sexp_heap_align(sizeof(h->data)+(sexp_uint_t)&(h->data));
|
||||||
free = h->free_list = (sexp_free_list) h->data;
|
free = h->free_list = (sexp_free_list) h->data;
|
||||||
h->next = NULL;
|
h->next = NULL;
|
||||||
|
@ -498,20 +499,24 @@ sexp_heap sexp_make_heap (size_t size, size_t max_size) {
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sexp_grow_heap (sexp ctx, size_t size) {
|
int sexp_grow_heap (sexp ctx, size_t size, size_t chunk_size) {
|
||||||
size_t cur_size, new_size;
|
size_t cur_size, new_size;
|
||||||
sexp_heap h = sexp_heap_last(sexp_context_heap(ctx));
|
sexp_heap h = sexp_heap_last(sexp_context_heap(ctx));
|
||||||
cur_size = h->size;
|
cur_size = h->size;
|
||||||
new_size = sexp_heap_align(((cur_size > size) ? cur_size : size) * 2);
|
new_size = sexp_heap_align(((cur_size > size) ? cur_size : size) * 2);
|
||||||
h->next = sexp_make_heap(new_size, h->max_size);
|
h->next = sexp_make_heap(new_size, h->max_size, chunk_size);
|
||||||
return (h->next != NULL);
|
return (h->next != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* sexp_try_alloc (sexp ctx, size_t size) {
|
void* sexp_try_alloc (sexp ctx, size_t size) {
|
||||||
sexp_free_list ls1, ls2, ls3;
|
sexp_free_list ls1, ls2, ls3;
|
||||||
sexp_heap h;
|
sexp_heap h;
|
||||||
for (h=sexp_context_heap(ctx); h; h=h->next)
|
for (h=sexp_context_heap(ctx); h; h=h->next) {
|
||||||
for (ls1=h->free_list, ls2=ls1->next; ls2; ls1=ls2, ls2=ls2->next)
|
#if SEXP_USE_FIXED_CHUNK_SIZE_HEAPS
|
||||||
|
if (h->chunk_size && h->chunk_size != size)
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
for (ls1=h->free_list, ls2=ls1->next; ls2; ls1=ls2, ls2=ls2->next) {
|
||||||
if (ls2->size >= size) {
|
if (ls2->size >= size) {
|
||||||
#if SEXP_USE_DEBUG_GC
|
#if SEXP_USE_DEBUG_GC
|
||||||
ls3 = (sexp_free_list) sexp_heap_end(h);
|
ls3 = (sexp_free_list) sexp_heap_end(h);
|
||||||
|
@ -531,6 +536,8 @@ void* sexp_try_alloc (sexp ctx, size_t size) {
|
||||||
memset((void*)ls2, 0, size);
|
memset((void*)ls2, 0, size);
|
||||||
return ls2;
|
return ls2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,7 +554,7 @@ void* sexp_alloc (sexp ctx, size_t size) {
|
||||||
|| ((total_size > sum_freed)
|
|| ((total_size > sum_freed)
|
||||||
&& (total_size - sum_freed) > (total_size*SEXP_GROW_HEAP_RATIO)))
|
&& (total_size - sum_freed) > (total_size*SEXP_GROW_HEAP_RATIO)))
|
||||||
&& ((!h->max_size) || (total_size < h->max_size)))
|
&& ((!h->max_size) || (total_size < h->max_size)))
|
||||||
sexp_grow_heap(ctx, size);
|
sexp_grow_heap(ctx, size, 0);
|
||||||
res = sexp_try_alloc(ctx, size);
|
res = sexp_try_alloc(ctx, size);
|
||||||
if (! res) {
|
if (! res) {
|
||||||
res = sexp_global(ctx, SEXP_G_OOM_ERROR);
|
res = sexp_global(ctx, SEXP_G_OOM_ERROR);
|
||||||
|
@ -703,7 +710,7 @@ sexp sexp_copy_context (sexp ctx, sexp dst, sexp flags) {
|
||||||
if (from->next) {
|
if (from->next) {
|
||||||
return sexp_user_exception(ctx, NULL, "can't copy a non-contiguous heap", ctx);
|
return sexp_user_exception(ctx, NULL, "can't copy a non-contiguous heap", ctx);
|
||||||
} else if (! dst || sexp_not(dst)) {
|
} else if (! dst || sexp_not(dst)) {
|
||||||
to = sexp_make_heap(from->size, from->max_size);
|
to = sexp_make_heap(from->size, from->max_size, from->chunk_size);
|
||||||
if (!to) return sexp_global(ctx, SEXP_G_OOM_ERROR);
|
if (!to) return sexp_global(ctx, SEXP_G_OOM_ERROR);
|
||||||
dst = (sexp) ((char*)ctx + ((char*)to - (char*)from));
|
dst = (sexp) ((char*)ctx + ((char*)to - (char*)from));
|
||||||
} else if (! sexp_contextp(dst)) {
|
} else if (! sexp_contextp(dst)) {
|
||||||
|
@ -731,7 +738,7 @@ void sexp_gc_init (void) {
|
||||||
sexp_uint_t size = sexp_heap_align(SEXP_INITIAL_HEAP_SIZE);
|
sexp_uint_t size = sexp_heap_align(SEXP_INITIAL_HEAP_SIZE);
|
||||||
#endif
|
#endif
|
||||||
#if SEXP_USE_GLOBAL_HEAP
|
#if SEXP_USE_GLOBAL_HEAP
|
||||||
sexp_global_heap = sexp_make_heap(size, SEXP_MAXIMUM_HEAP_SIZE);
|
sexp_global_heap = sexp_make_heap(size, SEXP_MAXIMUM_HEAP_SIZE, 0);
|
||||||
#endif
|
#endif
|
||||||
#if SEXP_USE_CONSERVATIVE_GC
|
#if SEXP_USE_CONSERVATIVE_GC
|
||||||
/* the +32 is a hack, but this is just for debugging anyway */
|
/* the +32 is a hack, but this is just for debugging anyway */
|
||||||
|
|
|
@ -67,6 +67,9 @@
|
||||||
/* uncomment this to disable weak references */
|
/* uncomment this to disable weak references */
|
||||||
/* #define SEXP_USE_WEAK_REFERENCES 0 */
|
/* #define SEXP_USE_WEAK_REFERENCES 0 */
|
||||||
|
|
||||||
|
/* uncomment this to enable heap regions for fixed-size chunks */
|
||||||
|
/* #define SEXP_USE_FIXED_CHUNK_SIZE_HEAPS 1 */
|
||||||
|
|
||||||
/* uncomment this to just malloc manually instead of any GC */
|
/* uncomment this to just malloc manually instead of any GC */
|
||||||
/* Mostly for debugging purposes, this is the no GC option. */
|
/* Mostly for debugging purposes, this is the no GC option. */
|
||||||
/* You can use just the read/write API and */
|
/* You can use just the read/write API and */
|
||||||
|
@ -356,6 +359,10 @@
|
||||||
#define SEXP_USE_WEAK_REFERENCES ! SEXP_USE_NO_FEATURES
|
#define SEXP_USE_WEAK_REFERENCES ! SEXP_USE_NO_FEATURES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef SEXP_USE_FIXED_CHUNK_SIZE_HEAPS
|
||||||
|
#define SEXP_USE_FIXED_CHUNK_SIZE_HEAPS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef SEXP_USE_MALLOC
|
#ifndef SEXP_USE_MALLOC
|
||||||
#define SEXP_USE_MALLOC 0
|
#define SEXP_USE_MALLOC 0
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -279,7 +279,7 @@ struct sexp_free_list_t {
|
||||||
|
|
||||||
typedef struct sexp_heap_t *sexp_heap;
|
typedef struct sexp_heap_t *sexp_heap;
|
||||||
struct sexp_heap_t {
|
struct sexp_heap_t {
|
||||||
sexp_uint_t size, max_size;
|
sexp_uint_t size, max_size, chunk_size;
|
||||||
sexp_free_list free_list;
|
sexp_free_list free_list;
|
||||||
sexp_heap next;
|
sexp_heap next;
|
||||||
/* note this must be aligned on a proper heap boundary, */
|
/* note this must be aligned on a proper heap boundary, */
|
||||||
|
@ -1518,7 +1518,8 @@ SEXP_API void sexp_maybe_unblock_port (sexp ctx, sexp in);
|
||||||
|
|
||||||
#if ! SEXP_USE_BOEHM && ! SEXP_USE_MALLOC
|
#if ! SEXP_USE_BOEHM && ! SEXP_USE_MALLOC
|
||||||
SEXP_API void sexp_gc_init (void);
|
SEXP_API void sexp_gc_init (void);
|
||||||
SEXP_API sexp_heap sexp_make_heap (size_t size, size_t max_size);
|
SEXP_API int sexp_grow_heap (sexp ctx, size_t size, size_t chunk_size);
|
||||||
|
SEXP_API sexp_heap sexp_make_heap (size_t size, size_t max_size, size_t chunk_size);
|
||||||
SEXP_API void sexp_mark (sexp ctx, sexp x);
|
SEXP_API void sexp_mark (sexp ctx, sexp x);
|
||||||
SEXP_API sexp sexp_sweep (sexp ctx, size_t *sum_freed_ptr);
|
SEXP_API sexp sexp_sweep (sexp ctx, size_t *sum_freed_ptr);
|
||||||
SEXP_API sexp sexp_finalize (sexp ctx);
|
SEXP_API sexp sexp_finalize (sexp ctx);
|
||||||
|
|
6
sexp.c
6
sexp.c
|
@ -444,7 +444,7 @@ sexp sexp_bootstrap_context (sexp_uint_t size, sexp_uint_t max_size) {
|
||||||
sexp_heap heap;
|
sexp_heap heap;
|
||||||
struct sexp_struct dummy_ctx;
|
struct sexp_struct dummy_ctx;
|
||||||
if (size < SEXP_MINIMUM_HEAP_SIZE) size = SEXP_INITIAL_HEAP_SIZE;
|
if (size < SEXP_MINIMUM_HEAP_SIZE) size = SEXP_INITIAL_HEAP_SIZE;
|
||||||
heap = sexp_make_heap(sexp_heap_align(size), sexp_heap_align(max_size));
|
heap = sexp_make_heap(sexp_heap_align(size), sexp_heap_align(max_size), 0);
|
||||||
if (!heap) return 0;
|
if (!heap) return 0;
|
||||||
sexp_pointer_tag(&dummy_ctx) = SEXP_CONTEXT;
|
sexp_pointer_tag(&dummy_ctx) = SEXP_CONTEXT;
|
||||||
sexp_context_saves(&dummy_ctx) = NULL;
|
sexp_context_saves(&dummy_ctx) = NULL;
|
||||||
|
@ -454,6 +454,10 @@ sexp sexp_bootstrap_context (sexp_uint_t size, sexp_uint_t max_size) {
|
||||||
sexp_free_heap(heap);
|
sexp_free_heap(heap);
|
||||||
} else {
|
} else {
|
||||||
sexp_context_heap(ctx) = heap;
|
sexp_context_heap(ctx) = heap;
|
||||||
|
#if SEXP_USE_FIXED_CHUNK_SIZE_HEAPS
|
||||||
|
heap->chunk_size = 1<<(4+SEXP_64_BIT);
|
||||||
|
sexp_grow_heap(ctx, sexp_heap_align(size), 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue