63-bit fixnums on 64-bit targets.
authorAlastair Bridgewater <nyef_sbcl@lisphacker.com>
Sun, 14 Feb 2010 15:56:01 +0000 (10:56 -0500)
committerAlastair Bridgewater <nyef@virtdev-1.lisphacker.com>
Thu, 20 Oct 2011 14:44:01 +0000 (10:44 -0400)
  * This is mostly just a matter of spreading the PADn lowtags around,
one or two cases of adjusting a constant, and some KLUDGEing around in
the runtime to make everything work for 1 <= n-fixnum-tag-bits <= 3.

  * Yes, this means that you can change n-fixnum-tag-bits before
building in order to return to a 61-bit fixnum world.  Or you can have
62-bit fixnums if you want.

NEWS
package-data-list.lisp-expr
src/compiler/generic/early-vm.lisp
src/runtime/gc-common.c
src/runtime/print.c

diff --git a/NEWS b/NEWS
index 092ae07..846ce95 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,11 @@
 ;;;; -*- coding: utf-8; fill-column: 78 -*-
+changes relative to sbcl-1.0.52:
+  * enhancement: on 64-bit targets, in src/compiler/generic/early-vm.lisp,
+    the parameter n-fixnum-tag-bits may now vary from 1 (fixnum =
+    (signed-byte 63)) to 3 (fixnum = (signed-byte 61)) at build-time.
+  * minor(?) incompatible(?) change: The default fixnum width on 64-bit
+    targets is now 63 bits (up from 61).
+
 changes in sbcl-1.0.52 relative to sbcl-1.0.51:
   * enhancement: ASDF has been updated to version 2.017.
   * enhancement: the --core command line option now accepts binaries with
index c5fb4ab..3adfbee 100644 (file)
@@ -2673,6 +2673,8 @@ structure representations"
                "OTHER-IMMEDIATE-2-LOWTAG"
                "OTHER-IMMEDIATE-3-LOWTAG"
                "OTHER-POINTER-LOWTAG"
+               "PAD0-LOWTAG" "PAD1-LOWTAG" "PAD2-LOWTAG"
+               "PAD3-LOWTAG" "PAD4-LOWTAG" "PAD5-LOWTAG"
                "PAD-DATA-BLOCK" "PENDING-INTERRUPT-TRAP"
                "PRIMITIVE-OBJECT" "PRIMITIVE-OBJECT-WIDETAG"
                "PRIMITIVE-OBJECT-LOWTAG" "PRIMITIVE-OBJECT-NAME"
index 8810860..304637d 100644 (file)
 ;;; pointer
 (def!constant lowtag-limit (ash 1 n-lowtag-bits))
 ;;; the number of tag bits used for a fixnum
-(def!constant n-fixnum-tag-bits (1- n-lowtag-bits))
+(def!constant n-fixnum-tag-bits
+    (if (= 64 sb!vm:n-word-bits)
+        ;; On 64-bit targets, this may be as low as 1 (for 63-bit
+        ;; fixnums) and as high as 3 (for 61-bit fixnums).  The
+        ;; constraint on the low end is that we need at least one bit
+        ;; to determine if a value is a fixnum or not, and the
+        ;; constraint on the high end is that it must not exceed
+        ;; WORD-SHIFT (defined below) due to the use of unboxed
+        ;; word-aligned byte pointers as boxed values in various
+        ;; places.  FIXME: This should possibly be exposed for
+        ;; configuration via customize-target-features.
+        1
+        ;; On 32-bit targets, this may be as low as 2 (for 30-bit
+        ;; fixnums) and as high as 2 (for 30-bit fixnums).  The
+        ;; constraint on the low end is simple overcrowding of the
+        ;; lowtag space, and the constraint on the high end is that it
+        ;; must not exceed WORD-SHIFT.
+        (1- n-lowtag-bits)))
 ;;; the fixnum tag mask
 (def!constant fixnum-tag-mask (1- (ash 1 n-fixnum-tag-bits)))
 ;;; the bit width of fixnums
