On Thursday, 29 November 2012 at 12:38:03 UTC, Dan wrote:
On Thursday, 29 November 2012 at 07:59:02 UTC, Maxim Fomin
wrote:
This doesn't look like assembly for previous source. Please
provide the source for which you have assembly and tell which
dmd options do you use.
Well, I'm using the latest dmd (from the trunk), phobos,
druntime, so I could build and step through.
This is version generated by rdmd -version=bug --force
--build-only -g -w -property. The only difference between this
and yours is in <+71>.
<+00>: push %rbp
<+01>: mov %rsp,%rbp
<+04>: sub $0x38,%rsp
<+08>: push %rbx
// push 3 as a pkey, -0x30(%rbp) is 3
<+09>: mov $0x3,%eax
<+14>: mov %eax,-0x30(%rbp)
<+17>: lea -0x30(%rbp),%rcx
// push valuesize
<+21>: movabs $0x8,%rdx
// push keyti
<+31>: movabs $0x430f50,%rsi
// push map address, it is tls object
<+41>: mov %fs:0x0,%rdi
<+50>: add 0x21e22f(%rip),%rdi # 0x636fb0
// call, keyti=8, aa=&map, valuesize=8, pkey=3
<+57>: callq 0x419140 <_aaGetX>
// store return value in -0x28(%rbp)
<+62>: mov %rax,-0x28(%rbp)
// check array bounds
<+66>: test %rax,%rax
<+69>: jne 0x418d99 <_Dmain+81>
<+71>: mov $0x13,%edi
<+76>: callq 0x418e28 <_D4main7__arrayZ>
// constructing S rhs for opAssign
<+81>: movabs $0x2a,%rax
<+91>: mov %rax,-0x18(%rbp) // rhs
<+95>: mov %rax,%rsi
// making this from -0x20(%rbp), but it was stored in -0x28(%rbp)
<+98>: lea -0x20(%rbp),%rdi
// opAssign loads this from %rdi
<+102>: callq 0x418ce0 <_D4main1S8opAssignMFS4main1SZv>
// replace content in -0x28(%rbp) by -0x20(%rbp)
<+107>: mov -0x20(%rbp),%rcx
<+111>: mov -0x28(%rbp),%rdx
<+115>: mov %rcx,(%rdx)
// load previously created object
<+118>: movl $0x3,-0x10(%rbp)
<+125>: lea -0x10(%rbp),%rcx
<+129>: movabs $0x8,%rdx
<+139>: movabs $0x430f50,%rsi
<+149>: mov %fs:0x0,%rax
<+158>: mov 0x21e1c3(%rip),%rbx # 0x636fb0
<+165>: mov (%rax,%rbx,1),%rdi
<+169>: callq 0x4192b8 <_aaGetRvalueX>
// store pointer to existed object
<+174>: mov %rax,-0x8(%rbp)
// check array bounds
<+178>: test %rax,%rax
<+181>: jne 0x418e09 <_Dmain+193>
<+183>: mov $0x14,%edi
<+188>: callq 0x418e28 <_D4main7__arrayZ>
// load x member
<+193>: mov -0x8(%rbp),%rcx
<+197>: mov (%rcx),%rsi
<+200>: movabs $0x430ac0,%rdi
<+210>: xor %eax,%eax
<+212>: callq 0x4188e0 <printf@plt>
<+217>: xor %eax,%eax
<+219>: pop %rbx
<+220>: leaveq
<+221>: retq
End of assembler dump.
Main stack frame looks follows:
-0x30(%rbp):-0x28(%rbp) 3 as a pkey arg to _aaGetX
-0x28(%rbp):-0x20(%rbp) pointer to S allocated by _aaGetX
-0x20(%rbp):-0x18(%rbp) uninitialized struct - "this" ptr
-0x18(%rbp):-0x10(%rbp) constructed struct passed as rhs to
opAssign
-0x10(%rbp):-0x08(%rbp) 3 as a pkey arg to _aaGetRvalueX
-0x08(%rbp):-0x00(%rbp) pointer to S returned from _aaGetRvalueX
It seems that dmd allocates space for two structs, one
non-initialized, second initialized, issues call to druntime,
then places a call to opAssign with non-initialized as "this"
object with initialized as rhs argument, then writes content on
non-initialized to allocated by druntime. So, this looks like a
codegen bug.
By the way, if the code is compiled with command "dmd main -g
-release -noboundscheck -version=bug", opAssign call is placed
before calling _aaGetX.