0.8.20.21:
[sbcl.git] / src / runtime / gc-common.c
index 08baf74..946873c 100644 (file)
  */
 
 /*
- * GENerational Conservative Garbage Collector for SBCL x86
- */
-
-/*
- * This software is part of the SBCL system. See the README file for
- * more information.
- *
- * This software is derived from the CMU CL system, which was
- * written at Carnegie Mellon University and released into the
- * public domain. The software is in the public domain and is
- * provided with absolutely no warranty. See the COPYING and CREDITS
- * files for more information.
- */
-
-/*
  * For a review of garbage collection techniques (e.g. generational
  * GC) and terminology (e.g. "scavenging") see Paul R. Wilson,
  * "Uniprocessor Garbage Collection Techniques". As of 20000618, this
@@ -42,8 +27,9 @@
 
 #include <stdio.h>
 #include <signal.h>
-#include "runtime.h"
+#include <string.h>
 #include "sbcl.h"
+#include "runtime.h"
 #include "os.h"
 #include "interr.h"
 #include "globals.h"
@@ -51,6 +37,7 @@
 #include "validate.h"
 #include "lispregs.h"
 #include "arch.h"
+#include "fixnump.h"
 #include "gc.h"
 #include "genesis/primitive-objects.h"
 #include "genesis/static-symbols.h"
@@ -94,9 +81,9 @@ set_forwarding_pointer(lispobj * pointer, lispobj newspace_copy) {
     return newspace_copy;
 }
 
-int (*scavtab[256])(lispobj *where, lispobj object);
+long (*scavtab[256])(lispobj *where, lispobj object);
 lispobj (*transother[256])(lispobj object);
-int (*sizetab[256])(lispobj *where);
+long (*sizetab[256])(lispobj *where);
 struct weak_pointer *weak_pointers;
 
 unsigned long bytes_consed_between_gcs = 12*1024*1024;
@@ -108,11 +95,10 @@ unsigned long bytes_consed_between_gcs = 12*1024*1024;
 
 /* to copy a boxed object */
 lispobj
-copy_object(lispobj object, int nwords)
+copy_object(lispobj object, long nwords)
 {
     int tag;
     lispobj *new;
-    lispobj *source, *dest;
 
     gc_assert(is_lisp_pointer(object));
     gc_assert(from_space_p(object));
@@ -122,37 +108,26 @@ copy_object(lispobj object, int nwords)
     tag = lowtag_of(object);
 
     /* Allocate space. */
-    new = gc_general_alloc(nwords*4,ALLOC_BOXED,ALLOC_QUICK);
-
-    dest = new;
-    source = (lispobj *) native_pointer(object);
+    new = gc_general_alloc(nwords*N_WORD_BYTES,ALLOC_BOXED,ALLOC_QUICK);
 
     /* Copy the object. */
-    while (nwords > 0) {
-       dest[0] = source[0];
-       dest[1] = source[1];
-       dest += 2;
-       source += 2;
-       nwords -= 2;
-    }
-
+    memcpy(new,native_pointer(object),nwords*N_WORD_BYTES);
     return make_lispobj(new,tag);
 }
 
-static int scav_lose(lispobj *where, lispobj object); /* forward decl */
+static long scav_lose(lispobj *where, lispobj object); /* forward decl */
 
 /* FIXME: Most calls end up going to some trouble to compute an
  * 'n_words' value for this function. The system might be a little
  * simpler if this function used an 'end' parameter instead. */
-
 void
 scavenge(lispobj *start, long n_words)
 {
     lispobj *end = start + n_words;
     lispobj *object_ptr;
-    int n_words_scavenged;
-    
+    long n_words_scavenged;
     for (object_ptr = start;
+
         object_ptr < end;
         object_ptr += n_words_scavenged) {
 
@@ -202,7 +177,7 @@ scavenge(lispobj *start, long n_words)
            }
        }
 #endif
