#include "gc.h"
-/* Register a function notifier_proc which will be called on each */
-/* object of the given kind before it is reclaimed. If notifier_proc */
-/* returns non-zero, the collector will not reclaim the object on this */
-/* GC cycle. Objects reachable from proc will be protected from */
-/* collection if mark_from_all=1, but at the expense that long chains */
-/* of objects will take many cycles to reclaim. */
-/* Not available if configured with --disable-disclaim. */
+/* Register "proc" to be called on each object of "kind" ready to be */
+/* reclaimed. If "proc" returns non-zero, the collector will not */
+/* reclaim the object on this GC cycle. Objects reachable from "proc" */
+/* will be protected from collection if "mark_from_all" is non-zero, */
+/* but at the expense that long chains of objects will take many cycles */
+/* to reclaim. */
int GC_register_disclaim_proc(int kind,
int (*proc)(void *obj, void *cd), void *cd,
int mark_from_all);
-/* The finalizer closure used by GC_finalized_malloc. */
+/* The finalizer closure used by GC_finalized_malloc. */
struct GC_finalizer_closure {
void (*proc)(void *obj, void *cd);
void *cd;
};
-/* Allocate size bytes which is finalized with fc. This uses a */
-/* dedicated object kind with the disclaim mechanism for maximum. It */
-/* is more efficient than GC_register_finalizer and friends. You need */
-/* to call GC_init_finalized_malloc before using this. */
+/* Allocate "size" bytes which is finalized by "fc". This uses a */
+/* dedicated object kind with a disclaim procedure, and is more */
+/* efficient than GC_register_finalizer and friends. You need to call */
+/* GC_init_finalized_malloc before using this. */
GC_API void *GC_finalized_malloc(size_t size, struct GC_finalizer_closure *fc);
-/* Prepare the object kind used for GC_finalized_malloc. */
+/* Prepare the object kind used for GC_finalized_malloc. */
GC_API void GC_init_finalized_malloc(void);
#endif
}
#ifdef MARK_UNCONDITIONALLY
-/* Mark all objects which have not been reclaimed according to the convension
- * that the first word is odd for live objects. This is used optionally to
- * guard the contents of objects passed to reclaim notifiers. */
+/* Unconditionally mark from all objects which have not been reclaimed. */
+/* This is useful in order to retain pointes which are reachable from */
+/* the disclaim notifiers. */
+/* */
+/* To determine whether an object has been reclaimed, we require that */
+/* any live object has a non-zero as one of the two lowest bits of the */
+/* first word. On the other hand, a reclaimed object is a members of */
+/* free-lists, and thus contains a word-aligned next-pointer as the */
+/* first word. */
void GC_push_unconditionally(struct hblk *h, hdr *hhdr)
{
int sz = hhdr -> hb_sz;
GC_obj_kinds[result].ok_relocate_descr = adjust;
GC_obj_kinds[result].ok_init = clear;
# ifdef ENABLE_DISCLAIM
- GC_obj_kinds[result].ok_disclaim_proc = 0;
- GC_obj_kinds[result].ok_disclaim_cd = 0;
+ GC_obj_kinds[result].ok_disclaim_proc = 0;
+ GC_obj_kinds[result].ok_disclaim_cd = 0;
# endif
return result;
}
/* so that you can convince yourself that it really is very stupid. */
GC_reclaim_all((GC_stop_func)0, FALSE);
# elif defined(MARK_UNCONDITIONALLY)
- /* However, make sure to clear reclaimable objects of kinds with */
- /* unconditional marking enabled before we do any significant */
- /* marking work. */
+ /* However, make sure to clear reclaimable objects of kinds with */
+ /* unconditional marking enabled before we do any significant */
+ /* marking work. */
GC_reclaim_unconditionally_marked();
# endif
# if defined(PARALLEL_MARK)
}
#if !defined(EAGER_SWEEP) && defined(MARK_UNCONDITIONALLY)
-/* Part of disclaim patch. This could be merged with the above, but I don't
- * want to clobber the original source too much by changing the prototype and
- * testing for defined(MARK_UNCONDITIONALLY). */
+/* We do an eager sweep on heap blocks where unconditional marking has */
+/* been enabled, so that any reclaimable objects have been reclaimed */
+/* before we start marking. This is a simplified GC_reclaim_all */
+/* restricted to kinds where ok_mark_unconditionally is true. */
void GC_reclaim_unconditionally_marked(void)
{
word sz;
struct hblk ** rlp;
struct hblk ** rlh;
for (kind = 0; kind < GC_n_kinds; kind++) {
- ok = &(GC_obj_kinds[kind]);
- if (!ok->ok_mark_unconditionally) continue;
- rlp = ok->ok_reclaim_list;
- if (rlp == 0) continue;
- for (sz = 1; sz <= MAXOBJGRANULES; sz++) {
- rlh = rlp + sz;
- while ((hbp = *rlh) != 0) {
- hhdr = HDR(hbp);
- *rlh = hhdr->hb_next;
- GC_reclaim_small_nonempty_block(hbp, FALSE);
- }
- }
+ ok = &(GC_obj_kinds[kind]);
+ if (!ok->ok_mark_unconditionally) continue;
+ rlp = ok->ok_reclaim_list;
+ if (rlp == 0) continue;
+ for (sz = 1; sz <= MAXOBJGRANULES; sz++) {
+ rlh = rlp + sz;
+ while ((hbp = *rlh) != 0) {
+ hhdr = HDR(hbp);
+ *rlh = hhdr->hb_next;
+ GC_reclaim_small_nonempty_block(hbp, FALSE);
+ }
+ }
}
}
#endif