Initial set of Ward sgen annotations (#5705)
[mono.git] / mono / sgen / sgen-fin-weak-hash.c
index 9641594483eec65cc456942dfaf37e235916ea16..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)
  * Copyright 2011 Xamarin, Inc.
  * Copyright (C) 2012 Xamarin Inc
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License 2.0 as published by the Free Software Foundation;
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License 2.0 along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 #include "config.h"
@@ -121,7 +111,7 @@ sgen_collect_bridge_objects (int generation, ScanCopyContext ctx)
        if (no_finalize)
                return;
 
-       SGEN_HASH_TABLE_FOREACH (hash_table, object, dummy) {
+       SGEN_HASH_TABLE_FOREACH (hash_table, GCObject *, object, gpointer, dummy) {
                int tag = tagged_object_get_tag (object);
                object = tagged_object_get_object (object);
 
@@ -191,7 +181,7 @@ sgen_finalize_in_range (int generation, ScanCopyContext ctx)
 
        if (no_finalize)
                return;
-       SGEN_HASH_TABLE_FOREACH (hash_table, object, dummy) {
+       SGEN_HASH_TABLE_FOREACH (hash_table, GCObject *, object, gpointer, dummy) {
                int tag = tagged_object_get_tag (object);
                object = tagged_object_get_object (object);
                if (!major_collector.is_object_live (object)) {
@@ -239,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);
@@ -356,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;
@@ -451,7 +441,7 @@ add_stage_entry (int num_entries, volatile gint32 *next_entry, StageEntry *entri
                                 * This seems like a good value.  Determined by timing
                                 * sgen-weakref-stress.exe.
                                 */
-                               g_usleep (200);
+                               mono_thread_info_usleep (200);
                                HEAVY_STAT (++stat_wait_for_processing);
                        }
                        continue;
@@ -538,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))
@@ -568,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;
-       SGEN_HASH_TABLE_FOREACH (hash_table, object, dummy) {
+       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;
 }
 
 /**
@@ -610,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
@@ -634,7 +614,7 @@ sgen_remove_finalizers_if (SgenObjectPredicateFunc predicate, void *user_data, i
        GCObject *object;
        gpointer dummy G_GNUC_UNUSED;
 
-       SGEN_HASH_TABLE_FOREACH (hash_table, object, dummy) {
+       SGEN_HASH_TABLE_FOREACH (hash_table, GCObject *, object, gpointer, dummy) {
                object = tagged_object_get_object (object);
 
                if (predicate (object, user_data)) {