RFC, ensureHeaped

Steven Schveighoffer schveiguy at yahoo.com
Tue Nov 16 04:40:28 PST 2010


On Mon, 15 Nov 2010 17:02:27 -0500, bearophile <bearophileHUGS at lycos.com>  
wrote:

> Steven Schveighoffer:
>
>> To have the language continually working against that goal is going to  
>> great for inexperienced programmers but hell for people trying to  
>> squeeze performance out of it.<
>
> The experienced programmers may write "scope int[] a...", and have no  
> heap allocations.

This is a good idea.  This isn't what I thought spir was saying, I thought  
he wanted the function to always allocate.

At first glance, I thought your idea might be bad, because duping an array  
decouples it from the original, but then I realized -- there *is* no  
original.  This is the only reference to that data, so you can't change  
any expectations.

The only issue I see here is that scope should really be the default,  
because that is what you want most of the time.  However, the compiler  
cannot prove that the data doesn't escape so it can't really enforce that  
as the default.  I have the same issue with closures (the compiler is too  
eager to allocate closures because it is too conservative).  But I don't  
know how this can be fixed without redesigning the compilation model.

>> I think what we need however, is a way to specify intentions inside the  
>> function.  If you intend to escape this data, then the runtime/compiler  
>> should make it easy to avoid re-duping something.<
>
> This is like for the "automatic" closures. The right design in a modern  
> language is to use the safer strategy on default, and the less safe on  
> request.

This is not always possible, I still see a good need for ensuring heaped  
data.  For example:

int[] y;

foo(int[] x...)
{
    y = ensureHeaped(x);
}

bar(int[] x)
{
    foo(x);
}

baz()
{
    int[3] x;
    bar(x);
}

I believe the compiler cannot really be made to enforce that all passed-in  
data will be heap-allocated when passed to foo.  A runtime check would be  
a very good safety net.

> If you want, a new compiler switch may be added that lists all the spots  
> in the code where a closure or hidden heap allocation occurs, useful for  
> performance tuning (an idea by Denis Koroskin):
> http://d.puremagic.com/issues/show_bug.cgi?id=5070

Also a good idea.

>
> I have even suggested a transitive @noheap annotation, similar to  
> @nothrow, that makes sure a function contains no heap allocations and  
> doesn't call other things that perform heap allocations:
> http://d.puremagic.com/issues/show_bug.cgi?id=5219
> The proliferation of function attributes produces "interesting" results:
> @noheap @safe nothrow pure real sin(in real x) { ... }

This is a bit much.  Introducing these attributes is viral -- once you go  
@noheap, anything you call must be @noheap, and the majority of functions  
will need to be marked @noheap.  The gain is marginal at best anyways.

>> To be fair, it was easy to spot when you gave us the pertinent code :)
>
> I didn't even know/remember that that array data is on the stack. That  
> error will give bad surprises to some D newbies that are not fluent in C.

I didn't know until about a month and a half ago (in dcollections, this  
bug was prominent in all the array-based classes).  Only after inspecting  
the disassembly did I realize.

I agree we need some sort of protection or alert for this -- it's too  
simple to make this mistake.

-Steve


More information about the Digitalmars-d mailing list