index 34248fe..a3eb313 100644 (file)
@@ -1916,7 +1916,7 @@ size_lose(lispobj *where)
 void
 gc_init_tables(void)
 {
-    unsigned long i;
+    unsigned long i, j;
 
     /* Set default value in all slots of scavenge table.  FIXME
      * replace this gnarly sizeof with something based on
@@ -1931,11 +1931,14 @@ gc_init_tables(void)
      */
 
     for (i = 0; i < (1<<(N_WIDETAG_BITS-N_LOWTAG_BITS)); i++) {
-        scavtab[EVEN_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_immediate;
+        for (j = 0; j < (1<<N_LOWTAG_BITS); j++) {
+            if (fixnump(j)) {
+                scavtab[j|(i<<N_LOWTAG_BITS)] = scav_immediate;
+            }
+        }
         scavtab[FUN_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_fun_pointer;
         /* skipping OTHER_IMMEDIATE_0_LOWTAG */
         scavtab[LIST_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_list_pointer;
-        scavtab[ODD_FIXNUM_LOWTAG|(i<<N_LOWTAG_BITS)] = scav_immediate;
         scavtab[INSTANCE_POINTER_LOWTAG|(i<<N_LOWTAG_BITS)] =
             scav_instance_pointer;
         /* skipping OTHER_IMMEDIATE_1_LOWTAG */
@@ -2213,11 +2216,14 @@ 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<<N_LOWTAG_BITS)] = size_immediate;
+        for (j = 0; j < (1<<N_LOWTAG_BITS); j++) {
+            if (fixnump(j)) {
+                sizetab[j|(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<<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<<N_LOWTAG_BITS)] = size_pointer;
index 484a99b..61d5a73 100644 (file)
@@ -101,8 +101,18 @@ static void newline(char *label)
 }
 
 
+static void print_unknown(lispobj obj)
+{
+  printf("unknown object: %p", (void *)obj);
+}
+
 static void brief_fixnum(lispobj obj)
 {
+    /* KLUDGE: Rather than update the tables in print_obj(), we
+       declare all fixnum-or-unknown tags to be fixnums and sort it
+       out here with a guard clause. */
+    if (!fixnump(obj)) return print_unknown(obj);
+
 #ifndef LISP_FEATURE_ALPHA
     printf("%ld", ((long)obj)>>2);
 #else
@@ -112,6 +122,11 @@ static void brief_fixnum(lispobj obj)
 
 static void print_fixnum(lispobj obj)
 {
+    /* KLUDGE: Rather than update the tables in print_obj(), we
+       declare all fixnum-or-unknown tags to be fixnums and sort it
+       out here with a guard clause. */
+    if (!fixnump(obj)) return print_unknown(obj);
+
 #ifndef LISP_FEATURE_ALPHA
     printf(": %ld", ((long)obj)>>2);
 #else
@@ -221,13 +236,6 @@ static void brief_list(lispobj obj)
     }
 }
 
-#ifdef LISP_FEATURE_X86_64
-static void print_unknown(lispobj obj)
-{
-  printf("unknown object: %p", (void *)obj);
-}
-#endif
-
 static void print_list(lispobj obj)
 {
     if (!is_valid_lisp_addr((os_vm_address_t)native_pointer(obj))) {
@@ -605,15 +613,15 @@ static void print_obj(char *prefix, lispobj obj)
 {
 #ifdef LISP_FEATURE_X86_64
     static void (*verbose_fns[])(lispobj obj)
-        = {print_fixnum,  print_otherimm, print_unknown, print_struct,
-           print_unknown, print_otherimm, print_unknown, print_list,
-           print_fixnum,  print_otherimm, print_unknown, print_otherptr,
-           print_unknown, print_otherimm, print_unknown, print_otherptr};
+        = {print_fixnum, print_otherimm, print_fixnum, print_struct,
+           print_fixnum, print_otherimm, print_fixnum, print_list,
+           print_fixnum, print_otherimm, print_fixnum, print_otherptr,
+           print_fixnum, print_otherimm, print_fixnum, print_otherptr};
     static void (*brief_fns[])(lispobj obj)
-        = {brief_fixnum,  brief_otherimm, print_unknown, brief_struct,
-           print_unknown, brief_otherimm, print_unknown, brief_list,
-           brief_fixnum,  brief_otherimm, print_unknown, brief_otherptr,
-           print_unknown, brief_otherimm, print_unknown, brief_otherptr};
+        = {brief_fixnum, brief_otherimm, brief_fixnum, brief_struct,
+           brief_fixnum, brief_otherimm, brief_fixnum, brief_list,
+           brief_fixnum, brief_otherimm, brief_fixnum, brief_otherptr,
+           brief_fixnum, brief_otherimm, brief_fixnum, brief_otherptr};
 #else
     static void (*verbose_fns[])(lispobj obj)
         = {print_fixnum, print_struct, print_otherimm, print_list,