-       else if ((object & 3) == 0) {
+       else if (fixnump(object)) {
            /* It's a fixnum: really easy.. */
            n_words_scavenged = 1;
        } else {
@@ -217,7 +192,7 @@ scavenge(lispobj *start, long n_words)
 static lispobj trans_fun_header(lispobj object); /* forward decls */
 static lispobj trans_boxed(lispobj object);
 
-static int
+static long
 scav_fun_pointer(lispobj *where, lispobj object)
 {
     lispobj *first_pointer;
@@ -233,7 +208,6 @@ scav_fun_pointer(lispobj *where, lispobj object)
 
     switch (widetag_of(*first_pointer)) {
     case SIMPLE_FUN_HEADER_WIDETAG:
-    case CLOSURE_FUN_HEADER_WIDETAG:
        copy = trans_fun_header(object);
        break;
     default:
@@ -260,7 +234,7 @@ trans_code(struct code *code)
 {
     struct code *new_code;
     lispobj first, l_code, l_new_code;
-    int nheader_words, ncode_words, nwords;
+    long nheader_words, ncode_words, nwords;
     unsigned long displacement;
     lispobj fheaderl, *prev_pointer;
 
@@ -328,7 +302,7 @@ trans_code(struct code *code)
                
        /* fix self pointer. */
        nfheaderp->self =
-#ifdef LISP_FEATURE_GENCGC     /* GENCGC?  Maybe x86 is better conditional  */
+#if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
            FUN_RAW_ADDR_OFFSET +
 #endif
            nfheaderl; 
@@ -338,19 +312,19 @@ trans_code(struct code *code)
        fheaderl = fheaderp->next;
        prev_pointer = &nfheaderp->next;
     }
-    os_flush_icache((os_vm_address_t) (((int *)new_code) + nheader_words),
-                   ncode_words * sizeof(int));
+    os_flush_icache((os_vm_address_t) (((long *)new_code) + nheader_words),
+                   ncode_words * sizeof(long));
 #ifdef LISP_FEATURE_GENCGC
     gencgc_apply_code_fixups(code, new_code);
 #endif
     return new_code;
 }
 
-static int
+static long
 scav_code_header(lispobj *where, lispobj object)
 {
     struct code *code;
-    int n_header_words, n_code_words, n_words;
+    long n_header_words, n_code_words, n_words;
     lispobj entry_point;       /* tagged pointer to entry point */
     struct simple_fun *function_ptr; /* untagged pointer to entry point */
 
@@ -392,11 +366,11 @@ trans_code_header(lispobj object)
 }
 
 
-static int
+static long
 size_code_header(lispobj *where)
 {
     struct code *code;
-    int nheader_words, ncode_words, nwords;
+    long nheader_words, ncode_words, nwords;
 
     code = (struct code *) where;
        
@@ -408,7 +382,8 @@ size_code_header(lispobj *where)
     return nwords;
 }
 
-static int
+#ifndef LISP_FEATURE_X86 || LISP_FEATURE_X86_64
+static long
 scav_return_pc_header(lispobj *where, lispobj object)
 {
     lose("attempted to scavenge a return PC header where=0x%08x object=0x%08x",
@@ -416,6 +391,7 @@ scav_return_pc_header(lispobj *where, lispobj object)
         (unsigned long) object);
     return 0; /* bogus return value to satisfy static type checking */
 }
+#endif /* LISP_FEATURE_X86 */
 
 static lispobj
 trans_return_pc_header(lispobj object)
@@ -425,7 +401,8 @@ trans_return_pc_header(lispobj object)
     struct code *code, *ncode;
 
     return_pc = (struct simple_fun *) native_pointer(object);
-    offset = HeaderValue(return_pc->header)  * 4 ;
+    /* FIXME: was times 4, should it really be N_WORD_BYTES? */
+    offset = HeaderValue(return_pc->header) * N_WORD_BYTES;
 
     /* Transport the whole code object */
     code = (struct code *) ((unsigned long) return_pc - offset);
@@ -440,8 +417,8 @@ trans_return_pc_header(lispobj object)
  * objects don't move, we don't need to update anything, but we do
  * have to figure out that the function is still live. */
 
-#ifdef LISP_FEATURE_X86
-static int
+#if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
+static long
 scav_closure_header(lispobj *where, lispobj object)
 {
     struct closure *closure;
@@ -460,7 +437,8 @@ scav_closure_header(lispobj *where, lispobj object)
 }
 #endif
 
-static int
+#if !(defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64))
+static long
 scav_fun_header(lispobj *where, lispobj object)
 {
     lose("attempted to scavenge a function header where=0x%08x object=0x%08x",
@@ -468,6 +446,7 @@ scav_fun_header(lispobj *where, lispobj object)
         (unsigned long) object);
     return 0; /* bogus return value to satisfy static type checking */
 }
+#endif /* LISP_FEATURE_X86 */
 
 static lispobj
 trans_fun_header(lispobj object)
@@ -477,7 +456,8 @@ trans_fun_header(lispobj object)
     struct code *code, *ncode;
        
     fheader = (struct simple_fun *) native_pointer(object);
-    offset = HeaderValue(fheader->header) * 4;
+    /* FIXME: was times 4, should it really be N_WORD_BYTES? */
+    offset = HeaderValue(fheader->header) * N_WORD_BYTES;
 
     /* Transport the whole code object */
     code = (struct code *) ((unsigned long) fheader - offset);
@@ -491,7 +471,7 @@ trans_fun_header(lispobj object)
  * instances
  */
 
-static int
+static long
 scav_instance_pointer(lispobj *where, lispobj object)
 {
     lispobj copy, *first_pointer;
@@ -517,7 +497,7 @@ scav_instance_pointer(lispobj *where, lispobj object)
 
 static lispobj trans_list(lispobj object);
 
-static int
+static long
 scav_list_pointer(lispobj *where, lispobj object)
 {
     lispobj first, *first_pointer;
@@ -601,7 +581,7 @@ trans_list(lispobj object)
  * scavenging and transporting other pointers
  */
 
-static int
+static long
 scav_other_pointer(lispobj *where, lispobj object)
 {
     lispobj first, *first_pointer;
@@ -631,13 +611,13 @@ scav_other_pointer(lispobj *where, lispobj object)
  * immediate, boxed, and unboxed objects
  */
 
-static int
+static long
 size_pointer(lispobj *where)
 {
     return 1;
 }
 
-static int
+static long
 scav_immediate(lispobj *where, lispobj object)
 {
     return 1;
@@ -650,14 +630,14 @@ trans_immediate(lispobj object)
     return NIL; /* bogus return value to satisfy static type checking */
 }
 
-static int
+static long
 size_immediate(lispobj *where)
 {
     return 1;
 }
 
 
-static int
+static long
 scav_boxed(lispobj *where, lispobj object)
 {
     return 1;
@@ -679,7 +659,7 @@ trans_boxed(lispobj object)
 }
 
 
-static int
+static long
 size_boxed(lispobj *where)
 {
     lispobj header;
@@ -695,7 +675,7 @@ size_boxed(lispobj *where)
 /* Note: on the sparc we don't have to do anything special for fdefns, */
 /* 'cause the raw-addr has a function lowtag. */
 #ifndef LISP_FEATURE_SPARC
-static int
+static long
 scav_fdefn(lispobj *where, lispobj object)
 {
     struct fdefn *fdefn;
@@ -714,8 +694,7 @@ scav_fdefn(lispobj *where, lispobj object)
            fdefn->raw_addr = (char *)(fdefn->fun + FUN_RAW_ADDR_OFFSET);
        /* gc.c has more casts here, which may be relevant or alternatively
           may be compiler warning defeaters.  try 
-        fdefn->raw_addr =
-           (u32)  ((char *) LOW_WORD(fdefn->fun)) + FUN_RAW_ADDR_OFFSET;
+        fdefn->raw_addr = ((char *) LOW_WORD(fdefn->fun)) + FUN_RAW_ADDR_OFFSET;
        */
        return sizeof(struct fdefn) / sizeof(lispobj);
     } else {
@@ -724,7 +703,7 @@ scav_fdefn(lispobj *where, lispobj object)
 }
 #endif
 
-static int
+static long
 scav_unboxed(lispobj *where, lispobj object)
 {
     unsigned long length;
@@ -751,7 +730,7 @@ trans_unboxed(lispobj object)
     return copy_unboxed_object(object, length);
 }
 
-static int
+static long
 size_unboxed(lispobj *where)
 {
     lispobj header;
@@ -764,12 +743,61 @@ size_unboxed(lispobj *where)
     return length;
 }
 
-static int\f
+\f
 /* vector-like objects */
+static long
+scav_base_string(lispobj *where, lispobj object)
+{
+    struct vector *vector;
+    long length, nwords;
 
-#define NWORDS(x,y) (CEILING((x),(y)) / (y))
+    /* NOTE: Strings contain one more byte of data than the length */
+    /* slot indicates. */
 
-scav_base_string(lispobj *where, lispobj object)
+    vector = (struct vector *) where;
+    length = fixnum_value(vector->length) + 1;
+    nwords = CEILING(NWORDS(length, 8) + 2, 2);
+
+    return nwords;
+}
+static lispobj
+trans_base_string(lispobj object)
+{
+    struct vector *vector;
+    long length, nwords;
+
+    gc_assert(is_lisp_pointer(object));
+
+    /* NOTE: A string contains one more byte of data (a terminating
+     * '\0' to help when interfacing with C functions) than indicated
+     * by the length slot. */
+
+    vector = (struct vector *) native_pointer(object);
+    length = fixnum_value(vector->length) + 1;
+    nwords = CEILING(NWORDS(length, 8) + 2, 2);
+
+    return copy_large_unboxed_object(object, nwords);
+}
+
+static long
+size_base_string(lispobj *where)
+{
+    struct vector *vector;
+    long length, nwords;
+
+    /* NOTE: A string contains one more byte of data (a terminating
+     * '\0' to help when interfacing with C functions) than indicated
+     * by the length slot. */
+
+    vector = (struct vector *) where;
+    length = fixnum_value(vector->length) + 1;
+    nwords = CEILING(NWORDS(length, 8) + 2, 2);
+
+    return nwords;
+}
+
+static long
+scav_character_string(lispobj *where, lispobj object)
 {
     struct vector *vector;
     int length, nwords;
@@ -779,12 +807,12 @@ scav_base_string(lispobj *where, lispobj object)
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length) + 1;
-    nwords = CEILING(NWORDS(length, 4) + 2, 2);
+    nwords = CEILING(NWORDS(length, 32) + 2, 2);
 
     return nwords;
 }
 static lispobj
-trans_base_string(lispobj object)
+trans_character_string(lispobj object)
 {
     struct vector *vector;
     int length, nwords;
@@ -797,13 +825,13 @@ trans_base_string(lispobj object)
 
     vector = (struct vector *) native_pointer(object);
     length = fixnum_value(vector->length) + 1;
-    nwords = CEILING(NWORDS(length, 4) + 2, 2);
+    nwords = CEILING(NWORDS(length, 32) + 2, 2);
 
     return copy_large_unboxed_object(object, nwords);
 }
 
-static int
-size_base_string(lispobj *where)
+static long
+size_character_string(lispobj *where)
 {
     struct vector *vector;
     int length, nwords;
@@ -814,7 +842,7 @@ size_base_string(lispobj *where)
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length) + 1;
-    nwords = CEILING(NWORDS(length, 4) + 2, 2);
+    nwords = CEILING(NWORDS(length, 32) + 2, 2);
 
     return nwords;
 }
@@ -823,7 +851,7 @@ static lispobj
 trans_vector(lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     gc_assert(is_lisp_pointer(object));
 
@@ -835,11 +863,11 @@ trans_vector(lispobj object)
     return copy_large_object(object, nwords);
 }
 
-static int
+static long
 size_vector(lispobj *where)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
@@ -848,7 +876,7 @@ size_vector(lispobj *where)
     return nwords;
 }
 
-static int
+static long
 scav_vector_nil(lispobj *where, lispobj object)
 {
     return 2;
@@ -861,22 +889,22 @@ trans_vector_nil(lispobj object)
     return copy_unboxed_object(object, 2);
 }
 
-static int
+static long
 size_vector_nil(lispobj *where)
 {
     /* Just the header word and the length word */
     return 2;
 }
 
-static int
+static long
 scav_vector_bit(lispobj *where, lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(NWORDS(length, 32) + 2, 2);
+    nwords = CEILING(NWORDS(length, 1) + 2, 2);
 
     return nwords;
 }
@@ -885,39 +913,39 @@ static lispobj
 trans_vector_bit(lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     gc_assert(is_lisp_pointer(object));
 
     vector = (struct vector *) native_pointer(object);
     length = fixnum_value(vector->length);
-    nwords = CEILING(NWORDS(length, 32) + 2, 2);
+    nwords = CEILING(NWORDS(length, 1) + 2, 2);
 
     return copy_large_unboxed_object(object, nwords);
 }
 
-static int
+static long
 size_vector_bit(lispobj *where)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(NWORDS(length, 32) + 2, 2);
+    nwords = CEILING(NWORDS(length, 1) + 2, 2);
 
     return nwords;
 }
 
-static int
+static long
 scav_vector_unsigned_byte_2(lispobj *where, lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(NWORDS(length, 16) + 2, 2);
+    nwords = CEILING(NWORDS(length, 2) + 2, 2);
 
     return nwords;
 }
@@ -926,39 +954,39 @@ static lispobj
 trans_vector_unsigned_byte_2(lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     gc_assert(is_lisp_pointer(object));
 
     vector = (struct vector *) native_pointer(object);
     length = fixnum_value(vector->length);
-    nwords = CEILING(NWORDS(length, 16) + 2, 2);
+    nwords = CEILING(NWORDS(length, 2) + 2, 2);
 
     return copy_large_unboxed_object(object, nwords);
 }
 
-static int
+static long
 size_vector_unsigned_byte_2(lispobj *where)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(NWORDS(length, 16) + 2, 2);
+    nwords = CEILING(NWORDS(length, 2) + 2, 2);
 
     return nwords;
 }
 
-static int
+static long
 scav_vector_unsigned_byte_4(lispobj *where, lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(NWORDS(length, 8) + 2, 2);
+    nwords = CEILING(NWORDS(length, 4) + 2, 2);
 
     return nwords;
 }
@@ -967,39 +995,39 @@ static lispobj
 trans_vector_unsigned_byte_4(lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     gc_assert(is_lisp_pointer(object));
 
     vector = (struct vector *) native_pointer(object);
     length = fixnum_value(vector->length);
-    nwords = CEILING(NWORDS(length, 8) + 2, 2);
+    nwords = CEILING(NWORDS(length, 4) + 2, 2);
 
     return copy_large_unboxed_object(object, nwords);
 }
-static int
+static long
 size_vector_unsigned_byte_4(lispobj *where)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(NWORDS(length, 8) + 2, 2);
+    nwords = CEILING(NWORDS(length, 4) + 2, 2);
 
     return nwords;
 }
 
 
-static int
+static long
 scav_vector_unsigned_byte_8(lispobj *where, lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(NWORDS(length, 4) + 2, 2);
+    nwords = CEILING(NWORDS(length, 8) + 2, 2);
 
     return nwords;
 }
@@ -1012,40 +1040,40 @@ static lispobj
 trans_vector_unsigned_byte_8(lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     gc_assert(is_lisp_pointer(object));
 
     vector = (struct vector *) native_pointer(object);
     length = fixnum_value(vector->length);
-    nwords = CEILING(NWORDS(length, 4) + 2, 2);
+    nwords = CEILING(NWORDS(length, 8) + 2, 2);
 
     return copy_large_unboxed_object(object, nwords);
 }
 
-static int
+static long
 size_vector_unsigned_byte_8(lispobj *where)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(NWORDS(length, 4) + 2, 2);
+    nwords = CEILING(NWORDS(length, 8) + 2, 2);
 
     return nwords;
 }
 
 
