Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRodrigo Kumpera <kumpera@gmail.com>2011-02-17 23:56:38 +0300
committerRodrigo Kumpera <kumpera@gmail.com>2011-02-18 00:58:12 +0300
commit32b3b31f74ec411d02efba37d58433ade9fa6d98 (patch)
tree689f3a9629b53e90f1f1b7bf47c3eafa86981086
parent1be427d6d3c4d46903e854e1e79fd07a355b8859 (diff)
Make sure we keep a root for the delegates when calling them.moon/3.99.0.2
* method-to-ir.c (mono_emit_method_call_full): Make sure we keep a root for delegates when calling them using the fast delegate dispatch. Fixes #667921
-rw-r--r--mono/mini/method-to-ir.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c
index 0b6a75d4aae..f4f9ed33892 100644
--- a/mono/mini/method-to-ir.c
+++ b/mono/mini/method-to-ir.c
@@ -2401,6 +2401,8 @@ mono_emit_method_call_full (MonoCompile *cfg, MonoMethod *method, MonoMethodSign
#ifdef MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE
if ((method->klass->parent == mono_defaults.multicastdelegate_class) && (!strcmp (method->name, "Invoke"))) {
+ MonoInst *dummy_use;
+
MONO_EMIT_NULL_CHECK (cfg, this_reg);
/* Make a call to delegate->invoke_impl */
@@ -2409,6 +2411,20 @@ mono_emit_method_call_full (MonoCompile *cfg, MonoMethod *method, MonoMethodSign
call->inst.inst_offset = G_STRUCT_OFFSET (MonoDelegate, invoke_impl);
MONO_ADD_INS (cfg->cbb, (MonoInst*)call);
+ /* We must emit a dummy use here because the delegate trampoline will
+ replace the 'this' argument with the delegate target making this activation
+ no longer a root for the delegate.
+ This is an issue for delegates that target collectible code such as dynamic
+ methods of GC'able assemblies.
+
+ For a test case look into #667921.
+
+ FIXME: a dummy use is not the best way to do it as the local register allocator
+ will put it on a caller save register and spil it around the call.
+ Ideally, we would either put it on a callee save register or only do the store part.
+ */
+ EMIT_NEW_DUMMY_USE (cfg, dummy_use, args [0]);
+
return (MonoInst*)call;
}
#endif