+#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;
+
+ /* 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)*/
+
+ GC_LOG( dolog("GC: Marking finished."); );
+
+#if defined(ENABLE_STATISTICS)
+ GC_ASSERT(gcstat_mark_depth == 0);
+#endif