-static int
+static long
 scav_vector_unsigned_byte_16(lispobj *where, lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(NWORDS(length, 2) + 2, 2);
+    nwords = CEILING(NWORDS(length, 16) + 2, 2);
 
     return nwords;
 }
@@ -1054,39 +1082,39 @@ static lispobj
 trans_vector_unsigned_byte_16(lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     gc_assert(is_lisp_pointer(object));
 
     vector = (struct vector *) native_pointer(object);
     length = fixnum_value(vector->length);
-    nwords = CEILING(NWORDS(length, 2) + 2, 2);
+    nwords = CEILING(NWORDS(length, 16) + 2, 2);
 
     return copy_large_unboxed_object(object, nwords);
 }
 
-static int
+static long
 size_vector_unsigned_byte_16(lispobj *where)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(NWORDS(length, 2) + 2, 2);
+    nwords = CEILING(NWORDS(length, 16) + 2, 2);
 
     return nwords;
 }
 
-static int
+static long
 scav_vector_unsigned_byte_32(lispobj *where, lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(length + 2, 2);
+    nwords = CEILING(NWORDS(length, 32) + 2, 2);
 
     return nwords;
 }
@@ -1095,39 +1123,82 @@ static lispobj
 trans_vector_unsigned_byte_32(lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     gc_assert(is_lisp_pointer(object));
 
     vector = (struct vector *) native_pointer(object);
     length = fixnum_value(vector->length);
-    nwords = CEILING(length + 2, 2);
+    nwords = CEILING(NWORDS(length, 32) + 2, 2);
 
     return copy_large_unboxed_object(object, nwords);
 }
 
