-/* mm/cacao-gc/mark.c - GC module for marking heap objects
+/* src/mm/cacao-gc/mark.c - GC module for marking heap objects
- Copyright (C) 2006 R. Grafl, A. Krall, C. Kruegel,
- C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
- E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 2006, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
/* this is an OBJECT */
/* for objects we need to check all (non-static) fields */
- for (; c; c = c->super.cls) {
+ for (; c; c = c->super) {
for (i = 0; i < c->fieldscount; i++) {
f = &(c->fields[i]);
}
-/* mark_classes ****************************************************************
+/* mark_post *******************************************************************
- Marks all the references from classinfo structures (static fields)
+ Perform some post-marking cleanup tasks.
- IN:
- start.....Region to be marked starts here
- end.......Region to be marked ends here
+ TASKS:
+ - mark unmarked objects with Finalizers
+ - clear unmarked Weak References
*******************************************************************************/
-void mark_classes(void *start, void *end)
+void mark_post(rootset_t *rs)
{
- java_object_t *ref;
- classinfo *c;
- fieldinfo *f;
- void *sys_start, *sys_end;
+ java_object_t *ref;
+#if defined(GCCONF_FINALIZER)
+ list_final_entry_t *fe;
+ u4 f_type;
+#endif
+ void *start, *end;
int i;
- GC_LOG( dolog("GC: Marking from classes ..."); );
+ /* TODO: this needs cleanup!!! */
+ start = heap_region_main->base;
+ end = heap_region_main->ptr;
- /* TODO: cleanup!!! */
- sys_start = heap_region_sys->base;
- sys_end = heap_region_sys->ptr;
+#if defined(GCCONF_FINALIZER)
+ /* objects with finalizers will also be marked here. if they have not been
+ marked before the finalization is triggered */
- /* walk through all classinfo blocks */
- for (c = sys_start; c < (classinfo *) sys_end; c++) {
+ /* REMEMBER: All threads are stopped, so we don't have to lock the
+ list here. */
- /* walk through all fields */
- f = c->fields;
- for (i = 0; i < c->fieldscount; i++, f++) {
+ fe = list_first(final_list);
- /* check if this is a static reference */
- if (!IS_ADR_TYPE(f->type) || !(f->flags & ACC_STATIC))
- continue;
+ while (fe) {
+ f_type = fe->type;
+ ref = fe->o;
+
+ /* we do not care about objects which have been marked already */
+ if (!GC_IS_MARKED(ref)) {
+
+ switch (f_type) {
+
+ case FINAL_REACHABLE: /* object was reachable before */
+ GC_LOG2( printf("Finalizer triggered for: ");
+ heap_print_object(ref); printf("\n"); );
+
+ /* object is now reclaimable */
+ fe->type = FINAL_RECLAIMABLE;
+
+ /* notify the finalizer after collection finished */
+ gc_notify_finalizer = true;
+
+ /* keep the object alive until finalizer finishes */
+ MARK(ref);
+ break;
+
+ case FINAL_RECLAIMABLE: /* object not yet finalized */
+ GC_LOG( printf("Finalizer not yet started for: ");
+ heap_print_object(ref); printf("\n"); );
+
+ /* keep the object alive until finalizer finishes */
+ MARK(ref);
+ break;
+
+#if 0
+ case FINAL_FINALIZING: /* object is still being finalized */
+ GC_LOG( printf("Finalizer not yet finished for: ");
+ heap_print_object(ref); printf("\n"); );
+
+ /* keep the object alive until finalizer finishes */
+ MARK(ref);
+ break;
+#endif
+
+ default: /* case not yet covered */
+ vm_abort("mark_post: uncovered case (type=%d)", f_type);
+
+ }
+ }
+
+ fe = list_next(final_list, fe);
+ }
+#endif /*defined(GCCONF_FINALIZER)*/
+
+ /* Clear all references in the rootset which have not yet been
+ marked. This applies to registered weak references. */
+
+ while (rs) {
+ GC_LOG( dolog("GC: Clearing in rootset (%d entries) ...", rs->refcount); );
+
+ /* mark all references of the rootset */
+ for (i = 0; i < rs->refcount; i++) {
/* load the reference */
- ref = (java_object_t *) (f->value);
+ ref = *( rs->refs[i].ref );
/* check for outside or null pointers */
if (!POINTS_INTO(ref, start, end))
continue;
- /* mark the reference */
- MARK(ref);
+ /* is this a marking reference? */
+ if (rs->refs[i].marks) {
+ assert(GC_IS_MARKED(ref));
+ } else {
+
+ /* clear unmarked references */
+ if (!GC_IS_MARKED(ref)) {
+ GC_LOG( printf("Clearing Weak Reference %p at %p\n", ref, rs->refs[i]); );
+ *( rs->refs[i].ref ) = NULL;
+ }
+ }
}
+ rs = rs->next;
}
}
void mark_me(rootset_t *rs)
{
- java_object_t *ref;
-#if defined(GCCONF_FINALIZER)
- list_final_entry_t *fe;
-#endif
- u4 f_type;
+ rootset_t *rstop;
+ java_object_t *ref;
void *start, *end;
int i;
/* TODO: this needs cleanup!!! */
start = heap_region_main->base;
end = heap_region_main->ptr;
+ rstop = rs;
GCSTAT_INIT(gcstat_mark_count);
GCSTAT_INIT(gcstat_mark_depth);
GCSTAT_INIT(gcstat_mark_depth_max);
- /* recursively mark all references from classes */
- /*mark_classes(heap_region_main->base, heap_region_main->ptr);*/
-
while (rs) {
GC_LOG( dolog("GC: Marking from rootset (%d entries) ...", rs->refcount); );
rs = rs->next;
}
-#if defined(GCCONF_FINALIZER)
- /* objects with finalizers will also be marked here. if they have not been
- * marked before the finalization is triggered */
- /* REMEMBER: all threads are stopped, so we can use unsynced access here */
- fe = list_first_unsynced(final_list);
- while (fe) {
- f_type = fe->type;
- ref = fe->o;
-
- /* we do not care about objects which have been marked already */
- if (!GC_IS_MARKED(ref)) {
-
- switch (f_type) {
-
- case FINAL_REACHABLE: /* object was reachable before */
- GC_LOG2( printf("Finalizer triggered for: ");
- heap_print_object(ref); printf("\n"); );
-
- /* object is now reclaimable */
- fe->type = FINAL_RECLAIMABLE;
+ GC_LOG( dolog("GC: Marking postprocessing ..."); );
- /* notify the finalizer after collection finished */
- gc_notify_finalizer = true;
-
- /* keep the object alive until finalizer finishes */
- MARK(ref);
- break;
-
- case FINAL_RECLAIMABLE: /* object not yet finalized */
- GC_LOG( printf("Finalizer not yet started for: ");
- heap_print_object(ref); printf("\n"); );
-
- /* keep the object alive until finalizer finishes */
- MARK(ref);
- break;
-
-#if 0
- case FINAL_FINALIZING: /* object is still being finalized */
- GC_LOG( printf("Finalizer not yet finished for: ");
- heap_print_object(ref); printf("\n"); );
-
- /* keep the object alive until finalizer finishes */
- MARK(ref);
- break;
-#endif
-
- default: /* case not yet covered */
- vm_abort("mark_me: uncovered case (type=%d)", f_type);
-
- }
- }
-
- fe = list_next_unsynced(final_list, fe);
- }
-#endif /*defined(GCCONF_FINALIZER)*/
+ /* perform some post processing of the marked heap */
+ mark_post(rstop);
GC_LOG( dolog("GC: Marking finished."); );