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

commit 8e631ca3f3a24773e55768e420735a43b8bd97de
Author: Andy Wingo <wi...@igalia.com>
AuthorDate: Mon Jan 6 15:47:20 2025 +0100

    Remove embedder requirement for per-object remset bits
    
    Since we now have a field-logging write barrier, we don't need
    per-object log bits.
---
 api/gc-embedder-api.h              |  8 --------
 benchmarks/simple-gc-embedder.h    | 26 --------------------------
 benchmarks/simple-tagging-scheme.h |  8 +++-----
 doc/manual.md                      | 16 ----------------
 src/large-object-space.h           |  2 --
 5 files changed, 3 insertions(+), 57 deletions(-)

diff --git a/api/gc-embedder-api.h b/api/gc-embedder-api.h
index 7535ea7bc..c1b272a51 100644
--- a/api/gc-embedder-api.h
+++ b/api/gc-embedder-api.h
@@ -50,14 +50,6 @@ GC_EMBEDDER_API inline void gc_trace_heap_roots(struct 
gc_heap_roots *roots,
                                                 struct gc_heap *heap,
                                                 void *trace_data);
 
-// Some heap objects have space for a "remembered" bit, indicating they
-// are in the remembered set.  Large or potentially large objects
-// (e.g. a vector whose size is a run-time property) must have a
-// remembered set bit.  Small objects may or may not have such a bit.
-GC_EMBEDDER_API inline int gc_object_set_remembered(struct gc_ref ref);
-GC_EMBEDDER_API inline int gc_object_is_remembered_nonatomic(struct gc_ref 
ref);
-GC_EMBEDDER_API inline void gc_object_clear_remembered_nonatomic(struct gc_ref 
ref);
-
 GC_EMBEDDER_API inline uintptr_t gc_object_forwarded_nonatomic(struct gc_ref 
ref);
 GC_EMBEDDER_API inline void gc_object_forward_nonatomic(struct gc_ref ref,
                                                         struct gc_ref new_ref);
diff --git a/benchmarks/simple-gc-embedder.h b/benchmarks/simple-gc-embedder.h
index 4e5fbb83d..d8ad3f0ad 100644
--- a/benchmarks/simple-gc-embedder.h
+++ b/benchmarks/simple-gc-embedder.h
@@ -102,32 +102,6 @@ static inline void gc_object_forward_nonatomic(struct 
gc_ref ref,
   *tag_word(ref) = gc_ref_value(new_ref);
 }
 
-static inline int gc_object_set_remembered(struct gc_ref ref) {
-  uintptr_t *loc = tag_word(ref);
-  uintptr_t tag = atomic_load_explicit(loc, memory_order_relaxed);
-  while (1) {
-    if (tag & gcobj_remembered_bit)
-      return 0;
-    if (atomic_compare_exchange_weak_explicit(loc, &tag,
-                                              tag | gcobj_remembered_bit,
-                                              memory_order_acq_rel,
-                                              memory_order_acquire))
-      return 1;
-  }
-}
-
-static inline int gc_object_is_remembered_nonatomic(struct gc_ref ref) {
-  uintptr_t *loc = tag_word(ref);
-  uintptr_t tag = *loc;
-  return tag & gcobj_remembered_bit;
-}
-
-static inline void gc_object_clear_remembered_nonatomic(struct gc_ref ref) {
-  uintptr_t *loc = tag_word(ref);
-  uintptr_t tag = *loc;
-  *loc = tag & ~(uintptr_t)gcobj_remembered_bit;
-}
-
 static inline struct gc_atomic_forward
 gc_atomic_forward_begin(struct gc_ref ref) {
   uintptr_t tag = atomic_load_explicit(tag_word(ref), memory_order_acquire);
diff --git a/benchmarks/simple-tagging-scheme.h 
b/benchmarks/simple-tagging-scheme.h
index aa0b707e4..b6b8a924c 100644
--- a/benchmarks/simple-tagging-scheme.h
+++ b/benchmarks/simple-tagging-scheme.h
@@ -7,11 +7,9 @@ struct gc_header {
   uintptr_t tag;
 };
 
-// Alloc kind is in bits 2-7, for live objects.
-static const uintptr_t gcobj_alloc_kind_mask = 0x3f;
-static const uintptr_t gcobj_alloc_kind_shift = 2;
-static const uintptr_t gcobj_remembered_mask = 0x2;
-static const uintptr_t gcobj_remembered_bit = 0x2;
+// Alloc kind is in bits 1-7, for live objects.
+static const uintptr_t gcobj_alloc_kind_mask = 0x7f;
+static const uintptr_t gcobj_alloc_kind_shift = 1;
 static const uintptr_t gcobj_forwarded_mask = 0x1;
 static const uintptr_t gcobj_not_forwarded_bit = 0x1;
 static const uintptr_t gcobj_busy = 0;
diff --git a/doc/manual.md b/doc/manual.md
index 7c784b626..c299128bf 100644
--- a/doc/manual.md
+++ b/doc/manual.md
@@ -87,22 +87,6 @@ in the `gc_trace_object` function by calling 
`gc_trace_ephemeron` from
 allocates finalizers, it should trace them by calling
 `gc_trace_finalizer` from [`gc-finalizer.h`](../api/gc-finalizer.h).
 
-### Remembered-set bits
-
-When built to support generational garbage collection, Whippet requires
-that all "large" or potentially large objects have a flag bit reserved
-for use of the garbage collector.  A large object is one whose size
-exceeds the `gc_allocator_large_threshold()` (see
-[`gc-attrs.h`](../api/gc-attrs.h)), which is a collector-specific value.
-Currently the only generational collector is the in-place `mmc`
-collector, whose large object threshold is 4096 bytes.  The
-`gc_object_set_remembered`, `gc_object_is_remembered_nonatomic`, and
-`gc_object_clear_remembered_nonatomic` embedder functions manage the
-remembered bit.  Setting the remembered bit should be idempotent;
-multiple threads can race to call `gc_object_set_remembered` and do not
-synchronize.  The query and clear functions are called without
-concurrent accessors and so don't have to be atomic.
-
 ### Forwarding objects
 
 When built with a collector that moves objects, the embedder must also
diff --git a/src/large-object-space.h b/src/large-object-space.h
index 7aba13d9a..18e6280da 100644
--- a/src/large-object-space.h
+++ b/src/large-object-space.h
@@ -113,8 +113,6 @@ static int large_object_space_copy(struct 
large_object_space *space,
   address_set_remove(&space->from_space, addr);
   address_set_add(GC_GENERATIONAL ? &space->survivor_space : &space->to_space,
                   addr);
-  if (GC_GENERATIONAL && gc_object_is_remembered_nonatomic(ref))
-    gc_object_clear_remembered_nonatomic(ref);
   // Object is grey; place it on mark stack to visit its fields.
   copied = 1;
 done:

Reply via email to