1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-05 06:50:21 +02:00

* 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).
This commit is contained in:
Michael Livshin 2000-04-03 13:55:54 +00:00
parent 54778cd312
commit 50fecba92d
2 changed files with 70 additions and 51 deletions

View file

@ -1,3 +1,11 @@
2000-04-03 Michael Livshin <mlivshin@bigfoot.com>
* 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 <D.Herrmann@tu-bs.de> 2000-04-03 Dirk Herrmann <D.Herrmann@tu-bs.de>
* evalext.c (scm_definedp, scm_m_undefine), gc.c * evalext.c (scm_definedp, scm_m_undefine), gc.c
@ -531,22 +539,22 @@
2000-03-18 Michael Livshin <mlivshin@bigfoot.com> 2000-03-18 Michael Livshin <mlivshin@bigfoot.com>
* 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.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). parameter (the span).
(CLUSTER_SIZE_IN_BYTES, ALIGNMENT_SLACK) new macros. (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. business being externally visible.
(typedef struct scm_heap_seg_data_t) renamed from (typedef struct scm_heap_seg_data_t) renamed from
scm_heap_seg_data, to be style-compliant. scm_heap_seg_data, to be style-compliant.
(scm_mark_locations) if the possible pointer points to a (scm_mark_locations) if the possible pointer points to a
multy-cell, check that it's properly aligned. double-cell, check that it's properly aligned.
(init_heap_seg) alighn multy-cells properly, work with the (init_heap_seg) align double-cells properly, work with the
assumption that the segment size divides cleanly by cluster size assumption that the segment size divides cleanly by cluster size.
(so that there's no spill).
(round_to_cluster_size) new function. (round_to_cluster_size) new function.
(alloc_some_heap, make_initial_segment) use round_to_cluster_size (alloc_some_heap, make_initial_segment) use round_to_cluster_size
to satisfy the new init_heap_seg invariant. to satisfy the new init_heap_seg invariant.

View file

@ -232,7 +232,8 @@ g_mark (SCM ptr)
its live list (tconc) to its zombie list (tconc). */ its live list (tconc) to its zombie list (tconc). */
void scm_guardian_zombify (void) 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 /* 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 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 guardians. The guardian mark function will stick them on the end
of this list, so they'll be processed properly. */ of this list, so they'll be processed properly. */
for (g = first_live_guardian; g; g = g->next) do {
{ guardian_t *g;
SCM tconc_tail = g->live.tail;
SCM *prev_ptr = &g->live.head;
SCM pair = g->live.head;
while (! SCM_EQ_P (pair, tconc_tail)) first_guardian = *link_field;
{ link_field = current_link_field;
SCM next_pair = SCM_CDR (pair);
if (SCM_NMARKEDP (SCM_CAR (pair))) /* first, scan all the guardians that are currently known to be live
{ and move their unmarked objects to zombie lists. */
/* got you, zombie! */
/* out of the live list! */ for (g = first_guardian; g; g = g->next)
*prev_ptr = next_pair; {
SCM tconc_tail = g->live.tail;
SCM *prev_ptr = &g->live.head;
SCM pair = g->live.head;
/* into the zombie list! */ while (! SCM_EQ_P (pair, tconc_tail))
TCONC_IN (g->zombies, SCM_CAR (pair), pair); {
} SCM next_pair = SCM_CDR (pair);
else
prev_ptr = SCM_CDRLOC (pair);
pair = next_pair; if (SCM_NMARKEDP (SCM_CAR (pair)))
} {
/* got you, zombie! */
/* Mark the cells of the live list (yes, the cells in the list, /* out of the live list! */
even though we don't care about objects pointed to by the list *prev_ptr = next_pair;
cars, since we know they are already marked). */
for (pair = g->live.head; SCM_NIMP (pair); pair = SCM_GCCDR (pair))
SCM_SETGCMARK (pair);
/* Preserve the zombies in their undead state, by marking to /* into the zombie list! */
prevent collection. */ TCONC_IN (g->zombies, SCM_CAR (pair), pair);
}
else
prev_ptr = SCM_CDRLOC (pair);
/* ghouston: possible bug: this may mark objects which are pair = next_pair;
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 /* Mark the cells of the live list (yes, the cells in the list,
to full life after getting returned from the guardian even though we don't care about objects pointed to by the list
procedure, it may reference objects which are in a guardian's cars, since we know they are already marked). */
zombie list? Is it not necessary to move such zombies back for (pair = g->live.head; SCM_NIMP (pair); pair = SCM_GCCDR (pair))
to the live list, to avoid allowing the guardian procedure to SCM_SETGCMARK (pair);
return an object which is referenced, so not collectable? }
The paper doesn't give this impression. */
/* 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); scm_gc_mark (g->zombies.head);
}
} while (current_link_field != link_field);
} }
/* not generally used, since guardian smob is wrapped in a closure. /* not generally used, since guardian smob is wrapped in a closure.