-static int
+static long
 size_vector_unsigned_byte_32(lispobj *where)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(length + 2, 2);
+    nwords = CEILING(NWORDS(length, 32) + 2, 2);
+
+    return nwords;
+}
+
+#if N_WORD_BITS == 64
+static long
+scav_vector_unsigned_byte_64(lispobj *where, lispobj object)
+{
+    struct vector *vector;
+    long length, nwords;
+
+    vector = (struct vector *) where;
+    length = fixnum_value(vector->length);
+    nwords = CEILING(NWORDS(length, 64) + 2, 2);
+
+    return nwords;
+}
+
+static lispobj
+trans_vector_unsigned_byte_64(lispobj object)
+{
+    struct vector *vector;
+    long length, nwords;
+
+    gc_assert(is_lisp_pointer(object));
+
+    vector = (struct vector *) native_pointer(object);
+    length = fixnum_value(vector->length);
+    nwords = CEILING(NWORDS(length, 64) + 2, 2);
+
+    return copy_large_unboxed_object(object, nwords);
+}
+
+static long
+size_vector_unsigned_byte_64(lispobj *where)
+{
+    struct vector *vector;
+    long length, nwords;
+
+    vector = (struct vector *) where;
+    length = fixnum_value(vector->length);
+    nwords = CEILING(NWORDS(length, 64) + 2, 2);
 
     return nwords;
 }
+#endif
 
-static int
+static long
 scav_vector_single_float(lispobj *where, lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(length + 2, 2);
+    nwords = CEILING(NWORDS(length, 32) + 2, 2);
 
     return nwords;
 }
@@ -1136,39 +1207,39 @@ static lispobj
 trans_vector_single_float(lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     gc_assert(is_lisp_pointer(object));
 
     vector = (struct vector *) native_pointer(object);
     length = fixnum_value(vector->length);
-    nwords = CEILING(length + 2, 2);
+    nwords = CEILING(NWORDS(length, 32) + 2, 2);
 
     return copy_large_unboxed_object(object, nwords);
 }
 
