Initial set of Ward sgen annotations (#5705)
[mono.git] / mono / sgen / sgen-fin-weak-hash.c
index dd7cca93dbecc2634a3c6dce3ece2278a5d040ca..814b516a272042624a2e9a95a73a86ba5ffc4659 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * sgen-fin-weak-hash.c: Finalizers and weak links.
+/**
+ * \file
+ * Finalizers and weak links.
  *
  * Author:
  *     Paolo Molaro (lupus@ximian.com)
@@ -228,7 +229,7 @@ sgen_finalize_in_range (int generation, ScanCopyContext ctx)
 }
 
 /* LOCKING: requires that the GC lock is held */
-static void
+static MONO_PERMIT (need (sgen_gc_locked)) void
 register_for_finalization (GCObject *obj, void *user_data, int generation)
 {
        SgenHashTable *hash_table = get_finalize_entry_hash_table (generation);
@@ -345,7 +346,7 @@ try_lock_stage_for_processing (int num_entries, volatile gint32 *next_entry)
 }
 
 /* LOCKING: requires that the GC lock is held */
-static void
+static MONO_PERMIT (need (sgen_gc_locked)) void
 process_stage_entries (int num_entries, volatile gint32 *next_entry, StageEntry *entries, void (*process_func) (GCObject*, void*, int))
 {
        int i;
@@ -527,7 +528,7 @@ add_stage_entry (int num_entries, volatile gint32 *next_entry, StageEntry *entri
 }
 
 /* LOCKING: requires that the GC lock is held */
-static void
+static MONO_PERMIT (need (sgen_gc_locked)) void
 process_fin_stage_entry (GCObject *obj, void *user_data, int index)
 {
        if (ptr_in_nursery (obj))
@@ -557,30 +558,27 @@ sgen_object_register_for_finalization (GCObject *obj, void *user_data)
 }
 
 /* LOCKING: requires that the GC lock is held */
-static int
-finalizers_with_predicate (SgenObjectPredicateFunc predicate, void *user_data, GCObject **out_array, int out_size, SgenHashTable *hash_table)
+static MONO_PERMIT (need (sgen_gc_locked)) void
+finalize_with_predicate (SgenObjectPredicateFunc predicate, void *user_data, SgenHashTable *hash_table)
 {
        GCObject *object;
        gpointer dummy G_GNUC_UNUSED;
-       int count;
 
-       if (no_finalize || !out_size || !out_array)
-               return 0;
-       count = 0;
+       if (no_finalize)
+               return;
        SGEN_HASH_TABLE_FOREACH (hash_table, GCObject *, object, gpointer, dummy) {
                object = tagged_object_get_object (object);
 
                if (predicate (object, user_data)) {
                        /* remove and put in out_array */
                        SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE);
-                       out_array [count ++] = object;
-                       SGEN_LOG (5, "Collecting object for finalization: %p (%s) (%d)", object, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE (object)), sgen_hash_table_num_entries (hash_table));
-                       if (count == out_size)
-                               return count;
-                       continue;
+                       sgen_queue_finalization_entry (object);
+                       SGEN_LOG (5, "Enqueuing object for finalization: %p (%s) (%d)", object, sgen_client_vtable_get_name (SGEN_LOAD_VTABLE (object)), sgen_hash_table_num_entries (hash_table));
                }
+
+               if (sgen_suspend_finalizers)
+                       break;
        } SGEN_HASH_TABLE_FOREACH_END;
-       return count;
 }
 
 /**
@@ -599,21 +597,14 @@ finalizers_with_predicate (SgenObjectPredicateFunc predicate, void *user_data, G
  * @out_array me be on the stack, or registered as a root, to allow the GC to know the
  * objects are still alive.
  */
-int
-sgen_gather_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, GCObject **out_array, int out_size)
+void
+sgen_finalize_if (SgenObjectPredicateFunc predicate, void *user_data)
 {
-       int result;
-
        LOCK_GC;
        sgen_process_fin_stage_entries ();
-       result = finalizers_with_predicate (predicate, user_data, (GCObject**)out_array, out_size, &minor_finalizable_hash);
-       if (result < out_size) {
-               result += finalizers_with_predicate (predicate, user_data, (GCObject**)out_array + result, out_size - result,
-                       &major_finalizable_hash);
-       }
+       finalize_with_predicate (predicate, user_data, &minor_finalizable_hash);
+       finalize_with_predicate (predicate, user_data, &major_finalizable_hash);
        UNLOCK_GC;
-
-       return result;
 }
 
 void