bearophile
| BCS:
> > But I'd also like to show that answer of mine to D developers,
> done here
> :)
Do D devs take a look at this D.learn newsgroup, once in a while? :-)
Anyway, just to be sure I have done four more little tests, that show an ideal situation. Real world situations are probably worse.
version(Tango) import tango.stdc.stdio: printf;
class Test1 {
int x;
}
class Test2 {
int _x;
int x() { return this._x; }
void x(int xx) { this._x = xx; }
}
void main() {
auto t = new Test1;
t.x = 4;
printf("%d\n", t.x);
}
/*
DMD ASM:
_D16getters_setters15Test21xMFZi comdat
mov EAX,8[EAX]
ret
_D16getters_setters15Test21xMFiZv comdat
mov ECX,4[ESP]
mov 8[EAX],ECX
ret 4
main:
push EAX
mov EAX,offset FLAT:_D16getters_setters15Test17__ClassZ
push EAX
call near ptr __d_newclass
mov ECX,offset FLAT:_D16getters_setters15Test26__vtblZ[020h]
mov dword ptr 8[EAX],4
push dword ptr 8[EAX]
push ECX
call near ptr _printf
add ESP,0Ch
xor EAX,EAX
pop ECX
ret
--------------------------
LDC ASM:
_D7getset15Test21xMFZi:
movl 8(%eax), %eax
ret
_D7getset15Test21xMFiZv:
movl 4(%esp), %ecx
movl %ecx, 8(%eax)
ret $4
main:
subl $12, %esp
movl $4, 4(%esp)
movl $.str2, (%esp)
call printf
xorl %eax, %eax
addl $12, %esp
ret $8
*/
Here the LDC code is almost optimal, thanks to Frits van Bommel and others.
==========================
Now with a (virtual) getter and setter:
version(Tango) import tango.stdc.stdio: printf;
class Test1 {
int x;
}
class Test2 {
int _x;
int x() { return this._x; }
void x(int xx) { this._x = xx; }
}
void main() {
auto t = new Test2;
t.x = 4;
printf("%d\n", t.x);
}
/*
DMD ASM:
_D16getters_setters25Test21xMFZi comdat
mov EAX,8[EAX]
ret
_D16getters_setters25Test21xMFiZv comdat
mov ECX,4[ESP]
mov 8[EAX],ECX
ret 4
main:
push EAX
mov EAX,offset FLAT:_D16getters_setters25Test27__ClassZ
push EBX
push ESI
push 4
push EAX
call near ptr __d_newclass
add ESP,4
mov ECX,[EAX]
mov EBX,EAX
call dword ptr 01Ch[ECX]
mov EDX,[EBX]
mov EAX,EBX
call dword ptr 018h[EDX]
mov ESI,offset FLAT:_D16getters_setters25Test26__vtblZ[020h]
push EAX
push ESI
call near ptr _printf
add ESP,8
xor EAX,EAX
pop ESI
pop EBX
pop ECX
ret
---------------------
LDC ASM:
_D7getset25Test21xMFZi:
movl 8(%eax), %eax
ret
_D7getset25Test21xMFiZv:
movl 4(%esp), %ecx
movl %ecx, 8(%eax)
ret $4
main:
subl $12, %esp
movl $_D7getset25Test27__ClassZ, (%esp)
call _d_allocclass
movl $_D7getset25Test26__vtblZ, (%eax)
movl $0, 4(%eax)
movl $4, 8(%eax)
movl $4, 4(%esp)
movl $.str2, (%esp)
call printf
xorl %eax, %eax
addl $12, %esp
ret $8
*/
I like LDC and LDC developers (and LLVM) :-)
If 't' is defined as a scoped class, then LDC produces this main:
main:
subl $20, %esp
movl $_D8getset2b5Test26__vtblZ, 8(%esp)
movl $0, 12(%esp)
movl $4, 16(%esp)
movl $4, 4(%esp)
movl $.str2, (%esp)
call printf
leal 8(%esp), %eax
movl %eax, (%esp)
call _d_callfinalizer
xorl %eax, %eax
addl $20, %esp
ret $8
That's better. But recently I have asked ChristianK to improve that some more,
removing part of that call to _d_callfinalizer, leaving only a call to the monitor management:
http://www.dsource.org/projects/ldc/ticket/339
*/
Bye,
bearophile
|