www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - codegen for Interfaces, and alias

When looking at the codegen related to interfaces, I noticed something odd
going on with alias'd names. Assume that you have an interface X like so:

interface X
{
   void put (Interface Y);
}

Here's an instance of calling the interface method:

2449:         Stdout.put (CR);
0041ECD3   push        dword ptr
[_D5mango2io6Writer2CRC5mango2io5model7IWriter14INewlineWriter (00550e38)]
0041ECD9   mov
eax,[_D5mango2io6Stdout6StdoutC5mango2io6Stdout13ConsoleWriter (005512b0)]
0041ECDE   mov         ecx,dword ptr [eax]
0041ECE0   call        dword ptr [ecx+38h]


That's cool. Now, lets add an alias to the interface, and apply it in the
same manner:

interface X
{
   alias put opCall;
   void put (Interface Y);
}

2449:         Stdout (CR);
0041ECD3   push        dword ptr
[_D5mango2io6Writer2CRC5mango2io5model7IWriter14INewlineWriter (00550e38)]
0041ECD9   cmp         dword ptr
[_D5mango2io6Stdout6StdoutC5mango2io6Stdout13ConsoleWriter (005512b0)],0
0041ECE0   je          _D8unittest14testTextWriterFZv+20h (0041ecec)
0041ECE2   mov
eax,[_D5mango2io6Stdout6StdoutC5mango2io6Stdout13ConsoleWriter (005512b0)]
0041ECE7   lea         eax,[eax+2Ch]
0041ECEA   jmp         _D8unittest14testTextWriterFZv+22h (0041ecee)
0041ECEC   xor         eax,eax
0041ECEE   cmp         dword ptr
[_D5mango2io6Stdout6StdoutC5mango2io6Stdout13ConsoleWriter (005512b0)],0
0041ECF5   je          _D8unittest14testTextWriterFZv+36h (0041ed02)
0041ECF7   mov         ecx,dword ptr
[_D5mango2io6Stdout6StdoutC5mango2io6Stdout13ConsoleWriter (005512b0)]
0041ECFD   lea         edx,[ecx+2Ch]
0041ED00   jmp         _D8unittest14testTextWriterFZv+38h (0041ed04)
0041ED02   xor         edx,edx
0041ED04   mov         ebx,dword ptr [edx]
0041ED06   call        dword ptr [ebx+78h]


Ack! What the heck happened there, you ask? It's truly awful, isn't it?

I was surprised to discover that adding the same alias to the /implementing
class/ got rid of the awful codegen. Unfortunately, that only works if you
use a class instance directly, as in the above example (Stdout is declared
as the class rather than the interface). If you use an interface instance
instead, all that crud comes piling back.

The whole point about interfaces is to abstract away the implementation
detail. Yet, recent versions of DMD have started producing the kind of code
that would make any self-repecting developer throw Interfaces upon the
garbage heap. Not good.

Please, please, please ... can we get this back to where it used to be?


In addition, when CR is declared as a class (rather than an interface) it
has to be converted to the interface before invoking put(). Contrast this
with the original four-line version above. Note that conversion to an
interface only requires an offset to get the correct vTable address:


2449:         Stdout (CR);
0041ECD3   push        dword ptr
[_D5mango2io6Writer2CRC5mango2io5model7IWriter14INewlineWriter (00550e38)]
0041ECD9   cmp         dword ptr
[_D5mango2io6Stdout6StdoutC5mango2io6Stdout13ConsoleWriter (005512b0)],0
0041ECE0   je          _D8unittest14testTextWriterFZv+20h (0041ecec)
0041ECE2   mov
eax,[_D5mango2io6Stdout6StdoutC5mango2io6Stdout13ConsoleWriter (005512b0)]
0041ECE7   lea         eax,[eax+2Ch]
0041ECEA   jmp         _D8unittest14testTextWriterFZv+22h (0041ecee)
0041ECEC   xor         eax,eax
0041ECEE   cmp         dword ptr
[_D5mango2io6Stdout6StdoutC5mango2io6Stdout13ConsoleWriter (005512b0)],0
0041ECF5   je          _D8unittest14testTextWriterFZv+36h (0041ed02)
0041ECF7   mov         ecx,dword ptr
[_D5mango2io6Stdout6StdoutC5mango2io6Stdout13ConsoleWriter (005512b0)]
0041ECFD   lea         edx,[ecx+2Ch]
0041ED00   jmp         _D8unittest14testTextWriterFZv+38h (0041ed04)
0041ED02   xor         edx,edx
0041ED04   mov         ebx,dword ptr [edx]
0041ED06   call        dword ptr [ebx+78h]


And for completeness, here's the version where the alias is missing from the
base-class (is in the interface only):

2449:         Stdout (CR);
0041F093   cmp         dword ptr
[_D5mango2io6Writer2CRC5mango2io6Writer13NewlineWriter (00551e38)],0
0041F09A   je          _D8unittest14testTextWriterFZv+1Ah (0041f0a6)
0041F09C   mov
eax,[_D5mango2io6Writer2CRC5mango2io6Writer13NewlineWriter (00551e38)]
0041F0A1   lea         ecx,[eax+10h]
0041F0A4   jmp         _D8unittest14testTextWriterFZv+1Ch (0041f0a8)
0041F0A6   xor         ecx,ecx
0041F0A8   push        ecx
0041F0A9   cmp         dword ptr
[_D5mango2io6Stdout6StdoutC5mango2io6Stdout13ConsoleWriter (005522b0)],0
0041F0B0   je          _D8unittest14testTextWriterFZv+31h (0041f0bd)
0041F0B2   mov         edx,dword ptr
[_D5mango2io6Stdout6StdoutC5mango2io6Stdout13ConsoleWriter (005522b0)]
0041F0B8   lea         eax,[edx+2Ch]
0041F0BB   jmp         _D8unittest14testTextWriterFZv+33h (0041f0bf)
0041F0BD   xor         eax,eax
0041F0BF   cmp         dword ptr
[_D5mango2io6Stdout6StdoutC5mango2io6Stdout13ConsoleWriter (005522b0)],0
0041F0C6   je          _D8unittest14testTextWriterFZv+47h (0041f0d3)
0041F0C8   mov         ebx,dword ptr
[_D5mango2io6Stdout6StdoutC5mango2io6Stdout13ConsoleWriter (005522b0)]
0041F0CE   lea         ecx,[ebx+2Ch]
0041F0D1   jmp         _D8unittest14testTextWriterFZv+49h (0041f0d5)
0041F0D3   xor         ecx,ecx
0041F0D5   mov         edx,dword ptr [ecx]
0041F0D7   call        dword ptr [edx+78h]


Oof! Again; please, please, triple please, can we get this fixed? Interfaces
used to have trivial overhead, but now?
May 20 2005