From a369686d65039bc87497039ac4db6c4c7c44f443 Mon Sep 17 00:00:00 2001 From: Alastair Bridgewater Date: Sun, 14 Feb 2010 10:56:01 -0500 Subject: [PATCH] 63-bit fixnums on 64-bit targets. * 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 | 7 +++++++ package-data-list.lisp-expr | 2 ++ src/compiler/generic/early-vm.lisp | 19 +++++++++++++++++- src/runtime/gc-common.c | 16 ++++++++++----- src/runtime/print.c | 38 ++++++++++++++++++++++-------------- 5 files changed, 61 insertions(+), 21 deletions(-) diff --git a/NEWS b/NEWS index 092ae07..846ce95 100644 --- 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 diff --git a/package-data-list.lisp-expr b/package-data-list.lisp-expr index c5fb4ab..3adfbee 100644 --- a/package-data-list.lisp-expr +++ b/package-data-list.lisp-expr @@ -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" diff --git a/src/compiler/generic/early-vm.lisp b/src/compiler/generic/early-vm.lisp index 8810860..304637d 100644 --- a/src/compiler/generic/early-vm.lisp +++ b/src/compiler/generic/early-vm.lisp @@ -19,7 +19,24 @@ ;;; 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 diff --git a/src/runtime/gc-common.c b/src/runtime/gc-common.c index 34248fe..a3eb313 100644 --- a/src/runtime/gc-common.c +++ b/src/runtime/gc-common.c @@ -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<>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, -- 1.7.10.4