From b4a1358cfb3419e564c8670537440ef1fd9aa8e7 Mon Sep 17 00:00:00 2001 From: Mikael Djurfeldt Date: Mon, 24 Feb 2003 19:21:56 +0000 Subject: [PATCH] * struct.c (scm_struct_prehistory): Init scm_i_structs_to_free to SCM_EOL. (scm_struct_prehistory): Move scm_free_structs to scm_before_mark_c_hook. * gc-card.c (sweep_card): Check that we haven't swept structs on this card before. That can happen if scm_i_sweep_all_segments has been called from some other place than scm_igc. --- libguile/ChangeLog | 15 ++++++++++----- libguile/gc-card.c | 18 +++++++++++------- libguile/struct.c | 11 ++++++++++- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/libguile/ChangeLog b/libguile/ChangeLog index 51706d323..0d5910f17 100644 --- a/libguile/ChangeLog +++ b/libguile/ChangeLog @@ -1,13 +1,18 @@ 2003-02-24 Mikael Djurfeldt - * struct.c (scm_struct_gc_init): Removed. - (scm_struct_prehistory): Init scm_i_structs_to_free to SCM_EOL. - (This fixes a serious GC bug, introduced during the latest - reorganization of the GC, preventing freeing of structs and GOOPS - objects.) + This fixes a serious GC bug, introduced during the latest + reorganization of the GC, which disabled freeing of structs and + GOOPS objects: + + * struct.c (scm_struct_prehistory): Init scm_i_structs_to_free to + SCM_EOL. (scm_struct_prehistory): Move scm_free_structs to scm_before_mark_c_hook. + * gc-card.c (sweep_card): Check that we haven't swept structs on + this card before. That can happen if scm_i_sweep_all_segments has + been called from some other place than scm_igc. + 2003-02-19 Mikael Djurfeldt * environments.c (DEFAULT_OBARRAY_SIZE): Changed from 137 to 31 diff --git a/libguile/gc-card.c b/libguile/gc-card.c index 3926fb77f..267c4c8fd 100644 --- a/libguile/gc-card.c +++ b/libguile/gc-card.c @@ -129,13 +129,17 @@ scm_i_sweep_card (scm_t_cell * p, SCM *free_list, scm_t_heap_segment*seg) switch (SCM_TYP7 (scmptr)) { case scm_tcs_struct: - { - /* Structs need to be freed in a special order. - * This is handled by GC C hooks in struct.c. - */ - SCM_SET_STRUCT_GC_CHAIN (p, scm_i_structs_to_free); - scm_i_structs_to_free = scmptr; - } + /* The card can be swept more than once. Check that it's + * the first time! + */ + if (!SCM_STRUCT_GC_CHAIN (p)) + { + /* Structs need to be freed in a special order. + * This is handled by GC C hooks in struct.c. + */ + SCM_SET_STRUCT_GC_CHAIN (p, scm_i_structs_to_free); + scm_i_structs_to_free = scmptr; + } continue; case scm_tcs_cons_imcar: diff --git a/libguile/struct.c b/libguile/struct.c index eb2c15cbf..94b431853 100644 --- a/libguile/struct.c +++ b/libguile/struct.c @@ -355,6 +355,15 @@ scm_struct_free_entity (scm_t_bits * vtable SCM_UNUSED, scm_t_bits * data) scm_gc_free ((void *) data[scm_struct_i_ptr], n, "entity struct"); } +static void * +scm_struct_gc_init (void *dummy1 SCM_UNUSED, + void *dummy2 SCM_UNUSED, + void *dummy3 SCM_UNUSED) +{ + scm_i_structs_to_free = SCM_EOL; + return 0; +} + static void * scm_free_structs (void *dummy1 SCM_UNUSED, void *dummy2 SCM_UNUSED, @@ -399,7 +408,6 @@ scm_free_structs (void *dummy1 SCM_UNUSED, } } while (!SCM_NULLP (newchain)); - scm_i_structs_to_free = SCM_EOL; return 0; } @@ -797,6 +805,7 @@ void scm_struct_prehistory () { scm_i_structs_to_free = SCM_EOL; + scm_c_hook_add (&scm_before_sweep_c_hook, scm_struct_gc_init, 0, 0); /* With the new lazy sweep GC, the point at which the entire heap is swept is just before the mark phase. */ scm_c_hook_add (&scm_before_mark_c_hook, scm_free_structs, 0, 0);