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");

Reply via email to