diff options
author | Rodrigo Kumpera <kumpera@gmail.com> | 2011-02-17 23:56:38 +0300 |
---|---|---|
committer | Rodrigo Kumpera <kumpera@gmail.com> | 2011-02-18 00:58:12 +0300 |
commit | 32b3b31f74ec411d02efba37d58433ade9fa6d98 (patch) | |
tree | 689f3a9629b53e90f1f1b7bf47c3eafa86981086 | |
parent | 1be427d6d3c4d46903e854e1e79fd07a355b8859 (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.c | 16 |
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 |