www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 10509] New: Closure is allocated even if it may be not needed

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10509

           Summary: Closure is allocated even if it may be not needed
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Keywords: wrong-code
          Severity: critical
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: verylonglogin.reg gmail.com


--- Comment #0 from Denis Shelomovskij <verylonglogin.reg gmail.com> 2013-06-30
16:52:06 MSD ---
The allocation is done eager but can be lazy:
---
bool noAllocations = false;

extern(C) void* gc_malloc(size_t sz, uint ba = 0);

extern(C) void* _d_allocmemory(size_t sz)
{
    assert(!noAllocations); // fails
    return gc_malloc(sz);
}

int delegate() del;

void f(int i)
{
    if(i)
        del = () => i;
}

void main()
{
    noAllocations = true;
    f(0);
    noAllocations = false;
}
---

This hits with pain as one do not expect such behaviour and can e.g. branch out
closures in destructors expecting no allocation is done and then get strange
InvalidMemoryOperationError-s when GC is collecting.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jun 30 2013
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10509


Don <clugdbug yahoo.com.au> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|wrong-code                  |performance
           Severity|critical                    |enhancement


--- Comment #1 from Don <clugdbug yahoo.com.au> 2013-09-19 23:28:25 PDT ---
This is a very difficult optimization.
Consider:

void f(int i)
{
    if (i)
        del = () => i;  // (1)
    ++i;                // (2)
}

If you put i on the heap only at (1), then the compiler has trouble generating
code at (2) -- is i on the heap, or on the stack?

Another example:

    if (cond1()) 
        del = () => i;
    if (cond2()) 
        del = () => i*2;
The compiler would then have to generate code to move i onto the heap in two
places, and in the second case, it might already be on the heap.

 This hits with pain as one do not expect such behaviour
I think that is inevitable. In some simple cases, the compiler might be able to avoid creating a closure, but it will always be rather conservative. This isn't wrong code, it's a missed optimization opportunity. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 19 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10509



--- Comment #2 from Denis Shelomovskij <verylonglogin.reg gmail.com> 2013-09-20
22:00:46 MSD ---
What I'm afraid is inlining. Is it possible that the function allocating
closure in `if` branch is inlined and results in the issue?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Sep 20 2013