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

commit 5a92b43e9452cd079e8f018259c5e0954f19afba
Author: Andy Wingo <wi...@igalia.com>
AuthorDate: Mon Mar 28 22:48:04 2022 +0200

    Change serial marker to deal in struct gcobj* instead of uintptr
    
    "struct gcobj*" is how we denote live objects, and the marker will only
    see live objects.
---
 serial-marker.h | 44 ++++++++++++++++++++++++++++----------------
 1 file changed, 28 insertions(+), 16 deletions(-)

diff --git a/serial-marker.h b/serial-marker.h
index 719ba1c51..8cc65a328 100644
--- a/serial-marker.h
+++ b/serial-marker.h
@@ -7,20 +7,22 @@
 #include "assert.h"
 #include "debug.h"
 
+struct gcobj;
+
 struct mark_queue {
   size_t size;
   size_t read;
   size_t write;
-  uintptr_t *buf;
+  struct gcobj **buf;
 };
 
 static const size_t mark_queue_max_size =
-  (1ULL << (sizeof(uintptr_t) * 8 - 1)) / sizeof(uintptr_t);
+  (1ULL << (sizeof(struct gcobj *) * 8 - 1)) / sizeof(struct gcobj *);
 static const size_t mark_queue_release_byte_threshold = 1 * 1024 * 1024;
 
-static void*
+static struct gcobj **
 mark_queue_alloc(size_t size) {
-  void *mem = mmap(NULL, size * sizeof(uintptr_t), PROT_READ|PROT_WRITE,
+  void *mem = mmap(NULL, size * sizeof(struct gcobj *), PROT_READ|PROT_WRITE,
                    MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
   if (mem == MAP_FAILED) {
     perror("Failed to grow mark queue");
@@ -32,20 +34,20 @@ mark_queue_alloc(size_t size) {
 
 static int
 mark_queue_init(struct mark_queue *q) {
-  q->size = getpagesize() / sizeof(uintptr_t);
+  q->size = getpagesize() / sizeof(struct gcobj *);
   q->read = 0;
   q->write = 0;
   q->buf = mark_queue_alloc(q->size);
   return !!q->buf;
 }
   
-static inline uintptr_t
+static inline struct gcobj *
 mark_queue_get(struct mark_queue *q, size_t idx) {
   return q->buf[idx & (q->size - 1)];
 }
 
 static inline void
-mark_queue_put(struct mark_queue *q, size_t idx, uintptr_t x) {
+mark_queue_put(struct mark_queue *q, size_t idx, struct gcobj *x) {
   q->buf[idx & (q->size - 1)] = x;
 }
 
@@ -54,14 +56,14 @@ static int mark_queue_grow(struct mark_queue *q) 
NEVER_INLINE;
 static int
 mark_queue_grow(struct mark_queue *q) {
   size_t old_size = q->size;
-  uintptr_t *old_buf = q->buf;
+  struct gcobj **old_buf = q->buf;
   if (old_size >= mark_queue_max_size) {
     DEBUG("mark queue already at max size of %zu bytes", old_size);
     return 0;
   }
 
   size_t new_size = old_size * 2;
-  uintptr_t *new_buf = mark_queue_alloc(new_size);
+  struct gcobj **new_buf = mark_queue_alloc(new_size);
   if (!new_buf)
     return 0;
 
@@ -71,7 +73,7 @@ mark_queue_grow(struct mark_queue *q) {
   for (size_t i = q->read; i < q->write; i++)
     new_buf[i & new_mask] = old_buf[i & old_mask];
 
-  munmap(old_buf, old_size * sizeof(uintptr_t));
+  munmap(old_buf, old_size * sizeof(struct gcobj *));
 
   q->size = new_size;
   q->buf = new_buf;
@@ -79,24 +81,34 @@ mark_queue_grow(struct mark_queue *q) {
 }
   
 static inline void
-mark_queue_push(struct mark_queue *q, void *p) {
+mark_queue_push(struct mark_queue *q, struct gcobj *p) {
   if (UNLIKELY(q->write - q->read == q->size)) {
     if (!mark_queue_grow(q))
       abort();
   }
-  mark_queue_put(q, q->write++, (uintptr_t)p);
+  mark_queue_put(q, q->write++, p);
+}
+
+static inline void
+mark_queue_push_many(struct mark_queue *q, struct gcobj **pv, size_t count) {
+  while (q->size - (q->write - q->read) < count) {
+    if (!mark_queue_grow(q))
+      abort();
+  }
+  for (size_t i = 0; i < count; i++)
+    mark_queue_put(q, q->write++, pv[i]);
 }
 
-static inline void*
+static inline struct gcobj*
 mark_queue_pop(struct mark_queue *q) {
   if (UNLIKELY(q->read == q->write))
     return NULL;
-  return (void*)mark_queue_get(q, q->read++);
+  return mark_queue_get(q, q->read++);
 }
 
 static void
 mark_queue_release(struct mark_queue *q) {
-  size_t byte_size = q->size * sizeof(uintptr_t);
+  size_t byte_size = q->size * sizeof(struct gcobj *);
   if (byte_size >= mark_queue_release_byte_threshold)
     madvise(q->buf, byte_size, MADV_DONTNEED);
   q->read = q->write = 0;
@@ -104,7 +116,7 @@ mark_queue_release(struct mark_queue *q) {
 
 static void
 mark_queue_destroy(struct mark_queue *q) {
-  size_t byte_size = q->size * sizeof(uintptr_t);
+  size_t byte_size = q->size * sizeof(struct gcobj *);
   munmap(q->buf, byte_size);
 }
 

Reply via email to