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

commit 8623e252bf65c60fedf0e2001cc79fab846bcc81
Author: Andy Wingo <wi...@pobox.com>
AuthorDate: Thu Jul 3 10:10:20 2025 +0200

    Separate tagged and untagged pointerless allocations
    
    Tagged allocations can move; untagged allocations cannot.
    
    * libguile/gc-inline.h:
    * libguile/gc-malloc.c:
    * libguile/gc.h: Split scm_allocate_pointerless into tagged and untagged
    variants.
    * libguile/bitvectors.c:
    * libguile/bytevectors.c:
    * libguile/foreign.c:
    * libguile/fports.c:
    * libguile/integers.c:
    * libguile/intrinsics.c:
    * libguile/load.c:
    * libguile/loader.c:
    * libguile/numbers.c:
    * libguile/programs.h:
    * libguile/random.c:
    * libguile/read.c:
    * libguile/regex-posix.c:
    * libguile/smob.c:
    * libguile/strings.c:
    * libguile/vm.c: Use the new functions.
---
 libguile/bitvectors.c  |  6 +++---
 libguile/bytevectors.c |  4 ++--
 libguile/foreign.c     |  5 +++--
 libguile/fports.c      |  4 ++--
 libguile/gc-inline.h   | 15 +++++++++++----
 libguile/gc-malloc.c   | 22 ++++++++++++++--------
 libguile/gc.h          |  3 ++-
 libguile/integers.c    |  3 ++-
 libguile/intrinsics.c  |  4 ++--
 libguile/load.c        |  4 ++--
 libguile/loader.c      |  6 +++---
 libguile/numbers.c     | 26 +++++++++++---------------
 libguile/programs.h    |  3 +--
 libguile/random.c      | 12 ++++++------
 libguile/read.c        |  9 +++++----
 libguile/regex-posix.c |  3 +--
 libguile/smob.c        |  4 ++--
 libguile/strings.c     | 10 ++++++----
 libguile/vm.c          |  2 +-
 19 files changed, 79 insertions(+), 66 deletions(-)

diff --git a/libguile/bitvectors.c b/libguile/bitvectors.c
index bad5ce429..c5c609ff4 100644
--- a/libguile/bitvectors.c
+++ b/libguile/bitvectors.c
@@ -109,9 +109,9 @@ make_bitvector (size_t len, int fill)
   size_t word_len = bit_count_to_word_count (len);
   struct scm_bitvector *bv;
 
-  bv = scm_allocate_pointerless (SCM_I_CURRENT_THREAD,
-                                 sizeof (struct scm_bitvector)
-                                  + sizeof (scm_t_bits) * word_len);
+  bv = scm_allocate_tagged_pointerless (SCM_I_CURRENT_THREAD,
+                                        sizeof (struct scm_bitvector)
+                                        + sizeof (scm_t_bits) * word_len);
 
   bv->tag_and_flags = scm_tc7_bitvector;
   bv->length = len;
diff --git a/libguile/bytevectors.c b/libguile/bytevectors.c
index 82132193c..616f200ac 100644
--- a/libguile/bytevectors.c
+++ b/libguile/bytevectors.c
@@ -233,8 +233,8 @@ make_bytevector (size_t len, scm_t_array_element_type 
element_type)
 
   size_t c_len = len * bytes_per_elt;
   struct scm_bytevector *bv =
-    scm_allocate_pointerless (SCM_I_CURRENT_THREAD,
-                              sizeof (struct scm_bytevector) + c_len);
+    scm_allocate_tagged_pointerless (SCM_I_CURRENT_THREAD,
+                                     sizeof (struct scm_bytevector) + c_len);
 
   scm_t_bits flags = SCM_F_BYTEVECTOR_CONTIGUOUS;
   bv->tag_flags_and_element_type = make_bytevector_tag (flags, element_type);
