Permalink
Browse files

Don't use finalization to cleanup dynamic methods.

	* reflection.c: Use a reference queue to cleanup
	dynamic methods instead of finalization.

	* runtime.c: Shutdown the dynamic method queue
	before runtime cleanup begins.

	* DynamicMethod.cs: No longer finalizable.

	* icall-def.h: Remove unused dynamic method icall.

	Fixes #660422
  • Loading branch information...
1 parent 8eb1189 commit 89d1455a80ef13cddee5d79ec00c06055da3085c @kumpera kumpera committed Feb 1, 2011
@@ -127,9 +127,6 @@ public DynamicMethod (string name, Type returnType, Type[] parameterTypes, bool
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void create_dynamic_method (DynamicMethod m);
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern void destroy_dynamic_method (DynamicMethod m);
-
private void CreateDynMethod () {
if (mhandle.Value == IntPtr.Zero) {
if (ilgen == null || ilgen.ILOffset == 0)
@@ -158,11 +155,6 @@ public DynamicMethod (string name, Type returnType, Type[] parameterTypes, bool
}
}
- ~DynamicMethod ()
- {
- destroy_dynamic_method (this);
- }
-
[ComVisible (true)]
public Delegate CreateDelegate (Type delegateType)
{
@@ -524,7 +524,6 @@ ICALL(DERIVEDTYPE_1, "create_unmanaged_type", mono_reflection_create_unmanaged_t
ICALL_TYPE(DYNM, "System.Reflection.Emit.DynamicMethod", DYNM_1)
ICALL(DYNM_1, "create_dynamic_method", mono_reflection_create_dynamic_method)
-ICALL(DYNM_2, "destroy_dynamic_method", mono_reflection_destroy_dynamic_method)
ICALL_TYPE(ENUMB, "System.Reflection.Emit.EnumBuilder", ENUMB_1)
ICALL(ENUMB_1, "setup_enum_type", ves_icall_EnumBuilder_setup_enum_type)
@@ -1539,6 +1539,9 @@ mono_object_new_pinned (MonoDomain *domain, MonoClass *klass) MONO_INTERNAL;
void
mono_field_static_get_value_for_thread (MonoInternalThread *thread, MonoVTable *vt, MonoClassField *field, void *value) MONO_INTERNAL;
+void
+mono_reflection_shutdown (void) MONO_INTERNAL;
+
#endif /* __MONO_OBJECT_INTERNALS_H__ */
View
@@ -11441,15 +11441,56 @@ mono_reflection_sighelper_get_signature_field (MonoReflectionSigHelper *sig)
return result;
}
+typedef struct {
+ MonoMethod *handle;
+ MonoDomain *domain;
+} DynamicMethodReleaseData;
+
+static MonoReferenceQueue *dynamic_method_queue;
+
+void
+mono_reflection_shutdown (void)
+{
+ MonoReferenceQueue *queue;
+ mono_loader_lock ();
+ queue = dynamic_method_queue;
+ dynamic_method_queue = NULL;
+ if (queue)
+ mono_gc_reference_queue_free (queue);
+ mono_loader_unlock ();
+}
+
+static void
+free_dynamic_method (void *dynamic_method)
+{
+ DynamicMethodReleaseData *data = dynamic_method;
+
+ mono_runtime_free_method (data->domain, data->handle);
+ g_free (data);
+}
+
void
mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
{
+ MonoReferenceQueue *queue;
+ MonoMethod *handle;
+ DynamicMethodReleaseData *release_data;
ReflectionMethodBuilder rmb;
MonoMethodSignature *sig;
MonoClass *klass;
GSList *l;
int i;
+ if (mono_runtime_is_shutting_down ())
+ mono_raise_exception (mono_get_exception_invalid_operation (""));
+
+ if (!(queue = dynamic_method_queue)) {
+ mono_loader_lock ();
+ if (!(queue = dynamic_method_queue))
+ queue = dynamic_method_queue = mono_gc_reference_queue_new (free_dynamic_method);
+ mono_loader_unlock ();
+ }
+
sig = dynamic_method_to_signature (mb);
reflection_methodbuilder_from_dynamic_method (&rmb, mb);
@@ -11507,7 +11548,12 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
klass = mb->owner ? mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner)) : mono_defaults.object_class;
- mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig);
+ mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig);
+ release_data = g_new (DynamicMethodReleaseData, 1);
+ release_data->handle = handle;
+ release_data->domain = mono_object_get_domain ((MonoObject*)mb);
+ if (!mono_gc_reference_queue_add (queue, (MonoObject*)mb, release_data))
+ g_free (release_data);
/* Fix up refs entries pointing at us */
for (l = mb->referenced_by; l; l = l->next) {
@@ -11533,16 +11579,6 @@ mono_reflection_create_dynamic_method (MonoReflectionDynamicMethod *mb)
#endif /* DISABLE_REFLECTION_EMIT */
-void
-mono_reflection_destroy_dynamic_method (MonoReflectionDynamicMethod *mb)
-{
- g_assert (mb);
-
- if (mb->mhandle)
- mono_runtime_free_method (
- mono_object_get_domain ((MonoObject*)mb), mb->mhandle);
-}
-
/**
*
* mono_reflection_is_valid_dynamic_token:
View
@@ -39,5 +39,8 @@ void
mono_runtime_shutdown (void)
{
mono_domain_foreach (fire_process_exit_event, NULL);
+
+ /*From this point on, no more DM methods can be created. */
+ mono_reflection_shutdown ();
}

0 comments on commit 89d1455

Please sign in to comment.