MonoTouch + IKVM项目中的JIT编译问题

时间:2012-05-08 22:37:11

标签: java ios xamarin.ios ikvm aot

我正在通过ikvm-monotouch和MonoTouch将Java游戏移植到iOS。我遇到了一个有点过头的错误,虽然我不确定它是否是MonoTouch中的一个实际错误,所以我在问这个问题之前就到了bug数据库。

我在一个反映对象字段的方法中遇到了JIT编译错误。我(到目前为止)只是在反映实现Cloneable的对象时才看到此错误,但我不确定这是否具体是触发此错误的原因。

Unhandled Exception: System.TypeInitializationException: An exception was thrown by the type initializer for ikvm.internal.ClassLiteral`1 ---> System.ExecutionEngineException: Attempting to JIT compile method 'ikvm.internal.ClassLiteral`1<java.lang.Cloneable>:.cctor ()' while running with --aot-only.
   --- End of inner exception stack trace ---
   at System.Reflection.MonoField.GetValue (System.Object obj) [0x0006a] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System.Reflection/MonoField.cs:124 
   at IKVM.Internal.TypeWrapper.LazyInitClass () [0x00063] in /Users/nathan/projects/ikvm-monotouch-git/runtime/TypeWrapper.cs:1841 
   at IKVM.Internal.TypeWrapper.get_ClassObject () [0x00027] in /Users/nathan/projects/ikvm-monotouch-git/runtime/TypeWrapper.cs:1756 
   at IKVM.NativeCode.java.lang.Class.getInterfaces (java.lang.Class thisClass) [0x0001c] in /Users/nathan/projects/ikvm-monotouch-git/runtime/openjdk.cs:2556 
   at java.lang.Class.getInterfaces () [0x00000] in <filename unknown>:0 
   at java.lang.Class.privateGetPublicFields (Set ) [0x00000] in <filename unknown>:0 
   at java.lang.Class.privateGetPublicFields (Set ) [0x00000] in <filename unknown>:0 
   at java.lang.Class.getFields (ikvm.internal.CallerID ) [0x00000] in <filename unknown>:0 

指向ikvm-monotouch TypeWrapper类的快速链接:https://github.com/samskivert/ikvm-monotouch/blob/master/runtime/TypeWrapper.cs

1 个答案:

答案 0 :(得分:1)

TypeWrapper.cs的第1841行是:

clazz = (java.lang.Class)typeof(ikvm.@internal.ClassLiteral<>).
    MakeGenericType(type).GetField("Value").GetValue(null);

因此它要么与:

相关

a)MakeGenericType在AOT编译器不知道编译时的意义上,它需要创建ClassLiteral<Cloneable>。由于它不知道,它不会编译导致ExecutionEngineException的所需代码。

您可以通过提示需要代码的AOT编译器来解决此问题。例如。在代码中的某处添加一个链接或优化的地方。

new ClassLiteral<Cloneable> ();

b)GetField("Value")在某种意义上(托管)链接器可以删除此字段。但是它应该在NullReferenceException(而不在.cctor中)失败,所以我认为这是一个链接器问题。

通过禁用项目中的链接器,在设备上重建和执行(如果它开始工作,那么它是链接器问题),非常快速且容易地消除这种可能性。您将能够通过使用{{来解决此问题1}} [Preserve]字段的属性(之后重新启用链接器)。