-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Allow preinitializing RuntimeType instances #94405
Conversation
Unblock serializing `RuntimeType` instances from the static constructor interpreter. With this we can now preinitialize `static readonly Type s_foo = typeof(Foo)` and RyuJIT will optimize reads of `s_foo` into loading a constant value. Contributes to dotnet#91704.
Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas Issue DetailsUnblock serializing With this we can now preinitialize Contributes to #91704. Cc @dotnet/ilc-contrib
|
@@ -8989,6 +8989,7 @@ void Compiler::impImportBlockCode(BasicBlock* block) | |||
FALLTHROUGH; | |||
case CORINFO_FIELD_STATIC_SHARED_STATIC_HELPER: | |||
case CORINFO_FIELD_STATIC_ADDRESS: | |||
case CORINFO_FIELD_STATIC_RELOCATABLE: |
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.
@EgorBo could you have a look at this? This affects a lot more than just RuntimeType and I might be missing why we weren't doing this before. (We might also want to do this for STATIC_RVA_ADDRESS
.)
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.
@MichalStrehovsky wow, it's actually a good catch! It should improve some things, e.g.:
static readonly string Fld = "Hello";
[MethodImpl(MethodImplOptions.NoInlining)]
static string Test() => Fld;
; Assembly listing for method Benchmarks:Test():System.String (FullOpts)
- mov rax, qword ptr [(reloc 0x400000000042c388)]
- mov rax, gword ptr [rax+0x08]
+ lea rax, gword ptr [(reloc 0x400000000042c398)] ; '"Hello"'
ret
; Total bytes of code 12
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.
Basically, static readonly
wasn't foldable for gc types for NAOT
@@ -689,6 +689,8 @@ class C3<T> : IInterface, IInterface<T> | |||
static IInterface<object> s_c3a = new C3<object>(); | |||
static IInterface s_c3b = new C3<object>(); | |||
|
|||
// Works around https://github.com/dotnet/runtime/pull/94342 | |||
[MethodImpl(MethodImplOptions.NoOptimization)] |
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 found a new bug. The Run
method is essentially optimized to a throw. It's ridiculous how well this optimizes:
- We figured out the value assigned to the static is read only using whole program view (the static is not marked read only in source code)
- RyuJIT then figured out exact type information from the preinit data blob.
- RyuJIT then devirtualized the call (into the wrong method, but that's the bug)
- RyuJIT then folded the string constant comparison.
All that's left is the throw (and a couple garbage instructions I couldn't fully make sense of).
/azp run runtime-nativeaot-outerloop |
Azure Pipelines successfully started running 1 pipeline(s). |
@dotnet/ilc-contrib could someone have a look? |
System.Threading.Tasks tests are failing with a message that we have not seen before:
Is it a pre-existing problem or a regression introduced by this change? |
I think I've seen this once on one of my PRs. |
This test sometimes fails, always with a failure mode that doesn't produce dumps. It never reproed for me locally. |
/azp run runtime-nativeaot-outerloop |
Azure Pipelines successfully started running 1 pipeline(s). |
Co-authored-by: Michal Strehovský <MichalStrehovsky@users.noreply.github.com>
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.
Thank you!
Unblock serializing
RuntimeType
instances from the static constructor interpreter.With this we can now preinitialize
static readonly Type s_foo = typeof(Foo)
and RyuJIT will optimize reads ofs_foo
into loading a constant value.Contributes to #91704.
Cc @dotnet/ilc-contrib