summaryrefslogtreecommitdiff
path: root/libguile/weaks.c
diff options
context:
space:
mode:
authorLudovic Courtes <ludovic.courtes@laas.fr>2006-06-25 22:42:19 +0000
committerLudovic Courtès <ludo@gnu.org>2008-09-10 20:27:34 +0200
commit986ec82209fe327e44dc897d8f5219b1f53ed939 (patch)
tree6fe27be780eebef2a160ae1e83fa49b0fcbac93e /libguile/weaks.c
parentc6a35e35f76e800bd85cb28e6ace743aedd87e61 (diff)
downloadguile-986ec82209fe327e44dc897d8f5219b1f53ed939.tar.gz
Moved weak pair code into `weaks.[ch]'.
* libguile/hashtab.c: Don't include <gc/gc_typed.h> and <gc/gc.h>. Updated users of weak (wcar_cell_descr): Removed. (wcdr_cell_descr): Removed. (scm_weak_car_cell): Removed. (scm_weak_cdr_cell): Removed. (scm_doubly_weak_cell): Removed. (SCM_WEAK_CELL_*_DELETED_P): Removed. (SCM_WEAK_CELL_WORD): Removed. (SCM_WEAK_CELL_C[AD]R): Removed. (scm_hashtab_prehistory): Don't initialize weak pairs. * libguile/init.c (scm_i_init_guile): Invoke `scm_weaks_prehistory ()' before `scm_hashtab_prehistory ()' in order to initialize weak pairs. * libguile/weaks.c: Include <gc/gc.h> and <gc/gc_typed.h>. (wc[ad]r_cell_descr): New. (scm_weak_c[ad]r_pair): New. (scm_doubly_weak_pair): New. (scm_weaks_prehistory): New. * libguile/weaks.h (scm_weak_c[ad]r_pair): New declaration. (scm_doubly_weak_pair): New declaration. (SCM_WEAK_PAIR_WORD_DELETED_P): New. (SCM_WEAK_PAIR_CAR_DELETED_P): New. (SCM_WEAK_PAIR_CDR_DELETED_P): New. (SCM_WEAK_PAIR_DELETED_P): New. (SCM_WEAK_PAIR_WORD): New. (SCM_WEAK_PAIR_CAR): New. (SCM_WEAK_PAIR_CDR): New. git-archimport-id: lcourtes@laas.fr--2005-libre/guile-core--boehm-gc--1.9--patch-39
Diffstat (limited to 'libguile/weaks.c')
-rw-r--r--libguile/weaks.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/libguile/weaks.c b/libguile/weaks.c
index 7950d891b..efb2d13ae 100644
--- a/libguile/weaks.c
+++ b/libguile/weaks.c
@@ -52,6 +52,92 @@
#include "libguile/validate.h"
#include "libguile/weaks.h"
+#include <gc/gc.h>
+#include <gc/gc_typed.h>
+
+
+
+/* Weak pairs for use in weak alist vectors and weak hash tables.
+
+ We have weal-car pairs, weak-cdr pairs, and doubly weak pairs. In weak
+ pairs, the weak component(s) are not scanned for pointers and are
+ registered as disapperaring links; therefore, the weak component may be
+ set to NULL by the garbage collector when no other reference to that word
+ exist. Thus, users should only access weak pairs via the
+ `SCM_WEAK_PAIR_C[AD]R ()' macros. See also `scm_fixup_weak_alist ()' in
+ `hashtab.c'. */
+
+/* Type descriptors for weak-c[ad]r pairs. */
+static GC_descr wcar_pair_descr, wcdr_pair_descr;
+
+
+SCM
+scm_weak_car_pair (SCM car, SCM cdr)
+{
+ scm_t_cell *cell;
+
+ cell = (scm_t_cell *)GC_malloc_explicitly_typed (sizeof (*cell),
+ wcar_pair_descr);
+
+ cell->word_0 = car;
+ cell->word_1 = cdr;
+
+ if (SCM_NIMP (car))
+ {
+ /* Weak car cells make sense iff the car is non-immediate. */
+ GC_GENERAL_REGISTER_DISAPPEARING_LINK ((GC_PTR)&cell->word_0,
+ (GC_PTR)SCM_UNPACK (car));
+ }
+
+ return (SCM_PACK (cell));
+}
+
+SCM
+scm_weak_cdr_pair (SCM car, SCM cdr)
+{
+ scm_t_cell *cell;
+
+ cell = (scm_t_cell *)GC_malloc_explicitly_typed (sizeof (*cell),
+ wcdr_pair_descr);
+
+ cell->word_0 = car;
+ cell->word_1 = cdr;
+
+ if (SCM_NIMP (cdr))
+ {
+ /* Weak cdr cells make sense iff the cdr is non-immediate. */
+ GC_GENERAL_REGISTER_DISAPPEARING_LINK ((GC_PTR)&cell->word_1,
+ (GC_PTR)SCM_UNPACK (cdr));
+ }
+
+ return (SCM_PACK (cell));
+}
+
+SCM
+scm_doubly_weak_pair (SCM car, SCM cdr)
+{
+ /* Doubly weak cells shall not be scanned at all for pointers. */
+ scm_t_cell *cell = (scm_t_cell *)scm_gc_malloc_pointerless (sizeof (*cell),
+ "weak cell");
+
+ cell->word_0 = car;
+ cell->word_1 = cdr;
+
+ if (SCM_NIMP (car))
+ {
+ GC_GENERAL_REGISTER_DISAPPEARING_LINK ((GC_PTR)&cell->word_0,
+ (GC_PTR)SCM_UNPACK (car));
+ }
+ if (SCM_NIMP (cdr))
+ {
+ GC_GENERAL_REGISTER_DISAPPEARING_LINK ((GC_PTR)&cell->word_1,
+ (GC_PTR)SCM_UNPACK (cdr));
+ }
+
+ return (SCM_PACK (cell));
+}
+
+
/* 1. The current hash table implementation in hashtab.c uses weak alist
@@ -202,6 +288,27 @@ scm_init_weaks_builtins ()
}
void
+scm_weaks_prehistory ()
+{
+ /* Initialize weak pairs. */
+ GC_word wcar_pair_bitmap[GC_BITMAP_SIZE (scm_t_cell)] = { 0 };
+ GC_word wcdr_pair_bitmap[GC_BITMAP_SIZE (scm_t_cell)] = { 0 };
+
+ /* In a weak-car pair, only the second word must be scanned for
+ pointers. */
+ GC_set_bit (wcar_pair_bitmap, GC_WORD_OFFSET (scm_t_cell, word_1));
+ wcar_pair_descr = GC_make_descriptor (wcar_pair_bitmap,
+ GC_WORD_LEN (scm_t_cell));
+
+ /* Conversely, in a weak-cdr pair, only the first word must be scanned for
+ pointers. */
+ GC_set_bit (wcdr_pair_bitmap, GC_WORD_OFFSET (scm_t_cell, word_0));
+ wcdr_pair_descr = GC_make_descriptor (wcdr_pair_bitmap,
+ GC_WORD_LEN (scm_t_cell));
+
+}
+
+void
scm_init_weaks ()
{
scm_c_define_gsubr ("%init-weaks-builtins", 0, 0, 0,