X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fsgen%2Fsgen-fin-weak-hash.c;h=814b516a272042624a2e9a95a73a86ba5ffc4659;hb=a984f20e232d863a9d3b7848023f78816aa282e7;hp=5130b1c6b3894de6727e094a73032dd045a6f42c;hpb=a8b276ed8c76125cdd282bb5bdefe89d3a51f579;p=mono.git diff --git a/mono/sgen/sgen-fin-weak-hash.c b/mono/sgen/sgen-fin-weak-hash.c index 5130b1c6b38..814b516a272 100644 --- a/mono/sgen/sgen-fin-weak-hash.c +++ b/mono/sgen/sgen-fin-weak-hash.c @@ -1,5 +1,6 @@ -/* - * sgen-fin-weak-hash.c: Finalizers and weak links. +/** + * \file + * Finalizers and weak links. * * Author: * Paolo Molaro (lupus@ximian.com) @@ -10,18 +11,7 @@ * 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" @@ -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; @@ -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; + 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