X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fgc.c;h=172660d1b55e93efbf291e6612ab9877883782ff;hb=ef0ddf45c3081e799edcb4e95770186514b80cf1;hp=7f85c3a0e04b33dee00a398c595a7e1510d138fe;hpb=2002994d0c06860d22253edbb7bae0ddcda7df44;p=mono.git diff --git a/mono/metadata/gc.c b/mono/metadata/gc.c index 7f85c3a0e04..172660d1b55 100644 --- a/mono/metadata/gc.c +++ b/mono/metadata/gc.c @@ -6,6 +6,7 @@ * Copyright 2002-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) * Copyright 2012 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include @@ -71,7 +72,7 @@ static MonoCoopCond exited_cond; static MonoInternalThread *gc_thread; -static void object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*)); +static void object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*), MonoError *error); static void reference_queue_proccess_all (void); static void mono_reference_queue_cleanup (void); @@ -108,6 +109,7 @@ static gboolean suspend_finalizers = FALSE; void mono_gc_run_finalize (void *obj, void *data) { + MonoError error; MonoObject *exc = NULL; MonoObject *o; #ifndef HAVE_SGEN_GC @@ -161,7 +163,8 @@ mono_gc_run_finalize (void *obj, void *data) #endif /* make sure the finalizer is not called again if the object is resurrected */ - object_register_finalizer ((MonoObject *)obj, NULL); + object_register_finalizer ((MonoObject *)obj, NULL, &error); + mono_error_assert_ok (&error); /* FIXME don't swallow the error */ if (log_finalizers) g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Registered finalizer as processed.", o->vtable->klass->name, o); @@ -228,7 +231,7 @@ mono_gc_run_finalize (void *obj, void *data) } /* - * To avoid the locking plus the other overhead of mono_runtime_invoke (), + * To avoid the locking plus the other overhead of mono_runtime_invoke_checked (), * create and precompile a wrapper which calls the finalize method using * a CALLVIRT. */ @@ -243,7 +246,8 @@ mono_gc_run_finalize (void *obj, void *data) runtime_invoke = (RuntimeInvokeFunction)domain->finalize_runtime_invoke; - mono_runtime_class_init (o->vtable); + mono_runtime_class_init_full (o->vtable, &error); + mono_error_raise_exception (&error); /* FIXME don't raise here */ if (G_UNLIKELY (MONO_GC_FINALIZE_INVOKE_ENABLED ())) { MONO_GC_FINALIZE_INVOKE ((unsigned long)o, mono_object_get_size (o), @@ -267,12 +271,14 @@ mono_gc_run_finalize (void *obj, void *data) void mono_gc_finalize_threadpool_threads (void) { + MonoError error; while (threads_to_finalize) { MonoInternalThread *thread = (MonoInternalThread*) mono_mlist_get_data (threads_to_finalize); /* Force finalization of the thread. */ thread->threadpool_thread = FALSE; - mono_object_register_finalizer ((MonoObject*)thread); + mono_object_register_finalizer ((MonoObject*)thread, &error); + mono_error_assert_ok (&error); /* FIXME don't swallow the error */ mono_gc_run_finalize (thread, NULL); @@ -302,12 +308,16 @@ mono_gc_out_of_memory (size_t size) * since that, too, can cause the underlying pointer to be offset. */ static void -object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*)) +object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*), MonoError *error) { MonoDomain *domain; - if (obj == NULL) - mono_raise_exception (mono_get_exception_argument_null ("obj")); + mono_error_init (error); + + if (obj == NULL) { + mono_error_set_argument_null (error, "obj", ""); + return; + } domain = obj->vtable->domain; @@ -349,10 +359,10 @@ object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*)) * */ void -mono_object_register_finalizer (MonoObject *obj) +mono_object_register_finalizer (MonoObject *obj, MonoError *error) { /* g_print ("Registered finalizer on %p %s.%s\n", obj, mono_object_class (obj)->name_space, mono_object_class (obj)->name); */ - object_register_finalizer (obj, mono_gc_run_finalize); + object_register_finalizer (obj, mono_gc_run_finalize, error); } /** @@ -470,14 +480,19 @@ ves_icall_System_GC_KeepAlive (MonoObject *obj) void ves_icall_System_GC_ReRegisterForFinalize (MonoObject *obj) { + MonoError error; + MONO_CHECK_ARG_NULL (obj,); - object_register_finalizer (obj, mono_gc_run_finalize); + object_register_finalizer (obj, mono_gc_run_finalize, &error); + mono_error_set_pending_exception (&error); } void ves_icall_System_GC_SuppressFinalize (MonoObject *obj) { + MonoError error; + MONO_CHECK_ARG_NULL (obj,); /* delegates have no finalizers, but we register them to deal with the @@ -491,7 +506,8 @@ ves_icall_System_GC_SuppressFinalize (MonoObject *obj) * generated for it that needs cleaned up, but user wants to suppress * their derived object finalizer. */ - object_register_finalizer (obj, NULL); + object_register_finalizer (obj, NULL, &error); + mono_error_set_pending_exception (&error); } void @@ -890,7 +906,7 @@ mono_gc_is_finalizer_internal_thread (MonoInternalThread *thread) * This routine tests whether the @thread argument represents the * finalization thread. * - * Returns true if @thread is the finalization thread. + * Returns: TRUE if @thread is the finalization thread. */ gboolean mono_gc_is_finalizer_thread (MonoThread *thread) @@ -1055,6 +1071,7 @@ mono_gc_reference_queue_new (mono_reference_queue_callback callback) gboolean mono_gc_reference_queue_add (MonoReferenceQueue *queue, MonoObject *obj, void *user_data) { + MonoError error; RefQueueEntry *entry; if (queue->should_be_deleted) return FALSE; @@ -1064,7 +1081,8 @@ mono_gc_reference_queue_add (MonoReferenceQueue *queue, MonoObject *obj, void *u entry->domain = mono_object_domain (obj); entry->gchandle = mono_gchandle_new_weakref (obj, TRUE); - mono_object_register_finalizer (obj); + mono_object_register_finalizer (obj, &error); + mono_error_assert_ok (&error); ref_list_push (&queue->queue, entry); return TRUE;