Mercurial > hg > xemacs-beta
changeset 1590:03009473262a
[xemacs-hg @ 2003-07-26 14:00:27 by michaels]
2003-07-24 Mike Sperber <mike@xemacs.org>
* lisp.h:
* data.c:
(init_marking_ephemerons):
(continue_marking_ephemerons):
(finish_marking_ephemerons):
(prune_ephemerons):
* alloc.c (garbage_collect_1): Rewrite the ephemeron marker once
again to allow ephemerons to be used for implementing simple
object finalization.
* data.c (Fmake_ephemeron): Fix comments
author | michaels |
---|---|
date | Sat, 26 Jul 2003 14:00:28 +0000 |
parents | ea138ff01850 |
children | 75b8038f720e |
files | src/ChangeLog src/alloc.c src/data.c src/lisp.h |
diffstat | 4 files changed, 104 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- a/src/ChangeLog Fri Jul 25 21:52:27 2003 +0000 +++ b/src/ChangeLog Sat Jul 26 14:00:28 2003 +0000 @@ -1,3 +1,16 @@ +2003-07-24 Mike Sperber <mike@xemacs.org> + + * lisp.h: + * data.c: + (init_marking_ephemerons): + (continue_marking_ephemerons): + (finish_marking_ephemerons): + (prune_ephemerons): + * alloc.c (garbage_collect_1): Rewrite the ephemeron marker once + again to allow ephemerons to be used for implementing simple + object finalization. + * data.c (Fmake_ephemeron): Fix comments + 2003-06-14 Ilya N. Golubev <gin@mo.msk.ru> * .gdbinit (pobj): Fix printing of symbol names.
--- a/src/alloc.c Fri Jul 25 21:52:27 2003 +0000 +++ b/src/alloc.c Sat Jul 26 14:00:28 2003 +0000 @@ -4609,10 +4609,19 @@ a weak hash table might be unmarked, but after processing a later weak hash table, the former one might get marked. So we have to iterate until nothing more gets marked. */ - + + init_marking_ephemerons (); while (finish_marking_weak_hash_tables () > 0 || finish_marking_weak_lists () > 0 || - finish_marking_ephemerons () > 0) + continue_marking_ephemerons () > 0) + ; + + /* At this point, we know which objects need to be finalized: we + still need to resurrect them */ + + while (finish_marking_ephemerons () > 0 || + finish_marking_weak_lists () > 0 || + finish_marking_weak_hash_tables () > 0) ; /* And prune (this needs to be called after everything else has been
--- a/src/data.c Fri Jul 25 21:52:27 2003 +0000 +++ b/src/data.c Sat Jul 26 14:00:28 2003 +0000 @@ -2132,72 +2132,106 @@ */ static Lisp_Object Vall_ephemerons; /* Gemarke es niemals ever!!! */ +static Lisp_Object Vnew_all_ephemerons; static Lisp_Object Vfinalize_list; +void +init_marking_ephemerons(void) +{ + Vnew_all_ephemerons = Qnil; +} + +/* Move all live ephemerons with live keys over to + * Vnew_all_ephemerons, marking the values and finalizers along the + * way. */ + +int +continue_marking_ephemerons(void) +{ + Lisp_Object rest = Vall_ephemerons, next, prev = Qnil; + int did_mark = 0; + + while (!NILP (rest)) + { + next = XEPHEMERON_NEXT (rest); + + if (marked_p (rest)) + { + MARK_CONS (XCONS (XEPHEMERON (rest)->cons_chain)); + if (marked_p (XEPHEMERON (rest)->key)) + { + mark_object (XCAR (XEPHEMERON (rest)->cons_chain)); + did_mark = 1; + XSET_EPHEMERON_NEXT (rest, Vnew_all_ephemerons); + Vnew_all_ephemerons = rest; + if (NILP (prev)) + Vall_ephemerons = next; + else + XSET_EPHEMERON_NEXT (prev, next); + } + else + prev = rest; + } + else + prev = rest; + + rest = next; + } + + return did_mark; +} + +/* At this point, everything that's in Vall_ephemerons is dead. + * Well, almost: we still need to run the finalizers, so we need to + * resurrect them. + */ + int finish_marking_ephemerons(void) { - Lisp_Object rest; + Lisp_Object rest = Vall_ephemerons, next, prev = Qnil; int did_mark = 0; - for (rest = Vall_ephemerons; - !NILP (rest); - rest = XEPHEMERON_NEXT (rest)) - { - if (marked_p (rest) && ! marked_p (XEPHEMERON (rest)->cons_chain)) - { - MARK_CONS (XCONS (XEPHEMERON (rest)->cons_chain)); - mark_object (XCAR (XEPHEMERON (rest)->cons_chain)); - did_mark = 1; - } - } - return did_mark; -} - -void -prune_ephemerons(void) -{ - int removep = 0; - Lisp_Object rest = Vall_ephemerons, next, prev = Qnil; - while (! NILP (rest)) { next = XEPHEMERON_NEXT (rest); if (marked_p (rest)) - /* The ephemeron itself is live ... */ + /* The ephemeron itself is live, but its key is garbage */ { - if (! marked_p(XEPHEMERON (rest)->key)) - /* ... but its key is garbage */ + /* tombstone */ + XSET_EPHEMERON_VALUE (rest, Qnil); + + if (! NILP (XEPHEMERON_FINALIZER (rest))) { - removep = 1; - XSET_EPHEMERON_VALUE (rest, Qnil); - if (! NILP (XEPHEMERON_FINALIZER (rest))) - /* Register the finalizer */ - { - XSET_EPHEMERON_NEXT (rest, Vfinalize_list); - Vfinalize_list = XEPHEMERON (rest)->cons_chain; - } + MARK_CONS (XCONS (XEPHEMERON (rest)->cons_chain)); + mark_object (XCAR (XEPHEMERON (rest)->cons_chain)); + + /* Register the finalizer */ + XSET_EPHEMERON_NEXT (rest, Vfinalize_list); + Vfinalize_list = XEPHEMERON (rest)->cons_chain; + did_mark = 1; } - } - else - /* The ephemeron itself is dead. */ - removep = 1; - if (removep) - { /* Remove it from the list. */ if (NILP (prev)) Vall_ephemerons = next; else XSET_EPHEMERON_NEXT (prev, next); - removep = 0; } else prev = rest; rest = next; } + + return did_mark; +} + +void +prune_ephemerons(void) +{ + Vall_ephemerons = Vnew_all_ephemerons; } Lisp_Object @@ -2282,13 +2316,13 @@ struct ephemeron); DEFUN ("make-ephemeron", Fmake_ephemeron, 2, 3, 0, /* -Return a new ephemeron with key KEY, value CONTENTS, and finalizer FINALIZER. -The ephemeron is a reference to CONTENTS which may be extracted with -`ephemeron-ref'. CONTENTS is only reachable through the ephemeron as +Return a new ephemeron with key KEY, value VALUE, and finalizer FINALIZER. +The ephemeron is a reference to VALUE which may be extracted with +`ephemeron-ref'. VALUE is only reachable through the ephemeron as long as KEY is reachable; the ephemeron does not contribute to the reachability of KEY. When KEY becomes unreachable while the ephemeron -itself is still reachable, CONTENTS is queued for finalization: FINALIZER -will possibly be called on CONTENTS some time in the future. Moreover, +itself is still reachable, VALUE is queued for finalization: FINALIZER +will possibly be called on VALUE some time in the future. Moreover, future calls to `ephemeron-ref' will return NIL. */ (key, value, finalizer))
--- a/src/lisp.h Fri Jul 25 21:52:27 2003 +0000 +++ b/src/lisp.h Sat Jul 26 14:00:28 2003 +0000 @@ -2756,6 +2756,8 @@ void prune_ephemerons (void); Lisp_Object ephemeron_value(Lisp_Object ephi); +void init_marking_ephemerons(void); +int continue_marking_ephemerons(void); int finish_marking_ephemerons(void); Lisp_Object zap_finalize_list(void); Lisp_Object make_ephemeron(Lisp_Object key, Lisp_Object value, Lisp_Object finalizer);