-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GDV: don't emit fallback call if classes are "exact" #87055
Conversation
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue Detailsusing System;
using System.Runtime.CompilerServices;
using System.Threading;
public interface IAnimal
{
void MakeSound();
}
public class Cat : IAnimal
{
public void MakeSound() => Console.WriteLine("Meow!");
}
public class Dog : IAnimal
{
public void MakeSound() => Console.WriteLine("Woof!");
}
public class Cow : IAnimal
{
public void MakeSound() => Console.WriteLine("Moo!");
}
public class Program
{
public static void Main(string[] args)
{
Test(new Cat());
Test(new Dog());
Test(new Cow());
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void Test(IAnimal a) => a.MakeSound();
} NativeAOT codegen for ; Method Program:Test(IAnimal)
sub rsp, 40
lea rax, [(reloc 0x4000000000423000)]
cmp qword ptr [rcx], rax ;; is it 'Cat'?
jne SHORT G_M31564_IG04
lea rcx, gword ptr [(reloc 0x4000000000423028)] ;; '"Meow!"'
call System.Console:WriteLine(System.String)
jmp SHORT G_M31564_IG07
G_M31564_IG04: ;; offset=001EH
lea rax, [(reloc 0x4000000000423010)]
cmp qword ptr [rcx], rax ;; is it 'Dog'?
jne SHORT G_M31564_IG06
lea rcx, gword ptr [(reloc 0x4000000000422f98)] ;; '"Woof!"'
call System.Console:WriteLine(System.String)
jmp SHORT G_M31564_IG07
G_M31564_IG06: ;; offset=0038H
lea rcx, gword ptr [(reloc 0x4000000000422f70)] ;; '"Moo!"'
call System.Console:WriteLine(System.String)
G_M31564_IG07: ;; offset=0044H
nop
add rsp, 40
ret
; Total bytes of code: 74 Virtual callback is not emitted since we took care of all possible classes implementing the given interface ("closed world" on NativeAOT). We might still emit it if we e.g. fail to inline one of the candidates (we currently don't do GDV just to devirtualize a call, we only do that when we're able to inline it).
|
For reference, codegen for JIT: static void Main()
{
for (int i = 0; i < 200; i++)
{
Test(new Cat());
Test(new Dog());
Test(new Cow());
Thread.Sleep(16);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void Test(IAnimal a) => a.MakeSound(); ; Assembly listing for method Program:Test(IAnimal)
push rsi
sub rsp, 32
mov rsi, qword ptr [rcx]
mov rax, 0x7FFF53C41C88 ; Cat
cmp rsi, rax
jne SHORT G_M31564_IG04
mov rcx, 0x26780208F80 ; 'Meow!'
call [System.Console:WriteLine(System.String)]
jmp SHORT G_M31564_IG07
G_M31564_IG04:
mov rax, 0x7FFF53C41E48 ; Dog
cmp rsi, rax
jne SHORT G_M31564_IG06
mov rcx, 0x26780209128 ; 'Woof!'
call [System.Console:WriteLine(System.String)]
jmp SHORT G_M31564_IG07
G_M31564_IG06:
mov rax, 0x7FFF53C42008 ; Cow
cmp rsi, rax
jne SHORT G_M31564_IG09
mov rcx, 0x26780209148 ; 'Moo!'
call [System.Console:WriteLine(System.String)]
G_M31564_IG07:
nop
add rsp, 32
pop rsi
ret
G_M31564_IG09:
mov r11, 0x7FFF53130280
call [r11]IAnimal:MakeSound():this
jmp SHORT G_M31564_IG07 (PGO-driven) |
/azp run runtime-extra-platforms, runtime-coreclr pgo |
Azure Pipelines successfully started running 2 pipeline(s). |
/azp run runtime-extra-platforms |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run runtime-extra-platforms |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run runtime-extra-platforms |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run runtime-extra-platforms |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run runtime-extra-platforms |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run runtime-extra-platforms |
Azure Pipelines successfully started running 1 pipeline(s). |
@AndyAyersMS PTAL, it passes NativeAOT outerloop tests + 3 type checks |
@@ -268,7 +273,7 @@ static unsigned getLikelyClassesOrMethods(LikelyClassMethodRecord* | |||
|
|||
// Distribute the rounding error and just apply it to the first entry. | |||
// Assume that there is no error If we have unknown handles. | |||
if (numberOfClasses == h.m_totalCount) | |||
if (!containsUnknownHandles) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an unrelated change, it's just that I used a wrong check in #86965 so it didn't work properly
Contributes to #86769 and closes #86235
NativeAOT codegen for
Test
:Virtual callback is not emitted since we took care of all possible classes implementing the given interface ("closed world" on NativeAOT). We might still emit it if we e.g. fail to inline one of the candidates (we currently don't do GDV just to devirtualize a call, we only do that when we're able to inline it) -- we might want to do that for cases where interface calls are expensive but that's a different task in #86769