diff options
author | Andy Wingo <wingo@pobox.com> | 2011-05-13 18:40:28 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2011-05-13 19:30:01 +0200 |
commit | c2f56e4d898b834e16d668b3d0aedfcca728a909 (patch) | |
tree | 103364a46cfe7df8afa0a758fb72fdbf41fc84bf | |
parent | 6ab63d44462324bc8dd6f0495e61a46397941203 (diff) | |
download | guile-c2f56e4d898b834e16d668b3d0aedfcca728a909.tar.gz |
SCM always 64 bits wide
* libguile/tags.h: Update some comments.
(scm_t_signed_bits, scm_t_bits): Bump to 64-bits for all platforms.
(SCM_T_SIGNED_BITS_MAX, SCM_T_SIGNED_BITS_MIN, SCM_T_BITS_MAX): Adapt
accordingly.
(union SCM): For 32-bit the pointer will be in the low half of the
bits. Define accessors to get at the low 32 bits.
(SCM_TO_POINTER, SCM_FROM_POINTER): New defines, will replace SCM2PTR
and PTR2SCM in common usage.
(SCM_HEAP_POINTER, SCM_HEAP_OBJECT, SCM_SET_HEAP_OBJECT, SCM_HEAP_DATA)
(SCM_SET_HEAP_DATA): New defines, will replace the SCM_GC_CELL
macros.
* libguile/gc.h: Remove comment about UNICOS. All pointer<->scm stuff
is handled by tags.h now.
(SCM2PTR, PTR2SCM): Define in terms of SCM_TO_POINTER and
SCM_FROM_POINTER.
(SCM_GC_CELL_OBJECT, SCM_GC_CELL_WORD, SCM_GC_SET_CELL_OBJECT)
(SCM_GC_SET_CELL_WORD): Define in terms of the SCM_HEAP_* macros.
* libguile/macros.c (scm_make_syntax_transformer): Cast a function
pointer to scm_t_bits; a new warning.
-rw-r--r-- | libguile/gc.h | 25 | ||||
-rw-r--r-- | libguile/macros.c | 2 | ||||
-rw-r--r-- | libguile/tags.h | 91 |
3 files changed, 74 insertions, 44 deletions
diff --git a/libguile/gc.h b/libguile/gc.h index 2e2fc1fa2..5bc54ed80 100644 --- a/libguile/gc.h +++ b/libguile/gc.h @@ -35,21 +35,9 @@ typedef struct scm_t_cell SCM word_1; } scm_t_cell; -/* Cray machines have pointers that are incremented once for each - * word, rather than each byte, the 3 most significant bits encode the - * byte within the word. The following macros deal with this by - * storing the native Cray pointers like the ones that looks like scm - * expects. This is done for any pointers that point to a cell, - * pointers to scm_vector elts, functions, &c are not munged. - */ -#ifdef _UNICOS -# define SCM2PTR(x) ((scm_t_cell *) (SCM_UNPACK (x) >> 3)) -# define PTR2SCM(x) (SCM_PACK (((scm_t_bits) (x)) << 3)) -#else -# define SCM2PTR(x) ((scm_t_cell *) (SCM_UNPACK (x))) -# define PTR2SCM(x) (SCM_PACK ((scm_t_bits) (x))) -#endif /* def _UNICOS */ +#define SCM2PTR(x) SCM_TO_POINTER (x) +#define PTR2SCM(x) SCM_FROM_POINTER (x) /* Low level cell data accessing macros. These macros should only be used @@ -58,12 +46,11 @@ typedef struct scm_t_cell * in debug mode. In particular these macros will even work for free cells, * which should never be encountered by user code. */ -#define SCM_GC_CELL_OBJECT(x, n) (((SCM *)SCM2PTR (x)) [n]) -#define SCM_GC_CELL_WORD(x, n) (SCM_UNPACK (SCM_GC_CELL_OBJECT ((x), (n)))) +#define SCM_GC_CELL_OBJECT(x, n) SCM_HEAP_OBJECT (x, n) +#define SCM_GC_CELL_WORD(x, n) SCM_HEAP_DATA (x, n) -#define SCM_GC_SET_CELL_OBJECT(x, n, v) ((((SCM *)SCM2PTR (x)) [n]) = (v)) -#define SCM_GC_SET_CELL_WORD(x, n, v) \ - (SCM_GC_SET_CELL_OBJECT ((x), (n), SCM_PACK (v))) +#define SCM_GC_SET_CELL_OBJECT(x, n, v) SCM_SET_HEAP_OBJECT (x, n, v) +#define SCM_GC_SET_CELL_WORD(x, n, v) SCM_SET_HEAP_DATA (x, n, v) #define SCM_GC_CELL_TYPE(x) (SCM_GC_CELL_OBJECT ((x), 0)) diff --git a/libguile/macros.c b/libguile/macros.c index 556e60f57..bf351e4c1 100644 --- a/libguile/macros.c +++ b/libguile/macros.c @@ -103,7 +103,7 @@ SCM_DEFINE (scm_make_syntax_transformer, "make-syntax-transformer", 3, 0, 0, SCM_VALIDATE_SYMBOL (2, type); z = scm_words (scm_tc16_macro, 5); - SCM_SET_SMOB_DATA_N (z, 1, prim); + SCM_SET_SMOB_DATA_N (z, 1, (scm_t_bits)prim); SCM_SET_SMOB_OBJECT_N (z, 2, name); SCM_SET_SMOB_OBJECT_N (z, 3, type); SCM_SET_SMOB_OBJECT_N (z, 4, binding); diff --git a/libguile/tags.h b/libguile/tags.h index 0db6e39dc..f5009027d 100644 --- a/libguile/tags.h +++ b/libguile/tags.h @@ -62,12 +62,12 @@ * scm_t_bits: */ -typedef scm_t_intptr scm_t_signed_bits; -typedef scm_t_uintptr scm_t_bits; +typedef scm_t_int64 scm_t_signed_bits; +typedef scm_t_uint64 scm_t_bits; -#define SCM_T_SIGNED_BITS_MAX SCM_T_INTPTR_MAX -#define SCM_T_SIGNED_BITS_MIN SCM_T_INTPTR_MIN -#define SCM_T_BITS_MAX SCM_T_UINTPTR_MAX +#define SCM_T_SIGNED_BITS_MAX SCM_T_INT64_MAX +#define SCM_T_SIGNED_BITS_MIN SCM_T_INT64_MIN +#define SCM_T_BITS_MAX SCM_T_UINT64_MAX /* But as external interface, we define SCM. @@ -75,6 +75,17 @@ typedef scm_t_uintptr scm_t_bits; union SCM { scm_t_bits as_bits; + + /* If you set a field of the SCM union, it needs to set all the bits. + The following types are not guaranteed to do so, so we put them in + a sub-union, to indicate that they are for read access only. */ + union SCM_read_only { +#if SCM_IS_BIG_ENDIAN + struct { scm_t_uint32 high, low; } as_uint32; +#else + struct { scm_t_uint32 low, high; } as_uint32; +#endif + } read; }; typedef union SCM SCM; @@ -110,29 +121,61 @@ typedef union SCM SCM; * being pointed to consists of at least two scm_t_bits variables and thus * can be used to hold pointers to malloc'ed memory of any size. * - * The 'heap' is the memory area that is under control of Guile's garbage - * collector. It holds 'single-cells' or 'double-cells', which consist of - * either two or four scm_t_bits variables, respectively. It is guaranteed - * that the address of a cell on the heap is 8-byte aligned. That is, since - * non-immediates hold a cell address, the three least significant bits of a - * non-immediate can be used to store additional information. The bits are - * used to store information about the object's type and thus are called - * tc3-bits, where tc stands for type-code. - * - * For a given SCM value, the distinction whether it holds an immediate or - * non-immediate object is based on the tc3-bits (see above) of its scm_t_bits + * The 'heap' is the memory area that is under control of Guile's + * garbage collector. The size of the pointed-to memory will be at + * least 8 bytes, and its address will be 8-byte aligned. + * + * This eight-byte alignment means that for a non-immediate -- a heap + * object -- that the three least significant bits of its address will + * be zero. Guile can then use these bits as type tags. These lowest + * three bits are called tc3-bits, where tc stands for type-code. + * + * For a given SCM value, the distinction whether it holds an immediate + * or non-immediate object is based on the tc3-bits of its scm_t_bits * equivalent: If the tc3-bits equal #b000, then the SCM value holds a - * non-immediate, and the scm_t_bits variable's value is just the pointer to - * the heap cell. + * non-immediate, and the scm_t_bits variable's value is just the + * pointer to the heap cell. * * Summarized, the data of a scheme object that is represented by a SCM * variable consists of a) the SCM variable itself, b) in case of - * non-immediates the data of the single-cell or double-cell the SCM object - * points to, c) in case of non-immediates potentially additional data outside - * of the heap (like for example malloc'ed data), and d) in case of - * non-immediates potentially additional data inside of the heap, since data - * stored in b) and c) may hold references to other cells. - * + * non-immediates the heap data that the SCM object points to, c) in + * case of non-immediates potentially additional data outside of the + * heap (like for example malloc'ed data), and d) in case of + * non-immediates potentially additional data inside of the heap, since + * data stored in b) and c) may hold references to other cells. + */ + + +/* Let's take a breather and define some helpers to access Scheme values + from the heap. + + Though C99 doesn't specify whether pointers are represented the same + way in memory as integers are, it seems to be universal, besides + UNICOS. We make that assumption, having checked at configure-time + that it does indeed hold true on this platform. */ + +#if SCM_SIZEOF_VOID_P == 4 +#define SCM_TO_POINTER(x) ((void *)((x).read.as_uint32.low)) +#elif SCM_SIZEOF_VOID_P == 8 +#define SCM_TO_POINTER(x) ((void *)((x).as_bits)) +#else +#error Unhandled word size. +#endif + +#define SCM_FROM_POINTER(x) SCM_PACK ((scm_t_bits)x) + +#define SCM_HEAP_POINTER(x) ((SCM *) SCM_TO_POINTER (x)) +#define SCM_HEAP_OBJECT(x, n) \ + (SCM_HEAP_POINTER (x) [(n)]) +#define SCM_SET_HEAP_OBJECT(x, n, o) \ + SCM_HEAP_OBJECT (x, n) = (o) + +#define SCM_HEAP_DATA(x, n) \ + (SCM_HEAP_OBJECT (x, n).as_bits) +#define SCM_SET_HEAP_DATA(x, n, b) \ + SCM_HEAP_DATA (x, n) = (b) + +/* * * Immediates * |