wingo pushed a commit to branch wip-whippet
in repository guile.

commit 4ab72e92b0ac2fb2782c9eafd812aa81a308ba65
Author: Andy Wingo <wi...@igalia.com>
AuthorDate: Fri Jan 10 16:33:38 2025 +0100

    gpcc: Don't mix survivors and new objects in same block
---
 src/copy-space.h | 35 ++++++++++++++++++++++-------------
 src/pcc.c        |  7 ++++---
 2 files changed, 26 insertions(+), 16 deletions(-)

diff --git a/src/copy-space.h b/src/copy-space.h
index bd2df7334..0fbf4b111 100644
--- a/src/copy-space.h
+++ b/src/copy-space.h
@@ -529,9 +529,30 @@ copy_space_flip(struct copy_space *space) {
   space->in_gc = 1;
 }
 
+static inline void
+copy_space_allocator_init(struct copy_space_allocator *alloc) {
+  memset(alloc, 0, sizeof(*alloc));
+}
+
+static inline void
+copy_space_allocator_finish(struct copy_space_allocator *alloc,
+                            struct copy_space *space) {
+  if (alloc->block)
+    copy_space_allocator_release_partly_full_block(alloc, space);
+}
+
 static void
-copy_space_finish_gc(struct copy_space *space) {
+copy_space_finish_gc(struct copy_space *space, int is_minor_gc) {
   // Mutators stopped, can access nonatomically.
+  if (is_minor_gc) {
+    // Avoid mixing survivors and new objects on the same blocks.
+    struct copy_space_allocator alloc;
+    copy_space_allocator_init(&alloc);
+    while (copy_space_allocator_acquire_partly_full_block(&alloc, space))
+      copy_space_allocator_release_full_block(&alloc, space);
+    copy_space_allocator_finish(&alloc, space);
+  }
+
   space->allocated_bytes_at_last_gc = space->allocated_bytes;
   space->fragmentation_at_last_gc = space->fragmentation;
   space->in_gc = 0;
@@ -778,18 +799,6 @@ copy_space_forget_edge(struct copy_space *space, struct 
gc_edge edge) {
   return 1;
 }
 
-static inline void
-copy_space_allocator_init(struct copy_space_allocator *alloc) {
-  memset(alloc, 0, sizeof(*alloc));
-}
-
-static inline void
-copy_space_allocator_finish(struct copy_space_allocator *alloc,
-                            struct copy_space *space) {
-  if (alloc->block)
-    copy_space_allocator_release_partly_full_block(alloc, space);
-}
-
 static size_t copy_space_is_power_of_two(size_t n) {
   GC_ASSERT(n != 0);
   return (n & (n - 1)) == 0;
diff --git a/src/pcc.c b/src/pcc.c
index 7ee017ae2..ff10375ef 100644
--- a/src/pcc.c
+++ b/src/pcc.c
@@ -774,11 +774,12 @@ copy_spaces_start_gc(struct gc_heap *heap, int 
is_minor_gc) {
 static void
 copy_spaces_finish_gc(struct gc_heap *heap, int is_minor_gc) {
   if (GC_GENERATIONAL) {
-    copy_space_finish_gc(heap_new_space(heap));
+    copy_space_finish_gc(heap_new_space(heap), is_minor_gc);
     if (!is_minor_gc)
-      copy_space_finish_gc(heap_old_space(heap));
+      copy_space_finish_gc(heap_old_space(heap), 0);
   } else {
-    copy_space_finish_gc(heap_mono_space(heap));
+    GC_ASSERT(!is_minor_gc);
+    copy_space_finish_gc(heap_mono_space(heap), 0);
   }
 }
 

Reply via email to