Skip to content
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

Merged
merged 1 commit into from
Nov 30, 2022

Conversation

MichalStrehovsky
Copy link
Member

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:

objData.EmitReloc(interfaceType, RelocType.IMAGE_REL_BASED_RELPTR32,
(int)InterfaceDispatchCellCachePointerFlags.CachePointerIsInterfaceRelativePointer);

Cc @dotnet/ilc-contrib

@ghost
Copy link

ghost commented Nov 23, 2022

Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas
See info in area-owners.md if you want to be subscribed.

Issue Details

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:

objData.EmitReloc(interfaceType, RelocType.IMAGE_REL_BASED_RELPTR32,
(int)InterfaceDispatchCellCachePointerFlags.CachePointerIsInterfaceRelativePointer);

Cc @dotnet/ilc-contrib

Author: MichalStrehovsky
Assignees: -
Labels:

area-NativeAOT-coreclr

Milestone: -

{
public InterfaceDispatchCellSectionNode(NodeFactory factory)
: base("__InterfaceDispatchCellSection_Start", "__InterfaceDispatchCellSection_End", new DispatchCellComparer(factory))
Copy link
Member

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?

Copy link
Member Author

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);
Copy link
Member

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?

objData.EmitReloc(interfaceType, RelocType.IMAGE_REL_BASED_RELPTR32,
(int)InterfaceDispatchCellCachePointerFlags.CachePointerIsInterfaceRelativePointer);

Copy link
Member Author

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).

@MichalStrehovsky MichalStrehovsky merged commit 9d8931e into dotnet:main Nov 30, 2022
@MichalStrehovsky MichalStrehovsky deleted the dispatchcell branch November 30, 2022 05:48
@ghost ghost locked as resolved and limited conversation to collaborators Dec 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants