/* * Some of our objects may point to a different address than the address returned by GC_malloc() * (because of the GetHashCode hack), but we need to pass the real address to register_finalizer. * This also means that in the callback we need to adjust the pointer to get back the real * MonoObject*. * We also need to be consistent in the use of the GC_debug* variants of malloc and register_finalizer, * since that, too, can cause the underlying pointer to be offset. */ static void object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*)) { MonoDomain *domain; if (obj == NULL) mono_raise_exception (mono_get_exception_argument_null ("obj")); domain = obj->vtable->domain; #if HAVE_BOEHM_GC if (mono_domain_is_unloading (domain) && (callback != NULL)) /* * Can't register finalizers in a dying appdomain, since they * could be invoked after the appdomain has been unloaded. */ return; mono_domain_finalizers_lock (domain); if (callback) g_hash_table_insert (domain->finalizable_objects_hash, obj, obj); else g_hash_table_remove (domain->finalizable_objects_hash, obj); mono_domain_finalizers_unlock (domain); mono_gc_register_for_finalization (obj, callback); #elif defined(HAVE_SGEN_GC) /* * If we register finalizers for domains that are unloading we might * end up running them while or after the domain is being cleared, so * the objects will not be valid anymore. */ if (!mono_domain_is_unloading (domain)) mono_gc_register_for_finalization (obj, callback); #endif }
/* * Some of our objects may point to a different address than the address returned by GC_malloc() * (because of the GetHashCode hack), but we need to pass the real address to register_finalizer. * This also means that in the callback we need to adjust the pointer to get back the real * MonoObject*. * We also need to be consistent in the use of the GC_debug* variants of malloc and register_finalizer, * since that, too, can cause the underlying pointer to be offset. */ static void object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*)) { #if HAVE_BOEHM_GC guint offset = 0; MonoDomain *domain; if (obj == NULL) mono_raise_exception (mono_get_exception_argument_null ("obj")); domain = obj->vtable->domain; #ifndef GC_DEBUG /* This assertion is not valid when GC_DEBUG is defined */ g_assert (GC_base (obj) == (char*)obj - offset); #endif if (mono_domain_is_unloading (domain) && (callback != NULL)) /* * Can't register finalizers in a dying appdomain, since they * could be invoked after the appdomain has been unloaded. */ return; mono_domain_finalizers_lock (domain); if (callback) g_hash_table_insert (domain->finalizable_objects_hash, obj, obj); else g_hash_table_remove (domain->finalizable_objects_hash, obj); mono_domain_finalizers_unlock (domain); GC_REGISTER_FINALIZER_NO_ORDER ((char*)obj - offset, callback, GUINT_TO_POINTER (offset), NULL, NULL); #elif defined(HAVE_SGEN_GC) if (obj == NULL) mono_raise_exception (mono_get_exception_argument_null ("obj")); /* * If we register finalizers for domains that are unloading we might * end up running them while or after the domain is being cleared, so * the objects will not be valid anymore. */ if (!mono_domain_is_unloading (obj->vtable->domain)) mono_gc_register_for_finalization (obj, callback); #endif }