Created attachment 19863 [details]
File which reproduces the issue
This issue was first reported to me under Xamarin.iOS (on the real device only, the simulator is fine). I managed to reproduce and reduce under Mono on Linux, which is why I filed under "Compilers" and "All Hardware / All OS". Please refile if this was a bad assumption.
Please see the attached sample. I've commented the bits that seem to be critical: it seems to be that the AOT can't figure out that a generic method is called with a struct generic type parameter, but only if that generic method references an enum member on the struct.
Steps to reproduce:
mono --aot=full Program.exe
mono --full-aot Program.exe
On my machine, the output is:
* Assertion at mini-generic-sharing.c:2351, condition `info' not met
at <unknown> <0xffffffff>
at Test.TestClass`1<T_INT>.Part1 () <0x00029>
at Test.Program.Main (string) <0x0001f>
at (wrapper runtime-invoke) object.runtime_invoke_dynamic (intptr,intptr,intptr,intptr) <0x000cc>
Debug info from gdb:
Got a SIGABRT while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
Aborted (core dumped)
(Disclaimer: when I first tried to reproduce it on my machine, it failed with "Failed to load AOT module '/usr/lib/mono/4.5/mscorlib.dll.so' while running in aot-only mode: not compiled with --aot=full". I manually copied dlls out of /usr/lib/mono/4.5 into my CWD, AOT'd them with --aot=full, and set MONO_PATH to the CWD. I don't believe this has affected the outcome in any way).
For completion, the original (non-reduced) problem produced the following output on Xamarin.iOS (probably incomplete - it was reported by a third party):
**System.ExecutionEngineException** has been thrown
Attempting to JiT compile method 'StateMechanic.StateMachine`1<StateMechanic.State>:RequestEver(StateMechanic.EventTransitionInvoker`1<StateMechanic.State>)' while running with --aot-only. See http://docs.xamarin.com/ios/about/limitations for more information
at StateMechanic.StateMachine`1[TState].StateMechanic.IEventDelegate.RequestEventFireFromEvent (StateMechanic.Event event, EventFireMethod eventFireMethod) [0x0000a] in <filename unknown>:0
at StateMechanic.Event.RequestEventFireFromEvent (EventFireMethod eventFireMethod) [0x0000f] in <filename unknown>:0
at StateMechanic.Event.Fire () [0x00000] in <filename unknown>:0
Fixed in mono master 15a6c8a875281b04b4bcd69c7b330faf0f4a7ace. Thanks for the testcase.
Awesome, nice one. Thanks!
Is there a sensible workaround, until that fix makes its way into Xamarin.iOS?
The workaround is to avoid calls which are made on 'constrained' types, and return enums, like in the testcase:
public void Part2<TFoo>(TFoo foo) where TFoo : IFoo // <-- Needs to be generic
Console.WriteLine(foo.Bar); // <-- Needs to reference the enum member from foo
// (if I add an int member and reference that, everything is OK)
Here TFoo can be either a reference or a struct type, since both can implement IFoo, so its a complicated case.
OK, so it's the combination of a constrained type and anything which returns an enum which causes the issue. I see, thanks!