-static int
+static long
 size_vector_single_float(lispobj *where)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(length + 2, 2);
+    nwords = CEILING(NWORDS(length, 32) + 2, 2);
 
     return nwords;
 }
 
-static int
+static long
 scav_vector_double_float(lispobj *where, lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(length * 2 + 2, 2);
+    nwords = CEILING(NWORDS(length, 64) + 2, 2);
 
     return nwords;
 }
@@ -1177,36 +1248,36 @@ static lispobj
 trans_vector_double_float(lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     gc_assert(is_lisp_pointer(object));
 
     vector = (struct vector *) native_pointer(object);
     length = fixnum_value(vector->length);
-    nwords = CEILING(length * 2 + 2, 2);
+    nwords = CEILING(NWORDS(length, 64) + 2, 2);
 
     return copy_large_unboxed_object(object, nwords);
 }
 
-static int
+static long
 size_vector_double_float(lispobj *where)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(length * 2 + 2, 2);
+    nwords = CEILING(NWORDS(length, 64) + 2, 2);
 
     return nwords;
 }
 
 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
-static int
+static long
 scav_vector_long_float(lispobj *where, lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
@@ -1220,7 +1291,7 @@ static lispobj
 trans_vector_long_float(lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     gc_assert(is_lisp_pointer(object));
 
@@ -1231,11 +1302,11 @@ trans_vector_long_float(lispobj object)
     return copy_large_unboxed_object(object, nwords);
 }
 
-static int
+static long
 size_vector_long_float(lispobj *where)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
@@ -1247,15 +1318,15 @@ size_vector_long_float(lispobj *where)
 
 
 #ifdef SIMPLE_ARRAY_COMPLEX_SINGLE_FLOAT_WIDETAG
-static int
+static long
 scav_vector_complex_single_float(lispobj *where, lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(length * 2 + 2, 2);
+    nwords = CEILING(NWORDS(length, 64) + 2, 2);
 
     return nwords;
 }
@@ -1264,41 +1335,41 @@ static lispobj
 trans_vector_complex_single_float(lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     gc_assert(is_lisp_pointer(object));
 
     vector = (struct vector *) native_pointer(object);
     length = fixnum_value(vector->length);
-    nwords = CEILING(length * 2 + 2, 2);
+    nwords = CEILING(NWORDS(length, 64) + 2, 2);
 
     return copy_large_unboxed_object(object, nwords);
 }
 
-static int
+static long
 size_vector_complex_single_float(lispobj *where)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(length * 2 + 2, 2);
+    nwords = CEILING(NWORDS(length, 64) + 2, 2);
 
     return nwords;
 }
 #endif
 
 #ifdef SIMPLE_ARRAY_COMPLEX_DOUBLE_FLOAT_WIDETAG
-static int
+static long
 scav_vector_complex_double_float(lispobj *where, lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(length * 4 + 2, 2);
+    nwords = CEILING(NWORDS(length, 128) + 2, 2);
 
     return nwords;
 }
@@ -1307,26 +1378,26 @@ static lispobj
 trans_vector_complex_double_float(lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     gc_assert(is_lisp_pointer(object));
 
     vector = (struct vector *) native_pointer(object);
     length = fixnum_value(vector->length);
-    nwords = CEILING(length * 4 + 2, 2);
+    nwords = CEILING(NWORDS(length, 128) + 2, 2);
 
     return copy_large_unboxed_object(object, nwords);
 }
 
-static int
+static long
 size_vector_complex_double_float(lispobj *where)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
-    nwords = CEILING(length * 4 + 2, 2);
+    nwords = CEILING(NWORDS(length, 128) + 2, 2);
 
     return nwords;
 }
@@ -1334,11 +1405,11 @@ size_vector_complex_double_float(lispobj *where)
 
 
 #ifdef SIMPLE_ARRAY_COMPLEX_LONG_FLOAT_WIDETAG
-static int
+static long
 scav_vector_complex_long_float(lispobj *where, lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
@@ -1351,7 +1422,7 @@ static lispobj
 trans_vector_complex_long_float(lispobj object)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     gc_assert(is_lisp_pointer(object));
 
@@ -1362,11 +1433,11 @@ trans_vector_complex_long_float(lispobj object)
     return copy_large_unboxed_object(object, nwords);
 }
 
-static int
+static long
 size_vector_complex_long_float(lispobj *where)
 {
     struct vector *vector;
-    int length, nwords;
+    long length, nwords;
 
     vector = (struct vector *) where;
     length = fixnum_value(vector->length);
@@ -1407,7 +1478,7 @@ trans_weak_pointer(lispobj object)
     return copy;
 }
 
-static int
+static long
 size_weak_pointer(lispobj *where)
 {
     return WEAK_POINTER_NWORDS;
@@ -1449,12 +1520,13 @@ void scan_weak_pointers(void)
  * initialization
  */
 
-static int
+static long
 scav_lose(lispobj *where, lispobj object)
 {
     lose("no scavenge function for object 0x%08x (widetag 0x%x)",
-        (unsigned long)object,
-        widetag_of(*(lispobj*)native_pointer(object)));
+         (unsigned long)object,
+         widetag_of(*(lispobj*)native_pointer(object)));
+
     return 0; /* bogus return value to satisfy static type checking */
 }
 
@@ -1467,7 +1539,7 @@ trans_lose(lispobj object)
     return NIL; /* bogus return value to satisfy static type checking */
 }
 
