Runtime: Mono: devirtualize sealed calls

Created on 29 Feb 2020  路  3Comments  路  Source: dotnet/runtime

Mono doesn't devirtualize (and inline) sealed methods, e.g.:

public class A 
{
    public virtual int Foo() => 1;
}

public sealed class B : A
{
    public sealed override int Foo() => 2;  // sealed!
}

...
static int Test(B b)
{
    return b.Foo(); // Foo should be devirtualized and inlined
}

b.Foo() is expected to be devirtualized and inlined because it is sealed.

Current codegen:

loWorld_Program_Test__HelloWorld_B_:
0000000000000000    pushq   %rax
0000000000000001    movq    (%rdi), %rax
0000000000000004    callq   *0x68(%rax)
0000000000000007    popq    %rcx
0000000000000008    retq
0000000000000009    movabsq $0x7fd559c02530, %rax
0000000000000013    movl    $0x120, %edi
0000000000000018    callq   *(%rax)

Expected codegen:

loWorld_Program_Test__HelloWorld_B_:
0000000000000000    movl    $0x2, %eax  ;; also: nullcheck
0000000000000005    retq

CoreCLR is able to do it, part of the jitdump for Test:

impDevirtualizeCall: Trying to devirtualize virtual call:
    class for 'this' is ConsoleApp4.B [final] (attrib 20000010)
    base method is ConsoleApp4.A::Foo
    devirt to ConsoleApp4.B::Foo -- final class
               [000001] --C-G-------              *  CALLV ind int    ConsoleApp4.A.Foo
               [000000] ------------ this in rcx  \--*  LCL_VAR   ref    V00 arg0         
    final class; can devirtualize
... after devirt...
               [000001] --C-G-------              *  CALL nullcheck int    ConsoleApp4.B.Foo
               [000000] ------------ this in rcx  \--*  LCL_VAR   ref    V00 arg0    
area-Codegen-meta-mono

Most helpful comment

Also, Xamarin.iOS has a linker substep where it marks all methods and classes as sealed if there are no subclasses/overrides.
So this opt will be nice to have.

All 3 comments

Also, Xamarin.iOS has a linker substep where it marks all methods and classes as sealed if there are no subclasses/overrides.
So this opt will be nice to have.

it marks all methods and classes as sealed if there are no subclasses/overrides.

@MichalStrehovsky Does CoreRT do the same?

@MichalStrehovsky Does CoreRT do the same?

Yes, and it's behind policies so that we don't do this if Assembly.Load or Reflection.Emit is allowed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

chunseoklee picture chunseoklee  路  3Comments

jchannon picture jchannon  路  3Comments

matty-hall picture matty-hall  路  3Comments

bencz picture bencz  路  3Comments

EgorBo picture EgorBo  路  3Comments