On 01/22/2016 09:47 PM, Vincent Povirk wrote:
Mono has a lock around the JIT compiler, and it caches the functions it generates. So we can have multiple threads writing the same function pointers into the vtable (which should be fine as long as every other thread that reads it will see either the old value or the new one). Mono doesn't reference-count JITed functions, and I'm not sure if cleaning them up is even possible.
Oh, I see. So it sounds like there is no clear way to unload the assembly and a DLL with it at all? Do you know if this the case with Win .NET? I am curious because I was trying to locate the issue I get with crash on exit in my test case. I am not filling it yet as bug report as we discussed because it also has MFC (which functions are actually crashing on exit), and I am not sure yet that it is not some issue unrelated to Mono. But this happens only if .Net assembly was loaded during the application run and I suspected that crashed could be triggered by some incompatible unitialization.
Non-locked write to fixup->done is also OK as long as no thread can incorrectly read the value as TRUE and return before the vtable is ready. If a thread incorrectly reads it as FALSE, it'll just do a bit of unnecessary work. Actually, I'm not sure that field is needed at all, it seems like overwriting the values in the vtable should be enough.
I think it is a sort of nearly theoretical question because it would be really very hard to get this in practice. I think if to remove fixup->done it would totally OK as you say. But if not AFAIK it is possible that you get an older vtable value but newer fixup->done if threads are at distinct CPUs (strong enough "fence" is required to guarantee memory access order).
BTW I submitted bug report with my test case and patch to mono: https://bugzilla.xamarin.com/show_bug.cgi?id=37913