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

commit 521cd44ebd85a5b093efe8f7a66abfdd2c89e22f
Author: Andy Wingo <wi...@igalia.com>
AuthorDate: Fri Mar 7 10:58:05 2025 +0100

    Add gc_allocation_kind argument to gc_allocate
    
    Adapt all users.  Will eventually allow for mmc to have untagged
    allocations.
---
 api/bdw-attrs.h               | 20 +++++++++++--
 api/gc-allocation-kind.h      | 19 +++++++++++++
 api/gc-api.h                  | 65 +++++++++++++++++++++++++------------------
 api/gc-attrs.h                |  6 ++--
 api/mmc-attrs.h               |  5 ++--
 api/pcc-attrs.h               |  4 +--
 api/semi-attrs.h              |  5 ++--
 benchmarks/simple-allocator.h |  4 +--
 src/bdw.c                     | 44 +++++++++++++++++++++--------
 src/mmc.c                     | 22 +++++++++------
 src/nofl-space.h              |  5 ++--
 src/pcc.c                     | 17 ++++++-----
 src/semi.c                    | 17 +++++++----
 13 files changed, 158 insertions(+), 75 deletions(-)

diff --git a/api/bdw-attrs.h b/api/bdw-attrs.h
index 7c03144b5..7f8000b3f 100644
--- a/api/bdw-attrs.h
+++ b/api/bdw-attrs.h
@@ -21,15 +21,29 @@ static inline size_t 
gc_allocator_allocation_limit_offset(void) {
   GC_CRASH();
 }
 
