wingo pushed a commit to branch wip-whippet in repository guile. commit 5bddd522cf20e871a363e5c0fbefa6bf755762d3 Author: Andy Wingo <wi...@igalia.com> AuthorDate: Fri Mar 7 10:47:41 2025 +0100
Rework large_object_space_alloc to also map if needed Also fix a bug in which objects reclaimed from freelists were not zeroed. --- src/large-object-space.h | 45 ++++++++++++++++++++------------------------- src/mmc.c | 2 -- src/pcc.c | 2 -- src/semi.c | 2 -- 4 files changed, 20 insertions(+), 31 deletions(-) diff --git a/src/large-object-space.h b/src/large-object-space.h index f7286614e..887cdef0e 100644 --- a/src/large-object-space.h +++ b/src/large-object-space.h @@ -444,37 +444,32 @@ large_object_space_alloc(struct large_object_space *space, size_t npages) { space->free_pages -= npages; ret = (void*)node->key.addr; + memset(ret, 0, size); break; } } - pthread_mutex_unlock(&space->lock); - return ret; -} -static void* -large_object_space_obtain_and_alloc(struct large_object_space *space, - size_t npages) { - size_t bytes = npages * space->page_size; - void *ret = gc_platform_acquire_memory(bytes, 0); - if (!ret) - return NULL; - - uintptr_t addr = (uintptr_t)ret; - struct large_object k = { addr, bytes }; - struct large_object_data v = {0,}; - v.is_live = 1; - v.live.mark = LARGE_OBJECT_NURSERY; + // If we didn't find anything in the quarantine, get fresh pages from the OS. + if (!ret) { + ret = gc_platform_acquire_memory(size, 0); + if (ret) { + uintptr_t addr = (uintptr_t)ret; + struct large_object k = { addr, size }; + struct large_object_data v = {0,}; + v.is_live = 1; + v.live.mark = LARGE_OBJECT_NURSERY; + + pthread_mutex_lock(&space->object_tree_lock); + struct large_object_node *node = + large_object_tree_insert(&space->object_tree, k, v); + uintptr_t node_bits = (uintptr_t)node; + address_map_add(&space->object_map, addr, node_bits); + space->total_pages += npages; + pthread_mutex_unlock(&space->object_tree_lock); + } + } - pthread_mutex_lock(&space->lock); - pthread_mutex_lock(&space->object_tree_lock); - struct large_object_node *node = - large_object_tree_insert(&space->object_tree, k, v); - uintptr_t node_bits = (uintptr_t)node; - address_map_add(&space->object_map, addr, node_bits); - space->total_pages += npages; - pthread_mutex_unlock(&space->object_tree_lock); pthread_mutex_unlock(&space->lock); - return ret; } diff --git a/src/mmc.c b/src/mmc.c index db7e1f512..0c9448e62 100644 --- a/src/mmc.c +++ b/src/mmc.c @@ -876,8 +876,6 @@ allocate_large(struct gc_mutator *mut, size_t size) { atomic_fetch_add(&heap->large_object_pages, npages); void *ret = large_object_space_alloc(lospace, npages); - if (!ret) - ret = large_object_space_obtain_and_alloc(lospace, npages); if (!ret) { perror("weird: we have the space but mmap didn't work"); diff --git a/src/pcc.c b/src/pcc.c index c480021f9..877827ed3 100644 --- a/src/pcc.c +++ b/src/pcc.c @@ -965,8 +965,6 @@ static void* allocate_large(struct gc_mutator *mut, size_t size) { atomic_fetch_add(&heap->large_object_pages, npages); void *ret = large_object_space_alloc(space, npages); - if (!ret) - ret = large_object_space_obtain_and_alloc(space, npages); if (!ret) { perror("weird: we have the space but mmap didn't work"); diff --git a/src/semi.c b/src/semi.c index 86541f913..833cfabef 100644 --- a/src/semi.c +++ b/src/semi.c @@ -496,8 +496,6 @@ static void* allocate_large(struct gc_mutator *mut, size_t size) { collect_for_large_alloc(mut, npages); void *ret = large_object_space_alloc(space, npages); - if (!ret) - ret = large_object_space_obtain_and_alloc(space, npages); if (!ret) { perror("weird: we have the space but mmap didn't work");