-static int
+static long
 size_lose(lispobj *where)
 {
     lose("no size function for object at 0x%08x (widetag 0x%x)",
@@ -1484,7 +1556,7 @@ size_lose(lispobj *where)
 void
 gc_init_tables(void)
 {
-    int i;
+    long i;
 
     /* Set default value in all slots of scavenge table.  FIXME
      * replace this gnarly sizeof with something based on
@@ -1513,7 +1585,11 @@ gc_init_tables(void)
      * tag) get one entry each in the scavenge table. */
     scavtab[BIGNUM_WIDETAG] = scav_unboxed;
     scavtab[RATIO_WIDETAG] = scav_boxed;
+#if N_WORD_BITS == 64
+    scavtab[SINGLE_FLOAT_WIDETAG] = scav_immediate;
+#else
     scavtab[SINGLE_FLOAT_WIDETAG] = scav_unboxed;
+#endif
     scavtab[DOUBLE_FLOAT_WIDETAG] = scav_unboxed;
 #ifdef LONG_FLOAT_WIDETAG
     scavtab[LONG_FLOAT_WIDETAG] = scav_unboxed;
@@ -1530,18 +1606,43 @@ gc_init_tables(void)
 #endif
     scavtab[SIMPLE_ARRAY_WIDETAG] = scav_boxed;
     scavtab[SIMPLE_BASE_STRING_WIDETAG] = scav_base_string;
+#ifdef SIMPLE_CHARACTER_STRING_WIDETAG
+    scavtab[SIMPLE_CHARACTER_STRING_WIDETAG] = scav_character_string;
+#endif
     scavtab[SIMPLE_BIT_VECTOR_WIDETAG] = scav_vector_bit;
     scavtab[SIMPLE_ARRAY_NIL_WIDETAG] = scav_vector_nil;
     scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG] =
        scav_vector_unsigned_byte_2;
     scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG] =
        scav_vector_unsigned_byte_4;
+    scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_7_WIDETAG] =
+       scav_vector_unsigned_byte_8;
     scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG] =
        scav_vector_unsigned_byte_8;
+    scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_15_WIDETAG] =
+       scav_vector_unsigned_byte_16;
     scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG] =
        scav_vector_unsigned_byte_16;
+#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
+    scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG] =
+       scav_vector_unsigned_byte_32;
+#endif
+    scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG] =
+       scav_vector_unsigned_byte_32;
     scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG] =
        scav_vector_unsigned_byte_32;
+#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
+    scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG] =
+       scav_vector_unsigned_byte_64;
+#endif
+#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
+    scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG] =
+       scav_vector_unsigned_byte_64;
+#endif
+#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG
+    scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG] =
+       scav_vector_unsigned_byte_64;
+#endif
 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
     scavtab[SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG] = scav_vector_unsigned_byte_8;
 #endif
@@ -1557,6 +1658,14 @@ gc_init_tables(void)
     scavtab[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG] =
        scav_vector_unsigned_byte_32;
 #endif
+#ifdef SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
+    scavtab[SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG] =
+       scav_vector_unsigned_byte_64;
+#endif
+#ifdef SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
+    scavtab[SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG] =
+       scav_vector_unsigned_byte_64;
+#endif
     scavtab[SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG] = scav_vector_single_float;
     scavtab[SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG] = scav_vector_double_float;
 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
@@ -1575,6 +1684,9 @@ gc_init_tables(void)
        scav_vector_complex_long_float;
 #endif
     scavtab[COMPLEX_BASE_STRING_WIDETAG] = scav_boxed;
+#ifdef COMPLEX_CHARACTER_STRING_WIDETAG
+    scavtab[COMPLEX_CHARACTER_STRING_WIDETAG] = scav_boxed;
+#endif
     scavtab[COMPLEX_VECTOR_NIL_WIDETAG] = scav_boxed;
     scavtab[COMPLEX_BIT_VECTOR_WIDETAG] = scav_boxed;
     scavtab[COMPLEX_VECTOR_WIDETAG] = scav_boxed;
@@ -1582,10 +1694,9 @@ gc_init_tables(void)
     scavtab[CODE_HEADER_WIDETAG] = scav_code_header;
 #ifndef LISP_FEATURE_GENCGC    /* FIXME ..._X86 ? */
     scavtab[SIMPLE_FUN_HEADER_WIDETAG] = scav_fun_header;
-    scavtab[CLOSURE_FUN_HEADER_WIDETAG] = scav_fun_header;
     scavtab[RETURN_PC_HEADER_WIDETAG] = scav_return_pc_header;
 #endif
-#ifdef LISP_FEATURE_X86
+#if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64)
     scavtab[CLOSURE_HEADER_WIDETAG] = scav_closure_header;
     scavtab[FUNCALLABLE_INSTANCE_HEADER_WIDETAG] = scav_closure_header;
 #else
@@ -1594,7 +1705,7 @@ gc_init_tables(void)
 #endif
     scavtab[VALUE_CELL_HEADER_WIDETAG] = scav_boxed;
     scavtab[SYMBOL_HEADER_WIDETAG] = scav_boxed;
-    scavtab[BASE_CHAR_WIDETAG] = scav_immediate;
+    scavtab[CHARACTER_WIDETAG] = scav_immediate;
     scavtab[SAP_WIDETAG] = scav_unboxed;
     scavtab[UNBOUND_MARKER_WIDETAG] = scav_immediate;
     scavtab[INSTANCE_HEADER_WIDETAG] = scav_boxed;
@@ -1609,7 +1720,12 @@ gc_init_tables(void)
        transother[i] = trans_lose;
     transother[BIGNUM_WIDETAG] = trans_unboxed;
     transother[RATIO_WIDETAG] = trans_boxed;
+
+#if N_WORD_BITS == 64
+    transother[SINGLE_FLOAT_WIDETAG] = trans_immediate;
+#else
     transother[SINGLE_FLOAT_WIDETAG] = trans_unboxed;
+#endif
     transother[DOUBLE_FLOAT_WIDETAG] = trans_unboxed;
 #ifdef LONG_FLOAT_WIDETAG
     transother[LONG_FLOAT_WIDETAG] = trans_unboxed;
