Skip to content

Commit

Permalink
Make sure we keep a root for the delegates when calling them.
Browse files Browse the repository at this point in the history
	* 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
  • Loading branch information
kumpera committed Feb 17, 2011
1 parent 1be427d commit 32b3b31
Showing 1 changed file with 16 additions and 0 deletions.
16 changes: 16 additions & 0 deletions mono/mini/method-to-ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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
Expand Down

0 comments on commit 32b3b31

Please sign in to comment.