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: