Reorder 64-bit lowtags.
authorAlastair Bridgewater <nyef_sbcl@lisphacker.com>
Mon, 30 Nov 2009 23:09:03 +0000 (18:09 -0500)
committerAlastair Bridgewater <nyef@virtdev-1.lisphacker.com>
Wed, 19 Oct 2011 19:49:32 +0000 (15:49 -0400)
  * Move 64-bit lowtags around so that all non-fixnum tags have the low
bit set.

  * Fix up print_obj() to compensate for the layout change.

  * Fix up is_lisp_pointer() to compensate for the layout change.

  * Change other_immediate_lowtag_p() to take advantage of the
distribution of other-immediate lowtags.

src/compiler/generic/early-objdef.lisp
src/runtime/print.c
src/runtime/runtime.h

index 6967fe4..bda8fcd 100644 (file)
 ;;; might easily be more, since these values have stayed highly
 ;;; constrained for more than a decade, an inviting target for
 ;;; inventive abstraction-phobic maintainers.:-)
+;;;
+;;; Another way to look at lowtags is that there is no one lowtag
+;;; length.  On 32-bit platforms, fixnums and other-immediates have a
+;;; lowtag length of two bits, and pointers have a lowtag length of
+;;; three bits.  On 64-bit platforms, fixnums and pointers gain an
+;;; extra bit, and six "pad" lowtags waste the extra encoding space so
+;;; obtained.
+;;;
+;;;  x00 -- fixnum
+;;;  x10 -- other-immediate
+;;;  001 -- instance-pointer
+;;;  011 -- list-pointer
+;;;  101 -- fun-pointer
+;;;  111 -- other-pointer
+;;;
+;;; If you change the tag layout, check the various functions in
+;;; src/runtime/runtime.h to see if they need to be updated, along
+;;; with print_obj() in src/runtime/print.c, possibly gc_init_tables()
+;;; in src/runtime/gc-common-c and possibly the code in src/code/room.
 (eval-when (:compile-toplevel :load-toplevel :execute)
   ;; The EVAL-WHEN is necessary (at least for Lispworks), because the
   ;; second DEFENUM uses the value of OTHER-IMMEDIATE-0-LOWTAG, which is
   #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
   (defenum ()
     even-fixnum-lowtag
-    instance-pointer-lowtag
     other-immediate-0-lowtag
     pad0-lowtag
-    pad1-lowtag pad2-lowtag
+    instance-pointer-lowtag
+    pad1-lowtag
     other-immediate-1-lowtag
+    pad2-lowtag
     list-pointer-lowtag
     odd-fixnum-lowtag
-    fun-pointer-lowtag
     other-immediate-2-lowtag
     pad3-lowtag
+    fun-pointer-lowtag
     pad4-lowtag
-    pad5-lowtag
     other-immediate-3-lowtag
+    pad5-lowtag
     other-pointer-lowtag)
   #!+#.(cl:if (cl:= 32 sb!vm:n-word-bits) '(and) '(or))
   (defenum ()
index a76c9ad..484a99b 100644 (file)
@@ -605,15 +605,15 @@ static void print_obj(char *prefix, lispobj obj)
 {
 #ifdef LISP_FEATURE_X86_64
     static void (*verbose_fns[])(lispobj obj)
-        = {print_fixnum, print_struct, print_otherimm, print_unknown,
-           print_unknown, print_unknown, print_otherimm, print_list,
-           print_fixnum, print_otherptr, print_otherimm, print_unknown,
-           print_unknown, print_unknown, print_otherimm, print_otherptr};
+        = {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};
     static void (*brief_fns[])(lispobj obj)
-        = {brief_fixnum, brief_struct, brief_otherimm, print_unknown,
-           print_unknown,  print_unknown, brief_otherimm, brief_list,
-           brief_fixnum, brief_otherptr, brief_otherimm, print_unknown,
-           print_unknown,  print_unknown,brief_otherimm, brief_otherptr};
+        = {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};
 #else
     static void (*verbose_fns[])(lispobj obj)
         = {print_fixnum, print_struct, print_otherimm, print_list,
index 65c2e48..abf27da 100644 (file)
@@ -168,7 +168,11 @@ FDEFN(lispobj obj)
 static inline int
 is_lisp_pointer(lispobj obj)
 {
+#if N_WORD_BITS == 64
+    return (obj & 3) == 3;
+#else
     return obj & 1;
+#endif
 }
 
 #include "fixnump.h"