Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

ExecutionEngineException: Attempting to JIT compile method..

Discussion in 'iOS and tvOS' started by Michael-Ryan, Mar 9, 2010.

  1. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    184
    I just discovered an issue I'm getting on the iPod device that I never received before.

    Code (csharp):
    1. ExecutionEngineException: Attempting to JIT compile method 'System.Reflection.MonoProperty:GetterAdapterFrame<Image, UnityEngine.Color> (System.Reflection.MonoProperty/Getter`2<Image, UnityEngine.Color>,object)' while running with --aot-only.
    2.  
    3.  
    4. System.Reflection.MonoProperty.GetValue (System.Object obj, System.Object[] index) [0x00000]
    5. Ani+AniValue.Get ()
    6. Ani.CreateAnimations (System.Object obj, System.Collections.Hashtable properties, Single duration, System.Collections.Hashtable options, AniType type)
    7. Ani.Method (AniType type, System.Object obj, Single duration, System.Collections.Hashtable _properties, System.Collections.Hashtable _options)
    8. Ani.From (System.Object obj, Single duration, System.Collections.Hashtable _properties)
    9. xObject+<>c__CompilerGenerated5.MoveNext ()
    10. UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
    11. xObject:StartAnimation(Animate, GameObject, Object, Object)
    12. SceneSplash:CreateBackground()
    13. SceneSplash:OnSetup()
    14. SceneSplash:OnSceneActivate(Callback)
    15. GameController:ActivateScene()
    16. GameController:DeactivateScene()
    17. GameController:SceneLoaded(Scene, GameObject, SceneBase)
    18. SceneBase:Start()
    I recently updated Unity iPhone to 1.6, and went though most of my code and replaced ArrayLists with List<> objects, where appropriate. I believe I tested on the device afterward to see if there were any obvious speed improvements, and the app ran fine.

    I usually work in the editor, and it wasn't until maybe an hour ago that I tested again on the device. Now, I'm receiving the above error shortly after launch.

    My code uses the AniMate script (C# version that shipped with GUIManager) from the Unify wiki, and I don't believe I've changed anything in it recently. It looks like the "Attempting to JIT compile method" is occurring when I fade an Image in from black. The Image class is basically a customized GameObject that has a reference to a quad (Sprite) in the SpriteManager.

    Anyhow, I have no idea what could cause this message to appear.


    It's generated by the "return propertyInfo.GetValue(obj, null);" line. Using Debug.Log(propertyInfo.ToString()) outputs, "UnityEngine.Color Color". The object 'obj' is the Image object, which has a Color property.

    Code (csharp):
    1. public System.Object Get()
    2. {
    3.     if (propertyInfo != null) return propertyInfo.GetValue(obj, null);
    4.     else return fieldInfo.GetValue(obj);
    5. }
    6.  

    Again, this worked fine earlier. Something must have changed, I'm guessing.

    I'm using Generics on the iPhone. I've enabled .NET 2.1 in the Editor -> PlayerSettings. I'm building to the "iPhone OS 2.2.1". Is that okay? I don't need to use a newer OS version, do I?
     
  2. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    the target is fine but ensure you you set the stripping to the appropriate level (start with nothing)

    also to me it looks like there is a Dictionary<..,...> involved which work for some types but not for others! (<int, ...> is known to work but <object,...> could potentially bite you due to the restrictions on aot)
     
  3. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    184
    Thanks for the reply. In Unity iPhone > Player Settings, "IPhone Stripping Level" is Disabled, and the field is grayed out. This is probably because I'm using the Basic version.

    I'm curious regarding the "appropriate level" in this case. Would reflection stop working if you were to use one of the other stripping options: Strip Assemblies, Strip ByteCode, or Use micro mscorlib?

    Also, on the Build Game dialog, "Strip Debug Symbols" is disabled, although I tried building with it enabled, and received the same error.


    I am pretty unfamiliar with aot restrictions. The Hashtable is using strings for the Key, but the Value is anything from a string or float to a UnityEngine.Color object.

    The animation and hashtable code worked before on the device, and nothing changed directly in those areas since it last worked.

    I guess I should attempt to revert back to the code revision right before I updated to 1.6 and see if that works. If so, I'll reintegrate changes and see what triggers the failure.

    If I am misunderstanding anything here, or if you have any other suggestions on what could be causing the issue, please let me know.

    Thanks again!
     
  4. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    184
    Okay. I reverted to an earlier revision from just before I installed 1.6.

    When I tried running the app using .NET 1.1, it ran fine. Just switching to .NET 2.1 in Unity iPhone > Player Setting caused the problem to reappear. I've gone back and forth a few times to verify the results.

    There is no .NET 2.1-specific code in the app at this point, but switching to the newer framework causes the error to appear.

    Does anyone have any ideas on what could be causing this? I would really love to take advantage of .NET 2.1, but at this point, the app is crapping out on the device after simply enabling the new framework.
     
  5. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    some generics are impossible to run without JIT though if it runs with 1.1 but not with 2.1 it seems like some generic related library part wants to force itself into jit although it could life without
     
  6. zibba

    zibba

    Joined:
    Mar 13, 2009
    Posts:
    165
    I've had a very similar problem. If you're doing anything with System.Reflection it does not work with .Net 2.1 and/or generics. Plus stripping level has to be disabled. Like Dreamora said it requires JIT and JIT ain't no good here.
     
  7. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    184
    So the only options are use 1.1 and take advantage of Reflection or 2.1 and take advantage of Generics. That is unfortunate. I think at this point, I'll have to stick with 1.1, since Reflection is used in a number of places in my app's code base.

    Thanks for the info.
     
  8. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    184
    I came across this list of Limitations on MonoTouch.net.

    My question to both the community and the Unity iPhone team is whether or not the limitations on that page are the same limitations we developers of Unity iPhone apps should be aware of.

    If not, is there a similar document that specifies the programming methods and patterns we should avoid when developing for the iPhone family of devices?

    It would be great if such a document existed in the Unity iPhone documentation set.
     
  9. zibba

    zibba

    Joined:
    Mar 13, 2009
    Posts:
    165
    Unity uses Mono Full-AOT, I think it's safe to assume that these limitations apply to both MonoTouch and Unity iPhone
     
  10. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    184
    Cool. Maybe I can work around those limitations. Thanks again!
     
  11. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    184
    I appreciate the information I've received so far, and apologize if it seems like I'm repeating myself. I'm still getting familiar with C#, JIT, and Reflection.

    After further investigation, I'm really confused by the situation. If Unity implements the same library as MonoTouch, then I'm not sure the exception should be occurring.

    According to their Limitations document for MonoTouch/Full AOT, System.Reflection.Emit is not supported, but they state that aside from Reflection.Emit, "the entire Reflection API, including Type.GetType("someClass"), listing methods, listing properties, fetching attributes and values works just fine."

    In the GUIManager package available on the forum, the CreateAnimations() method accepts a System.Object and Hashtable as parameters. In a foreach, the object and a property name (retrieved from the Hashtable) are used to create an instance of an AniValue object. Immediately afterward, the Get() method is called on that new instance, which should simply call GetValue(obj, null) on a System.Reflection.PropertyInfo object that was created earlier in the AniValue() constructor.

    I'll include the code chunks here:


    Code (csharp):
    1. void CreateAnimations(System.Object obj, Hashtable properties, float duration,
    2.                       Hashtable options, AniType type)
    3. {
    4.     foreach (DictionaryEntry item in properties)
    5.     {
    6.         name = (string)item.Key;                // Get name and value
    7.         System.Object value = item.Value;
    8.  
    9.         AniValue foo = new AniValue(obj, name); // Create value object
    10.  
    11.         /* To exception occurs inside Get() */
    12.         System.Object current = foo.Get();      // Get current value
    13.  
    14.         ...

    Code (csharp):
    1. using System.Reflection
    2.  
    3. public class AniValue
    4. {
    5.     static BindingFlags bFlags = BindingFlags.Public
    6.                                  | BindingFlags.NonPublic
    7.                                  | BindingFlags.Instance
    8.                                  | BindingFlags.Static;
    9.  
    10.     System.Object obj;  // Object a field or property is animated on
    11.     string name;        // Name of the field or property
    12.  
    13.     System.Type objType;          // Type object
    14.     FieldInfo fieldInfo;          // FieldInfo object
    15.     PropertyInfo propertyInfo;    // PropertyInfo object
    16.  
    17.     public AniValue(System.Object o, string n)
    18.     {
    19.         obj = o;
    20.         name = n;
    21.         objType = obj.GetType();
    22.         fieldInfo = objType.GetField(n, AniValue.bFlags);
    23.         propertyInfo = objType.GetProperty(n, AniValue.bFlags);
    24.         if (fieldInfo == null  propertyInfo == null)
    25.         {
    26.             throw new System.MissingMethodException("Property or field '"
    27.                 + n + "' not found on " + obj);
    28.         }
    29.     }
    30.  
    31.     // Get field or property
    32.     public System.Object Get()
    33.     {
    34.         if (propertyInfo != null)
    35.         {
    36.             /* The next line causes the Exception */
    37.             return propertyInfo.GetValue(obj, null);
    38.         }
    39.         else
    40.         {
    41.             return fieldInfo.GetValue(obj);
    42.         }
    43.     }
    44.  
    45.     ...


    From what I read in the MonoTouch Limitations document, I understand that this should be fine. No generics are being used at this point anywhere in the project code, otherwise I don't expect it would run under .NET 1.1, which is does.

    Furthermore, when I manually worked around the problem GetValue() call, using the following code, the rest of the app runs fine, even though there are later Reflection calls to Set the same property and those work without issue.



    Code (csharp):
    1. //System.Object current = aniv.Get();  // === Generates an exception
    2. System.Object current = null;
    3.  
    4. switch (name)
    5. {
    6.     case "Alpha":
    7.         if (obj is Button)     current = ((Button)obj).Alpha;
    8.         break;
    9.  
    10.     case "Color":
    11.         if (obj is Image)      current = ((Image)obj).Color;
    12.         else if (obj is Label) current = ((Label)obj).Color;
    13.         break;
    14.  
    15.     case "localPosition":
    16.         if (obj is Transform)  current = ((Transform)obj).localPosition;
    17.         break;
    18.  
    19.     case "Rotation":
    20.         if (obj is Image)      current = ((Image)obj).Rotation;
    21.         break;
    22.  
    23.     case "Scale":
    24.         if (obj is Image)      current = ((Image)obj).Scale;
    25.         else if (obj is Label) current = ((Label)obj).Scale;
    26.         break;
    27. }
    28.  
    29. if (current == null)
    30. {
    31.     throw new System.NotImplementedException("Animating " +
    32.         obj.GetType() + "." + name + " is not yet implemented");
    33. }

    Code (csharp):
    1. public class AniValue
    2. {
    3.  
    4.     ...
    5.  
    6.     // Set field or property
    7.     public void Set(System.Object value)
    8.     {
    9.         if (propertyInfo != null)
    10.             propertyInfo.SetValue(obj, value, null);    // Works fine
    11.         else
    12.             fieldInfo.SetValue(obj, value);
    13.     }
    14.  
    15.     ...


    So my question is, is there really a limitation that prevents GetValue(), but allows SetValue() on non-generic object properties, or is this a bug? Could it be a bug in the Mono code?

    I admit that I'm not very experienced in the workings of JIT and Reflection, but I don't think this is using System.Reflection.Emit anywhere in my code, and nothing in the Limitations document linked above leads me to believe this should generate an exception. The fact that they clearly state, "listing methods, listing properties, fetching attributes and values works just fine", leads me to believe it should actually work.

    If you are interested in duplicating the error, do the following:

    1. Download the either the GUIManager or GM2 package from the forum
    2. Create a new project in Unity iPhone 1.6
    3. Import that package
    4. Load the Demo scene installed by the package
    5. Enable .NET 2.1 in Player Settings
    6. Build to the device (I'm building to OS 2.2.1)

    I really appreciate any and all assistance in this matter.
     
  12. cchuter

    cchuter

    Joined:
    Mar 11, 2010
    Posts:
    9
    I want to add my voice to this thread.

    I am having the *exact* same problem. Everything works fine in the editor, but I get a SIGBUS crash when running on the iPhone.

    I have tracked it down to the Ani.js file in the exact same spot that mryan found. I don't know what to do next either. For the time being, we have all downgraded to Unity 1.5 to get around the crash and keep working (changing from .NET 2.1 to 1.1 has no effect - it crashes in either version)

    Should this thread turn into a bug report?

    Are there any Unity dev's out there who can help with this issue?

    I fear anyone using the AniMate class from unifycommunity.com (http://www.unifycommunity.com/wiki/index.php?title=AniMate) will be exposed to this crash. AniMate is a great add-on and I'd like to continue using it.
     
  13. zibba

    zibba

    Joined:
    Mar 13, 2009
    Posts:
    165
    I had the same problem with another piece of code that was using GetValue on a property. Rather than downgrading to 1.5 I'm building against .Net 1.1 (I'd rather use List<> than ArrayList casting, alas...).

    I'm not 100% on this but I think it's because .Net 2.1 is using .Net Generics to convert the return type of GetValue into a method. As the GetValue() is returning a property, it has to convert that property into a method call and without knowing what the type is, it uses generics. Either there's a bug or it requires JIT.

    As .Net 1.1 doesn't support generics it must use another mechanism, perhaps simply a virtual function.

    File a bug report with your code and reproduction case, someone at Unity may know the exact answer...
     
  14. cchuter

    cchuter

    Joined:
    Mar 11, 2010
    Posts:
    9
    I will file a bug report. Changing the .NET setting from 2.1 to 1.1 has no effect for me, so I assume its something else.

    I'm using a javascript version of Ani.Mate() for the record. And, I have coded a work around that manually downcasts the object (similar to mryan's workaround).
     
  15. Malveka

    Malveka

    Joined:
    Nov 6, 2009
    Posts:
    191
    I'm also experiencing exactly the problem described in this thread, namely AniMate fails to animate properly in iPhone 1.6 under .Net2.1.

    Thank you, mryan, for the excellent research!

    In order to get the GM2 test scene to run properly I had to use the following variation on mryan's workaround:



    Code (csharp):
    1.                  
    2. System.Object current = null;
    3. Debug.Log("Exception patch: type name = " + name);
    4. switch (name)
    5. {
    6.     case "Rotation":
    7.        if (obj is GUIQuadObj)   current = (GUIQuadObj)obj).Rotation;
    8.        break;
    9.                    
    10.      case "LocX":
    11.        if (obj is GUITextureObj)   current = ((GUITextureObj)obj).LocX;
    12.        break;
    13.                    
    14.      case "LocY":
    15.         if (obj is GUITextureObj)   current = ((GUITextureObj)obj).LocY;
    16.         break;
    17.                    
    18.      case "Location":
    19.           if (obj is GUIQuadObj)   current = ((GUIQuadObj)obj).Location;
    20.          break;
    21.  
    22. }
    23. if (current == null)
    24. {
    25.     throw new System.NotImplementedException("Animating " + obj.GetType() + "." + name + " is not yet implemented");
    26. }
    27.  
    mryan, I assume the workaround you posted was for animating objects whose types (Button, Image, etc.) you had declared yourself?

    Cheers,
    Mal
     
  16. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    184
    That's exactly right. They are objects that I created, each of which can be animated with the same code.

    Hopefully we'll learn if this is actually a bug in Unity or the Mono codebase soon. I submitted a bug report regarding this issue, and it is currently open.
     
  17. marjan

    marjan

    Joined:
    Jun 6, 2009
    Posts:
    563
    Just found this, cause i am trying to "port" a title to unity 3.

    Too bad, there is no .net 1.1 anymore, so my whole gui dousn´t work any more.
     
  18. gfoot

    gfoot

    Joined:
    Jan 5, 2011
    Posts:
    550
    It does look like Mono's PropertyInfo.GetValue() method requires JIT. There are a few overloads you could try, maybe one of the others doesn't - but the first thing I tried was this, and it seems to work fine (on Xbox360):

    Code (csharp):
    1.  
    2.     // replacement for: object result = property.GetValue(object, arguments);
    3.     object result = property.GetGetMethod().Invoke(object, arguments);
    4.  
     
  19. mpmoreti

    mpmoreti

    Joined:
    Dec 5, 2009
    Posts:
    4
    I was having the same problem on iOS and your solution seems to be working fine. Thank you.

     
  20. whydoidoit

    whydoidoit

    Joined:
    Mar 12, 2012
    Posts:
    365
    I needed better performance than the GetProperty("xxx").GetGetMethod().Invoke(o, new object[] { x }) approach and have come up with a way of accelerating it without the need for Reflection.Emit although it does require providing hints to the compiler so that there's no need to JIT the lambdas you need to get it to work. Runs about 4.5x faster than an Invoke.

    You can find it here
     
    Last edited: Apr 24, 2012
  21. Altaf-Navalur

    Altaf-Navalur

    Joined:
    Mar 1, 2013
    Posts:
    3
    Hello,
    I am getting ExecutionEngineException: Attempting to JIT compile method.. for Disctionary<MyClass, GameObject>. Any idea on how to fix this in c#..



    Thanks in Advance,
    Altaf