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

dietmar dietmar at ximian.com
Mon Apr 14 06:20:51 EDT 2003


IMO the wrapper approach is much easier to implement since it does not
need to handle any special cases. The exception handling stuff is
already complex enough, and it is also architecture dependent. So I
would implement the wrapper approach until it turns out that its not
usable for some reasons.

- Dietmar

On Sun, 2003-04-13 at 10:54, Paolo Molaro wrote:
> 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().
> 
> With:
> void
> 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
>                 MONO_INST_NEW_CALL (cfg, call, CEE_CALL);
>                 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
> things.
> 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
> 
> -- 
> -----------------------------------------------------------------
> lupus at debian.org                                     debian/rules
> lupus at ximian.com                             Monkeys do it better
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list
> 




More information about the Mono-devel-list mailing list