[Issue 9334] Dtor and postblit for struct heap object are not always called
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Thu Jan 17 09:47:31 PST 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9334
--- Comment #2 from Maxim Fomin <maxim at maxim-fomin.ru> 2013-01-17 09:47:29 PST ---
(In reply to comment #1)
> I don't think so: The postblit (and destructor) you are seeing comes (AFAIK)
> from moving a stack allocated S() into the heap, *during* the new.
You misunderstood the point. The problem is not that D's GC does not collect
structs, the problem is within foo.
The code:
/* to reduce phobos bloat and remove postblit*/
import core.stdc.stdio : printf;
struct S
{
int i;
~this() { printf("%X dtor\n", i); }
}
auto foo()
{
S* s = new S(); // add any argument to new to call dtor
}
void main()
{
foo();
}
Dump of assembler code for function _D4main3fooFZv:
0x0000000000418768 <+0>: push %rbp
0x0000000000418769 <+1>: mov %rsp,%rbp
0x000000000041876c <+4>: movabs $0x6362a0,%rdi
0x0000000000418776 <+14>: callq 0x41a09c <_d_newitemT>
0x000000000041877b <+19>: pop %rbp
0x000000000041877c <+20>: retq
End of assembler dump.
As you see there is no stack allocation.
Case #2 add non-default parameter (1)
Dump of assembler code for function _D4main3fooFZv:
0x0000000000418768 <+0>: push %rbp
0x0000000000418769 <+1>: mov %rsp,%rbp
0x000000000041876c <+4>: sub $0x10,%rsp
0x0000000000418770 <+8>: movabs $0x6362a0,%rdi
0x000000000041877a <+18>: callq 0x41a0c4 <_d_newitemT>
0x000000000041877f <+23>: movl $0x1,-0x8(%rbp)
0x0000000000418786 <+30>: lea -0x8(%rbp),%rsi
0x000000000041878a <+34>: mov %rax,%rdi
0x000000000041878d <+37>: movsb %ds:(%rsi),%es:(%rdi)
0x000000000041878e <+38>: movsb %ds:(%rsi),%es:(%rdi)
0x000000000041878f <+39>: movsb %ds:(%rsi),%es:(%rdi)
0x0000000000418790 <+40>: movsb %ds:(%rsi),%es:(%rdi)
0x0000000000418791 <+41>: callq 0x418798 <_D4main3fooFZv+48>
0x0000000000418796 <+46>: jmp 0x4187a2 <_D4main3fooFZv+58>
0x0000000000418798 <+48>: lea -0x8(%rbp),%rdi
0x000000000041879c <+52>: callq 0x4186f0 <_D4main1S6__dtorMFZv>
0x00000000004187a1 <+57>: retq
0x00000000004187a2 <+58>: leaveq
0x00000000004187a3 <+59>: retq
End of assembler dump.
Now there is S(1) (struct, not pointer - why?) which is written over memory
allocated by new and dtor is called for this stack struct. Note, even if you
pass 0 (which useless because i is zero anyway), dmd still emits dummy code
like above except that there is 0 instead of 1.
However, it need not to create a temporary S(1), just write 1 directly to value
returned from new, or in other words the expected code in case #2 is:
Dump of assembler code for function _D4main3fooFZv:
0x0000000000418768 <+0>: push %rbp
0x0000000000418769 <+1>: mov %rsp,%rbp
0x000000000041876c <+4>: movabs $0x6362a0,%rdi
0x0000000000418776 <+14>: callq 0x41a09c <_d_newitemT>
<change allocated value>: movl $0x1, (%eax)
0x000000000041877b <+19>: pop %rbp
0x000000000041877c <+20>: retq
End of assembler dump.
Note, this is not about optimizing, because
auto foo()
{
S* s = new S(1);
}
have no reason to create a temporary struct and than call destructor on it.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
More information about the Digitalmars-d-bugs
mailing list