[Mono-devel-list] implementing the synchronized method attribute

Paolo Molaro lupus at ximian.com
Sun Apr 13 04:54:03 EDT 2003

On 04/12/03 Varga Zoltan wrote:
>   I would like to implement the 'synchronized' method
> attribute in the
> runtime. I thought about using the wrapper facility for
> this, i.e. creating
> a synchronized wrapper for the method which would call the
> non-synchronized version. Is this a good idea?

I don't think using a wrapper would buy you anything.
The best way, IMO, is to insert the calls to
mono_monitor_enter/mono_monitor_leave in mono_method_to_ir().

mono_monitor_enter (MonoObject* obj)
	mono_monitor_try_enter (obj, infinite_ms_value);

The call should be simply added at the start of the init_locals basic
block; to do so make sure this block is created for synchronized methods
(check mini.c at line about 2130).
The actual call needs to be inserted at line about 4130, see for example
how the call to mono_domain_get is done there.

mono_monitor_leave () needs to be handled similarly: I suggest doing
that in the case for CEE_RET in the big switch (I would also disable
inlining for synchronized methods).

Inserting the call is something like:

		MonoCallInst *call;
		MonoInst *args [1];

		NEW_ARGLOAD (cfg, args [0], 0); // load this
		call->args = args;
		call->signature = helper_sig_monitor_op;
		call->fptr = mono_monitor_enter; // mono_monitor_leave
		call = mono_arch_call_opcode (cfg, init_localsbb, call, FALSE);
		MONO_ADD_INS (init_localsbb, call);

You need to setup helper_sig_monitor_op with a void return type,
instance method and no arguments.
That is the easy stuff and after you've done that you can start testing
At this point there is just one missing issue: calling
mono_monitor_leave() on stack unwind. This needs to be done in
exceptions-x86.c: when a synchronized method is exited using stack
unwind, we need to retrieve the 'this' pointer and call
mono_monitor_leave() manually. The easy way is to add a field to
MonoJitInfo (in metadata/appdomain.h) that describes where the this
pointer is stored (it can be a register or a reg+offset).
The unwind code has access to the registers, so it can retrieve the
pointer value and call mono_monitor_leave ().
The info in MonoJitInfo needs to be saved in mini_method_compile()
from cfg->varinfo [0] at line about 5670 in mini.c.


lupus at debian.org                                     debian/rules
lupus at ximian.com                             Monkeys do it better

More information about the Mono-devel-list mailing list