-static inline size_t gc_allocator_freelist_offset(size_t size) {
+static inline size_t gc_allocator_freelist_offset(size_t size,
+                                                  enum gc_allocation_kind 
kind) {
   GC_ASSERT(size);
-  return sizeof(void*) * ((size - 1) / gc_allocator_small_granule_size());
+  size_t base;
+  switch (kind) {
+    case GC_ALLOCATION_TAGGED:
+    case GC_ALLOCATION_UNTAGGED_CONSERVATIVE:
+      base = 0;
+      break;
+    case GC_ALLOCATION_UNTAGGED_POINTERLESS:
+    case GC_ALLOCATION_TAGGED_POINTERLESS:
+      base = (sizeof(void*) * gc_allocator_large_threshold() /
+              gc_allocator_small_granule_size());
+      break;
+  }
+  size_t bucket = (size - 1) / gc_allocator_small_granule_size();
+  return base + sizeof(void*) * bucket;
 }
 
 static inline size_t gc_allocator_alloc_table_alignment(void) {
   return 0;
 }
-static inline uint8_t gc_allocator_alloc_table_begin_pattern(void) {
+static inline uint8_t gc_allocator_alloc_table_begin_pattern(enum 
gc_allocation_kind) {
   GC_CRASH();
 }
 static inline uint8_t gc_allocator_alloc_table_end_pattern(void) {
diff --git a/api/gc-allocation-kind.h b/api/gc-allocation-kind.h
new file mode 100644
index 000000000..72de3b6be
--- /dev/null
+++ b/api/gc-allocation-kind.h
@@ -0,0 +1,19 @@
+#ifndef GC_ALLOCATION_KIND_H
+#define GC_ALLOCATION_KIND_H
+
+enum gc_allocation_kind {
+  // An object whose type can be inspected at run-time based on its contents,
+  // and whose fields be traced via the gc_trace_object procedure.
+  GC_ALLOCATION_TAGGED,
+  // Like GC_ALLOCATION_TAGGED, but not containing any fields that reference
+  // GC-managed objects.  The GC may choose to handle these specially.
+  GC_ALLOCATION_TAGGED_POINTERLESS,
+  // A raw allocation whose type cannot be inspected at trace-time, and whose
+  // fields should be traced conservatively.
+  GC_ALLOCATION_UNTAGGED_CONSERVATIVE,
+  // A raw allocation whose type cannot be inspected at trace-time, but
+  // containing no fields that reference GC-managed objects.
+  GC_ALLOCATION_UNTAGGED_POINTERLESS
+};
+
+#endif // GC_ALLOCATION_KIND_H
diff --git a/api/gc-api.h b/api/gc-api.h
index 2b08d18b3..245784b33 100644
--- a/api/gc-api.h
+++ b/api/gc-api.h
@@ -2,6 +2,7 @@
 #define GC_API_H_
 
 #include "gc-config.h"
+#include "gc-allocation-kind.h"
 #include "gc-assert.h"
 #include "gc-attrs.h"
 #include "gc-collection-kind.h"
@@ -56,10 +57,10 @@ GC_API_ void* gc_call_without_gc(struct gc_mutator *mut, 
void* (*f)(void*),
 GC_API_ void gc_collect(struct gc_mutator *mut,
                         enum gc_collection_kind requested_kind);
 
-static inline void gc_update_alloc_table(struct gc_ref obj,
-                                         size_t size) GC_ALWAYS_INLINE;
-static inline void gc_update_alloc_table(struct gc_ref obj,
-                                         size_t size) {
+static inline void gc_update_alloc_table(struct gc_ref obj, size_t size,
+                                         enum gc_allocation_kind kind) 
GC_ALWAYS_INLINE;
+static inline void gc_update_alloc_table(struct gc_ref obj, size_t size,
+                                         enum gc_allocation_kind kind) {
   size_t alignment = gc_allocator_alloc_table_alignment();
   if (!alignment) return;
 
@@ -69,7 +70,7 @@ static inline void gc_update_alloc_table(struct gc_ref obj,
   uintptr_t granule = (addr & (alignment - 1)) / granule_size;
   uint8_t *alloc = (uint8_t*)(base + granule);
 
-  uint8_t begin_pattern = gc_allocator_alloc_table_begin_pattern();
+  uint8_t begin_pattern = gc_allocator_alloc_table_begin_pattern(kind);
   uint8_t end_pattern = gc_allocator_alloc_table_end_pattern();
   if (end_pattern) {
     size_t granules = size / granule_size;
@@ -86,11 +87,15 @@ static inline void gc_update_alloc_table(struct gc_ref obj,
   }
 }
 
-GC_API_ void* gc_allocate_slow(struct gc_mutator *mut, size_t bytes) 
GC_NEVER_INLINE;
+GC_API_ void* gc_allocate_slow(struct gc_mutator *mut, size_t bytes,
+                               enum gc_allocation_kind kind) GC_NEVER_INLINE;
 
 static inline void*
-gc_allocate_small_fast_bump_pointer(struct gc_mutator *mut, size_t size) 
GC_ALWAYS_INLINE;
-static inline void* gc_allocate_small_fast_bump_pointer(struct gc_mutator 
*mut, size_t size) {
+gc_allocate_small_fast_bump_pointer(struct gc_mutator *mut, size_t size,
+                                    enum gc_allocation_kind kind) 
GC_ALWAYS_INLINE;
+static inline void* gc_allocate_small_fast_bump_pointer(struct gc_mutator *mut,
+                                                        size_t size,
+                                                        enum 
gc_allocation_kind kind) {
   GC_ASSERT(size <= gc_allocator_large_threshold());
 
   size_t granule_size = gc_allocator_small_granule_size();
@@ -111,17 +116,20 @@ static inline void* 
gc_allocate_small_fast_bump_pointer(struct gc_mutator *mut,
 
   *hp_loc = new_hp;
 
-  gc_update_alloc_table(gc_ref(hp), size);
+  gc_update_alloc_table(gc_ref(hp), size, kind);
 
   return (void*)hp;
 }
 
 static inline void* gc_allocate_small_fast_freelist(struct gc_mutator *mut,
-                                                    size_t size) 
GC_ALWAYS_INLINE;
-static inline void* gc_allocate_small_fast_freelist(struct gc_mutator *mut, 
size_t size) {
+                                                    size_t size,
+                                                    enum gc_allocation_kind 
kind) GC_ALWAYS_INLINE;
+static inline void* gc_allocate_small_fast_freelist(struct gc_mutator *mut,
+                                                    size_t size,
+                                                    enum gc_allocation_kind 
kind) {
   GC_ASSERT(size <= gc_allocator_large_threshold());
 
-  size_t freelist_offset = gc_allocator_freelist_offset(size);
+  size_t freelist_offset = gc_allocator_freelist_offset(size, kind);
   uintptr_t base_addr = (uintptr_t)mut;
   void **freelist_loc = (void**)(base_addr + freelist_offset);
 
@@ -131,21 +139,23 @@ static inline void* 
gc_allocate_small_fast_freelist(struct gc_mutator *mut, size
 
   *freelist_loc = *(void**)head;
 
-  gc_update_alloc_table(gc_ref_from_heap_object(head), size);
+  gc_update_alloc_table(gc_ref_from_heap_object(head), size, kind);
 
   return head;
 }
 
-static inline void* gc_allocate_small_fast(struct gc_mutator *mut, size_t 
size) GC_ALWAYS_INLINE;
-static inline void* gc_allocate_small_fast(struct gc_mutator *mut, size_t 
size) {
+static inline void* gc_allocate_small_fast(struct gc_mutator *mut, size_t size,
+                                           enum gc_allocation_kind kind) 
GC_ALWAYS_INLINE;
+static inline void* gc_allocate_small_fast(struct gc_mutator *mut, size_t size,
+                                           enum gc_allocation_kind kind) {
   GC_ASSERT(size != 0);
   GC_ASSERT(size <= gc_allocator_large_threshold());
 
   switch (gc_allocator_kind()) {
   case GC_ALLOCATOR_INLINE_BUMP_POINTER:
-    return gc_allocate_small_fast_bump_pointer(mut, size);
+    return gc_allocate_small_fast_bump_pointer(mut, size, kind);
   case GC_ALLOCATOR_INLINE_FREELIST:
-    return gc_allocate_small_fast_freelist(mut, size);
+    return gc_allocate_small_fast_freelist(mut, size, kind);
   case GC_ALLOCATOR_INLINE_NONE:
     return NULL;
   default:
@@ -153,27 +163,28 @@ static inline void* gc_allocate_small_fast(struct 
gc_mutator *mut, size_t size)
   }
 }
 
-static inline void* gc_allocate_fast(struct gc_mutator *mut, size_t size) 
GC_ALWAYS_INLINE;
-static inline void* gc_allocate_fast(struct gc_mutator *mut, size_t size) {
+static inline void* gc_allocate_fast(struct gc_mutator *mut, size_t size,
+                                     enum gc_allocation_kind kind) 
GC_ALWAYS_INLINE;
+static inline void* gc_allocate_fast(struct gc_mutator *mut, size_t size,
+                                     enum gc_allocation_kind kind) {
   GC_ASSERT(size != 0);
   if (size > gc_allocator_large_threshold())
     return NULL;
 
-  return gc_allocate_small_fast(mut, size);
+  return gc_allocate_small_fast(mut, size, kind);
 }
 
-static inline void* gc_allocate(struct gc_mutator *mut, size_t size) 
GC_ALWAYS_INLINE;
-static inline void* gc_allocate(struct gc_mutator *mut, size_t size) {
-  void *ret = gc_allocate_fast(mut, size);
+static inline void* gc_allocate(struct gc_mutator *mut, size_t size,
+                                          enum gc_allocation_kind kind) 
GC_ALWAYS_INLINE;
+static inline void* gc_allocate(struct gc_mutator *mut, size_t size,
+                                          enum gc_allocation_kind kind) {
+  void *ret = gc_allocate_fast(mut, size, kind);
   if (GC_LIKELY(ret != NULL))
     return ret;
 
-  return gc_allocate_slow(mut, size);
+  return gc_allocate_slow(mut, size, kind);
 }
 
-// FIXME: remove :P
-GC_API_ void* gc_allocate_pointerless(struct gc_mutator *mut, size_t bytes);
-
 GC_API_ int gc_object_is_old_generation_slow(struct gc_mutator *mut,
                                              struct gc_ref obj) 
GC_NEVER_INLINE;
 
diff --git a/api/gc-attrs.h b/api/gc-attrs.h
index e7ea8c8f3..44d5d47e6 100644
--- a/api/gc-attrs.h
+++ b/api/gc-attrs.h
@@ -2,6 +2,7 @@
 #define GC_ATTRS_H
 
 #include "gc-inline.h"
+#include "gc-allocation-kind.h"
 
 #include <stddef.h>
 #include <stdint.h>
@@ -19,10 +20,11 @@ static inline size_t gc_allocator_small_granule_size(void) 
GC_ALWAYS_INLINE;
 static inline size_t gc_allocator_allocation_pointer_offset(void) 
GC_ALWAYS_INLINE;
 static inline size_t gc_allocator_allocation_limit_offset(void) 
GC_ALWAYS_INLINE;
 
-static inline size_t gc_allocator_freelist_offset(size_t size) 
GC_ALWAYS_INLINE;
+static inline size_t gc_allocator_freelist_offset(size_t size,
+                                                  enum gc_allocation_kind 
kind) GC_ALWAYS_INLINE;
 
 static inline size_t gc_allocator_alloc_table_alignment(void) GC_ALWAYS_INLINE;
-static inline uint8_t gc_allocator_alloc_table_begin_pattern(void) 
GC_ALWAYS_INLINE;
+static inline uint8_t gc_allocator_alloc_table_begin_pattern(enum 
gc_allocation_kind kind) GC_ALWAYS_INLINE;
 static inline uint8_t gc_allocator_alloc_table_end_pattern(void) 
GC_ALWAYS_INLINE;
 
 enum gc_old_generation_check_kind {
diff --git a/api/mmc-attrs.h b/api/mmc-attrs.h
index 0c6162dc9..3241677dd 100644
--- a/api/mmc-attrs.h
+++ b/api/mmc-attrs.h
@@ -22,14 +22,15 @@ static inline size_t 
gc_allocator_allocation_limit_offset(void) {
   return sizeof(uintptr_t) * 1;
 }
 
-static inline size_t gc_allocator_freelist_offset(size_t size) {
+static inline size_t gc_allocator_freelist_offset(size_t size,
+                                                  enum gc_allocation_kind 
kind) {
   GC_CRASH();
 }
 
 static inline size_t gc_allocator_alloc_table_alignment(void) {
   return 4 * 1024 * 1024;
 }
-static inline uint8_t gc_allocator_alloc_table_begin_pattern(void) {
+static inline uint8_t gc_allocator_alloc_table_begin_pattern(enum 
gc_allocation_kind kind) {
   return 1;
 }
 static inline uint8_t gc_allocator_alloc_table_end_pattern(void) {
diff --git a/api/pcc-attrs.h b/api/pcc-attrs.h
index 064e5181a..12a555a5d 100644
--- a/api/pcc-attrs.h
+++ b/api/pcc-attrs.h
@@ -25,14 +25,14 @@ static inline size_t 
gc_allocator_allocation_limit_offset(void) {
   return sizeof(uintptr_t) * 1;
 }
 
-static inline size_t gc_allocator_freelist_offset(size_t size) {
+static inline size_t gc_allocator_freelist_offset(size_t size, enum 
gc_allocation_kind kind) {
   GC_CRASH();
 }
 
 static inline size_t gc_allocator_alloc_table_alignment(void) {
   return 0;
 }
-static inline uint8_t gc_allocator_alloc_table_begin_pattern(void) {
+static inline uint8_t gc_allocator_alloc_table_begin_pattern(enum 
gc_allocation_kind kind) {
   GC_CRASH();
 }
 static inline uint8_t gc_allocator_alloc_table_end_pattern(void) {
diff --git a/api/semi-attrs.h b/api/semi-attrs.h
index 763f45606..f2efbd831 100644
--- a/api/semi-attrs.h
+++ b/api/semi-attrs.h
@@ -24,14 +24,15 @@ static inline size_t 
gc_allocator_allocation_limit_offset(void) {
   return sizeof(uintptr_t) * 1;
 }
 
-static inline size_t gc_allocator_freelist_offset(size_t size) {
+static inline size_t gc_allocator_freelist_offset(size_t size,
+                                                  enum gc_allocation_kind 
kind) {
   GC_CRASH();
 }
 
 static inline size_t gc_allocator_alloc_table_alignment(void) {
   return 0;
 }
-static inline uint8_t gc_allocator_alloc_table_begin_pattern(void) {
+static inline uint8_t gc_allocator_alloc_table_begin_pattern(enum 
gc_allocation_kind kind) {
   GC_CRASH();
 }
 static inline uint8_t gc_allocator_alloc_table_end_pattern(void) {
diff --git a/benchmarks/simple-allocator.h b/benchmarks/simple-allocator.h
index 1edba85d3..09ed8f3be 100644
--- a/benchmarks/simple-allocator.h
+++ b/benchmarks/simple-allocator.h
@@ -6,14 +6,14 @@
 
 static inline void*
 gc_allocate_with_kind(struct gc_mutator *mut, enum alloc_kind kind, size_t 
bytes) {
-  void *obj = gc_allocate(mut, bytes);
+  void *obj = gc_allocate(mut, bytes, GC_ALLOCATION_TAGGED);
   *tag_word(gc_ref_from_heap_object(obj)) = tag_live(kind);
   return obj;
 }
 
 static inline void*
 gc_allocate_pointerless_with_kind(struct gc_mutator *mut, enum alloc_kind 
kind, size_t bytes) {
-  void *obj = gc_allocate_pointerless(mut, bytes);
+  void *obj = gc_allocate(mut, bytes, GC_ALLOCATION_TAGGED_POINTERLESS);
   *tag_word(gc_ref_from_heap_object(obj)) = tag_live(kind);
   return obj;
 }
diff --git a/src/bdw.c b/src/bdw.c
index 5f90057a7..332e4a7ec 100644
--- a/src/bdw.c
+++ b/src/bdw.c
@@ -63,6 +63,7 @@ struct gc_heap {
 
 struct gc_mutator {
   void *freelists[GC_INLINE_FREELIST_COUNT];
+  void *pointerless_freelists[GC_INLINE_FREELIST_COUNT];
   struct gc_heap *heap;
   struct gc_mutator_roots *roots;
   struct gc_mutator *next; // with heap lock
@@ -122,27 +123,48 @@ allocate_small(void **freelist, size_t idx, enum 
gc_inline_kind kind) {
   }
 
   *freelist = *(void **)(head);
+
+  if (kind == GC_INLINE_KIND_POINTERLESS)
+    memset(head, 0, gc_inline_freelist_object_size(idx));
+
   return head;
 }
 
-void* gc_allocate_slow(struct gc_mutator *mut, size_t size) {
+void* gc_allocate_slow(struct gc_mutator *mut, size_t size,
+                       enum gc_allocation_kind kind) {
   GC_ASSERT(size != 0);
   if (size <= gc_allocator_large_threshold()) {
     size_t idx = gc_inline_bytes_to_freelist_index(size);
-    return allocate_small(&mut->freelists[idx], idx, GC_INLINE_KIND_NORMAL);
+    void **freelists;
+    enum gc_inline_kind freelist_kind;
+    switch (kind) {
+      case GC_ALLOCATION_TAGGED:
+      case GC_ALLOCATION_UNTAGGED_CONSERVATIVE:
+        return allocate_small(&mut->freelists[idx], idx, 
GC_INLINE_KIND_NORMAL);
+      case GC_ALLOCATION_TAGGED_POINTERLESS:
+      case GC_ALLOCATION_UNTAGGED_POINTERLESS:
+        return allocate_small(&mut->pointerless_freelists[idx], idx,
+                              GC_INLINE_KIND_POINTERLESS);
+      default:
+        GC_CRASH();
+    }
   } else {
-    return GC_malloc(size);
+    switch (kind) {
+      case GC_ALLOCATION_TAGGED:
+      case GC_ALLOCATION_UNTAGGED_CONSERVATIVE:
+        return GC_malloc(size);
+      case GC_ALLOCATION_TAGGED_POINTERLESS:
+      case GC_ALLOCATION_UNTAGGED_POINTERLESS: {
+        void *ret = GC_malloc_atomic(size);
+        memset(ret, 0, size);
+        return ret;
+      }
+      default:
+        GC_CRASH();
+    }
   }
 }
 
-void* gc_allocate_pointerless(struct gc_mutator *mut,
-                                            size_t size) {
-  // Because the BDW API requires us to implement a custom marker so
-  // that the pointerless freelist gets traced, even though it's in a
-  // pointerless region, we punt on thread-local pointerless freelists.
-  return GC_malloc_atomic(size);
-}
-
 void gc_pin_object(struct gc_mutator *mut, struct gc_ref ref) {
   // Nothing to do.
 }
diff --git a/src/mmc.c b/src/mmc.c
index 0c9448e62..d5716558f 100644
--- a/src/mmc.c
+++ b/src/mmc.c
@@ -891,7 +891,15 @@ collect_for_small_allocation(void *mut) {
 }
 
 void*
-gc_allocate_slow(struct gc_mutator *mut, size_t size) {
+gc_allocate_slow(struct gc_mutator *mut, size_t size,
+                 enum gc_allocation_kind kind) {
+  if (GC_UNLIKELY(kind != GC_ALLOCATION_TAGGED
+                  && kind != GC_ALLOCATION_TAGGED_POINTERLESS)) {
+    fprintf(stderr, "mmc collector cannot make allocations of kind %d\n",
+            (int)kind);
+    GC_CRASH();
+  }
+
   GC_ASSERT(size > 0); // allocating 0 bytes would be silly
 
   if (size > gc_allocator_large_threshold())
@@ -900,12 +908,7 @@ gc_allocate_slow(struct gc_mutator *mut, size_t size) {
   return gc_ref_heap_object(nofl_allocate(&mut->allocator,
                                           heap_nofl_space(mutator_heap(mut)),
                                           size, collect_for_small_allocation,
-                                          mut));
-}
-
-void*
-gc_allocate_pointerless(struct gc_mutator *mut, size_t size) {
-  return gc_allocate(mut, size);
+                                          mut, kind));
 }
 
 void
@@ -952,7 +955,8 @@ gc_write_barrier_slow(struct gc_mutator *mut, struct gc_ref 
obj,
 struct gc_ephemeron*
 gc_allocate_ephemeron(struct gc_mutator *mut) {
   struct gc_ref ret =
-    gc_ref_from_heap_object(gc_allocate(mut, gc_ephemeron_size()));
+    gc_ref_from_heap_object(gc_allocate(mut, gc_ephemeron_size(),
+                                        GC_ALLOCATION_TAGGED));
   nofl_space_set_ephemeron_flag(ret);
   return gc_ref_heap_object(ret);
 }
@@ -977,7 +981,7 @@ gc_heap_ephemeron_trace_epoch(struct gc_heap *heap) {
 
 struct gc_finalizer*
 gc_allocate_finalizer(struct gc_mutator *mut) {
-  return gc_allocate(mut, gc_finalizer_size());
+  return gc_allocate(mut, gc_finalizer_size(), GC_ALLOCATION_TAGGED);
 }
 
 void
diff --git a/src/nofl-space.h b/src/nofl-space.h
index 9e7245ebf..2ad64dc4f 100644
--- a/src/nofl-space.h
+++ b/src/nofl-space.h
@@ -871,7 +871,8 @@ nofl_allocator_next_hole(struct nofl_allocator *alloc,
 
 static struct gc_ref
 nofl_allocate(struct nofl_allocator *alloc, struct nofl_space *space,
-              size_t size, void (*gc)(void*), void *gc_data) {
+              size_t size, void (*gc)(void*), void *gc_data,
+              enum gc_allocation_kind kind) {
   GC_ASSERT(size > 0);
   GC_ASSERT(size <= gc_allocator_large_threshold());
   size = align_up(size, NOFL_GRANULE_SIZE);
@@ -890,7 +891,7 @@ nofl_allocate(struct nofl_allocator *alloc, struct 
nofl_space *space,
 
   struct gc_ref ret = gc_ref(alloc->alloc);
   alloc->alloc += size;
-  gc_update_alloc_table(ret, size);
+  gc_update_alloc_table(ret, size, kind);
   return ret;
 }
 
diff --git a/src/pcc.c b/src/pcc.c
index 877827ed3..e4c4e37e3 100644
--- a/src/pcc.c
+++ b/src/pcc.c
@@ -978,7 +978,14 @@ static void get_more_empty_blocks_for_mutator(void *mut) {
   trigger_collection(mut, GC_COLLECTION_MINOR);
 }
 
-void* gc_allocate_slow(struct gc_mutator *mut, size_t size) {
+void* gc_allocate_slow(struct gc_mutator *mut, size_t size,
+                       enum gc_allocation_kind kind) {
+  if (GC_UNLIKELY(kind != GC_ALLOCATION_TAGGED
+                  && kind != GC_ALLOCATION_TAGGED_POINTERLESS)) {
+    fprintf(stderr, "pcc collector cannot make allocations of kind %d\n",
+            (int)kind);
+    GC_CRASH();
+  }
   GC_ASSERT(size > 0); // allocating 0 bytes would be silly
 
   if (size > gc_allocator_large_threshold())
@@ -998,10 +1005,6 @@ void* gc_allocate_slow(struct gc_mutator *mut, size_t 
size) {
   return gc_ref_heap_object(ret);
 }
 
-void* gc_allocate_pointerless(struct gc_mutator *mut, size_t size) {
-  return gc_allocate(mut, size);
-}
-
 void gc_pin_object(struct gc_mutator *mut, struct gc_ref ref) {
   GC_CRASH();
 }
@@ -1056,7 +1059,7 @@ void gc_safepoint_slow(struct gc_mutator *mut) {
 }
   
 struct gc_ephemeron* gc_allocate_ephemeron(struct gc_mutator *mut) {
-  return gc_allocate(mut, gc_ephemeron_size());
+  return gc_allocate(mut, gc_ephemeron_size(), GC_ALLOCATION_TAGGED);
 }
 
 void gc_ephemeron_init(struct gc_mutator *mut, struct gc_ephemeron *ephemeron,
@@ -1077,7 +1080,7 @@ unsigned gc_heap_ephemeron_trace_epoch(struct gc_heap 
*heap) {
 }
 
 struct gc_finalizer* gc_allocate_finalizer(struct gc_mutator *mut) {
-  return gc_allocate(mut, gc_finalizer_size());
+  return gc_allocate(mut, gc_finalizer_size(), GC_ALLOCATION_TAGGED);
 }
 
 void gc_finalizer_attach(struct gc_mutator *mut, struct gc_finalizer 
*finalizer,
diff --git a/src/semi.c b/src/semi.c
index 833cfabef..b1abee836 100644
--- a/src/semi.c
+++ b/src/semi.c
@@ -505,7 +505,15 @@ static void* allocate_large(struct gc_mutator *mut, size_t 
size) {
   return ret;
 }
 
-void* gc_allocate_slow(struct gc_mutator *mut, size_t size) {
+void* gc_allocate_slow(struct gc_mutator *mut, size_t size,
+                       enum gc_allocation_kind kind) {
+  if (GC_UNLIKELY(kind != GC_ALLOCATION_TAGGED
+                  && kind != GC_ALLOCATION_TAGGED_POINTERLESS)) {
+    fprintf(stderr, "semispace collector cannot make allocations of kind %d\n",
+            (int)kind);
+    GC_CRASH();
+  }
+
   if (size > gc_allocator_large_threshold())
     return allocate_large(mut, size);
 
@@ -522,16 +530,13 @@ void* gc_allocate_slow(struct gc_mutator *mut, size_t 
size) {
     return (void *)addr;
   }
 }
-void* gc_allocate_pointerless(struct gc_mutator *mut, size_t size) {
-  return gc_allocate(mut, size);
-}
 
 void gc_pin_object(struct gc_mutator *mut, struct gc_ref ref) {
   GC_CRASH();
 }
 
 struct gc_ephemeron* gc_allocate_ephemeron(struct gc_mutator *mut) {
-  return gc_allocate(mut, gc_ephemeron_size());
+  return gc_allocate(mut, gc_ephemeron_size(), GC_ALLOCATION_TAGGED);
 }
 
 void gc_ephemeron_init(struct gc_mutator *mut, struct gc_ephemeron *ephemeron,
@@ -540,7 +545,7 @@ void gc_ephemeron_init(struct gc_mutator *mut, struct 
gc_ephemeron *ephemeron,
 }
 
 struct gc_finalizer* gc_allocate_finalizer(struct gc_mutator *mut) {
-  return gc_allocate(mut, gc_finalizer_size());
+  return gc_allocate(mut, gc_finalizer_size(), GC_ALLOCATION_TAGGED);
 }
 
 void gc_finalizer_attach(struct gc_mutator *mut, struct gc_finalizer 
*finalizer,

Reply via email to