digitalmars.D - Looking for details of how interface method tables are implemented in
- Dibyendu Majumdar (9/9) Jun 17 2023 Hi
- user456 (7/16) Jun 17 2023 That is specified
- FeepingCreature (63/72) Jun 17 2023 Note: While writing this answer, I found the actual specified
- Dibyendu Majumdar (3/11) Jun 17 2023 It seems closer to C++ design, as Java does not adjust an object
- FeepingCreature (18/31) Jun 17 2023 Ah, GPT-4 (and then Google) points me at
- Dibyendu Majumdar (7/7) Jun 23 2023 Follow up question.
- FeepingCreature (16/23) Jun 23 2023 Yep, that's correct. Though note this only applies to interfaces
Hi I am looking for details of how interface method dispatch works in D. I would be grateful for any documentation of code references I can lookup. In particular, I wanted to understand how similar / different the implementation is compared to Java. Regards Dibyendu
Jun 17 2023
On Saturday, 17 June 2023 at 12:34:41 UTC, Dibyendu Majumdar wrote:Hi I am looking for details of how interface method dispatch works in D. I would be grateful for any documentation of code references I can lookup. In particular, I wanted to understand how similar / different the implementation is compared to Java. Regards DibyenduThat is specified [here](https://dlang.org/spec/abi.html#interfaces). So you have additional dereference to access the vtbl of an interface (vs class vtbl). Then an address is read in this table, cast to a function type, then called like a standard virtual call.
Jun 17 2023
On Saturday, 17 June 2023 at 12:34:41 UTC, Dibyendu Majumdar wrote:Hi I am looking for details of how interface method dispatch works in D. I would be grateful for any documentation of code references I can lookup. In particular, I wanted to understand how similar / different the implementation is compared to Java. Regards DibyenduNote: While writing this answer, I found the actual specified answer in the D ABI docs: https://dlang.org/spec/abi.html#classes I still think this explanation is good though. ---- I don't know for sure, but I think pretty much every single-inheritance with interface implementation in a C-like language works like this: You have a class C. C has a vtable of dynamic methods: ``` C { C_VTable* __vtable; classdata goes here } C_VTable { void function(void*) method1; void function(void*) method2; void function(void*) method3; } ``` You have a class D that inherits from C. It starts with a pointer to a D_VTable, that looks like this: ``` D_VTable { // all methods that D overrides are replaced in the C part C_VTable parent; // methods that only appear in D go here void function(void*) method4; } ``` It has to be like this, so that you can take a pointer to D and implicitly treat it as a pointer to C. --- Now what about interfaces? They're a bit complicated. Obviously an interface pointer cannot be the same pointer as the class pointer of the class that implements it. Because the interface methods would have to be at a fixed offset from the start of the vtable, and then they could collide with methods added by the class. So an interface reference is an *additional vtable pointer* in the object, that points at a dedicated interface vtable. That vtable usually also has the offset from the vtable pointer to the start of the object, because we need that to get the object reference back so we can actually call methods with it. ``` C : I { C_VTable* __vtable; C data goes here. // I i = c; results in a pointer *to this field.* I_VTable* __i_vtable; } I_VTable { size_t i_to_c_offset = -20; // or whatever void function(void*) i_method_1; void function(void*) i_method_2; void function(void*) i_method_3; } ``` Anyway, how does all that compare to Java? No clue! Sorry. I can only assume it's pretty similar, because this is really is the "unambiguously sensible" way to do it.
Jun 17 2023
On Saturday, 17 June 2023 at 17:16:16 UTC, FeepingCreature wrote:I am looking for details of how interface method dispatch works in D.Note: While writing this answer, I found the actual specified answer in the D ABI docs: https://dlang.org/spec/abi.html#classes Anyway, how does all that compare to Java? No clue! Sorry. I can only assume it's pretty similar, because this is really is the "unambiguously sensible" way to do it.It seems closer to C++ design, as Java does not adjust an object pointer when casting to an interface or subtype.
Jun 17 2023
On Saturday, 17 June 2023 at 20:29:35 UTC, Dibyendu Majumdar wrote:On Saturday, 17 June 2023 at 17:16:16 UTC, FeepingCreature wrote:Ah, GPT-4 (and then Google) points me at https://wiki.openjdk.org/display/HotSpot/InterfaceCalls (It is impossible to directly google 'java interface implementation' because the results are far, far too flooded with beginner tutorials.) To summarize, it looks like Java can do interface calls on the same reference as the object mostly by paying a lot of runtime cost to find the actual method in question. In comparison, the D approach can just call the interface method at a fixed vtable offset, as it does with class methods. Once the runtime has the interface vtable, calls proceed as in D. I think comparatively, Java can more readily commit to overhead costs for interface resolution because in inner loops it expects to find a deterministic object type and create a direct call anyways. D has to compile in one shot and be done, so it has to be fast from the start.I am looking for details of how interface method dispatch works in D.Note: While writing this answer, I found the actual specified answer in the D ABI docs: https://dlang.org/spec/abi.html#classes Anyway, how does all that compare to Java? No clue! Sorry. I can only assume it's pretty similar, because this is really is the "unambiguously sensible" way to do it.It seems closer to C++ design, as Java does not adjust an object pointer when casting to an interface or subtype.
Jun 17 2023
Follow up question. If a class implements 5 interfaces. I create an object of this class. Is it correct that the resulting object has 6 vtable pointers embedded, one for the class, and 5 for the interfaces? And every object that is allocated will have this overhead? In Java land, no vtables are embedded in the object.
Jun 23 2023
On Friday, 23 June 2023 at 09:53:25 UTC, Dibyendu Majumdar wrote:Follow up question. If a class implements 5 interfaces. I create an object of this class. Is it correct that the resulting object has 6 vtable pointers embedded, one for the class, and 5 for the interfaces? And every object that is allocated will have this overhead? In Java land, no vtables are embedded in the object.Yep, that's correct. Though note this only applies to interfaces that are direct parents of the class; interfaces that are parents of other interfaces don't count. However conversely you do still need space for the interface pointers of your superclass. Java is a dynamically compiled language. This allows it to take liberties that are simply unfeasible for a statically compiled language. D cannot specialize a method call for a particular class at runtime; it has to be fast on its first execution, and every successive one. So trading off space for speed makes sense here. That said, if you're creating an object with six interfaces, which you are instantiating so often that its size matters, you're almost certainly writing unidiomatic D. Keep in mind that if you write D as if it was Java, you will be setting yourself up for GC and performance pain down the road.
Jun 23 2023