diff --git a/libguile/foreign.c b/libguile/foreign.c
index 4a288d02c..3002ed1e8 100644
--- a/libguile/foreign.c
+++ b/libguile/foreign.c
@@ -817,7 +817,7 @@ make_cif (SCM return_type, SCM arg_types, const char 
*caller)
   cif_len = (ROUND_UP (cif_len, alignof_type (ffi_type))
             + (nargs + n_struct_elts + 1)*sizeof(ffi_type));
 
-  mem = scm_allocate_pointerless (SCM_I_CURRENT_THREAD, cif_len);
+  mem = scm_allocate_untagged_pointerless (SCM_I_CURRENT_THREAD, cif_len);
   /* ensure all the memory is initialized, even the holes */
   memset (mem, 0, cif_len);
   cif = (ffi_cif *) mem;
@@ -1133,7 +1133,8 @@ pack (const ffi_type * type, const void *loc, int 
return_value_p)
 
     case FFI_TYPE_STRUCT:
       {
-       void *mem = scm_allocate_pointerless (SCM_I_CURRENT_THREAD, type->size);
+       void *mem =
+          scm_allocate_untagged_pointerless (SCM_I_CURRENT_THREAD, type->size);
        memcpy (mem, loc, type->size);
        return scm_from_pointer (mem, NULL);
       }
diff --git a/libguile/fports.c b/libguile/fports.c
index 9f11cce9a..b51f3b219 100644
--- a/libguile/fports.c
+++ b/libguile/fports.c
@@ -455,8 +455,8 @@ scm_i_fdes_to_port (int fdes, long mode_bits, SCM name, 
unsigned options)
         }
     }
 
-  fp = (scm_t_fport *) scm_allocate_pointerless (SCM_I_CURRENT_THREAD,
-                                                 sizeof (scm_t_fport));
+  fp = (scm_t_fport *) scm_allocate_untagged_pointerless (SCM_I_CURRENT_THREAD,
+                                                          sizeof 
(scm_t_fport));
   fp->fdes = fdes;
   fp->options = options;
   fp->revealed = 0;
diff --git a/libguile/gc-inline.h b/libguile/gc-inline.h
index 5b53a67f6..26f5126a7 100644
--- a/libguile/gc-inline.h
+++ b/libguile/gc-inline.h
@@ -46,17 +46,24 @@
 
 
 static inline void *
-scm_inline_allocate_pointerless (scm_thread *thread, size_t bytes)
+scm_inline_allocate_tagged (scm_thread *thread, size_t bytes)
 {
   return gc_allocate (thread->mutator, bytes,
-                      GC_ALLOCATION_UNTAGGED_POINTERLESS);
+                      GC_ALLOCATION_TAGGED);
 }
 
 static inline void *
-scm_inline_allocate_tagged (scm_thread *thread, size_t bytes)
+scm_inline_allocate_tagged_pointerless (scm_thread *thread, size_t bytes)
 {
   return gc_allocate (thread->mutator, bytes,
-                      GC_ALLOCATION_TAGGED);
+                      GC_ALLOCATION_TAGGED_POINTERLESS);
+}
+
+static inline void *
+scm_inline_allocate_untagged_pointerless (scm_thread *thread, size_t bytes)
+{
+  return gc_allocate (thread->mutator, bytes,
+                      GC_ALLOCATION_UNTAGGED_POINTERLESS);
 }
 
 static inline void *
diff --git a/libguile/gc-malloc.c b/libguile/gc-malloc.c
index 229e2c98d..ed1910951 100644
--- a/libguile/gc-malloc.c
+++ b/libguile/gc-malloc.c
@@ -150,17 +150,24 @@ scm_gc_unregister_collectable_memory (void *mem, size_t 
size, const char *what)
 }
 
 void *
-scm_allocate_pointerless (struct scm_thread *thr, size_t size)
+scm_allocate_tagged (struct scm_thread *thr, size_t size)
 {
   if (!size) abort();
-  return scm_inline_allocate_pointerless (thr, size);
+  return scm_inline_allocate_tagged (thr, size);
 }
 
 void *
