Skip to content
This repository has been archived by the owner on Nov 1, 2020. It is now read-only.

Interface dispatch support #626

Merged
merged 1 commit into from
Jan 14, 2016
Merged

Conversation

nattress
Copy link
Contributor

Emit the supporting data structures for interface dispatch:

  • Interface dispatch cell for each call site providing the resolution function entry point as well as the interface type and interface method slot number
  • Interface map on EETypes specifying the list of interfaces they implement
  • Dispatch map that provides, for each type, the lookup rows for interface type, interface method slot, and implementing method's VTable slot
  • Dispatch map table that provides dispatch map pointers (the index into this table is stored on an EEType instead of a pointer to the map for space savings)

Added a work-around in the runtime to provide access to the dispatch map table until full module headers are implemented

@nattress
Copy link
Contributor Author

@jkotas @davidwrighton @smosier Please take a look. David, I removed a couple type system asserts in TypeSystemContext::GetMethodForInstantiatedType. For interface method impls, they had instantiations in my testing and removing the asserts seemed to work fine :)

Scott: I added you to make sure you're okay with my temporary workaround for no ModuleHeader support. I plumbed the dispatch map table in via a RuntimeInstance helper.

@@ -7,7 +7,76 @@ internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine("Hello world");
MyInterface i1 = new Foo(false, 1, "Foo implementation") as MyInterface;
Copy link
Member

Choose a reason for hiding this comment

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

I would keep the Program.cs in repro as is. Instead, we should add a new smoke test under tests\src\simple that has what you got here.

@jkotas
Copy link
Member

jkotas commented Jan 12, 2016

For Unix, could you please just fix the build breaks (e.g. by adding dummy methods to portable.cpp)? We can deal with porting the assembly code in separate change.

@jkotas
Copy link
Member

jkotas commented Jan 12, 2016

LGTM otherwise

public override ObjectData GetData(NodeFactory factory, bool relocsOnly)
{
ObjectDataBuilder objData = new ObjectDataBuilder(factory);
objData.Alignment = 16;
objData.DefinedSymbols.Add(this);

Copy link
Member

Choose a reason for hiding this comment

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

Nit: can you do a sweep of all the whitespace you're checking in?

@nattress
Copy link
Contributor Author

@jkotas @MichalStrehovsky @davidwrighton Updated based on your feedback.

Also, I split TypeDesc.MethodImpls.cs into two (based on the type names stored in it): MetadataType.MethodImpls.cs, InstantiatedType.MethodImpls.cs

I added a stub .S for the cross-plat assembly code needed for dispatch. Portable.cpp should already have the missing entry points (we'll see when CI finishes).

@manu-st
Copy link

manu-st commented Jan 13, 2016

@nattress Could you add stub for Linux arm and arm64 as well?

@jkotas
Copy link
Member

jkotas commented Jan 13, 2016

split TypeDesc.MethodImpls.cs into two (based on the type names stored in it)

The split files need to be in the common directory - you have added them to the compiler directory.

We have been going back and forth on whether the files should be split for cases like this or not. I believe that we have been leaning towards keeping them together. Splitting these into multiple files rigorously leads to way too many little files.

@@ -545,6 +546,10 @@ COOP_PINVOKE_HELPER(PTR_Code, RhpResolveInterfaceMethodCacheMiss, (Object * pObj
PInvokeTransitionFrame * pTransitionFrame))
{
CID_COUNTER_INC(CacheMisses);
#ifdef CORERT
return RhpCidResolve(pObject, pCell);
Copy link
Member

Choose a reason for hiding this comment

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

This needs @TODO: CORERT: Use ManagedCallout2.

@nattress nattress force-pushed the interface_dispatch branch 2 times, most recently from d0bb358 to 0ffd71f Compare January 13, 2016 03:11

foreach (MethodDesc interfaceMethod in interfaceType.GetMethods())
{
Debug.Assert(interfaceMethod.IsVirtual);
Copy link
Member

Choose a reason for hiding this comment

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

Interfaces are allowed to have static methods. Might need to skip them here.

Copy link
Member

Choose a reason for hiding this comment

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

Instead of asserting the method is virtual, we should probably throw (unless this is guarded in some other place).

Emit the supporting data structures for interface dispatch:
- Interface dispatch cell for each call site providing the resolution function entry point as well as the interface type and interface method slot number
- Interface map on EETypes specifying the list of interfaces they implement
- Dispatch map that provides, for each type, the lookup rows for interface type, interface method slot, and implementing method's VTable slot
- Dispatch map table that provides dispatch map pointers (the index into this table is stored on an EEType instead of a pointer to the map for space savings)

Added a work-around in the runtime to provide access to the dispatch map table until full module headers are implemented
nattress added a commit that referenced this pull request Jan 14, 2016
@nattress nattress merged commit 811a323 into dotnet:master Jan 14, 2016
@nattress nattress deleted the interface_dispatch branch January 14, 2016 03:04
MichalStrehovsky added a commit that referenced this pull request Jul 24, 2018
When interface dispatch was initially implemented in CoreRT, we took a number of shortcuts (#626). Skipping the size on disk optimization around generating runs of interface dispatch cells with the same slot number was one of the shortcuts (each cell represented its own run).

With this, I'm implementing the same optimization that binder does. For PureNative shared library, this saves 100 kB. I didn't measure savings for apps, but I expect them to be similar.

[tfs-changeset: 1708487]
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.

None yet

7 participants