dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.96k stars 4.65k forks source link

Fastest possible CLR delegates #11617

Open dmitriyse opened 5 years ago

dmitriyse commented 5 years ago

Current delegate implementation is not so fast as it possible. The idea of this feature request is the same as described here: https://www.codeproject.com/Articles/1170503/The-Impossibly-Fast-Cplusplus-Delegates-Fixed

Pointer to an instance member (or static member) can be described by two values: 1) Object reference (or null for static member) 64/32 bit 2) Pointer to a machine code 64/32 bit with minimal indirection (preferrably direct pointer to machine code) - this is new type of data that is currently encapsulated inside JIT This type of pointer takes 128/64 bit for 64/32 bit platforms.

Currently I have no idea how to implement it without additional OpCodes: 1) Load Pointer to a instance member machine code (ldvirtftnptr) 2) Call Pointer to an instance member machine code (callvirtptr)

Current instructions ldvirtftn/callvirt stores most inderect pointer to method code.

callvirtptr should be as fast as "call" OpCode in contrast with callvirt

category:design theme:delegates skill-level:expert cost:large impact:medium

jkotas commented 5 years ago

Duplicate of https://github.com/dotnet/csharplang/issues/1060

dmitriyse commented 5 years ago

@jkotas Please do not close this issue so fast. The issue dotnet/csharplang#1060 does not covers CLR/JIT level pefromance of ldvirtftn/callvirt.

Here I am trying to find why ldvirtftn use most indirect pointer to a method machine code and thus callvirt has performance penalty for virtual methods. (fetch method table, fetch method chunk, fetch target address).

Can ldvirtftn just return direct pointer to machine code ? ldvirtftn returns 64 bit pointer that is opaque for anyone else except JIT. So in this case callvirt will be faster.

If the current infrastructure/logic with ldvirtftn/callvirt does not allow to use direct pointers, I suggest in this issue to create another one solution with new ldvirtftnptr/callvirtptr that would use most direct pointers and will be "fastest possible CLR delegates".

dmitriyse commented 5 years ago

For example current C# Delegates allows to get MethodInfo of target of invocation, probably it's possible because ldvirtftn returns offset in vtable. With "Fastest possible CLR delegates" metadata would be unretrievable but it's ok, performance is more important.