-scm_allocate_tagged (struct scm_thread *thr, size_t size)
+scm_allocate_tagged_pointerless (struct scm_thread *thr, size_t size)
 {
   if (!size) abort();
-  return scm_inline_allocate_tagged (thr, size);
+  return scm_inline_allocate_tagged_pointerless (thr, size);
+}
+
+void *
+scm_allocate_untagged_pointerless (struct scm_thread *thr, size_t size)
+{
+  if (!size) abort();
+  return scm_inline_allocate_untagged_pointerless (thr, size);
 }
 
 void *
@@ -171,13 +178,12 @@ scm_allocate_sloppy (struct scm_thread *thr, size_t size)
 }
 
 /* Allocate SIZE bytes of memory whose contents should not be scanned
-   for pointers (useful, e.g., for strings).  Note though that this
-   memory is *not* cleared; be sure to initialize it to prevent
-   information leaks.  */
+   for pointers (useful, e.g., for strings).  The memory is cleared.  */
 void *
 scm_gc_malloc_pointerless (size_t size, const char *what)
 {
-  return scm_allocate_pointerless (SCM_I_CURRENT_THREAD, size ? size : 1);
+  return scm_allocate_untagged_pointerless (SCM_I_CURRENT_THREAD,
+                                            size ? size : 1);
 }
 
 void *
diff --git a/libguile/gc.h b/libguile/gc.h
index f545c2aa6..1c6b549c7 100644
--- a/libguile/gc.h
+++ b/libguile/gc.h
@@ -112,8 +112,9 @@ SCM_API void scm_gc_register_collectable_memory (void *mem, 
size_t size,
 SCM_API void scm_gc_unregister_collectable_memory (void *mem, size_t size,
                                                   const char *what);
 
-SCM_API void *scm_allocate_pointerless (struct scm_thread *thr, size_t size);
 SCM_API void *scm_allocate_tagged (struct scm_thread *thr, size_t size);
+SCM_API void *scm_allocate_tagged_pointerless (struct scm_thread *thr, size_t 
size);
+SCM_API void *scm_allocate_untagged_pointerless (struct scm_thread *thr, 
size_t size);
 SCM_API void *scm_allocate_sloppy (struct scm_thread *thr, size_t size);
 
 SCM_API void scm_gc_pin_object (struct scm_thread *thr, SCM x);
diff --git a/libguile/integers.c b/libguile/integers.c
index 39867e774..71059e372 100644
--- a/libguile/integers.c
+++ b/libguile/integers.c
@@ -139,7 +139,8 @@ allocate_bignum (size_t nlimbs)
   ASSERT (nlimbs <= NLIMBS_MAX);
 
   size_t size = sizeof (struct scm_bignum) + nlimbs * sizeof(mp_limb_t);
-  struct scm_bignum *z = scm_allocate_pointerless (SCM_I_CURRENT_THREAD, size);
+  struct scm_bignum *z =
+    scm_allocate_tagged_pointerless (SCM_I_CURRENT_THREAD, size);
 
   z->tag = scm_tc16_big;
   z->size = nlimbs;
diff --git a/libguile/intrinsics.c b/libguile/intrinsics.c
index d686964e8..3aa7b5d06 100644
--- a/libguile/intrinsics.c
+++ b/libguile/intrinsics.c
@@ -469,8 +469,8 @@ allocate_words (scm_thread *thread, size_t n)
 static SCM
 allocate_pointerless_words (scm_thread *thread, size_t n)
 {
-  return SCM_PACK_POINTER (scm_inline_allocate_pointerless (thread,
-                                                            n * sizeof (SCM)));
+  return SCM_PACK_POINTER
+    (scm_inline_allocate_untagged_pointerless (thread, n * sizeof (SCM)));
 }
 
 static SCM
diff --git a/libguile/load.c b/libguile/load.c
index 1939eb98b..bfd00c2a0 100644
--- a/libguile/load.c
+++ b/libguile/load.c
@@ -430,8 +430,8 @@ stringbuf_grow (struct stringbuf *buf)
   ptroff = buf->ptr - buf->buf;
 
   buf->buf_len *= 2;
-  buf->buf = scm_allocate_pointerless (SCM_I_CURRENT_THREAD,
-                                       buf->buf_len);
+  buf->buf = scm_allocate_untagged_pointerless (SCM_I_CURRENT_THREAD,
+                                                buf->buf_len);
   memcpy (buf->buf, prev_buf, prev_len);
   buf->ptr = buf->buf + ptroff;
 }
