-
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
Place dispatch cells in dehydrated section #78748
Conversation
Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas Issue DetailsSimilar to #78688 - changing the base type of the node to allow dehydration and keep track of dispatch cells in the metadata manager. Saves ~0.2% on Hello World on Windows, likely closer to 1% on Linux because this is a full pointer reloc. This required a small change in the dehydration logic since now we have relocs with deltas - references to symbols that are offset by some number of bytes. Relocs with deltas are represented with the inline reloc format. I tried to extend the "popular symbol lookup table" to allow referencing things with deltas, but it didn't bring a meaningful improvement so not including that part. It might bring more meaningful savings if we find a way to get rid of the delta: Lines 103 to 104 in 722745e
Cc @dotnet/ilc-contrib
|
{ | ||
public InterfaceDispatchCellSectionNode(NodeFactory factory) | ||
: base("__InterfaceDispatchCellSection_Start", "__InterfaceDispatchCellSection_End", new DispatchCellComparer(factory)) |
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.
Do we need to emit the end symbol separately now? What are the end symbols used for in general - is it just bookkeeping to make the exe easier to inspect? Or are they used at runtime?
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.
We didn't need an end symbol for this one - the structure of the base class just required one.
We have some tables where the start and end symbols are used to figure out the length of the table. But dispatch cells are individually addressable and there's no code to enumerate all the dispatch cells (we don't have a purpose for such code) - end symbol is not needed.
long delta = Relocation.ReadValue(reloc.RelocType, pData); | ||
// Extra work needed to be able to encode/decode relocs with deltas | ||
Debug.Assert(delta == 0); | ||
delta = Relocation.ReadValue(reloc.RelocType, pData); |
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.
Just checking my understanding - before this change, all of the object data we were dehydrating had zeros in place of the relocs, but now some other component is writing an offset there, right?
Is this the place where the offset is written?
Lines 103 to 104 in d4d12c5
objData.EmitReloc(interfaceType, RelocType.IMAGE_REL_BASED_RELPTR32, | |
(int)InterfaceDispatchCellCachePointerFlags.CachePointerIsInterfaceRelativePointer); |
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.
Yep, this matches how it's represented in the object file as well. The relocation is basically an addend - if the value is all zeros, the effect is that the address of the relocation target is written. But if it's non-zero, we get a "displaced" pointer to the target of the relocation (the displacement is the value that was originally stored there). If we know the target is going to be aligned, we sometimes use displacement as a way to get "spare bits". Those bits get masked off before dereferencing the pointer at runtime and can indicate the thing the pointer points to (like in the above case, they indicate CachePointerIsInterfaceRelativePointer
).
Similar to #78688 - changing the base type of the node to allow dehydration and keep track of dispatch cells in the metadata manager.
Saves ~0.2% on Hello World on Windows, likely closer to 1% on Linux because this is a full pointer reloc.
This required a small change in the dehydration logic since now we have relocs with deltas - references to symbols that are offset by some number of bytes.
Relocs with deltas are represented with the inline reloc format. I tried to extend the "popular symbol lookup table" to allow referencing things with deltas, but it didn't bring a meaningful improvement so not including that part. It might bring more meaningful savings if we find a way to get rid of the delta:
runtime/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/InterfaceDispatchCellNode.cs
Lines 103 to 104 in 722745e
Cc @dotnet/ilc-contrib