[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