digitalmars.D.bugs - codegen for Interfaces, and alias
- Kris (110/110) May 20 2005 When looking at the codegen related to interfaces, I noticed something o...
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