diff --git a/libguile/ChangeLog b/libguile/ChangeLog index 4565be6c6..d21f7c7e8 100644 --- a/libguile/ChangeLog +++ b/libguile/ChangeLog @@ -1,3 +1,11 @@ +2000-04-03 Michael Livshin + + * guardians.c (scm_guardian_zombify): mark all zombies in a + separate loop after processing all the currently known live + guardians, so as to not introduce order dependencies (thanks to + Gary Houston). also, make another outer loop to process zombified + guardians (which are uncovered while marking zombies). + 2000-04-03 Dirk Herrmann * evalext.c (scm_definedp, scm_m_undefine), gc.c @@ -531,22 +539,22 @@ 2000-03-18 Michael Livshin - * tags.h: (SCM_DOUBLE_CELLP, SCM_NDOUBLE_CELLP): new macros. + * tags.h: (SCM_DOUBLE_CELLP, SCM_NDOUBLE_CELLP): new macros (bad + names, anyone got any better ones?) * gc.h: (typedef struct scm_freelist_t) remove from here. - * gc.c: (CELL_UP, CELL_DN) make these macros take additional + * gc.c: (CELL_UP, CELL_DN) made these macros take additional parameter (the span). (CLUSTER_SIZE_IN_BYTES, ALIGNMENT_SLACK) new macros. - (typedef struct scm_freelist_t) move here from gc.h, it had no + (typedef struct scm_freelist_t) moved here from gc.h, it had no business being externally visible. (typedef struct scm_heap_seg_data_t) renamed from scm_heap_seg_data, to be style-compliant. (scm_mark_locations) if the possible pointer points to a - multy-cell, check that it's properly aligned. - (init_heap_seg) alighn multy-cells properly, work with the - assumption that the segment size divides cleanly by cluster size - (so that there's no spill). + double-cell, check that it's properly aligned. + (init_heap_seg) align double-cells properly, work with the + assumption that the segment size divides cleanly by cluster size. (round_to_cluster_size) new function. (alloc_some_heap, make_initial_segment) use round_to_cluster_size to satisfy the new init_heap_seg invariant. diff --git a/libguile/guardians.c b/libguile/guardians.c index ccf0d284c..73348f898 100644 --- a/libguile/guardians.c +++ b/libguile/guardians.c @@ -232,7 +232,8 @@ g_mark (SCM ptr) its live list (tconc) to its zombie list (tconc). */ void scm_guardian_zombify (void) { - guardian_t *g; + guardian_t *first_guardian; + guardian_t **link_field = &first_live_guardian; /* Note that new guardians may be stuck on the end of the live guardian list as we run this loop. As we move unmarked objects @@ -240,59 +241,69 @@ void scm_guardian_zombify (void) guardians. The guardian mark function will stick them on the end of this list, so they'll be processed properly. */ - for (g = first_live_guardian; g; g = g->next) - { - SCM tconc_tail = g->live.tail; - SCM *prev_ptr = &g->live.head; - SCM pair = g->live.head; + do { + guardian_t *g; + + first_guardian = *link_field; + link_field = current_link_field; - while (! SCM_EQ_P (pair, tconc_tail)) - { - SCM next_pair = SCM_CDR (pair); + /* first, scan all the guardians that are currently known to be live + and move their unmarked objects to zombie lists. */ - if (SCM_NMARKEDP (SCM_CAR (pair))) - { - /* got you, zombie! */ + for (g = first_guardian; g; g = g->next) + { + SCM tconc_tail = g->live.tail; + SCM *prev_ptr = &g->live.head; + SCM pair = g->live.head; - /* out of the live list! */ - *prev_ptr = next_pair; + while (! SCM_EQ_P (pair, tconc_tail)) + { + SCM next_pair = SCM_CDR (pair); - /* into the zombie list! */ - TCONC_IN (g->zombies, SCM_CAR (pair), pair); - } - else - prev_ptr = SCM_CDRLOC (pair); + if (SCM_NMARKEDP (SCM_CAR (pair))) + { + /* got you, zombie! */ - pair = next_pair; - } + /* out of the live list! */ + *prev_ptr = next_pair; - /* Mark the cells of the live list (yes, the cells in the list, - even though we don't care about objects pointed to by the list - cars, since we know they are already marked). */ - for (pair = g->live.head; SCM_NIMP (pair); pair = SCM_GCCDR (pair)) - SCM_SETGCMARK (pair); + /* into the zombie list! */ + TCONC_IN (g->zombies, SCM_CAR (pair), pair); + } + else + prev_ptr = SCM_CDRLOC (pair); - /* Preserve the zombies in their undead state, by marking to - prevent collection. */ + pair = next_pair; + } - /* ghouston: possible bug: this may mark objects which are - protected by other guardians, but which have no references - from outside of the guardian system. section 3 of the paper - mentions shared and cyclic objects and it seems that all - parts should be made available for collection. Currently the - behaviour depends on the order in which guardians are - scanned. - - Doesn't it seem a bit disturbing that if a zombie is returned - to full life after getting returned from the guardian - procedure, it may reference objects which are in a guardian's - zombie list? Is it not necessary to move such zombies back - to the live list, to avoid allowing the guardian procedure to - return an object which is referenced, so not collectable? - The paper doesn't give this impression. */ + /* Mark the cells of the live list (yes, the cells in the list, + even though we don't care about objects pointed to by the list + cars, since we know they are already marked). */ + for (pair = g->live.head; SCM_NIMP (pair); pair = SCM_GCCDR (pair)) + SCM_SETGCMARK (pair); + } + /* ghouston: Doesn't it seem a bit disturbing that if a zombie + is returned to full life after getting returned from the + guardian procedure, it may reference objects which are in a + guardian's zombie list? Is it not necessary to move such + zombies back to the live list, to avoid allowing the + guardian procedure to return an object which is referenced, + so not collectable? The paper doesn't give this + impression. + + cmm: the paper does explicitly say that an object that is + guarded more than once should be returned more than once. + I believe this covers the above scenario. */ + + /* Preserve the zombies in their undead state, by marking to + prevent collection. Note that this may uncover zombified + guardians -- if so, they'll be processed in the next loop. */ + + for (g = first_guardian; g && (!*link_field || g != *link_field); g = g->next) scm_gc_mark (g->zombies.head); - } + + } while (current_link_field != link_field); } /* not generally used, since guardian smob is wrapped in a closure.