Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by NerdClown · Mar 10, 2017 at 03:43 PM · c#monocompilercompilation

AOT compilation problem - ExecutionEngineException - AOT not compiling as expected.

Hello people. Have a problem with with compilation to an AOT platform. Have found a number of posts on the subject, but still haven't been able to solve my problem. Any help will be very much appreciated!

I'm trying to port an existing project to a platform where JIT compilation is not possible. The project is networked and makes use of generic types, and when running the project I get the following error message:

 ExecutionEngineException: Attempting to JIT compile method 'dk.Apex.NightSkies.Networking.PhotonFS.PhotonNetworkConnection:HandleNetworkMessage<object, int> (string,object,int)' while running with --aot-only.

I read the Unity documentation (https://docs.unity3d.com/Manual/ScriptingRestrictions.html) and attempted to implement a similar solution for my problem. When that did not work, I made a project containing the sample problem from the documentation, and it worked as described in the documentation.

I made a sample project with the bare bones of the code that's giving me problems, and I managed to reproduce the issue. I'll include the code, in case someone wants to attempt to replicate the issue.

We have an abstract network connection class:

 using UnityEngine;
 
 namespace dk.Apex.NightSkies.Networking
 {
     public abstract class ANetworkConnection : MonoBehaviour
     {
         protected static ANetworkConnection instance;
         public static ANetworkConnection Instance
         {
             get { return instance; }
         }
 
         protected void Awake()
         {
             //Debug.Log("nc awake");
             instance = this;
         }
 
         //handle network messages/events, pass them to server response handler
         public abstract void HandleNetworkMessage<T, H>(string cmd, T content, H user);
     }
 }

And a photon specific version (the abstract networking class is there to facilitate switching network solutions). This includes the method that should force the compiler to AOT compile a version of the HandleNetworkMessage method:

 using UnityEngine;
 using System;
 
 namespace dk.Apex.NightSkies.Networking.PhotonFS
 {
     public class PhotonNetworkConnection : ANetworkConnection
     {
         public override void HandleNetworkMessage<T, H>(string cmd, T content, H user)
         {
             Debug.Log("MEH I'MA DOING STUFF!");
         }
 
         public void UsedOnlyForAOTCodeGeneration()
         {
             HandleNetworkMessage<object, int>("meh", new object(), 42);
             HandleNetworkMessage((string)"meh", (object)new BasicInfo(), (int)1);
 
             // Include an exception so we can be sure to know if this method is ever called.
             throw new InvalidOperationException("This method is used for AOT code generation only. Do not call it at runtime.");
         }
     }
 }

Also a bare-bones network data type + abstract network data type:

 namespace dk.Apex.NightSkies.Networking
 {
     public class BasicInfo : ANetworkDataType
     {
         public static object Deserialize(byte[] bytes)
         {
             BasicInfo obj = new BasicInfo();
             //obj = (BasicInfo)Unpack(bytes, obj);
             return obj;
         }
     }
 }

and

 namespace dk.Apex.NightSkies.Networking
 {      
     //abstract class for all network data types
     public abstract class ANetworkDataType
     {
     }
 }

And finally the script that tests that calls the method:

 using UnityEngine;
 using dk.Apex.NightSkies.Networking;

 public class JITTest : MonoBehaviour {
     void Start ()
     {
         ANetworkConnection.Instance.HandleNetworkMessage("string", new BasicInfo(), 2001);
     }
 }

I would expect the inclusion of the UsedOnlyForAOTCodeGeneration method would force the compiler to prepare an version of that method, but it does not work as I expect. Am I overlooking or misunderstanding something?

One suggestion that I often read is using IL2CPP in stead of MONO as the scripting backend. That solution makes my code throw a LOT of null reference exceptions. As it would produce a lot of extra work in all corners and it would definitely be much nicer to just get it working with the mono backend.

Hope someone has some suggestions!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by HaraldNielsen · Mar 12, 2017 at 06:42 PM

Hi @NerdClown , when using mono AOT and overriding generic virtual methods, you are going to get into trouble, because there is no compiled version of the generic type of the derived class. There are only a compiled version of the generic type on the base class.

What you could do is to have HandleNetworkMessage<T, H> in an Interface, put it on the derived class and implement that instead, that would work because AOT would compile the generic types directly. You could also basically make HandleNetworkMessage<T, H> virtual with a bogus body in the base class, and in the derived class mark it as new. Not that, that would be a nice solution.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image NerdClown · Mar 13, 2017 at 01:56 PM 0
Share

Hi @eble

Thanks for the response! Good info in there. Both suggested solutions work, and neither seem to require the stuff in the UsedOnlyForAOTCodeGeneration method. In the end I landed on a third solution that's only slightly different.

I wish I knew a bit more about the workings of the compiler/runtime: I still don't really understand why the calls to HandleNetworkConnection from the UsedOnlyForAOTCodeGeneration method (which afaik should be a reference to the method in the PhotonNetworkConnection, not in the abstract class) does not force the compiler to generate an object/int version of the method for the PhotonNetworkConnection.

Oh well, problem solved, thanks a bunch.

avatar image HaraldNielsen NerdClown · Mar 13, 2017 at 02:11 PM 1
Share

@NerdClown Np.

You could say that its an error in $$anonymous$$ono AOT. Im sitting with the same problem as you currently and therefor looked a bit into it. If you look in IL code, it tells the instance to call the method, that is the type of the base class: IL_0001: newobj instance void DerivedClass::.ctor() ... IL_0009: callvirt instance !!0/*bool*/ BaseClass::ApplyTo<bool>(!!0/*bool*/) So when AOT goes trough this, its looking for the compiled generic type (in this case bool) on both the the base and derived class. And for some reason, it has only compiled the BaseClass::ApplyTo<bool> type. I think It just looks on the IL and chooses to build the BaseClass::ApplyTo<bool> part

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

294 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Distribute terrain in zones 3 Answers

Unity compilation order 2 Answers

Multiple Cars not working 1 Answer

An OS design issue: File types associated with their appropriate programs 1 Answer

Where is the Mono C# compiler for Unity iPhone? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges