Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

[il2cpp] Is `sealed` Not Worked As Said Anymore In Unity 2018.3?

Discussion in 'General Discussion' started by timwzw, Apr 10, 2019.

  1. timwzw

    timwzw

    Joined:
    Jul 4, 2017
    Posts:
    5
    In IL2CPP Optimizations: Devirtualization, it suggested use sealed keyword to devirtualization and gain performance.

    But when I checked it on my own in Unity 2018.3.5, I found it did not work as the post said.

    My Code is simple
    Code (CSharp):
    1. public class Animal
    2. {
    3.     public virtual void Speak()
    4.     {
    5.     }
    6. }
    7.  
    8. public class Dog : Animal
    9. {
    10.     public override void Speak()
    11.     {
    12.         Debug.Log("Dog");
    13.     }
    14. }
    15.  
    16. public sealed class Cat : Animal
    17. {
    18.     public override void Speak()
    19.     {
    20.         Debug.Log("Cat");
    21.     }
    22. }
    And Test code is
    Code (CSharp):
    1. Cat cat = new Cat();
    2. cat.Speak();
    3.  
    4. Dog dog = new Dog();
    5. dog.Speak();
    And the IL Code is
    Code (CSharp):
    1.     // [37 9 - 37 29]
    2.     IL_000f: newobj       instance void Cat::.ctor()
    3.     IL_0014: stloc.0      // cat
    4.  
    5.     // [38 9 - 38 21]
    6.     IL_0015: ldloc.0      // cat
    7.     IL_0016: callvirt     instance void Animal::Speak()
    8.     IL_001b: nop
    9.  
    10.     // [40 9 - 40 29]
    11.     IL_001c: newobj       instance void Dog::.ctor()
    12.     IL_0021: stloc.1      // dog
    13.  
    14.     // [41 9 - 41 21]
    15.     IL_0022: ldloc.1      // dog
    16.     IL_0023: callvirt     instance void Animal::Speak()
    17.     IL_0028: nop
    The Cpp Code generated by IL2CPP is:
    Code (CSharp):
    1. Cat_tC86B56F89EF64EBC7575B2E551959B31E9874724 * L_0 = (Cat_tC86B56F89EF64EBC7575B2E551959B31E9874724 *)il2cpp_codegen_object_new(Cat_tC86B56F89EF64EBC7575B2E551959B31E9874724_il2cpp_TypeInfo_var);
    2. Cat__ctor_m7757DD1CFFF12E726940C571707FEBB1720A6221(L_0, /*hidden argument*/NULL);
    3. VirtActionInvoker0::Invoke(4 /* System.Void Animal::Speak() */, L_0);
    4. Dog_tF96DDAC719857CC7A194BF7D3A0776F8D4A6F521 * L_1 = (Dog_tF96DDAC719857CC7A194BF7D3A0776F8D4A6F521 *)il2cpp_codegen_object_new(Dog_tF96DDAC719857CC7A194BF7D3A0776F8D4A6F521_il2cpp_TypeInfo_var);
    5. Dog__ctor_m01507A82581E1AD5704DCDA45A9DD230A5A5F764(L_1, /*hidden argument*/NULL);
    6. VirtActionInvoker0::Invoke(4 /* System.Void Animal::Speak() */, L_1);
    As you can see even I use `sealed` to decorate Cat, but the Cat's Speak is still called by VirtActionInvoker0.

    Do you guys meet the same problem? Or am I doing anything wrong?
     
  2. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,494
    You are not doing anything wrong. Unfortunately newer C# compilers emit different IL code that we used in that blog post. The different IL code uses the base class method reference for the call, which means that IL2CPP cannot assume the call can be devirtualized. We might be able to do more in-depth IL analysis of the code to guarantee devirtualization, but we've not implemented that yet.
     
    ImpossibleRobert likes this.
  3. timwzw

    timwzw

    Joined:
    Jul 4, 2017
    Posts:
    5
    Maybe you can change the post a little bit to make it more precise. Thanks!
     
  4. Murgilod

    Murgilod

    Joined:
    Nov 12, 2013
    Posts:
    9,165
    ...It's three years old.
     
  5. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,133
    Could still warrant a note to explain that it's no longer accurate for new compilers.