diff --git a/api/gc-embedder-api.h b/api/gc-embedder-api.h index ad33bc170..30ba62946 100644 --- a/api/gc-embedder-api.h +++ b/api/gc-embedder-api.h @@ -66,6 +66,7 @@ GC_EMBEDDER_API inline struct gc_atomic_forward gc_atomic_forward_begin(struct g GC_EMBEDDER_API inline void gc_atomic_forward_acquire(struct gc_atomic_forward *); GC_EMBEDDER_API inline int gc_atomic_forward_retry_busy(struct gc_atomic_forward *); GC_EMBEDDER_API inline void gc_atomic_forward_abort(struct gc_atomic_forward *); +GC_EMBEDDER_API inline size_t gc_atomic_forward_object_size(struct gc_atomic_forward *); GC_EMBEDDER_API inline void gc_atomic_forward_commit(struct gc_atomic_forward *, struct gc_ref new_ref); GC_EMBEDDER_API inline uintptr_t gc_atomic_forward_address(struct gc_atomic_forward *); diff --git a/benchmarks/simple-gc-embedder.h b/benchmarks/simple-gc-embedder.h index 2c599655b..5f77a7cc9 100644 --- a/benchmarks/simple-gc-embedder.h +++ b/benchmarks/simple-gc-embedder.h @@ -168,6 +168,20 @@ gc_atomic_forward_abort(struct gc_atomic_forward *fwd) { fwd->state = GC_FORWARDING_STATE_ABORTED; } +static inline size_t +gc_atomic_forward_object_size(struct gc_atomic_forward *fwd) { + GC_ASSERT(fwd->state == GC_FORWARDING_STATE_ACQUIRED); + switch (tag_live_alloc_kind(fwd->data)) { +#define SCAN_OBJECT(name, Name, NAME) \ + case ALLOC_KIND_##NAME: \ + return name##_size(gc_ref_heap_object(ref)); \ + FOR_EACH_HEAP_OBJECT_KIND(SCAN_OBJECT) +#undef SCAN_OBJECT + default: + GC_CRASH(); + } +} + static inline void gc_atomic_forward_commit(struct gc_atomic_forward *fwd, struct gc_ref new_ref) { GC_ASSERT(fwd->state == GC_FORWARDING_STATE_ACQUIRED); diff --git a/doc/manual.md b/doc/manual.md index 4156defdf..ab0656db0 100644 --- a/doc/manual.md +++ b/doc/manual.md @@ -140,7 +140,10 @@ acquired and completed the forwarding attempt. An `ACQUIRED` object can then be forwarded via `gc_atomic_forward_commit`, or the forwarding attempt can be aborted via -`gc_atomic_forward_abort`. +`gc_atomic_forward_abort`. Also, when an object is acquired, the +collector may call `gc_atomic_forward_object_size` to compute how many +bytes to copy. (The collector may choose instead to record object sizes +in a different way.) All of these `gc_atomic_forward` functions are to be implemented by the embedder. Some programs may allocate a dedicated forwarding word in all diff --git a/src/whippet.c b/src/whippet.c index 0b4dd61d6..af9b3dbd4 100644 --- a/src/whippet.c +++ b/src/whippet.c @@ -831,13 +831,6 @@ static inline size_t mark_space_object_size(struct mark_space *space, return granules * GRANULE_SIZE; } -static inline size_t gc_object_allocation_size(struct gc_heap *heap, - struct gc_ref ref) { - if (GC_LIKELY(mark_space_contains(heap_mark_space(heap), ref))) - return mark_space_object_size(heap_mark_space(heap), ref); - return large_object_space_object_size(heap_large_object_space(heap), ref); -} - static int heap_has_multiple_mutators(struct gc_heap *heap) { return atomic_load_explicit(&heap->multithreaded, memory_order_relaxed); }