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

Initial default interface method support #368

Merged

Conversation

MichalStrehovsky
Copy link
Member

Support for default interface methods in the compiler and runtime.

It felt like the most straightforward approach is to just give interface types a dispatch map and populate vtables of interface method with the default implementation. I didn't realize they get a full vtable with a bunch of null slots. This might be something we could potentially optimize, but it's orthogonal.

There's plenty of things missing still, but it's a start and tests are starting to pass.

Support for default interface methods in the compiler and runtime.

It felt like the most straightforward approach is to just give interface types a dispatch map and populate vtables of interface method with the default implementation. I didn't realize they get a full vtable with a bunch of null slots. This might be something we could potentially optimize, but it's orthogonal.

There's plenty of things missing still, but it's a start and tests are starting to pass.
@MichalStrehovsky MichalStrehovsky added the area-NativeAOT-coreclr .NET runtime optimized for ahead of time compilation label Nov 19, 2020
Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@jkotas
Copy link
Member

jkotas commented Nov 20, 2020

What is the type loader behavior when it hits a type with DIMs? It would be nice if it was a clean crash, and not a bad AV somewhere.

@jkotas
Copy link
Member

jkotas commented Nov 20, 2020

cc @davidwrighton

@MichalStrehovsky
Copy link
Member Author

What is the type loader behavior when it hits a type with DIMs? It would be nice if it was a clean crash, and not a bad AV somewhere.

The type loader is not involved right now since I'm not attempting to solve the "we need an instantiating stub for shared methods on generic interfaces". Right now we would just end up calling a shared method without its generic context.

I pushed out an improvement that treats these as a reabstraction instead (so we never end up placing the canonical method without a generic context into the vtable).

I also added a couple very basic tests so that we can smoke test this. We should definitely do a Pri-0 test pass before merging.

@MichalStrehovsky
Copy link
Member Author

/azp run runtimelab-nativeaot Pri-0 Tests

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MichalStrehovsky
Copy link
Member Author

/azp run runtimelab-nativeaot Pri-0 Tests

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@MichalStrehovsky
Copy link
Member Author

The StaticInterfaceMembers failure was also present in the https://github.com/dotnet/runtimelab/runs/1405225153 run so it's unrelated. I'll take a look when we clean up the Pri-0 runs again. I couldn't get it to repro in single file, so it's probably a multifile specific wart.

@MichalStrehovsky MichalStrehovsky merged commit 6898730 into dotnet:feature/NativeAOT Nov 25, 2020
@MichalStrehovsky MichalStrehovsky deleted the BAK_DefaultIntf branch November 25, 2020 14:37
MichalStrehovsky added a commit to MichalStrehovsky/runtimelab that referenced this pull request May 11, 2021
MichalStrehovsky added a commit to MichalStrehovsky/runtimelab that referenced this pull request May 11, 2021
Different take from dotnet#368 - this time we're adding extra slots into the (sealed) vtable of the implementing class and pointing the dispatch map of the owning type to those slots when a default implementation is needed.

This strategy has a couple advantages:
* Main motivation: it will make implementing canonical interface methods possible - we will have a good spot to grab the interface type (instantiation argument of the default interface method) from, since we can now have per-implementing-type entrypoints.
* We are now able to figure out a default implementation is not needed at compile time (we don't generate a body unless there's a class that needs it)
* Dispatch is pre-computed (no longer have to hunt for the default implementation in dispatch maps of the interfaces at runtime).

The disadvantage is that this strategy is a bit more complicated, but it doesn't actually look too terrible.
MichalStrehovsky added a commit to MichalStrehovsky/runtimelab that referenced this pull request May 11, 2021
Different take from dotnet#368 - this time we're adding extra slots into the (sealed) vtable of the implementing class and pointing the dispatch map of the owning type to those slots when a default implementation is needed.

This strategy has a couple advantages:
* Main motivation: it will make implementing canonical interface methods possible - we will have a good spot to grab the interface type (instantiation argument of the default interface method) from, since we can now have per-implementing-type entrypoints.
* We are now able to figure out a default implementation is not needed at compile time (we don't generate a body unless there's a class that needs it)
* Dispatch is pre-computed (no longer have to hunt for the default implementation in dispatch maps of the interfaces at runtime).

The disadvantage is that this strategy is a bit more complicated, but it doesn't actually look too terrible.
jkotas pushed a commit that referenced this pull request May 11, 2021
* Revert "Initial default interface method support (#368)"

This reverts commit 6898730.

* Add back changes we want to keep

* Implement support for default interface methods

Different take from #368 - this time we're adding extra slots into the (sealed) vtable of the implementing class and pointing the dispatch map of the owning type to those slots when a default implementation is needed.

This strategy has a couple advantages:
* Main motivation: it will make implementing canonical interface methods possible - we will have a good spot to grab the interface type (instantiation argument of the default interface method) from, since we can now have per-implementing-type entrypoints.
* We are now able to figure out a default implementation is not needed at compile time (we don't generate a body unless there's a class that needs it)
* Dispatch is pre-computed (no longer have to hunt for the default implementation in dispatch maps of the interfaces at runtime).

The disadvantage is that this strategy is a bit more complicated, but it doesn't actually look too terrible.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-NativeAOT-coreclr .NET runtime optimized for ahead of time compilation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants