~ chicken-core (chicken-5) 08f30102f3ec998a7372861b6ca52ab44db6c4d9


commit 08f30102f3ec998a7372861b6ca52ab44db6c4d9
Author:     Peter Bex <peter@more-magic.net>
AuthorDate: Fri Jun 30 21:39:04 2017 +0200
Commit:     Evan Hanson <evhan@foldling.org>
CommitDate: Mon Jul 17 10:29:24 2017 +1200

    Simplify forwarding pointer wrapping/unwrapping
    
    The original version would take the high bit and put it in the low
    bit, clobbering what was there.  That's okay because pointers are
    word-aligned so they won't have their lowest bit set anyway.
    
    Then the high bit would be set to mark the header as a forwarding
    pointer.  But a much simpler way of achieving the same is to simply
    shift right by one and set the high bit.
    
    Signed-off-by: Evan Hanson <evhan@foldling.org>

diff --git a/runtime.c b/runtime.c
index e93026e3..b40e3ba4 100644
--- a/runtime.c
+++ b/runtime.c
@@ -193,7 +193,6 @@ static C_TLS int timezone;
 /* Constants: */
 
 #ifdef C_SIXTY_FOUR
-# define FORWARDING_BIT_SHIFT          63
 # ifdef C_LLP
 #  define ALIGNMENT_HOLE_MARKER         ((C_word)0xfffffffffffffffeLL)
 #  define UWORD_FORMAT_STRING           "0x%016llx"
@@ -205,7 +204,6 @@ static C_TLS int timezone;
 # endif
 #else
 # define ALIGNMENT_HOLE_MARKER         ((C_word)0xfffffffe)
-# define FORWARDING_BIT_SHIFT          31
 # define UWORD_FORMAT_STRING           "0x%08x"
 # define UWORD_COUNT_FORMAT_STRING     "%u"
 #endif
@@ -242,9 +240,13 @@ static C_TLS int timezone;
 #define C_uhword_set(x, p, d)        (C_uhword_ref(x,p) = (d))
 
 #define free_tmp_bignum(b)           C_free((void *)(b))
+
+/* Forwarding pointers abuse the fact that objects must be
+ * word-aligned, so we can just drop the lowest bit.
+ */
 #define is_fptr(x)                   (((x) & C_GC_FORWARDING_BIT) != 0)
-#define ptr_to_fptr(x)               ((((x) >> FORWARDING_BIT_SHIFT) & 1) | C_GC_FORWARDING_BIT | ((x) & ~1))
-#define fptr_to_ptr(x)               (((C_uword)(x) << FORWARDING_BIT_SHIFT) | ((x) & ~(C_GC_FORWARDING_BIT | 1)))
+#define ptr_to_fptr(x)               (((C_uword)(x) >> 1) | C_GC_FORWARDING_BIT)
+#define fptr_to_ptr(x)               ((C_uword)(x) << 1)
 
 #define C_check_real(x, w, v)       if(((x) & C_FIXNUM_BIT) != 0) v = C_unfix(x); \
                                      else if(C_immediatep(x) || C_block_header(x) != C_FLONUM_TAG) \
Trap