@@ -1626,6 +1742,9 @@ gc_init_tables(void)
 #endif
     transother[SIMPLE_ARRAY_WIDETAG] = trans_boxed; /* but not GENCGC */
     transother[SIMPLE_BASE_STRING_WIDETAG] = trans_base_string;
+#ifdef SIMPLE_CHARACTER_STRING_WIDETAG
+    transother[SIMPLE_CHARACTER_STRING_WIDETAG] = trans_character_string;
+#endif
     transother[SIMPLE_BIT_VECTOR_WIDETAG] = trans_vector_bit;
     transother[SIMPLE_VECTOR_WIDETAG] = trans_vector;
     transother[SIMPLE_ARRAY_NIL_WIDETAG] = trans_vector_nil;
@@ -1633,12 +1752,34 @@ gc_init_tables(void)
        trans_vector_unsigned_byte_2;
     transother[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG] =
        trans_vector_unsigned_byte_4;
+    transother[SIMPLE_ARRAY_UNSIGNED_BYTE_7_WIDETAG] =
+       trans_vector_unsigned_byte_8;
     transother[SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG] =
        trans_vector_unsigned_byte_8;
+    transother[SIMPLE_ARRAY_UNSIGNED_BYTE_15_WIDETAG] =
+       trans_vector_unsigned_byte_16;
     transother[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG] =
        trans_vector_unsigned_byte_16;
+#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
+    transother[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG] =
+       trans_vector_unsigned_byte_32;
+#endif
+    transother[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG] =
+       trans_vector_unsigned_byte_32;
     transother[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG] =
        trans_vector_unsigned_byte_32;
+#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
+    transother[SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG] =
+       trans_vector_unsigned_byte_64;
+#endif
+#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
+    transother[SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG] =
+       trans_vector_unsigned_byte_64;
+#endif
+#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG
+    transother[SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG] =
+       trans_vector_unsigned_byte_64;
+#endif
 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
     transother[SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG] =
        trans_vector_unsigned_byte_8;
@@ -1655,6 +1796,14 @@ gc_init_tables(void)
     transother[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG] =
        trans_vector_unsigned_byte_32;
 #endif
+#ifdef SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
+    transother[SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG] =
+       trans_vector_unsigned_byte_64;
+#endif
+#ifdef SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
+    transother[SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG] =
+       trans_vector_unsigned_byte_64;
+#endif
     transother[SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG] =
        trans_vector_single_float;
     transother[SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG] =
@@ -1676,19 +1825,21 @@ gc_init_tables(void)
        trans_vector_complex_long_float;
 #endif
     transother[COMPLEX_BASE_STRING_WIDETAG] = trans_boxed;
+#ifdef COMPLEX_CHARACTER_STRING_WIDETAG
+    transother[COMPLEX_CHARACTER_STRING_WIDETAG] = trans_boxed;
+#endif
     transother[COMPLEX_BIT_VECTOR_WIDETAG] = trans_boxed;
     transother[COMPLEX_VECTOR_NIL_WIDETAG] = trans_boxed;
     transother[COMPLEX_VECTOR_WIDETAG] = trans_boxed;
     transother[COMPLEX_ARRAY_WIDETAG] = trans_boxed;
     transother[CODE_HEADER_WIDETAG] = trans_code_header;
     transother[SIMPLE_FUN_HEADER_WIDETAG] = trans_fun_header;
-    transother[CLOSURE_FUN_HEADER_WIDETAG] = trans_fun_header;
     transother[RETURN_PC_HEADER_WIDETAG] = trans_return_pc_header;
     transother[CLOSURE_HEADER_WIDETAG] = trans_boxed;
     transother[FUNCALLABLE_INSTANCE_HEADER_WIDETAG] = trans_boxed;
     transother[VALUE_CELL_HEADER_WIDETAG] = trans_boxed;
     transother[SYMBOL_HEADER_WIDETAG] = trans_boxed;
-    transother[BASE_CHAR_WIDETAG] = trans_immediate;
+    transother[CHARACTER_WIDETAG] = trans_immediate;
     transother[SAP_WIDETAG] = trans_unboxed;
     transother[UNBOUND_MARKER_WIDETAG] = trans_immediate;
     transother[WEAK_POINTER_WIDETAG] = trans_weak_pointer;
