From 3f5d82cd9a59cc94cd056c95c61e3e9beda50bcc Mon Sep 17 00:00:00 2001 From: Dirk Herrmann Date: Mon, 10 Jul 2000 14:25:53 +0000 Subject: [PATCH] * Use a set of dedicated macros to access and modify free cells. --- libguile/ChangeLog | 16 ++++++++++++++++ libguile/gc.c | 41 ++++++++++++++++++++--------------------- libguile/gc.h | 20 ++++++++++++++------ 3 files changed, 50 insertions(+), 27 deletions(-) diff --git a/libguile/ChangeLog b/libguile/ChangeLog index c26394e76..f72ec1cf0 100644 --- a/libguile/ChangeLog +++ b/libguile/ChangeLog @@ -1,3 +1,19 @@ +2000-07-10 Dirk Herrmann + + * gc.h (SCM_SET_FREE_CELL_TYPE, SCM_SET_FREE_CELL_CDR, + SCM_FREE_CELL_P, SCM_FREE_CELL_CDR): Added since free cells + should not be accessed via SCM_C[AD]R. Further, using dedicated + macros to access free cells allows all other cell accessing macros + to treat acesses to free cells as errors, thus enabling better + error checks for cell accesses. SCM_FREE_CELL_P is supposed to + replace SCM_FREEP some time. + + * gc.h (SCM_NEWCELL, SCM_NEWCELL2), gc.c (map_free_list, + free_list_length, scm_check_freelist, scm_debug_newcell, + scm_debug_newcell2, freelist_length, scm_gc_for_newcell, + scm_gc_mark, scm_gc_sweep, init_heap_seg): Only use the dedicated + cell accessors when accessing free cells. + 2000-07-10 Dirk Herrmann * gc.h (SCM_CELL_WORD, SCM_CELL_OBJECT): Treat the referenced diff --git a/libguile/gc.c b/libguile/gc.c index 0c4491af2..1c053c27c 100644 --- a/libguile/gc.c +++ b/libguile/gc.c @@ -314,7 +314,7 @@ map_free_list (scm_freelist_t *master, SCM freelist) int last_seg = -1, count = 0; SCM f; - for (f = freelist; SCM_NIMP (f); f = SCM_CDR (f)) + for (f = freelist; !SCM_NULLP (f); f = SCM_FREE_CELL_CDR (f)) { int this_seg = which_seg (f); @@ -365,8 +365,8 @@ free_list_length (char *title, int i, SCM freelist) { SCM ls; int n = 0; - for (ls = freelist; SCM_NNULLP (ls); ls = SCM_CDR (ls)) - if (SCM_CELL_TYPE (ls) == scm_tc_free_cell) + for (ls = freelist; !SCM_NULLP (ls); ls = SCM_FREE_CELL_CDR (ls)) + if (SCM_FREE_CELL_P (ls)) ++n; else { @@ -441,8 +441,8 @@ scm_check_freelist (SCM freelist) SCM f; int i = 0; - for (f = freelist; SCM_NIMP (f); f = SCM_CDR (f), i++) - if (SCM_CAR (f) != (SCM) scm_tc_free_cell) + for (f = freelist; !SCM_NULLP (f); f = SCM_FREE_CELL_CDR (f), i++) + if (!SCM_FREE_CELL_P (f)) { fprintf (stderr, "Bad cell in freelist on newcell %lu: %d'th elt\n", scm_newcell_count, i); @@ -479,13 +479,13 @@ scm_debug_newcell (void) /* The rest of this is supposed to be identical to the SCM_NEWCELL macro. */ - if (SCM_IMP (scm_freelist)) + if (SCM_NULLP (scm_freelist)) new = scm_gc_for_newcell (&scm_master_freelist, &scm_freelist); else { new = scm_freelist; - scm_freelist = SCM_CDR (scm_freelist); - SCM_SETCAR (new, scm_tc16_allocated); + scm_freelist = SCM_FREE_CELL_CDR (scm_freelist); + SCM_SET_FREE_CELL_TYPE (new, scm_tc16_allocated); } return new; @@ -505,13 +505,13 @@ scm_debug_newcell2 (void) /* The rest of this is supposed to be identical to the SCM_NEWCELL macro. */ - if (SCM_IMP (scm_freelist2)) + if (SCM_NULLP (scm_freelist2)) new = scm_gc_for_newcell (&scm_master_freelist2, &scm_freelist2); else { new = scm_freelist2; - scm_freelist2 = SCM_CDR (scm_freelist2); - SCM_SETCAR (new, scm_tc16_allocated); + scm_freelist2 = SCM_FREE_CELL_CDR (scm_freelist2); + SCM_SET_FREE_CELL_TYPE (new, scm_tc16_allocated); } return new; @@ -534,7 +534,7 @@ static unsigned long freelist_length (SCM freelist) { int n; - for (n = 0; SCM_NNULLP (freelist); freelist = SCM_CDR (freelist)) + for (n = 0; !SCM_NULLP (freelist); freelist = SCM_FREE_CELL_CDR (freelist)) ++n; return n; } @@ -741,8 +741,8 @@ scm_gc_for_newcell (scm_freelist_t *master, SCM *freelist) } while (SCM_NULLP (cell)); --scm_ints_disabled; - *freelist = SCM_CDR (cell); - SCM_SET_CELL_TYPE (cell, scm_tc16_allocated); + *freelist = SCM_FREE_CELL_CDR (cell); + SCM_SET_FREE_CELL_TYPE (cell, scm_tc16_allocated); return cell; } @@ -919,7 +919,7 @@ gc_mark_loop: return; gc_mark_nimp: - if (SCM_NCELLP (ptr)) + if (!SCM_CELLP (ptr)) SCM_MISC_ERROR ("rogue pointer in heap", SCM_EOL); switch (SCM_TYP7 (ptr)) @@ -1264,7 +1264,6 @@ scm_mark_locations (SCM_STACKITEM x[], scm_sizet n) scm_gc_mark (* (SCM *) &x[m]); break; } - } } } @@ -1321,7 +1320,7 @@ gc_sweep_freelist_finish (scm_freelist_t *freelist) { int collected; *freelist->clustertail = freelist->cells; - if (SCM_NNULLP (freelist->cells)) + if (!SCM_NULLP (freelist->cells)) { SCM c = freelist->cells; SCM_SETCAR (c, SCM_CDR (c)); @@ -1574,7 +1573,7 @@ scm_gc_sweep () SCM_MISC_ERROR ("unknown type", SCM_EOL); } #if 0 - if (SCM_CAR (scmptr) == (SCM) scm_tc_free_cell) + if (SCM_FREE_CELL_P (scmptr)) exit (2); #endif if (!--left_to_collect) @@ -1594,7 +1593,7 @@ scm_gc_sweep () conservative collector might trace it as some other type of object. */ SCM_SET_CELL_TYPE (scmptr, scm_tc_free_cell); - SCM_SETCDR (scmptr, nfreelist); + SCM_SET_FREE_CELL_CDR (scmptr, nfreelist); nfreelist = scmptr; } @@ -1930,11 +1929,11 @@ init_heap_seg (SCM_CELLPTR seg_org, scm_sizet size, scm_freelist_t *freelist) SCM scmptr = PTR2SCM (ptr); SCM_SET_CELL_TYPE (scmptr, scm_tc_free_cell); - SCM_SETCDR (scmptr, PTR2SCM (ptr + span)); + SCM_SET_FREE_CELL_CDR (scmptr, PTR2SCM (ptr + span)); ptr += span; } - SCM_SETCDR (PTR2SCM (ptr - span), SCM_EOL); + SCM_SET_FREE_CELL_CDR (PTR2SCM (ptr - span), SCM_EOL); } /* Patch up the last cluster pointer in the segment diff --git a/libguile/gc.h b/libguile/gc.h index a90d47614..49a8ecc97 100644 --- a/libguile/gc.h +++ b/libguile/gc.h @@ -146,13 +146,21 @@ typedef scm_cell * SCM_CELLPTR; #define SCM_PTR_GE(x, y) (!SCM_PTR_LT (x, y)) -/* Dirk:FIXME:: */ /* Freelists consist of linked cells where the type entry holds the value * scm_tc_free_cell and the second entry holds a pointer to the next cell of * the freelist. Due to this structure, freelist cells are not cons cells * and thus may not be accessed using SCM_CAR and SCM_CDR. */ +#define SCM_FREE_CELL_P(x) \ + (!SCM_IMP (x) && (* (const scm_bits_t *) SCM2PTR (x) == scm_tc_free_cell)) +#define SCM_FREE_CELL_CDR(x) \ + (((const scm_bits_t *) SCM2PTR (x)) [1]) +#define SCM_SET_FREE_CELL_TYPE(x, v) \ + (((scm_bits_t *) SCM2PTR (x)) [0] = (v)) +#define SCM_SET_FREE_CELL_CDR(x, v) \ + (((scm_bits_t *) SCM2PTR (x)) [1] = (v)) + /* the allocated thing: The car of new cells is set to scm_tc16_allocated to avoid the fragile state of newcells wrt the gc. If it stays as a freecell, any allocation afterwards could @@ -174,8 +182,8 @@ typedef scm_cell * SCM_CELLPTR; else \ { \ _into = scm_freelist; \ - scm_freelist = SCM_CDR (scm_freelist); \ - SCM_SET_CELL_TYPE (_into, scm_tc16_allocated); \ + scm_freelist = SCM_FREE_CELL_CDR (scm_freelist); \ + SCM_SET_FREE_CELL_TYPE (_into, scm_tc16_allocated); \ } \ } while(0) #define SCM_NEWCELL2(_into) \ @@ -186,14 +194,14 @@ typedef scm_cell * SCM_CELLPTR; else \ { \ _into = scm_freelist2; \ - scm_freelist2 = SCM_CDR (scm_freelist2); \ - SCM_SET_CELL_TYPE (_into, scm_tc16_allocated); \ + scm_freelist2 = SCM_FREE_CELL_CDR (scm_freelist2); \ + SCM_SET_FREE_CELL_TYPE (_into, scm_tc16_allocated); \ } \ } while(0) #endif -#define SCM_FREEP(x) (SCM_NIMP (x) && (SCM_CELL_TYPE (x) == scm_tc_free_cell)) +#define SCM_FREEP(x) (SCM_FREE_CELL_P (x)) #define SCM_NFREEP(x) (!SCM_FREEP (x)) /* 1. This shouldn't be used on immediates.