[Issue 19539] Interface address is offset by 16bytes, causing memory leaks

d-bugmail at puremagic.com d-bugmail at puremagic.com
Tue Oct 3 17:11:00 UTC 2023


https://issues.dlang.org/show_bug.cgi?id=19539

Mai Lapyst <info at lapyst.by> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
                 CC|                            |info at lapyst.by
         Resolution|---                         |INVALID

--- Comment #1 from Mai Lapyst <info at lapyst.by> ---
This is actually correct. This happends because of the way interfaces are
implemented in machine code.

First of we need to understand how AX is layed out in memory:
---
<vtable>, <monitor>, <vtable for interface A>, <...rest of AX's fields>
---

Since vtable and monitor are both pointers, skipping 16 bytes means we now have
the interface's vtable at the head. This is more effective in the long run for
looking up methods to be called.

Secondly we need to know how exactly interface methods are invoked. One would
belive that 'a.func()' simply would call 'func()' of 'AX' but thats not quite
right. D (like many other languages) compiles here so called "thunk-functions",
which essentially are specialized wrapper function that know what original
method we're wanting to call and how to get from the modified pointer that 'a'
has, back to the original pointer of 'ax', so that 'func()' still has all the
data it needs. In this case it simply subtracts 16 bytes from the pointer,
landing at exactly the original address.

This same behaviour is also the magic that make inheritance work in the first
place.

If you print the address of 'this' inside 'func()' you'll see we got the
orginal address back.

Also: If you run 'writeln(cast(void*)cast(AX)a);', you'll also get the original
address back :)

--


More information about the Digitalmars-d-bugs mailing list