Merged with tip.
[cacao.git] / src / mm / cacao-gc / mark.c
index 500391b93dc1f8b9fc820493a35bcb5729813c95..c2c8a5c9b71a4896bf5b2c9743b3c9b0e91830ae 100644 (file)
@@ -1,9 +1,7 @@
-/* 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.
 
@@ -131,7 +129,7 @@ void mark_recursive(java_object_t *o)
                /* 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]);
 
@@ -164,53 +162,121 @@ void mark_recursive(java_object_t *o)
 }
 
 
-/* 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;
        }
 
 }
@@ -229,25 +295,20 @@ void mark_classes(void *start, void *end)
 
 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); );
 
@@ -273,61 +334,10 @@ void mark_me(rootset_t *rs)
                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."); );