diff --git a/libguile/loader.c b/libguile/loader.c
index f4c0533fc..2740699ee 100644
--- a/libguile/loader.c
+++ b/libguile/loader.c
@@ -698,9 +698,9 @@ register_elf (char *data, size_t len, char *frame_maps)
 
         prev = mapped_elf_images;
         mapped_elf_images =
-          scm_allocate_pointerless (SCM_I_CURRENT_THREAD,
-                                    sizeof (*mapped_elf_images)
-                                     * mapped_elf_images_allocated);
+          scm_allocate_untagged_pointerless (SCM_I_CURRENT_THREAD,
+                                             sizeof (*mapped_elf_images)
+                                             * mapped_elf_images_allocated);
 
         for (n = 0; n < mapped_elf_images_count; n++)
           {
diff --git a/libguile/numbers.c b/libguile/numbers.c
index 0c497655b..d660aa8f6 100644
--- a/libguile/numbers.c
+++ b/libguile/numbers.c
@@ -422,15 +422,13 @@ scm_i_fraction2double (SCM z)
 static SCM
 scm_i_from_double (double val)
 {
-  SCM z;
+  struct scm_t_double *z =
+    scm_allocate_tagged_pointerless (SCM_I_CURRENT_THREAD, sizeof (*z));
 
-  z = SCM_PACK_POINTER
-    (scm_allocate_pointerless (SCM_I_CURRENT_THREAD, sizeof (scm_t_double)));
+  z->type = scm_tc16_real;
+  z->real = val;
 
-  SCM_SET_CELL_TYPE (z, scm_tc16_real);
-  SCM_REAL_VALUE (z) = val;
-
-  return z;
+  return SCM_PACK_POINTER (z);
 }
 
 SCM_PRIMITIVE_GENERIC (scm_exact_p, "exact?", 1, 0, 0, 
@@ -6074,14 +6072,12 @@ SCM_PRIMITIVE_GENERIC (scm_sys_atanh, "atanh", 1, 0, 0,
 SCM
 scm_c_make_rectangular (double re, double im)
 {
-  SCM z;
-
-  z = SCM_PACK_POINTER
-    (scm_allocate_pointerless (SCM_I_CURRENT_THREAD, sizeof (scm_t_complex)));
-  SCM_SET_CELL_TYPE (z, scm_tc16_complex);
-  SCM_COMPLEX_REAL (z) = re;
-  SCM_COMPLEX_IMAG (z) = im;
-  return z;
+  struct scm_t_complex *z =
+    scm_allocate_tagged_pointerless (SCM_I_CURRENT_THREAD, sizeof (*z));
+  z->type = scm_tc16_complex;
+  z->real = re;
+  z->imag = im;
+  return SCM_PACK_POINTER (z);
 }
 
 SCM_DEFINE (scm_make_rectangular, "make-rectangular", 2, 0, 0,
diff --git a/libguile/programs.h b/libguile/programs.h
index 7fcf41672..8f7bab084 100644
--- a/libguile/programs.h
+++ b/libguile/programs.h
@@ -127,8 +127,7 @@ static inline SCM
 scm_i_make_program (const uint32_t *code)
 {
   struct scm_program *ret =
-    scm_allocate_pointerless (SCM_I_CURRENT_THREAD,
-                              sizeof (struct scm_program));
+    scm_allocate_tagged_pointerless (SCM_I_CURRENT_THREAD, sizeof (*ret));
   ret->tag_flags_and_free_variable_count = scm_tc7_program;
   ret->code = code;
   return scm_from_program (ret);
diff --git a/libguile/random.c b/libguile/random.c
index 09c7ab6cf..1e663d4da 100644
--- a/libguile/random.c
+++ b/libguile/random.c
@@ -137,8 +137,8 @@ scm_i_copy_rstate (scm_t_rstate *state)
 {
   scm_t_rstate *new_state;
 
-  new_state = scm_allocate_pointerless (SCM_I_CURRENT_THREAD,
-                                        state->rng->rstate_size);
+  new_state = scm_allocate_tagged_pointerless (SCM_I_CURRENT_THREAD,
+                                               state->rng->rstate_size);
   return memcpy (new_state, state, state->rng->rstate_size);
 }
 
@@ -183,8 +183,8 @@ scm_c_make_rstate (const char *seed, int n)
 {
   scm_t_rstate *state;
 
-  state = scm_allocate_pointerless (SCM_I_CURRENT_THREAD,
-                                    scm_the_rng.rstate_size);
+  state = scm_allocate_tagged_pointerless (SCM_I_CURRENT_THREAD,
+                                           scm_the_rng.rstate_size);
   state->tag = scm_tc16_random_state;
   state->rng = &scm_the_rng;
   state->normal_next = 0.0;
@@ -197,8 +197,8 @@ scm_c_rstate_from_datum (SCM datum)
 {
   scm_t_rstate *state;
 
-  state = scm_allocate_pointerless (SCM_I_CURRENT_THREAD,
-                                    scm_the_rng.rstate_size);
+  state = scm_allocate_tagged_pointerless (SCM_I_CURRENT_THREAD,
+                                           scm_the_rng.rstate_size);
   state->tag = scm_tc16_random_state;
   state->rng = &scm_the_rng;
   state->normal_next = 0.0;
diff --git a/libguile/read.c b/libguile/read.c
index b64984c89..95a57c82b 100644
--- a/libguile/read.c
+++ b/libguile/read.c
@@ -234,16 +234,17 @@ read_complete_token (SCM port, char *buffer, size_t 
buffer_size, size_t *read)
         {
           if (overflow_size == 0)
             {
-              overflow_buffer = scm_allocate_pointerless (SCM_I_CURRENT_THREAD,
-                                                          bytes_read);
+              overflow_buffer =
+                scm_allocate_untagged_pointerless (SCM_I_CURRENT_THREAD,
+                                                   bytes_read);
               memcpy (overflow_buffer, buffer, bytes_read);
               overflow_size = bytes_read;
             }
           else
             {
              char *new_buf =
-               scm_allocate_pointerless (SCM_I_CURRENT_THREAD,
-                                          overflow_size + bytes_read);
+               scm_allocate_untagged_pointerless (SCM_I_CURRENT_THREAD,
+                                                   overflow_size + bytes_read);
 
              memcpy (new_buf, overflow_buffer, overflow_size);
               memcpy (new_buf + overflow_size, buffer, bytes_read);
diff --git a/libguile/regex-posix.c b/libguile/regex-posix.c
index 98cee5315..06db4e2b4 100644
--- a/libguile/regex-posix.c
+++ b/libguile/regex-posix.c
@@ -153,8 +153,7 @@ SCM_DEFINE_STATIC (make_regexp, "make-regexp", 1, 0, 1,
       flag = SCM_CDR (flag);
     }
 
-  rx = scm_allocate_pointerless (SCM_I_CURRENT_THREAD,
-                                 sizeof (*rx));
+  rx = scm_allocate_tagged_pointerless (SCM_I_CURRENT_THREAD, sizeof (*rx));
   rx->tag = scm_tc16_regexp;
   c_pat = scm_to_locale_string (pat);
   status = regcomp (&rx->regex, c_pat,
diff --git a/libguile/smob.c b/libguile/smob.c
index e1f895491..ad9a68ae7 100644
--- a/libguile/smob.c
+++ b/libguile/smob.c
@@ -308,7 +308,7 @@ scm_new_smob (scm_t_bits tc, scm_t_bits data)
       uint32_t all_fields_unmanaged = -1;
       all_fields_unmanaged >>= 32 - desc->field_count;
       if (desc->unmanaged_fields == all_fields_unmanaged)
-        ret = scm_allocate_pointerless (thr, sz);
+        ret = scm_allocate_tagged_pointerless (thr, sz);
       else
         ret = scm_allocate_tagged (thr, sz);
     }
@@ -345,7 +345,7 @@ scm_new_double_smob (scm_t_bits tc, scm_t_bits data1,
       uint32_t all_fields_unmanaged = -1;
       all_fields_unmanaged >>= 32 - desc->field_count;
       if (desc->unmanaged_fields == all_fields_unmanaged)
-        ret = scm_allocate_pointerless (thr, sz);
+        ret = scm_allocate_tagged_pointerless (thr, sz);
       else
         ret = scm_allocate_tagged (thr, sz);
     }
diff --git a/libguile/strings.c b/libguile/strings.c
index ef2dfef37..f83d986c1 100644
--- a/libguile/strings.c
+++ b/libguile/strings.c
@@ -199,7 +199,8 @@ make_narrow_stringbuf (size_t len)
     return (struct scm_narrow_stringbuf *) &null_stringbuf;
 
   struct scm_narrow_stringbuf *buf =
-    scm_allocate_pointerless (SCM_I_CURRENT_THREAD, sizeof (*buf) + len + 1);
+    scm_allocate_tagged_pointerless (SCM_I_CURRENT_THREAD,
+                                     sizeof (*buf) + len + 1);
   buf->header.tag_and_flags = scm_tc7_stringbuf;
   buf->header.length = len;
 
@@ -222,8 +223,9 @@ make_wide_stringbuf (size_t len)
     scm_out_of_range ("make_stringbuf", scm_from_size_t (len));
 
   struct scm_wide_stringbuf *buf =
-    scm_allocate_pointerless (SCM_I_CURRENT_THREAD,
-                              sizeof (*buf) + (len + 1) * sizeof 
(scm_t_wchar));
+    scm_allocate_tagged_pointerless (SCM_I_CURRENT_THREAD,
+                                     sizeof (*buf)
+                                     + (len + 1) * sizeof (scm_t_wchar));
   buf->header.tag_and_flags = scm_tc7_stringbuf | SCM_I_STRINGBUF_F_WIDE;
   buf->header.length = len;
 
@@ -1513,7 +1515,7 @@ decoding_error (const char *func_name, int errno_save,
   SCM bv;
   signed char *buf;
 
-  buf = scm_allocate_pointerless (SCM_I_CURRENT_THREAD, len);
+  buf = scm_allocate_untagged_pointerless (SCM_I_CURRENT_THREAD, len);
   memcpy (buf, str, len);
   bv = scm_c_take_gc_bytevector (buf, len, SCM_BOOL_F);
 
diff --git a/libguile/vm.c b/libguile/vm.c
index 16867a2a8..3820310ac 100644
--- a/libguile/vm.c
+++ b/libguile/vm.c
@@ -480,7 +480,7 @@ define_vm_builtins (void)
     size_t sz = sizeof (builtin##_code);                                \
     vm_builtin_##builtin##_code = instrumented_code (builtin##_code, sz); \
     struct scm_program *p =                                             \
-      scm_allocate_pointerless (thr, sizeof (struct scm_program));      \
+      scm_allocate_tagged_pointerless (thr, sizeof (*p));               \
     scm_t_bits tag = scm_tc7_program | SCM_F_PROGRAM_IS_PRIMITIVE;      \
     p->tag_flags_and_free_variable_count = tag;                         \
     p->code = vm_builtin_##builtin##_code;                              \

Reply via email to