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.
This commit is contained in:
Alastair Bridgewater 2010-02-14 10:56:01 -05:00 committed by Alastair Bridgewater
parent 48d0753f3d
commit a369686d65
5 changed files with 61 additions and 21 deletions

7
NEWS
View file

@ -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

View 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"

View file

@ -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

View 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;

View 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,