@@ -1699,18 +1850,22 @@ gc_init_tables(void)
     for (i = 0; i < ((sizeof sizetab)/(sizeof sizetab[0])); i++)
        sizetab[i] = size_lose;
     for (i = 0; i < (1<<(N_WIDETAG_BITS-N_LOWTAG_BITS)); i++) {
-       sizetab[EVEN_FIXNUM_LOWTAG|(i<<3)] = size_immediate;
-       sizetab[FUN_POINTER_LOWTAG|(i<<3)] = size_pointer;
+       sizetab[EVEN_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = size_immediate;
+       sizetab[FUN_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = size_pointer;
        /* skipping OTHER_IMMEDIATE_0_LOWTAG */
-       sizetab[LIST_POINTER_LOWTAG|(i<<3)] = size_pointer;
-       sizetab[ODD_FIXNUM_LOWTAG|(i<<3)] = size_immediate;
-       sizetab[INSTANCE_POINTER_LOWTAG|(i<<3)] = size_pointer;
+       sizetab[LIST_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = size_pointer;
+       sizetab[ODD_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = size_immediate;
+       sizetab[INSTANCE_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = size_pointer;
        /* skipping OTHER_IMMEDIATE_1_LOWTAG */
-       sizetab[OTHER_POINTER_LOWTAG|(i<<3)] = size_pointer;
+       sizetab[OTHER_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = size_pointer;
     }
     sizetab[BIGNUM_WIDETAG] = size_unboxed;
     sizetab[RATIO_WIDETAG] = size_boxed;
+#if N_WORD_BITS == 64
+    sizetab[SINGLE_FLOAT_WIDETAG] = size_immediate;
+#else
     sizetab[SINGLE_FLOAT_WIDETAG] = size_unboxed;
+#endif
     sizetab[DOUBLE_FLOAT_WIDETAG] = size_unboxed;
 #ifdef LONG_FLOAT_WIDETAG
     sizetab[LONG_FLOAT_WIDETAG] = size_unboxed;
@@ -1727,6 +1882,9 @@ gc_init_tables(void)
 #endif
     sizetab[SIMPLE_ARRAY_WIDETAG] = size_boxed;
     sizetab[SIMPLE_BASE_STRING_WIDETAG] = size_base_string;
+#ifdef SIMPLE_CHARACTER_STRING_WIDETAG
+    sizetab[SIMPLE_CHARACTER_STRING_WIDETAG] = size_character_string;
+#endif
     sizetab[SIMPLE_BIT_VECTOR_WIDETAG] = size_vector_bit;
     sizetab[SIMPLE_VECTOR_WIDETAG] = size_vector;
     sizetab[SIMPLE_ARRAY_NIL_WIDETAG] = size_vector_nil;
@@ -1734,12 +1892,34 @@ gc_init_tables(void)
        size_vector_unsigned_byte_2;
     sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG] =
        size_vector_unsigned_byte_4;
+    sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_7_WIDETAG] =
+       size_vector_unsigned_byte_8;
     sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG] =
        size_vector_unsigned_byte_8;
+    sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_15_WIDETAG] =
+       size_vector_unsigned_byte_16;
     sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_16_WIDETAG] =
        size_vector_unsigned_byte_16;
+#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG
+    sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_29_WIDETAG] =
+       size_vector_unsigned_byte_32;
+#endif
+    sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_31_WIDETAG] =
+       size_vector_unsigned_byte_32;
     sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_32_WIDETAG] =
        size_vector_unsigned_byte_32;
+#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG
+    sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_60_WIDETAG] =
+       size_vector_unsigned_byte_64;
+#endif
+#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG
+    sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_63_WIDETAG] =
+       size_vector_unsigned_byte_64;
+#endif
+#ifdef SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG
+    sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_64_WIDETAG] =
+       size_vector_unsigned_byte_64;
+#endif
 #ifdef SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG
     sizetab[SIMPLE_ARRAY_SIGNED_BYTE_8_WIDETAG] = size_vector_unsigned_byte_8;
 #endif
@@ -1755,6 +1935,14 @@ gc_init_tables(void)
     sizetab[SIMPLE_ARRAY_SIGNED_BYTE_32_WIDETAG] =
        size_vector_unsigned_byte_32;
 #endif
+#ifdef SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG
+    sizetab[SIMPLE_ARRAY_SIGNED_BYTE_61_WIDETAG] =
+       size_vector_unsigned_byte_64;
+#endif
+#ifdef SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG
+    sizetab[SIMPLE_ARRAY_SIGNED_BYTE_64_WIDETAG] =
+       size_vector_unsigned_byte_64;
+#endif
     sizetab[SIMPLE_ARRAY_SINGLE_FLOAT_WIDETAG] = size_vector_single_float;
     sizetab[SIMPLE_ARRAY_DOUBLE_FLOAT_WIDETAG] = size_vector_double_float;
 #ifdef SIMPLE_ARRAY_LONG_FLOAT_WIDETAG
@@ -1773,6 +1961,9 @@ gc_init_tables(void)
        size_vector_complex_long_float;
 #endif
     sizetab[COMPLEX_BASE_STRING_WIDETAG] = size_boxed;
+#ifdef COMPLEX_CHARACTER_STRING_WIDETAG
+    sizetab[COMPLEX_CHARACTER_STRING_WIDETAG] = size_boxed;
+#endif
     sizetab[COMPLEX_VECTOR_NIL_WIDETAG] = size_boxed;
     sizetab[COMPLEX_BIT_VECTOR_WIDETAG] = size_boxed;
     sizetab[COMPLEX_VECTOR_WIDETAG] = size_boxed;
@@ -1781,17 +1972,38 @@ gc_init_tables(void)
 #if 0
     /* We shouldn't see these, so just lose if it happens. */
     sizetab[SIMPLE_FUN_HEADER_WIDETAG] = size_function_header;
-    sizetab[CLOSURE_FUN_HEADER_WIDETAG] = size_function_header;
     sizetab[RETURN_PC_HEADER_WIDETAG] = size_return_pc_header;
 #endif
     sizetab[CLOSURE_HEADER_WIDETAG] = size_boxed;
     sizetab[FUNCALLABLE_INSTANCE_HEADER_WIDETAG] = size_boxed;
     sizetab[VALUE_CELL_HEADER_WIDETAG] = size_boxed;
     sizetab[SYMBOL_HEADER_WIDETAG] = size_boxed;
-    sizetab[BASE_CHAR_WIDETAG] = size_immediate;
+    sizetab[CHARACTER_WIDETAG] = size_immediate;
     sizetab[SAP_WIDETAG] = size_unboxed;
     sizetab[UNBOUND_MARKER_WIDETAG] = size_immediate;
     sizetab[WEAK_POINTER_WIDETAG] = size_weak_pointer;
     sizetab[INSTANCE_HEADER_WIDETAG] = size_boxed;
     sizetab[FDEFN_WIDETAG] = size_boxed;
 }
+
+\f
+/* Find the code object for the given pc, or return NULL on
+   failure. */
+lispobj *
+component_ptr_from_pc(lispobj *pc)
+{
+    lispobj *object = NULL;
+
+    if ( (object = search_read_only_space(pc)) )
+       ;
+    else if ( (object = search_static_space(pc)) )
+       ;
+    else
+       object = search_dynamic_space(pc);
+
+    if (object) /* if we found something */
+       if (widetag_of(*object) == CODE_HEADER_WIDETAG)
+           return(object);
+
+    return (NULL);
+}