/* garbage.c Object system garbage collector. Copyright (C) 2003 Brian Koropoff Author: Brian Koropoff Date: November 28, 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif static __attribute__ ((unused)) const char rcsid[] = "$Id$"; #include #include "QF/sys.h" #include "QF/object.h" #include "garbage.h" Object *junk = NULL; unsigned int junked = 0; void Garbage_Do_Mark (Object *root) { if (!root->marked) { ObjRefs_t *allrefs; root->marked = true; Sys_DPrintf ("GC: Marked %s@%p.\n", root->cl->name, root); if (root->allRefs) for (allrefs = methodCall(root, allRefs); allrefs; allrefs = allrefs->next) { unsigned int i; for (i = 0; i < allrefs->count; i++) Garbage_Do_Mark (allrefs->objs[i]); } } } Object * Garbage_Do_Sweep (Object **allobjs) { Object **prevNext; Object *obj; for (prevNext = allobjs, obj = *allobjs;; obj = *prevNext) { if (obj->marked) { obj->marked = false; prevNext = &obj->next; } else if (!obj->refs) { if (!obj->finalized && methodCall(obj, finalize)) { obj->finalized = true; Garbage_Do_Mark (obj); prevNext = &obj->next; } else { *prevNext = obj->next; obj->next = junk; junk = obj; junked++; Sys_DPrintf ("GC: %s@%p is ready for disposal...\n", obj->cl->name, obj); } } else *prevNext = obj->next; if (!*prevNext) return obj; } } unsigned int Garbage_Pending (void) { return junked; } void Garbage_Dispose (Object **allobjs, unsigned int amount) { Object *next; for (; junk && amount; junk = next, amount--) { next = junk->next; if (junk->marked) { junk->marked = false; junk->next = *allobjs; *allobjs = junk; } else { Sys_DPrintf ("GC: Disposing of %s@%p...\n", junk->cl->name, junk); Object_Delete (junk); junked--; } } }