1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00

Add gc_heap_set_allocation_failure_handler

Also wire it up to bdw.
This commit is contained in:
Andy Wingo 2025-04-23 11:42:21 +02:00
parent 1e41f0e093
commit e2b75d302d
5 changed files with 54 additions and 9 deletions

View file

@ -42,6 +42,10 @@ struct gc_heap_roots;
GC_API_ void gc_heap_set_roots(struct gc_heap *heap, GC_API_ void gc_heap_set_roots(struct gc_heap *heap,
struct gc_heap_roots *roots); struct gc_heap_roots *roots);
GC_API_ void gc_heap_set_allocation_failure_handler(struct gc_heap *heap,
void* (*)(struct gc_heap*,
size_t));
struct gc_extern_space; struct gc_extern_space;
GC_API_ void gc_heap_set_extern_space(struct gc_heap *heap, GC_API_ void gc_heap_set_extern_space(struct gc_heap *heap,
struct gc_extern_space *space); struct gc_extern_space *space);

View file

@ -60,6 +60,7 @@ struct gc_heap {
struct gc_finalizer_state *finalizer_state; struct gc_finalizer_state *finalizer_state;
gc_finalizer_callback have_finalizers; gc_finalizer_callback have_finalizers;
void *event_listener_data; void *event_listener_data;
void* (*allocation_failure)(struct gc_heap *, size_t);
}; };
struct gc_mutator { struct gc_mutator {
@ -116,11 +117,8 @@ allocate_small(void **freelist, size_t idx, enum gc_inline_kind kind) {
size_t bytes = gc_inline_freelist_object_size(idx); size_t bytes = gc_inline_freelist_object_size(idx);
GC_generic_malloc_many(bytes, kind, freelist); GC_generic_malloc_many(bytes, kind, freelist);
head = *freelist; head = *freelist;
if (GC_UNLIKELY (!head)) { if (GC_UNLIKELY (!head))
fprintf(stderr, "ran out of space, heap size %zu\n", return __the_bdw_gc_heap->allocation_failure(__the_bdw_gc_heap, bytes);
GC_get_heap_size());
GC_CRASH();
}
} }
*freelist = *(void **)(head); *freelist = *(void **)(head);
@ -152,13 +150,20 @@ void* gc_allocate_slow(struct gc_mutator *mut, size_t size,
} else { } else {
switch (kind) { switch (kind) {
case GC_ALLOCATION_TAGGED: case GC_ALLOCATION_TAGGED:
case GC_ALLOCATION_UNTAGGED_CONSERVATIVE: case GC_ALLOCATION_UNTAGGED_CONSERVATIVE: {
return GC_malloc(size); void *ret = GC_malloc(size);
if (GC_LIKELY (ret != NULL))
return ret;
return __the_bdw_gc_heap->allocation_failure(__the_bdw_gc_heap, size);
}
case GC_ALLOCATION_TAGGED_POINTERLESS: case GC_ALLOCATION_TAGGED_POINTERLESS:
case GC_ALLOCATION_UNTAGGED_POINTERLESS: { case GC_ALLOCATION_UNTAGGED_POINTERLESS: {
void *ret = GC_malloc_atomic(size); void *ret = GC_malloc_atomic(size);
memset(ret, 0, size); if (GC_LIKELY (ret != NULL)) {
return ret; memset(ret, 0, size);
return ret;
}
return __the_bdw_gc_heap->allocation_failure(__the_bdw_gc_heap, size);
} }
default: default:
GC_CRASH(); GC_CRASH();
@ -521,6 +526,22 @@ uint64_t gc_allocation_counter(struct gc_heap *heap) {
return GC_get_total_bytes(); return GC_get_total_bytes();
} }
static void* allocation_failure(struct gc_heap *heap, size_t size) {
fprintf(stderr, "ran out of space, heap size %zu\n", GC_get_heap_size());
GC_CRASH();
return NULL;
}
static void* oom_fn(size_t nbytes) {
return NULL;
}
void gc_heap_set_allocation_failure_handler(struct gc_heap *heap,
void* (*handler)(struct gc_heap*,
size_t)) {
heap->allocation_failure = handler;
}
int gc_init(const struct gc_options *options, struct gc_stack_addr stack_base, int gc_init(const struct gc_options *options, struct gc_stack_addr stack_base,
struct gc_heap **heap, struct gc_mutator **mutator, struct gc_heap **heap, struct gc_mutator **mutator,
struct gc_event_listener event_listener, struct gc_event_listener event_listener,
@ -607,6 +628,8 @@ int gc_init(const struct gc_options *options, struct gc_stack_addr stack_base,
HEAP_EVENT(init, GC_get_heap_size()); HEAP_EVENT(init, GC_get_heap_size());
GC_set_on_collection_event(on_collection_event); GC_set_on_collection_event(on_collection_event);
GC_set_on_heap_resize(on_heap_resize); GC_set_on_heap_resize(on_heap_resize);
GC_set_oom_fn (oom_fn);
(*heap)->allocation_failure = allocation_failure;
*mutator = add_mutator(*heap); *mutator = add_mutator(*heap);

View file

@ -1121,6 +1121,12 @@ static void* allocation_failure(struct gc_heap *heap, size_t size) {
return NULL; return NULL;
} }
void gc_heap_set_allocation_failure_handler(struct gc_heap *heap,
void* (*handler)(struct gc_heap*,
size_t)) {
heap->allocation_failure = handler;
}
static int static int
heap_init(struct gc_heap *heap, const struct gc_options *options) { heap_init(struct gc_heap *heap, const struct gc_options *options) {
// *heap is already initialized to 0. // *heap is already initialized to 0.

View file

@ -1199,6 +1199,12 @@ static void* allocation_failure(struct gc_heap *heap, size_t size) {
return NULL; return NULL;
} }
void gc_heap_set_allocation_failure_handler(struct gc_heap *heap,
void* (*handler)(struct gc_heap*,
size_t)) {
heap->allocation_failure = handler;
}
static int heap_init(struct gc_heap *heap, const struct gc_options *options) { static int heap_init(struct gc_heap *heap, const struct gc_options *options) {
// *heap is already initialized to 0. // *heap is already initialized to 0.

View file

@ -636,6 +636,12 @@ static void* allocation_failure(struct gc_heap *heap, size_t size) {
return NULL; return NULL;
} }
void gc_heap_set_allocation_failure_handler(struct gc_heap *heap,
void* (*handler)(struct gc_heap*,
size_t)) {
heap->allocation_failure = handler;
}
static int heap_init(struct gc_heap *heap, const struct gc_options *options) { static int heap_init(struct gc_heap *heap, const struct gc_options *options) {
heap->extern_space = NULL; heap->extern_space = NULL;
heap->pending_ephemerons_size_factor = 0.01; heap->pending_ephemerons_size_factor = 0.01;