~ chicken-core (chicken-5) f2315e8e883b0db3e22292727bc6e6eba8c103da


commit f2315e8e883b0db3e22292727bc6e6eba8c103da
Author:     Peter Bex <peter@more-magic.net>
AuthorDate: Sun Feb 22 15:44:05 2015 +0100
Commit:     Peter Bex <peter@more-magic.net>
CommitDate: Sun May 31 14:55:23 2015 +0200

    Convert bignum representation to be a string wrapped in a structure.
    
    This is exactly the same representation as the numbers egg uses.  This
    will allow us to store the data block in a different place in memory.

diff --git a/c-backend.scm b/c-backend.scm
index 0ef353b0..f010355a 100644
--- a/c-backend.scm
+++ b/c-backend.scm
@@ -681,9 +681,9 @@
 
     (define (literal-size lit)
       (cond ((immediate? lit) 0)
-	    ((big-fixnum? lit) 0)       ; immediate or statically allocated
+	    ((big-fixnum? lit) 3)       ; immediate if fixnum, bignum see below
 	    ((string? lit) 0)		; statically allocated
-	    ((bignum? lit) 0)		; statically allocated
+	    ((bignum? lit) 3)		; internal vector statically allocated
 	    ((flonum? lit) words-per-flonum)
 	    ((symbol? lit) 10)          ; size of symbol, and possibly a bucket
 	    ((pair? lit) (+ 3 (literal-size (car lit)) (literal-size (cdr lit))))
@@ -1435,9 +1435,12 @@ return((C_header_bits(lit) >> 24) & 0xff);
 	 ((exact-integer? lit)
 	  ;; Encode as hex to save space and get exact size
 	  ;; calculation.  We could encode as base 32 to save more
-	  ;; space, but that makes debugging harder.
+	  ;; space, but that makes debugging harder.  The type tag is
+	  ;; a bit of a hack: we encode as "GC forwarded" string to
+	  ;; get a unique new type, as bignums don't have their own
+	  ;; type tag (they're encoded as structures).
 	  (let ((str (number->string lit 16)))
-	    (string-append "\x46" (encode-size (string-length str)) str)))
+	    (string-append "\xc2" (encode-size (string-length str)) str)))
 	 ((flonum? lit)
 	  (string-append "\x55" (number->string lit) "\x00") )
 	 ((symbol? lit)
diff --git a/chicken.h b/chicken.h
index df145825..d470d9af 100644
--- a/chicken.h
+++ b/chicken.h
@@ -470,7 +470,7 @@ static inline int isinf_ld (long double x)
 # define C_PAIR_TYPE              (0x0300000000000000L)
 # define C_CLOSURE_TYPE           (0x0400000000000000L | C_SPECIALBLOCK_BIT)
 # define C_FLONUM_TYPE            (0x0500000000000000L | C_BYTEBLOCK_BIT | C_8ALIGN_BIT)
-# define C_BIGNUM_TYPE            (0x0600000000000000L | C_BYTEBLOCK_BIT)
+/*       unused                   (0x0600000000000000L ...) */
 # define C_PORT_TYPE              (0x0700000000000000L | C_SPECIALBLOCK_BIT)
 # define C_STRUCTURE_TYPE         (0x0800000000000000L)
 # define C_POINTER_TYPE           (0x0900000000000000L | C_SPECIALBLOCK_BIT)
@@ -500,7 +500,7 @@ static inline int isinf_ld (long double x)
 # else
 #  define C_FLONUM_TYPE           (0x05000000 | C_BYTEBLOCK_BIT | C_8ALIGN_BIT)
 # endif
-# define C_BIGNUM_TYPE            (0x06000000 | C_BYTEBLOCK_BIT)
+/*       unused                   (0x06000000 ...) */
 # define C_PORT_TYPE              (0x07000000 | C_SPECIALBLOCK_BIT)
 # define C_STRUCTURE_TYPE         (0x08000000)
 # define C_POINTER_TYPE           (0x09000000 | C_SPECIALBLOCK_BIT)
@@ -533,9 +533,12 @@ static inline int isinf_ld (long double x)
 #define C_SIZEOF_PORT             16
 #define C_SIZEOF_STRUCTURE(n)     ((n)+1)
 #define C_SIZEOF_CLOSURE(n)       ((n)+1)
-#define C_SIZEOF_BIGNUM(n)        ((n)+2)
+#define C_SIZEOF_INTERNAL_BIGNUM_VECTOR(n) (C_SIZEOF_VECTOR((n)+1))
+#define C_internal_bignum_vector(b)        (C_block_item(b,1))
+
 /* This is for convenience and allows flexibility in representation */
 #define C_SIZEOF_FIX_BIGNUM       C_SIZEOF_BIGNUM(1)
+#define C_SIZEOF_BIGNUM(n)        (C_SIZEOF_INTERNAL_BIGNUM_VECTOR(n)+C_SIZEOF_STRUCTURE(2))
 
 /* Fixed size types have pre-computed header tags */
 #define C_PAIR_TAG                (C_PAIR_TYPE | (C_SIZEOF_PAIR - 1))
@@ -546,6 +549,7 @@ static inline int isinf_ld (long double x)
 #define C_SYMBOL_TAG              (C_SYMBOL_TYPE | (C_SIZEOF_SYMBOL - 1))
 #define C_FLONUM_TAG              (C_FLONUM_TYPE | sizeof(double))
 #define C_STRUCTURE3_TAG          (C_STRUCTURE_TYPE | 3)
+#define C_STRUCTURE2_TAG          (C_STRUCTURE_TYPE | 2)
 
 /* Locative subtypes */
 #define C_SLOT_LOCATIVE           0
@@ -1117,7 +1121,7 @@ extern double trunc(double);
 #define C_set_block_item(x,i,y)    (C_block_item(x, i) = (y))
 #define C_header_bits(bh)          (C_block_header(bh) & C_HEADER_BITS_MASK)
 #define C_header_size(bh)          (C_block_header(bh) & C_HEADER_SIZE_MASK)
-#define C_bignum_size(b)           (C_bytestowords(C_header_size(b))-1)
+#define C_bignum_size(b)           (C_bytestowords(C_header_size(C_internal_bignum_vector(b)))-1)
 #define C_make_header(type, size)  ((C_header)(((type) & C_HEADER_BITS_MASK) | ((size) & C_HEADER_SIZE_MASK)))
 #define C_symbol_value(x)          (C_block_item(x, 0))
 #define C_save(x)	           (*(--C_temporary_stack) = (C_word)(x))
@@ -1159,11 +1163,11 @@ extern double trunc(double);
 #define C_mk_nbool(x)              ((x) ? C_SCHEME_FALSE : C_SCHEME_TRUE)
 #define C_port_file(p)             C_CHECKp(p,C_portp(C_VAL1(p)),(C_FILEPTR)C_block_item(C_VAL1(p), 0))
 #define C_data_pointer(b)          C_CHECKp(b,C_blockp((C_word)C_VAL1(b)),(void *)(((C_SCHEME_BLOCK *)(C_VAL1(b)))->data))
-#define C_bignum_negativep(b)      C_CHECKp(b,C_bignump(C_VAL1(b)),(C_block_item(b,0)!=0))
-#define C_bignum_digits(b)         C_CHECKp(b,C_bignump(C_VAL1(b)),(((C_uword *)C_data_pointer(C_VAL1(b)))+1))
+#define C_bignum_negativep(b)      C_CHECKp(b,C_bignump(C_VAL1(b)),(C_block_item(C_internal_bignum_vector(C_VAL1(b)),0)!=0))
+#define C_bignum_digits(b)         C_CHECKp(b,C_bignump(C_VAL1(b)),(((C_uword *)C_data_pointer(C_internal_bignum_vector(C_VAL1(b))))+1))
 #define C_fitsinbignumhalfdigitp(n)(C_BIGNUM_DIGIT_HI_HALF(n) == 0)
 #define C_bignum_negated_fitsinfixnump(b) (C_bignum_size(b) == 1 && (C_bignum_negativep(b) ? C_ufitsinfixnump(*C_bignum_digits(b)) : !(*C_bignum_digits(b) & C_INT_SIGN_BIT) && C_fitsinfixnump(-(C_word)*C_bignum_digits(b))))
-#define C_bignum_mutate_size(b,s)  (C_block_header(b) = (C_BIGNUM_TYPE | C_wordstobytes((s)+1)))
+#define C_bignum_mutate_size(b, s) (C_block_header(C_internal_bignum_vector(b)) = (C_STRING_TYPE | C_wordstobytes((s)+1)))
 #define C_fitsinfixnump(n)         (((n) & C_INT_SIGN_BIT) == (((n) & C_INT_TOP_BIT) << 1))
 #define C_ufitsinfixnump(n)        (((n) & (C_INT_SIGN_BIT | (C_INT_SIGN_BIT >> 1))) == 0)
 #define C_and(x, y)                (C_truep(x) ? (y) : C_SCHEME_FALSE)
@@ -1236,7 +1240,7 @@ extern double trunc(double);
 #define C_forwardedp(x)           C_mk_bool((C_block_header(x) & C_GC_FORWARDING_BIT) != 0)
 #define C_immp(x)                 C_mk_bool(C_immediatep(x))
 #define C_flonump(x)              C_mk_bool(C_block_header(x) == C_FLONUM_TAG)
-#define C_bignump(x)              C_mk_bool(C_header_bits(x) == C_BIGNUM_TYPE)
+#define C_bignump(x)              C_mk_bool(C_block_header(x) == C_STRUCTURE2_TAG && C_block_item(x, 0) == C_bignum_type_tag)
 #define C_stringp(x)              C_mk_bool(C_header_bits(x) == C_STRING_TYPE)
 #define C_symbolp(x)              C_mk_bool(C_block_header(x) == C_SYMBOL_TAG)
 #define C_pairp(x)                C_mk_bool(C_block_header(x) == C_PAIR_TAG)
@@ -1752,6 +1756,7 @@ C_varextern C_TLS C_word
   *C_temporary_stack_bottom,
   *C_temporary_stack_limit,
   *C_stack_limit,
+   C_bignum_type_tag,
    C_ratnum_type_tag,
    C_cplxnum_type_tag;
 C_varextern C_TLS C_long
@@ -2293,29 +2298,147 @@ C_inline C_word C_double_to_number(C_word n)
   else return n;
 }
 
+C_inline C_word C_a_i_record1(C_word **ptr, int n, C_word x1)
+{
+  C_word *p = *ptr, *p0 = p; 
+
+  *(p++) = C_STRUCTURE_TYPE | 1;
+  *(p++) = x1;
+  *ptr = p;
+  return (C_word)p0;
+}
+
+
+C_inline C_word C_a_i_record2(C_word **ptr, int n, C_word x1, C_word x2)
+{
+  C_word *p = *ptr, *p0 = p; 
+
+  *(p++) = C_STRUCTURE_TYPE | 2;
+  *(p++) = x1;
+  *(p++) = x2;
+  *ptr = p;
+  return (C_word)p0;
+}
+
+
+C_inline C_word C_a_i_record3(C_word **ptr, int n, C_word x1, C_word x2, C_word x3)
+{
+  C_word *p = *ptr, *p0 = p; 
+
+  *(p++) = C_STRUCTURE_TYPE | 3;
+  *(p++) = x1;
+  *(p++) = x2;
+  *(p++) = x3;
+  *ptr = p;
+  return (C_word)p0;
+}
+
+
+C_inline C_word C_a_i_record4(C_word **ptr, int n, C_word x1, C_word x2, C_word x3, C_word x4)
+{
+  C_word *p = *ptr, *p0 = p; 
+
+  *(p++) = C_STRUCTURE_TYPE | 4;
+  *(p++) = x1;
+  *(p++) = x2;
+  *(p++) = x3;
+  *(p++) = x4;
+  *ptr = p;
+  return (C_word)p0;
+}
+
+
+C_inline C_word C_a_i_record5(C_word **ptr, int n, C_word x1, C_word x2, C_word x3, C_word x4,
+				 C_word x5)
+{
+  C_word *p = *ptr, *p0 = p; 
+
+  *(p++) = C_STRUCTURE_TYPE | 5;
+  *(p++) = x1;
+  *(p++) = x2;
+  *(p++) = x3;
+  *(p++) = x4;
+  *(p++) = x5;
+  *ptr = p;
+  return (C_word)p0;
+}
+
+
+C_inline C_word C_a_i_record6(C_word **ptr, int n, C_word x1, C_word x2, C_word x3, C_word x4,
+				 C_word x5, C_word x6)
+{
+  C_word *p = *ptr, *p0 = p; 
+
+  *(p++) = C_STRUCTURE_TYPE | 6;
+  *(p++) = x1;
+  *(p++) = x2;
+  *(p++) = x3;
+  *(p++) = x4;
+  *(p++) = x5;
+  *(p++) = x6;
+  *ptr = p;
+  return (C_word)p0;
+}
+
+
+C_inline C_word C_a_i_record7(C_word **ptr, int n, C_word x1, C_word x2, C_word x3, C_word x4,
+				 C_word x5, C_word x6, C_word x7)
+{
+  C_word *p = *ptr, *p0 = p; 
+
+  *(p++) = C_STRUCTURE_TYPE | 7;
+  *(p++) = x1;
+  *(p++) = x2;
+  *(p++) = x3;
+  *(p++) = x4;
+  *(p++) = x5;
+  *(p++) = x6;
+  *(p++) = x7;
+  *ptr = p;
+  return (C_word)p0;
+}
+
+
+C_inline C_word C_a_i_record8(C_word **ptr, int n, C_word x1, C_word x2, C_word x3, C_word x4,
+				 C_word x5, C_word x6, C_word x7, C_word x8)
+{
+  C_word *p = *ptr, *p0 = p; 
+
+  *(p++) = C_STRUCTURE_TYPE | 8;
+  *(p++) = x1;
+  *(p++) = x2;
+  *(p++) = x3;
+  *(p++) = x4;
+  *(p++) = x5;
+  *(p++) = x6;
+  *(p++) = x7;
+  *(p++) = x8;
+  *ptr = p;
+  return (C_word)p0;
+}
+
 /* Silly (this is not normalized) but in some cases needed internally */
 C_inline C_word C_bignum0(C_word **ptr)
 {
   C_word *p = *ptr, p0 = (C_word)p;
 
-  /* Not using C_a_i_vector4, to make it easier to rewrite later */
-  *(p++) = C_BIGNUM_TYPE | C_wordstobytes(1);
+  *(p++) = C_STRING_TYPE | C_wordstobytes(1);
   *(p++) = 0; /* zero is always positive */
   *ptr = p;
 
-  return p0;
+  return C_a_i_record2(ptr, 2, C_bignum_type_tag, p0);
 }
 
 C_inline C_word C_bignum1(C_word **ptr, int negp, C_uword d1)
 {
   C_word *p = *ptr, p0 = (C_word)p;
 
-  *(p++) = C_BIGNUM_TYPE | C_wordstobytes(2);
+  *(p++) = C_STRING_TYPE | C_wordstobytes(2);
   *(p++) = negp;
   *(p++) = d1;
   *ptr = p;
 
-  return p0;
+  return C_a_i_record2(ptr, 2, C_bignum_type_tag, p0);
 }
 
 /* Here d1, d2, ... are low to high (ie, little endian)! */
@@ -2323,15 +2446,23 @@ C_inline C_word C_bignum2(C_word **ptr, int negp, C_uword d1, C_uword d2)
 {
   C_word *p = *ptr, p0 = (C_word)p;
 
-  *(p++) = C_BIGNUM_TYPE | C_wordstobytes(3);
+  *(p++) = C_STRING_TYPE | C_wordstobytes(3);
   *(p++) = negp;
   *(p++) = d1;
   *(p++) = d2;
   *ptr = p;
 
-  return p0;
+  return C_a_i_record2(ptr, 2, C_bignum_type_tag, p0);
 }
 
+C_inline C_word C_i_bignump(C_word x)
+{
+  return C_mk_bool(!C_immediatep(x) &&
+                   C_block_header(x) == C_STRUCTURE2_TAG &&
+                   C_block_item(x, 0) == C_bignum_type_tag);
+}
+
+
 
 /* XXX TODO OBSOLETE: This can be removed after recompiling c-platform.scm */
 C_inline C_word C_fits_in_int_p(C_word x)
@@ -2340,7 +2471,7 @@ C_inline C_word C_fits_in_int_p(C_word x)
 
   if(x & C_FIXNUM_BIT) return C_SCHEME_TRUE;
 
-  if(!C_immediatep(x) && C_header_bits(x) == C_BIGNUM_TYPE) {
+  if(C_truep(C_i_bignump(x))) {
     return C_mk_bool(C_bignum_size(x) == 1 &&
                      (!C_bignum_negativep(x) ||
                       !(C_bignum_digits(x)[0] & C_INT_SIGN_BIT)));
@@ -2357,10 +2488,7 @@ C_inline C_word C_fits_in_unsigned_int_p(C_word x)
   double n, m;
 
   if(x & C_FIXNUM_BIT) return C_SCHEME_TRUE;
-
-  if(!C_immediatep(x) && C_header_bits(x) == C_BIGNUM_TYPE) {
-    return C_mk_bool(C_bignum_size(x) == 1);
-  }
+  if(C_truep(C_i_bignump(x))) return C_mk_bool(C_bignum_size(x) == 1);
 
   /* XXX OBSOLETE remove on the next round, remove check above */
   n = C_flonum_magnitude(x);
@@ -2384,7 +2512,7 @@ C_inline C_word C_num_to_int(C_word x)
 {
   if(x & C_FIXNUM_BIT) {
     return C_unfix(x);
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     if (C_bignum_negativep(x)) return -(C_word)C_bignum_digits(x)[0];
     else return (C_word)C_bignum_digits(x)[0];  /* should never be larger */
   } else {
@@ -2398,7 +2526,7 @@ C_inline C_s64 C_num_to_int64(C_word x)
 {
   if(x & C_FIXNUM_BIT) {
     return (C_s64)C_unfix(x);
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     C_s64 num = C_bignum_digits(x)[0];
 #ifndef C_SIXTY_FOUR
     if (C_bignum_size(x) > 1) num |= ((C_s64)C_bignum_digits(x)[1]) << 32;
@@ -2416,7 +2544,7 @@ C_inline C_u64 C_num_to_uint64(C_word x)
 {
   if(x & C_FIXNUM_BIT) {
     return (C_u64)C_unfix(x);
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     C_u64 num = C_bignum_digits(x)[0];
 #ifndef C_SIXTY_FOUR
     if (C_bignum_size(x) > 1) num |= ((C_u64)C_bignum_digits(x)[1]) << 32;
@@ -2433,7 +2561,7 @@ C_inline C_uword C_num_to_unsigned_int(C_word x)
 {
   if(x & C_FIXNUM_BIT) {
     return (C_uword)C_unfix(x);
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     return C_bignum_digits(x)[0]; /* should never be larger */
   } else {
     /* XXX OBSOLETE remove on the next round, remove check above */
@@ -2577,8 +2705,10 @@ C_inline C_word basic_eqvp(C_word x, C_word y)
            
            ((C_block_header(x) == C_FLONUM_TAG &&
              C_flonum_magnitude(x) == C_flonum_magnitude(y)) ||
-            
-            (C_header_bits(x) == C_BIGNUM_TYPE &&
+
+            (C_block_header(x) == C_STRUCTURE2_TAG &&
+             C_block_item(x, 0) == C_bignum_type_tag &&
+             C_block_item(y, 0) == C_bignum_type_tag &&
              C_i_bignum_cmp(x, y) == C_fix(0)))));
 }
 
@@ -2636,17 +2766,12 @@ C_inline C_word C_i_closurep(C_word x)
   return C_mk_bool(!C_immediatep(x) && C_header_bits(x) == C_CLOSURE_TYPE);
 }
 
-C_inline C_word C_i_bignump(C_word x)
-{
-  return C_mk_bool(!C_immediatep(x) && C_header_bits(x) == C_BIGNUM_TYPE);
-}
-
 C_inline C_word C_i_numberp(C_word x)
 {
   return C_mk_bool((x & C_FIXNUM_BIT) ||
                    (!C_immediatep(x) && 
                     (C_block_header(x) == C_FLONUM_TAG ||
-                     C_header_bits(x) == C_BIGNUM_TYPE ||
+                     C_truep(C_bignump(x)) ||
                      (C_block_header(x) == C_STRUCTURE3_TAG &&
                       (C_block_item(x, 0) == C_ratnum_type_tag ||
                        C_block_item(x, 0) == C_cplxnum_type_tag)))));
@@ -2658,8 +2783,8 @@ C_inline C_word C_i_realp(C_word x)
   return C_mk_bool((x & C_FIXNUM_BIT) ||
                    (!C_immediatep(x) && 
                     (C_block_header(x) == C_FLONUM_TAG ||
-                     C_header_bits(x) == C_BIGNUM_TYPE ||
-                     (C_header_bits(x) == C_STRUCTURE_TYPE &&
+                     C_truep(C_bignump(x)) ||
+                     (C_block_header(x) == C_STRUCTURE3_TAG &&
                       C_block_item(x, 0) == C_ratnum_type_tag))));
 }
 
@@ -2674,8 +2799,8 @@ C_inline C_word C_i_rationalp(C_word x)
     double n = C_flonum_magnitude(x);
     return C_mk_bool(!C_isinf(n) && !C_isnan(n));
   } else {
-    return C_mk_bool(C_header_bits(x) == C_BIGNUM_TYPE ||
-                     (C_header_bits(x) == C_STRUCTURE_TYPE &&
+    return C_mk_bool(C_truep(C_bignump(x)) ||
+                     (C_block_header(x) == C_STRUCTURE3_TAG &&
                       C_block_item(x, 0) == C_ratnum_type_tag));
   }
 }
@@ -2702,8 +2827,7 @@ C_inline int C_ub_i_fpintegerp(double x)
 
 C_inline C_word C_i_exact_integerp(C_word x)
 {
-  return C_mk_bool((x) & C_FIXNUM_BIT ||
-                   (!C_immediatep(x) && (C_header_bits(x) == C_BIGNUM_TYPE)));
+  return C_mk_bool((x) & C_FIXNUM_BIT || C_truep(C_i_bignump(x)));
 }
 
 C_inline C_word C_u_i_exactp(C_word x)
@@ -2746,11 +2870,10 @@ C_inline C_word C_i_integerp(C_word x)
 {
   double dummy, val;
 
-  if (x & C_FIXNUM_BIT ||
-      (!C_immediatep(x) && (C_header_bits(x) == C_BIGNUM_TYPE)))
-	  return C_SCHEME_TRUE;
+  if (x & C_FIXNUM_BIT || C_truep(C_i_bignump(x)))
+    return C_SCHEME_TRUE;
   if (C_immediatep(x) || C_block_header(x) != C_FLONUM_TAG)
-	  return C_SCHEME_FALSE;
+    return C_SCHEME_FALSE;
 
   val = C_flonum_magnitude(x);
   if(C_isnan(val) || C_isinf(val)) return C_SCHEME_FALSE;
@@ -3310,125 +3433,6 @@ C_inline C_word C_a_i_list8(C_word **a, int n, C_word x1, C_word x2, C_word x3,
 }
 
 
-C_inline C_word C_a_i_record1(C_word **ptr, int n, C_word x1)
-{
-  C_word *p = *ptr, *p0 = p; 
-
-  *(p++) = C_STRUCTURE_TYPE | 1;
-  *(p++) = x1;
-  *ptr = p;
-  return (C_word)p0;
-}
-
-
-C_inline C_word C_a_i_record2(C_word **ptr, int n, C_word x1, C_word x2)
-{
-  C_word *p = *ptr, *p0 = p; 
-
-  *(p++) = C_STRUCTURE_TYPE | 2;
-  *(p++) = x1;
-  *(p++) = x2;
-  *ptr = p;
-  return (C_word)p0;
-}
-
-
-C_inline C_word C_a_i_record3(C_word **ptr, int n, C_word x1, C_word x2, C_word x3)
-{
-  C_word *p = *ptr, *p0 = p; 
-
-  *(p++) = C_STRUCTURE_TYPE | 3;
-  *(p++) = x1;
-  *(p++) = x2;
-  *(p++) = x3;
-  *ptr = p;
-  return (C_word)p0;
-}
-
-
-C_inline C_word C_a_i_record4(C_word **ptr, int n, C_word x1, C_word x2, C_word x3, C_word x4)
-{
-  C_word *p = *ptr, *p0 = p; 
-
-  *(p++) = C_STRUCTURE_TYPE | 4;
-  *(p++) = x1;
-  *(p++) = x2;
-  *(p++) = x3;
-  *(p++) = x4;
-  *ptr = p;
-  return (C_word)p0;
-}
-
-
-C_inline C_word C_a_i_record5(C_word **ptr, int n, C_word x1, C_word x2, C_word x3, C_word x4,
-				 C_word x5)
-{
-  C_word *p = *ptr, *p0 = p; 
-
-  *(p++) = C_STRUCTURE_TYPE | 5;
-  *(p++) = x1;
-  *(p++) = x2;
-  *(p++) = x3;
-  *(p++) = x4;
-  *(p++) = x5;
-  *ptr = p;
-  return (C_word)p0;
-}
-
-
-C_inline C_word C_a_i_record6(C_word **ptr, int n, C_word x1, C_word x2, C_word x3, C_word x4,
-				 C_word x5, C_word x6)
-{
-  C_word *p = *ptr, *p0 = p; 
-
-  *(p++) = C_STRUCTURE_TYPE | 6;
-  *(p++) = x1;
-  *(p++) = x2;
-  *(p++) = x3;
-  *(p++) = x4;
-  *(p++) = x5;
-  *(p++) = x6;
-  *ptr = p;
-  return (C_word)p0;
-}
-
-
-C_inline C_word C_a_i_record7(C_word **ptr, int n, C_word x1, C_word x2, C_word x3, C_word x4,
-				 C_word x5, C_word x6, C_word x7)
-{
-  C_word *p = *ptr, *p0 = p; 
-
-  *(p++) = C_STRUCTURE_TYPE | 7;
-  *(p++) = x1;
-  *(p++) = x2;
-  *(p++) = x3;
-  *(p++) = x4;
-  *(p++) = x5;
-  *(p++) = x6;
-  *(p++) = x7;
-  *ptr = p;
-  return (C_word)p0;
-}
-
-
-C_inline C_word C_a_i_record8(C_word **ptr, int n, C_word x1, C_word x2, C_word x3, C_word x4,
-				 C_word x5, C_word x6, C_word x7, C_word x8)
-{
-  C_word *p = *ptr, *p0 = p; 
-
-  *(p++) = C_STRUCTURE_TYPE | 8;
-  *(p++) = x1;
-  *(p++) = x2;
-  *(p++) = x3;
-  *(p++) = x4;
-  *(p++) = x5;
-  *(p++) = x6;
-  *(p++) = x7;
-  *(p++) = x8;
-  *ptr = p;
-  return (C_word)p0;
-}
-
 /*
  * From Hacker's Delight by Henry S. Warren
  * based on a modified nlz() from section 5-3 (fig. 5-7)
diff --git a/library.scm b/library.scm
index e1d83657..35da3b7f 100644
--- a/library.scm
+++ b/library.scm
@@ -199,7 +199,7 @@ EOF
 (define return-to-host (##core#primitive "C_return_to_host"))
 (define ##sys#symbol-table-info (##core#primitive "C_get_symbol_table_info"))
 (define ##sys#memory-info (##core#primitive "C_get_memory_info"))
-(define (current-milliseconds) (##core#inline_allocate ("C_a_i_current_milliseconds" 4) #f))
+(define (current-milliseconds) (##core#inline_allocate ("C_a_i_current_milliseconds" 7) #f))
 (define (current-gc-milliseconds) (##sys#fudge 31))
 (define ##sys#decode-seconds (##core#primitive "C_decode_seconds"))
 (define get-environment-variable (foreign-lambda c-string "C_getenv" c-string))
@@ -232,7 +232,7 @@ EOF
   (##sys#setslot x i y) )
 
 (define (current-seconds) 
-  (##core#inline_allocate ("C_a_get_current_seconds" 4) #f))
+  (##core#inline_allocate ("C_a_get_current_seconds" 7) #f))
 
 (define cpu-time
   (let ((buf (vector #f #f)))
@@ -5456,7 +5456,7 @@ EOF
 (define (##sys#bytevector? x) (##core#inline "C_bytevectorp" x))
 (define (##sys#string->pbytevector s) (##core#inline "C_string_to_pbytevector" s))
 (define (##sys#permanent? x) (##core#inline "C_permanentp" x))
-(define (##sys#block-address x) (##core#inline_allocate ("C_block_address" 4) x))
+(define (##sys#block-address x) (##core#inline_allocate ("C_block_address" 6) x))
 (define (##sys#locative? x) (##core#inline "C_locativep" x))
 (define (##sys#srfi-4-vector? x)
   (and (##core#inline "C_blockp" x)
@@ -5478,8 +5478,8 @@ EOF
     ptr) )
 
 (define (##sys#pointer->address ptr)
-  ;;XXX '4' is platform dependent!
-  (##core#inline_allocate ("C_a_unsigned_int_to_num" 4) (##sys#slot ptr 0)) )
+  ;;XXX '6' is platform dependent!
+  (##core#inline_allocate ("C_a_unsigned_int_to_num" 6) (##sys#slot ptr 0)) )
 
 (define (##sys#make-c-string str #!optional (loc '##sys#make-c-string))
   (let* ([len (##sys#size str)]
diff --git a/lolevel.scm b/lolevel.scm
index 159e2ab6..ededa8fc 100644
--- a/lolevel.scm
+++ b/lolevel.scm
@@ -347,25 +347,25 @@ EOF
 
 (define pointer-u32-ref
   (getter-with-setter
-   (lambda (p) (##core#inline_allocate ("C_a_u_i_pointer_u32_ref" 3) p)) ;XXX hardcoded size
+   (lambda (p) (##core#inline_allocate ("C_a_u_i_pointer_u32_ref" 6) p)) ;XXX hardcoded size
    pointer-u32-set!
    "(pointer-u32-ref p)"))
 
 (define pointer-s32-ref
   (getter-with-setter
-   (lambda (p) (##core#inline_allocate ("C_a_u_i_pointer_s32_ref" 3) p)) ;XXX hardcoded size
+   (lambda (p) (##core#inline_allocate ("C_a_u_i_pointer_s32_ref" 6) p)) ;XXX hardcoded size
    pointer-s32-set!
    "(pointer-s32-ref p)"))
 
 (define pointer-u64-ref
   (getter-with-setter
-   (lambda (p) (##core#inline_allocate ("C_a_u_i_pointer_u64_ref" 4) p)) ;XXX hardcoded size
+   (lambda (p) (##core#inline_allocate ("C_a_u_i_pointer_u64_ref" 7) p)) ;XXX hardcoded size
    pointer-u64-set!
    "(pointer-u64-ref p)"))
 
 (define pointer-s64-ref
   (getter-with-setter
-   (lambda (p) (##core#inline_allocate ("C_a_u_i_pointer_s64_ref" 4) p)) ;XXX hardcoded size
+   (lambda (p) (##core#inline_allocate ("C_a_u_i_pointer_s64_ref" 7) p)) ;XXX hardcoded size
    pointer-s64-set!
    "(pointer-s64-ref p)"))
 
diff --git a/manual/Data representation b/manual/Data representation
index efc29df7..129e7058 100644
--- a/manual/Data representation	
+++ b/manual/Data representation	
@@ -86,13 +86,6 @@ a flat closure representation is used).
 64 bit architectures) contain a 64-bit floating-point number, in the
 representation used by the host system's C compiler.
 
-'''bignums''': byte-vector objects with type bits {{C_BIGNUM_TYPE}},
-currently 0110.  The first word of the data element contains 0 if the
-number is positive or 1 if it is negative.  The remaining data encodes
-the bignum's digits (sometimes called "bigits" or "limbs"), which are
-accessed as machine words.  The internal byte representation will be
-stored in the endianness of the host machine.
-
 '''ports''': special vector objects with type bits
 {{C_PORT_TYPE}}, currently 0111. The first slot contains a pointer to a file-
 stream, if this is a file-pointer, or NULL if not. The other slots
diff --git a/posix-common.scm b/posix-common.scm
index 65e77b92..b4fc8c7a 100644
--- a/posix-common.scm
+++ b/posix-common.scm
@@ -329,7 +329,7 @@ EOF
    (lambda (port)
      (let ((pos (cond ((port? port)
 		       (if (eq? (##sys#slot port 7) 'stream)
-			   (##core#inline_allocate ("C_ftell" 4) port)
+			   (##core#inline_allocate ("C_ftell" 7) port)
 			   -1) )
 		      ((fixnum? port)
 		       (##core#inline "C_lseek" port 0 _seek_cur) )
@@ -579,7 +579,7 @@ EOF
   (let ((tm-size (foreign-value "sizeof(struct tm)" int)))
     (lambda (tm)
       (check-time-vector 'local-time->seconds tm)
-      (let ((t (##core#inline_allocate ("C_a_mktime" 4) tm (##sys#make-string tm-size #\nul))))
+      (let ((t (##core#inline_allocate ("C_a_mktime" 7) tm (##sys#make-string tm-size #\nul))))
         (if (fp= -1.0 t)
             (##sys#error 'local-time->seconds "cannot convert time vector to seconds" tm)
             t)))))
diff --git a/posixunix.scm b/posixunix.scm
index fa65e1a1..61514e8e 100644
--- a/posixunix.scm
+++ b/posixunix.scm
@@ -1443,7 +1443,7 @@ EOF
   (let ((tm-size (foreign-value "sizeof(struct tm)" int)))
     (lambda (tm)
       (check-time-vector 'utc-time->seconds tm)
-      (let ((t (##core#inline_allocate ("C_a_timegm" 4) tm (##sys#make-string tm-size #\nul))))
+      (let ((t (##core#inline_allocate ("C_a_timegm" 7) tm (##sys#make-string tm-size #\nul))))
         (if (fp= -1.0 t)
             (##sys#error 'utc-time->seconds "cannot convert time vector to seconds" tm)
             t)))))
diff --git a/runtime.c b/runtime.c
index bc8b66f0..bd885e5b 100644
--- a/runtime.c
+++ b/runtime.c
@@ -327,6 +327,7 @@ C_TLS C_word
   *C_temporary_stack_bottom,
   *C_temporary_stack_limit,
   *C_stack_limit,
+   C_bignum_type_tag,
    C_ratnum_type_tag,
    C_cplxnum_type_tag;
 C_TLS C_long
@@ -1084,6 +1085,7 @@ void initialize_symbol_table(void)
   for(i = 0; i < symbol_table->size; symbol_table->table[ i++ ] = C_SCHEME_END_OF_LIST);
 
   /* Obtain reference to hooks for later: */
+  C_bignum_type_tag = C_intern2(C_heaptop, C_text("\003sysbignum"));
   C_ratnum_type_tag = C_intern2(C_heaptop, C_text("\003sysratnum"));
   C_cplxnum_type_tag = C_intern2(C_heaptop, C_text("\003syscplxnum"));
   interrupt_hook_symbol = C_intern2(C_heaptop, C_text("\003sysinterrupt-hook"));
@@ -2542,7 +2544,7 @@ C_regparm C_word C_fcall C_static_string(C_word **ptr, int len, C_char *str)
 
 C_regparm C_word C_fcall C_static_bignum(C_word **ptr, int len, C_char *str)
 {
-  C_word *dptr, bignum, retval, size, negp = 0;
+  C_word *dptr, bignum, bigvec, retval, size, negp = 0;
 
   if (*str == '+' || *str == '-') {
     negp = ((*str++) == '-') ? 1 : 0;
@@ -2550,16 +2552,19 @@ C_regparm C_word C_fcall C_static_bignum(C_word **ptr, int len, C_char *str)
   }
   size = C_BIGNUM_BITS_TO_DIGITS(len << 2);
 
-  dptr = (C_word *)C_malloc(C_wordstobytes(C_SIZEOF_BIGNUM(size)));
+  dptr = (C_word *)C_malloc(C_wordstobytes(C_SIZEOF_INTERNAL_BIGNUM_VECTOR(size)));
   if(dptr == NULL)
     panic(C_text("out of memory - cannot allocate static bignum"));
 
-  bignum = (C_word)dptr;
-  C_block_header_init(bignum, C_BIGNUM_TYPE | C_wordstobytes(size + 1));
-  C_set_block_item(bignum, 0, negp);
+  bigvec = (C_word)dptr;
+  C_block_header_init(bigvec, C_STRING_TYPE | C_wordstobytes(size + 1));
+  C_set_block_item(bigvec, 0, negp);
+  /* This needs to be allocated at ptr, not dptr, because GC moves type tag */
+  bignum = C_a_i_record2(ptr, 2, C_bignum_type_tag, bigvec);
 
   retval = str_to_bignum(bignum, str, str + len, 16);
-  if (retval & C_FIXNUM_BIT) C_free(dptr); /* Might have been simplified */
+  if (retval & C_FIXNUM_BIT)
+    C_free(dptr); /* Might have been simplified */
   return retval;
 }
 
@@ -3244,6 +3249,7 @@ C_regparm void C_fcall C_reclaim(void *trampoline, void *proc)
 
 C_regparm void C_fcall mark_system_globals(void)
 {
+  mark(&C_bignum_type_tag);
   mark(&C_ratnum_type_tag);
   mark(&C_cplxnum_type_tag);
   mark(&interrupt_hook_symbol);
@@ -3584,6 +3590,7 @@ C_regparm void C_fcall C_rereclaim2(C_uword size, int double_plus)
 
 C_regparm void C_fcall remark_system_globals(void)
 {
+  remark(&C_bignum_type_tag);
   remark(&C_ratnum_type_tag);
   remark(&C_cplxnum_type_tag);
   remark(&interrupt_hook_symbol);
@@ -4837,7 +4844,7 @@ C_regparm C_word C_fcall C_i_nanp(C_word x)
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "nan?", x);
   } else if (C_block_header(x) == C_FLONUM_TAG) {
     return C_u_i_flonum_nanp(x);
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     return C_SCHEME_FALSE;
   } else if (C_block_header(x) == C_STRUCTURE3_TAG) {
     if (C_block_item(x, 0) == C_ratnum_type_tag)
@@ -4860,7 +4867,7 @@ C_regparm C_word C_fcall C_i_finitep(C_word x)
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "finite?", x);
   } else if (C_block_header(x) == C_FLONUM_TAG) {
     return C_u_i_flonum_finitep(x);
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     return C_SCHEME_TRUE;
   } else if (C_block_header(x) == C_STRUCTURE3_TAG) {
     if (C_block_item(x, 0) == C_ratnum_type_tag)
@@ -4883,7 +4890,7 @@ C_regparm C_word C_fcall C_i_infinitep(C_word x)
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "infinite?", x);
   } else if (C_block_header(x) == C_FLONUM_TAG) {
     return C_u_i_flonum_infinitep(x);
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     return C_SCHEME_FALSE;
   } else if (C_block_header(x) == C_STRUCTURE3_TAG) {
     if (C_block_item(x, 0) == C_ratnum_type_tag)
@@ -4906,7 +4913,7 @@ C_regparm C_word C_fcall C_i_exactp(C_word x)
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "exact?", x);
   } else if (C_block_header(x) == C_FLONUM_TAG) {
     return C_SCHEME_FALSE;
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     return C_SCHEME_TRUE;
   } else if (C_block_header(x) == C_STRUCTURE3_TAG) {
     if (C_block_item(x, 0) == C_ratnum_type_tag)
@@ -4929,7 +4936,7 @@ C_regparm C_word C_fcall C_i_inexactp(C_word x)
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "inexact?", x);
   } else if (C_block_header(x) == C_FLONUM_TAG) {
     return C_SCHEME_TRUE;
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     return C_SCHEME_FALSE;
   } else if (C_block_header(x) == C_STRUCTURE3_TAG) {
     if (C_block_item(x, 0) == C_ratnum_type_tag)
@@ -4952,8 +4959,8 @@ C_regparm C_word C_fcall C_i_zerop(C_word x)
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "zero?", x);
   } else if (C_block_header(x) == C_FLONUM_TAG) {
     return C_mk_bool(C_flonum_magnitude(x) == 0.0);
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE ||
-	     (C_block_header(x) == C_STRUCTURE3_TAG &&
+  } else if (C_truep(C_bignump(x)) ||
+             (C_block_header(x) == C_STRUCTURE3_TAG &&
 	      (C_block_item(x, 0) == C_ratnum_type_tag ||
 	       C_block_item(x, 0) == C_cplxnum_type_tag))) {
     return C_SCHEME_FALSE;
@@ -4980,7 +4987,7 @@ C_regparm C_word C_fcall C_i_positivep(C_word x)
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "positive?", x);
   else if (C_block_header(x) == C_FLONUM_TAG)
     return C_mk_bool(C_flonum_magnitude(x) > 0.0);
-  else if (C_header_bits(x) == C_BIGNUM_TYPE)
+  else if (C_truep(C_bignump(x)))
     return C_mk_nbool(C_bignum_negativep(x));
   else if (C_block_header(x) == C_STRUCTURE3_TAG &&
            (C_block_item(x, 0) == C_ratnum_type_tag))
@@ -5013,7 +5020,7 @@ C_regparm C_word C_fcall C_i_negativep(C_word x)
     barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "negative?", x);
   else if (C_block_header(x) == C_FLONUM_TAG)
     return C_mk_bool(C_flonum_magnitude(x) < 0.0);
-  else if (C_header_bits(x) == C_BIGNUM_TYPE)
+  else if (C_truep(C_bignump(x)))
     return C_mk_bool(C_bignum_negativep(x));
   else if (C_block_header(x) == C_STRUCTURE3_TAG &&
            (C_block_item(x, 0) == C_ratnum_type_tag))
@@ -5052,7 +5059,7 @@ C_regparm C_word C_fcall C_i_evenp(C_word x)
       barf(C_BAD_ARGUMENT_TYPE_NO_INTEGER_ERROR, "even?", x);
     else
       return C_mk_bool(fmod(val, 2.0) == 0.0);
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     return C_mk_nbool(C_bignum_digits(x)[0] & 1);
   } else { /* No need to try extended number */
     barf(C_BAD_ARGUMENT_TYPE_NO_INTEGER_ERROR, "even?", x);
@@ -5085,7 +5092,7 @@ C_regparm C_word C_fcall C_i_oddp(C_word x)
       barf(C_BAD_ARGUMENT_TYPE_NO_INTEGER_ERROR, "odd?", x);
     else
       return C_mk_bool(fmod(val, 2.0) != 0.0);
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     return C_mk_bool(C_bignum_digits(x)[0] & 1);
   } else {
     barf(C_BAD_ARGUMENT_TYPE_NO_INTEGER_ERROR, "odd?", x);
@@ -5503,7 +5510,7 @@ void C_ccall C_abs(C_word c, C_word self, C_word k, C_word x)
   } else if (C_block_header(x) == C_FLONUM_TAG) {
     C_word *a = C_alloc(C_SIZEOF_FLONUM);
     C_kontinue(k, C_a_i_flonum_abs(&a, 1, x));
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     C_u_integer_abs(3, (C_word)NULL, k, x);
   } else {
     try_extended_number("\003sysextended-abs", 2, k, x);
@@ -5533,7 +5540,7 @@ void C_ccall C_signum(C_word c, C_word self, C_word k, C_word x)
   } else if (C_block_header(x) == C_FLONUM_TAG) {
     C_word *a = C_alloc(C_SIZEOF_FLONUM);
     C_kontinue(k, C_a_u_i_flonum_signum(&a, 1, x));
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     C_kontinue(k, C_bignum_negativep(x) ? C_fix(-1) : C_fix(1));
   } else {
     try_extended_number("\003sysextended-signum", 2, k, x);
@@ -5562,7 +5569,7 @@ void C_ccall C_negate(C_word c, C_word self, C_word k, C_word x)
   } else if (C_block_header(x) == C_FLONUM_TAG) {
     C_word *a = C_alloc(C_SIZEOF_FLONUM);
     C_kontinue(k, C_a_i_flonum_negate(&a, 1, x));
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     C_u_integer_negate(3, (C_word)NULL, k, x);
   } else {
     try_extended_number("\003sysextended-negate", 2, k, x);
@@ -5745,8 +5752,7 @@ C_regparm C_word C_fcall C_i_bit_setp(C_word n, C_word i)
   if (!C_truep(C_i_exact_integerp(n))) {
     barf(C_BAD_ARGUMENT_TYPE_NO_EXACT_INTEGER_ERROR, "bit-set?", n);
   } else if (!(i & C_FIXNUM_BIT)) {
-    if (!C_immediatep(i) && (C_header_bits(i) == C_BIGNUM_TYPE) &&
-        !C_bignum_negativep(i)) {
+    if (!C_immediatep(i) && C_truep(C_bignump(i)) && !C_bignum_negativep(i)) {
       return C_i_integer_negativep(n); /* A bit silly, but strictly correct */
     } else {
       barf(C_BAD_ARGUMENT_TYPE_NO_UINTEGER_ERROR, "bit-set?", i);
@@ -6668,7 +6674,7 @@ C_regparm C_word C_fcall C_i_foreign_unsigned_integer_argumentp(C_word x)
 
   if((x & C_FIXNUM_BIT) != 0) return x;
 
-  if(!C_immediatep(x) && C_header_bits(x) == C_BIGNUM_TYPE) {
+  if(C_truep(C_i_bignump(x))) {
     if (C_bignum_size(x) == 1) return x;
     else barf(C_BAD_ARGUMENT_TYPE_FOREIGN_LIMITATION, NULL, x);
   }
@@ -6691,7 +6697,7 @@ C_regparm C_word C_fcall C_i_foreign_unsigned_integer64_argumentp(C_word x)
 
   if((x & C_FIXNUM_BIT) != 0) return x;
 
-  if(!C_immediatep(x) && C_header_bits(x) == C_BIGNUM_TYPE) {
+  if(C_truep(C_i_bignump(x))) {
 #ifdef C_SIXTY_FOUR
     if (C_bignum_size(x) == 1) return x;
 #else
@@ -7092,7 +7098,7 @@ C_2_basic_times(C_word c, C_word self, C_word k, C_word x, C_word y)
     } else if (C_block_header(y) == C_FLONUM_TAG) {
       C_word *a = C_alloc(C_SIZEOF_FLONUM);
       C_kontinue(k, C_flonum(&a, (double)C_unfix(x) * C_flonum_magnitude(y)));
-    } else if (C_header_bits(y) == C_BIGNUM_TYPE) {
+    } else if (C_truep(C_bignump(y))) {
       C_u_2_integer_times(4, (C_word)NULL, k, x, y);
     } else {
       try_extended_number("\003sysextended-times", 3, k, x, y);
@@ -7107,12 +7113,12 @@ C_2_basic_times(C_word c, C_word self, C_word k, C_word x, C_word y)
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "*", y);
     } else if (C_block_header(y) == C_FLONUM_TAG) {
       C_kontinue(k, C_a_i_flonum_times(&a, 2, x, y));
-    } else if (C_header_bits(y) == C_BIGNUM_TYPE) {
+    } else if (C_truep(C_bignump(y))) {
       C_kontinue(k, C_flonum(&a, C_flonum_magnitude(x)*C_bignum_to_double(y)));
     } else {
       try_extended_number("\003sysextended-times", 3, k, x, y);
     }
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     if (y & C_FIXNUM_BIT) {
       C_u_2_integer_times(4, (C_word)NULL, k, x, y);
     } else if (C_immediatep(y)) {
@@ -7120,7 +7126,7 @@ C_2_basic_times(C_word c, C_word self, C_word k, C_word x, C_word y)
     } else if (C_block_header(y) == C_FLONUM_TAG) {
       C_word *a = C_alloc(C_SIZEOF_FLONUM);
       C_kontinue(k, C_flonum(&a, C_bignum_to_double(x)*C_flonum_magnitude(y)));
-    } else if (C_header_bits(y) == C_BIGNUM_TYPE) {
+    } else if (C_truep(C_bignump(y))) {
       C_u_2_integer_times(4, (C_word)NULL, k, x, y);
     } else {
       try_extended_number("\003sysextended-times", 3, k, x, y);
@@ -7373,7 +7379,7 @@ C_2_basic_plus(C_word c, C_word self, C_word k, C_word x, C_word y)
     } else if (C_block_header(y) == C_FLONUM_TAG) {
       C_word *a = C_alloc(C_SIZEOF_FLONUM);
       C_kontinue(k, C_flonum(&a, (double)C_unfix(x) + C_flonum_magnitude(y)));
-    } else if (C_header_bits(y) == C_BIGNUM_TYPE) {
+    } else if (C_truep(C_bignump(y))) {
       C_u_2_integer_plus(4, (C_word)NULL, k, x, y);
     } else {
       try_extended_number("\003sysextended-plus", 3, k, x, y);
@@ -7388,12 +7394,12 @@ C_2_basic_plus(C_word c, C_word self, C_word k, C_word x, C_word y)
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "+", y);
     } else if (C_block_header(y) == C_FLONUM_TAG) {
       C_kontinue(k, C_a_i_flonum_plus(&a, 2, x, y));
-    } else if (C_header_bits(y) == C_BIGNUM_TYPE) {
+    } else if (C_truep(C_bignump(y))) {
       C_kontinue(k, C_flonum(&a, C_flonum_magnitude(x)+C_bignum_to_double(y)));
     } else {
       try_extended_number("\003sysextended-plus", 3, k, x, y);
     }
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     if (y & C_FIXNUM_BIT) {
       C_u_2_integer_plus(4, (C_word)NULL, k, x, y);
     } else if (C_immediatep(y)) {
@@ -7401,7 +7407,7 @@ C_2_basic_plus(C_word c, C_word self, C_word k, C_word x, C_word y)
     } else if (C_block_header(y) == C_FLONUM_TAG) {
       C_word *a = C_alloc(C_SIZEOF_FLONUM);
       C_kontinue(k, C_flonum(&a, C_bignum_to_double(x)+C_flonum_magnitude(y)));
-    } else if (C_header_bits(y) == C_BIGNUM_TYPE) {
+    } else if (C_truep(C_bignump(y))) {
       C_u_2_integer_plus(4, (C_word)NULL, k, x, y);
     } else {
       try_extended_number("\003sysextended-plus", 3, k, x, y);
@@ -7585,7 +7591,7 @@ C_2_basic_minus(C_word c, C_word self, C_word k, C_word x, C_word y)
     } else if (C_block_header(y) == C_FLONUM_TAG) {
       C_word *a = C_alloc(C_SIZEOF_FLONUM);
       C_kontinue(k, C_flonum(&a, (double)C_unfix(x) - C_flonum_magnitude(y)));
-    } else if (C_header_bits(y) == C_BIGNUM_TYPE) {
+    } else if (C_truep(C_bignump(y))) {
       C_u_2_integer_minus(4, (C_word)NULL, k, x, y);
     } else {
       try_extended_number("\003sysextended-minus", 3, k, x, y);
@@ -7600,12 +7606,12 @@ C_2_basic_minus(C_word c, C_word self, C_word k, C_word x, C_word y)
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, "-", y);
     } else if (C_block_header(y) == C_FLONUM_TAG) {
       C_kontinue(k, C_a_i_flonum_difference(&a, 2, x, y)); /* XXX NAMING! */
-    } else if (C_header_bits(y) == C_BIGNUM_TYPE) {
+    } else if (C_truep(C_bignump(y))) {
       C_kontinue(k, C_flonum(&a, C_flonum_magnitude(x)-C_bignum_to_double(y)));
     } else {
       try_extended_number("\003sysextended-minus", 3, k, x, y);
     }
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     if (y & C_FIXNUM_BIT) {
       C_u_2_integer_minus(4, (C_word)NULL, k, x, y);
     } else if (C_immediatep(y)) {
@@ -7613,7 +7619,7 @@ C_2_basic_minus(C_word c, C_word self, C_word k, C_word x, C_word y)
     } else if (C_block_header(y) == C_FLONUM_TAG) {
       C_word *a = C_alloc(C_SIZEOF_FLONUM);
       C_kontinue(k, C_flonum(&a, C_bignum_to_double(x)-C_flonum_magnitude(y)));
-    } else if (C_header_bits(y) == C_BIGNUM_TYPE) {
+    } else if (C_truep(C_bignump(y))) {
       C_u_2_integer_minus(4, (C_word)NULL, k, x, y);
     } else {
       try_extended_number("\003sysextended-minus", 3, k, x, y);
@@ -7875,7 +7881,7 @@ basic_divrem(C_word c, C_word self, C_word k, C_word x, C_word y, C_word return_
       x = C_a_i_fix_to_flo(&a, 1, x);
       RETURN_Q_AND_OR_R(C_a_i_flonum_actual_quotient_checked(&a, 2, x, y),
                         C_a_i_flonum_remainder_checked(&a, 2, x, y));
-    } else if (C_header_bits(y) == C_BIGNUM_TYPE) {
+    } else if (C_truep(C_bignump(y))) {
       integer_divrem(6, (C_word)NULL, k, x, y, return_q, return_r);
     } else {
       barf(C_BAD_ARGUMENT_TYPE_NO_INTEGER_ERROR, DIVREM_LOC, y);
@@ -7900,7 +7906,7 @@ basic_divrem(C_word c, C_word self, C_word k, C_word x, C_word y, C_word return_
 
       RETURN_Q_AND_OR_R(C_a_i_flonum_actual_quotient_checked(&a, 2, x, y),
                         C_a_i_flonum_remainder_checked(&a, 2, x, y));
-    } else if (C_header_bits(y) == C_BIGNUM_TYPE) {
+    } else if (C_truep(C_bignump(y))) {
       C_word k2, ab[C_SIZEOF_CLOSURE(3)], *a = ab;
       x = flo_to_tmp_bignum(x);
       k2 = C_closure(&a, 3, (C_word)divrem_intflo_2, k, x);
@@ -7908,7 +7914,7 @@ basic_divrem(C_word c, C_word self, C_word k, C_word x, C_word y, C_word return_
     } else {
       barf(C_BAD_ARGUMENT_TYPE_NO_INTEGER_ERROR, DIVREM_LOC, y);
     }
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     if (y & C_FIXNUM_BIT) {
       integer_divrem(6, (C_word)NULL, k, x, y, return_q, return_r);
     } else if (C_immediatep(y)) {
@@ -7924,7 +7930,7 @@ basic_divrem(C_word c, C_word self, C_word k, C_word x, C_word y, C_word return_
         k2 = C_closure(&a, 3, (C_word)divrem_intflo_2, k, y);
         integer_divrem(6, (C_word)NULL, k2, x, y, return_q, return_r);
       }
-    } else if (C_header_bits(y) == C_BIGNUM_TYPE) {
+    } else if (C_truep(C_bignump(y))) {
       bignum_divrem(6, (C_word)NULL, k, x, y, return_q, return_r);
     } else {
       barf(C_BAD_ARGUMENT_TYPE_NO_INTEGER_ERROR, DIVREM_LOC, y);
@@ -8214,7 +8220,7 @@ static C_word rat_cmp(C_word x, C_word y)
   }
 
   /* Extract components x=x1/x2 and y=y1/y2 */
-  if (x & C_FIXNUM_BIT || (C_header_bits(x) == C_BIGNUM_TYPE)) {
+  if (x & C_FIXNUM_BIT || C_truep(C_bignump(x))) {
     x1 = x;
     x2 = C_fix(1);
   } else {
@@ -8222,7 +8228,7 @@ static C_word rat_cmp(C_word x, C_word y)
     x2 = C_block_item(x, 2);
   }
 
-  if (y & C_FIXNUM_BIT || (C_header_bits(y) == C_BIGNUM_TYPE)) {
+  if (y & C_FIXNUM_BIT || C_truep(C_bignump(y))) {
     y1 = y;
     y2 = C_fix(1);
   } else {
@@ -8526,7 +8532,7 @@ static C_word basic_cmp(C_word x, C_word y, char *loc, int eqp)
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
     } else if (C_block_header(y) == C_FLONUM_TAG) {
       return int_flo_cmp(x, y);
-    } else if (C_header_bits(y) == C_BIGNUM_TYPE) {
+    } else if (C_truep(C_bignump(y))) {
       C_word ab[C_SIZEOF_FIX_BIGNUM], *a = ab;
       return C_i_bignum_cmp(C_a_u_i_fix_to_big(&a, x), y);
     } else if (C_block_header(y) == C_STRUCTURE3_TAG) {
@@ -8553,7 +8559,7 @@ static C_word basic_cmp(C_word x, C_word y, char *loc, int eqp)
       double a = C_flonum_magnitude(x), b = C_flonum_magnitude(y);
       if (C_isnan(a) || C_isnan(b)) return C_SCHEME_FALSE; /* "mu" */
       else return C_fix((a < b) ? -1 : ((a > b) ? 1 : 0));
-    } else if (C_header_bits(y) == C_BIGNUM_TYPE) {
+    } else if (C_truep(C_bignump(y))) {
       return flo_int_cmp(x, y);
     } else if (C_block_header(y) == C_STRUCTURE3_TAG) {
       if (C_block_item(y, 0) == C_ratnum_type_tag) {
@@ -8567,7 +8573,7 @@ static C_word basic_cmp(C_word x, C_word y, char *loc, int eqp)
     } else {
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
     }
-  } else if (C_header_bits(x) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(x))) {
     if (y & C_FIXNUM_BIT) {
       C_word ab[C_SIZEOF_FIX_BIGNUM], *a = ab;
       return C_i_bignum_cmp(x, C_a_u_i_fix_to_big(&a, y));
@@ -8575,7 +8581,7 @@ static C_word basic_cmp(C_word x, C_word y, char *loc, int eqp)
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
     } else if (C_block_header(y) == C_FLONUM_TAG) {
       return int_flo_cmp(x, y);
-    } else if (C_header_bits(y) == C_BIGNUM_TYPE) {
+    } else if (C_truep(C_bignump(y))) {
       return C_i_bignum_cmp(x, y);
     } else if (C_block_header(y) == C_STRUCTURE3_TAG) {
       if (C_block_item(y, 0) == C_ratnum_type_tag) {
@@ -8599,7 +8605,7 @@ static C_word basic_cmp(C_word x, C_word y, char *loc, int eqp)
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
     } else if (C_block_header(y) == C_FLONUM_TAG) {
       return rat_flo_cmp(x, y);
-    } else if (C_header_bits(y) == C_BIGNUM_TYPE) {
+    } else if (C_truep(C_bignump(y))) {
       if (eqp) return C_SCHEME_FALSE;
       else return rat_cmp(x, y);
     } else if (C_block_header(y) == C_STRUCTURE3_TAG &&
@@ -8629,9 +8635,9 @@ static C_word basic_cmp(C_word x, C_word y, char *loc, int eqp)
     } else if (C_immediatep(y)) {
       barf(C_BAD_ARGUMENT_TYPE_NO_NUMBER_ERROR, loc, y);
     } else if (C_block_header(y) == C_FLONUM_TAG ||
-               C_header_bits(y) == C_BIGNUM_TYPE ||
+               C_truep(C_bignump(x)) ||
                (C_block_header(y) == C_STRUCTURE3_TAG &&
-                (C_block_item(y, 0) == C_ratnum_type_tag))) {
+                C_block_item(y, 0) == C_ratnum_type_tag)) {
       return C_SCHEME_FALSE;
     } else if (C_block_header(y) == C_STRUCTURE3_TAG &&
                (C_block_item(y, 0) == C_cplxnum_type_tag)) {
@@ -9073,12 +9079,12 @@ void allocate_vector_2(void *dummy)
 void C_ccall
 C_allocate_bignum(C_word c, C_word self, C_word k, C_word size, C_word negp, C_word initp)
 {
-  C_uword bytes = C_wordstobytes(C_unfix(size) + 1); /* add slot for negp */
+  C_uword bytes = C_wordstobytes(C_SIZEOF_INTERNAL_BIGNUM_VECTOR(C_unfix(size)));
 
   if(bytes > C_HEADER_SIZE_MASK)
     barf(C_OUT_OF_RANGE_ERROR, NULL, size, C_fix(C_HEADER_SIZE_MASK));
 
-  bytes += sizeof(C_word); /* header slot */
+  bytes += C_wordstobytes(C_SIZEOF_STRUCTURE(2)); /* Add wrapper struct */
 
   C_save(k);
   C_save(negp);
@@ -9105,7 +9111,7 @@ static void allocate_bignum_2(void *dummy)
   C_word  initp = C_restore;
   C_word  negp = C_restore;
   C_word  k = C_restore;
-  C_word  *v0, v;
+  C_word  *v0, *v1, bigvec;
 
   if(C_truep(mode)) {
     while((C_uword)(C_fromspace_limit - C_fromspace_top) < (bytes + stack_size)) {
@@ -9122,31 +9128,34 @@ static void allocate_bignum_2(void *dummy)
   }
   else v0 = C_alloc(C_bytestowords(bytes));
 
-  v = (C_word)v0;
+  v1 = v0 + C_SIZEOF_STRUCTURE(2);
+  bigvec = (C_word)v1;
+  bytes -= C_wordstobytes(C_SIZEOF_STRUCTURE(2));
+  bytes -= sizeof(C_word); /* internal bignum vector's header */
 
-  *(v0++) = C_BIGNUM_TYPE | (bytes-sizeof(C_word)); /* subtract header again */
+  *(v1++) = C_STRING_TYPE | bytes;
 
-  *(v0++) = C_truep(negp);
-  if(C_truep(initp)) C_memset(v0, '\0', bytes - sizeof(C_word));
+  *(v1++) = C_truep(negp);
+  if(C_truep(initp)) C_memset(v1, '\0', bytes - sizeof(C_word));
 
-  C_kontinue(k, v);
+  C_kontinue(k, C_a_i_record2(&v0, 2, C_bignum_type_tag, bigvec));
 }
 
 static C_word allocate_tmp_bignum(C_word size, C_word negp, C_word initp)
 {
   C_word *mem = C_malloc(C_wordstobytes(C_SIZEOF_BIGNUM(C_unfix(size)))),
-          bignum = (C_word)mem;
+          bigvec = (C_word)(mem + C_SIZEOF_STRUCTURE(2));
   if (mem == NULL) abort();     /* TODO: panic */
   
-  C_block_header_init(bignum, C_BIGNUM_TYPE | C_wordstobytes(C_unfix(size)+1));
-  C_set_block_item(bignum, 0, C_truep(negp));
+  C_block_header_init(bigvec, C_STRING_TYPE | C_wordstobytes(C_unfix(size)+1));
+  C_set_block_item(bigvec, 0, C_truep(negp));
 
   if (C_truep(initp)) {
-    C_memset(((C_uword *)C_data_pointer(bignum))+1,
+    C_memset(((C_uword *)C_data_pointer(bigvec))+1,
              0, C_wordstobytes(C_unfix(size)));
   }
 
-  return bignum;
+  return C_a_i_record2(&mem, 2, C_bignum_type_tag, bigvec);
 }
 
 /* Simplification: scan trailing zeroes, then return a fixnum if the
@@ -10011,7 +10020,7 @@ void C_ccall C_number_to_string(C_word c, C_word closure, C_word k, C_word num,
     barf(C_BAD_ARGUMENT_TYPE_ERROR, "number->string", num);
   } else if(C_block_header(num) == C_FLONUM_TAG) {
     C_flonum_to_string(4, (C_word)NULL, k, num, radix);
-  } else if (C_header_bits(num) == C_BIGNUM_TYPE) {
+  } else if (C_truep(C_bignump(num))) {
     C_integer_to_string(4, (C_word)NULL, k, num, radix);
   } else {
     try_extended_number("\003sysextended-number->string", 3, k, num, radix);
@@ -11326,11 +11335,11 @@ static C_regparm C_word C_fcall decode_literal2(C_word **ptr, C_char **str,
       break;
 
 #ifdef C_SIXTY_FOUR
-    case (C_BIGNUM_TYPE >> (24 + 32)) & 0xff:
+    case ((C_STRING_TYPE | C_GC_FORWARDING_BIT) >> (24 + 32)) & 0xff:
 #else
-    case (C_BIGNUM_TYPE >> 24) & 0xff:
+    case ((C_STRING_TYPE | C_GC_FORWARDING_BIT) >> 24) & 0xff:
 #endif
-      bits = C_BIGNUM_TYPE;
+      bits = (C_STRING_TYPE | C_GC_FORWARDING_BIT);
       break;
 
     default: 
@@ -11380,6 +11389,13 @@ static C_regparm C_word C_fcall decode_literal2(C_word **ptr, C_char **str,
   size = decode_size(str);
 
   switch(bits) {
+  /* This cannot be encoded as a blob due to endianness differences */
+  case (C_STRING_TYPE | C_GC_FORWARDING_BIT): /* This represents "exact int" */
+    /* bignums are also allocated statically */
+    val = C_static_bignum(ptr, size, *str);
+    *str += size;
+    break;
+
   case C_STRING_TYPE:
     /* strings are always allocated statically */
     val = C_static_string(ptr, size, *str);
@@ -11406,13 +11422,6 @@ static C_regparm C_word C_fcall decode_literal2(C_word **ptr, C_char **str,
     *str += size;
     break;
 
-  /* This cannot be encoded as a blob due to endianness differences */
-  case C_BIGNUM_TYPE:
-    /* bignums are also allocated statically */
-    val = C_static_bignum(ptr, size, *str);
-    *str += size;
-    break;
-
   default:
     *((*ptr)++) = C_make_header(bits, size);
     data = *ptr;
diff --git a/scheduler.scm b/scheduler.scm
index 1dc78821..0193ef6d 100644
--- a/scheduler.scm
+++ b/scheduler.scm
@@ -176,7 +176,7 @@ EOF
     (let loop1 ()
       ;; Unblock threads waiting for timeout:
       (unless (null? ##sys#timeout-list)
-	(let ((now (##core#inline_allocate ("C_a_i_current_milliseconds" 4) #f)))
+	(let ((now (##core#inline_allocate ("C_a_i_current_milliseconds" 7) #f)))
 	  (let loop ((lst ##sys#timeout-list))
 	    (if (null? lst)
 		(set! ##sys#timeout-list '())
@@ -440,7 +440,7 @@ EOF
 	 (rq? (pair? ready-queue-head))
 	 (tmo (if (and to? (not rq?)) ; no thread was unblocked by timeout, so wait
 		  (let* ((tmo1 (caar ##sys#timeout-list))
-			 (now (##core#inline_allocate ("C_a_i_current_milliseconds" 4) #f)))
+			 (now (##core#inline_allocate ("C_a_i_current_milliseconds" 7) #f)))
 		    (max 0 (- tmo1 now)) )
 		  0.0) ) )		; otherwise immediate timeout.
     (dbg "waiting for I/O with timeout " tmo)
diff --git a/srfi-4.scm b/srfi-4.scm
index c4f5f476..50d05d92 100644
--- a/srfi-4.scm
+++ b/srfi-4.scm
@@ -238,7 +238,7 @@ EOF
      (##sys#check-structure x 'u32vector 'u32vector-ref)
      (let ((len (##core#inline "C_u_i_u32vector_length" x)))
        (check-range i 0 len 'u32vector-ref)
-       (##core#inline_allocate ("C_a_u_i_u32vector_ref" 3) x i)))
+       (##core#inline_allocate ("C_a_u_i_u32vector_ref" 6) x i)))
    u32vector-set!
    "(u32vector-ref v i)"))
 
@@ -248,7 +248,7 @@ EOF
      (##sys#check-structure x 's32vector 's32vector-ref)
      (let ((len (##core#inline "C_u_i_s32vector_length" x)))
        (check-range i 0 len 's32vector-ref)
-       (##core#inline_allocate ("C_a_u_i_s32vector_ref" 3) x i)))
+       (##core#inline_allocate ("C_a_u_i_s32vector_ref" 6) x i)))
    s32vector-set!
    "(s32vector-ref v i)"))
 
@@ -258,7 +258,7 @@ EOF
      (##sys#check-structure x 'u64vector 'u64vector-ref)
      (let ((len (##core#inline "C_u_i_u64vector_length" x)))
        (check-range i 0 len 'u64vector-ref)
-       (##core#inline_allocate ("C_a_u_i_u64vector_ref" 4) x i)))
+       (##core#inline_allocate ("C_a_u_i_u64vector_ref" 7) x i)))
    u64vector-set!
    "(u64vector-ref v i)"))
 
@@ -268,7 +268,7 @@ EOF
      (##sys#check-structure x 's64vector 's64vector-ref)
      (let ((len (##core#inline "C_u_i_s64vector_length" x)))
        (check-range i 0 len 's64vector-ref)
-       (##core#inline_allocate ("C_a_u_i_s64vector_ref" 4) x i)))
+       (##core#inline_allocate ("C_a_u_i_s64vector_ref" 7) x i)))
    s64vector-set!
    "(s64vector-ref v i)"))
 
diff --git a/types.db b/types.db
index 14d36cb7..dd350439 100644
--- a/types.db
+++ b/types.db
@@ -317,14 +317,14 @@
    ((float float) (float)
     (##core#inline_allocate ("C_a_i_flonum_plus" 4) #(1) #(2)))
    ((fixnum fixnum) (integer)
-    (##core#inline_allocate ("C_a_i_fixnum_plus" 3) #(1) #(2)))
+    (##core#inline_allocate ("C_a_i_fixnum_plus" 6) #(1) #(2)))
    ((integer integer) (integer)
     (##sys#integer-plus #(1) #(2)))
    ((* *) (number)
     (##sys#+-2 #(1) #(2))))
 
 (- (#(procedure #:clean #:enforce #:foldable) - (number #!rest number) number)
-   ((fixnum) (integer) (##core#inline_allocate ("C_a_i_fixnum_negate" 3) #(1)))
+   ((fixnum) (integer) (##core#inline_allocate ("C_a_i_fixnum_negate" 6) #(1)))
    ((integer) (integer) (##sys#integer-negate #(1)))
    ((float) (float) (##core#inline_allocate ("C_a_i_flonum_negate" 4) #(1)))
    ((number) (number) (##sys#negate #(1)))
@@ -341,7 +341,7 @@
    ((float float) (float)
     (##core#inline_allocate ("C_a_i_flonum_difference" 4) #(1) #(2)))
    ((fixnum fixnum) (integer)
-    (##core#inline_allocate ("C_a_i_fixnum_difference" 3) #(1) #(2)))
+    (##core#inline_allocate ("C_a_i_fixnum_difference" 6) #(1) #(2)))
    ((integer integer) (integer)
     (##sys#integer-minus #(1) #(2)))
    ((* *) (number)
@@ -369,7 +369,7 @@
    ((float float) (float)
     (##core#inline_allocate ("C_a_i_flonum_times" 4) #(1) #(2)))
    ((fixnum fixnum) (integer)
-    (##core#inline_allocate ("C_a_i_fixnum_times" 4) #(1) #(2)))
+    (##core#inline_allocate ("C_a_i_fixnum_times" 7) #(1) #(2)))
    ((integer integer) (integer)
     (##sys#integer-times #(1) #(2)))
    ((* *) (number)
@@ -440,7 +440,7 @@
 	   (##core#inline_allocate
 	    ("C_a_i_flonum_actual_quotient_checked" 4) #(1) #(2)))
 	  ((fixnum fixnum) (integer)
-	   (##core#inline_allocate ("C_a_i_fixnum_quotient_checked" 3)
+	   (##core#inline_allocate ("C_a_i_fixnum_quotient_checked" 6)
 				   #(1) #(2)))
 	  ((integer integer) (integer)
 	   (##sys#integer-quotient #(1) #(2))))
@@ -469,7 +469,7 @@
 	    (let ((#(tmp1) #(1)))
 	      (let ((#(tmp2) #(2)))
 		(##sys#values
-		 (##core#inline_allocate ("C_a_i_fixnum_quotient_checked" 3)
+		 (##core#inline_allocate ("C_a_i_fixnum_quotient_checked" 6)
 					 #(tmp1) #(tmp2))
 		 (##core#inline
 		  "C_i_fixnum_remainder_checked" #(tmp1) #(tmp2))))))
@@ -497,7 +497,7 @@
 (##sys#lcm (#(procedure #:clean #:enforce #:foldable) ##sys#lcm (number number) number))
 
 (abs (#(procedure #:clean #:enforce #:foldable) abs (number) number)
-     ((fixnum) (integer) (##core#inline_allocate ("C_a_i_fixnum_abs" 3) #(1)))
+     ((fixnum) (integer) (##core#inline_allocate ("C_a_i_fixnum_abs" 6) #(1)))
      ((float) (float) (##core#inline_allocate ("C_a_i_flonum_abs" 4) #(1)))
      ((integer) (integer) (##sys#integer-abs #(1))))
 
@@ -792,7 +792,7 @@
 	   ((cplxnum) (##sys#slot #(1) '2)))
 
 (magnitude (#(procedure #:clean #:enforce #:foldable) magnitude (number) number)
-	   ((fixnum) (integer) (##core#inline_allocate ("C_a_i_fixnum_abs" 3) #(1)))
+	   ((fixnum) (integer) (##core#inline_allocate ("C_a_i_fixnum_abs" 6) #(1)))
 	   ((integer) (##sys#integer-abs #(1)))
 	   ((float) (float) (##core#inline_allocate ("C_a_i_flonum_abs" 4) #(1)))
 	   (((or fixnum float bignum ratnum)) (abs #(1))))
Trap