summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2011-05-13 18:40:28 +0200
committerAndy Wingo <wingo@pobox.com>2011-05-13 19:30:01 +0200
commitc2f56e4d898b834e16d668b3d0aedfcca728a909 (patch)
tree103364a46cfe7df8afa0a758fb72fdbf41fc84bf
parent6ab63d44462324bc8dd6f0495e61a46397941203 (diff)
downloadguile-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.h25
-rw-r--r--libguile/macros.c2
-rw-r--r--libguile/tags.h91
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
*