RFC, ensureHeaped

bearophile bearophileHUGS at lycos.com
Mon Nov 15 14:02:27 PST 2010


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.

All the other people need first of all a program that doesn't contain hard to spot bugs, and a fast progam then. Such people don't stick the "scope" there, so in this case the compiler performs the test you were talking about, if it's on the heap it doesn't copy it and takes a slice of it, otherwise if the data was on the heap it dups it.


>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.

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

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) { ... }


>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.

It's a problem of perception: typesafe variadic arguments don't look like normal function arguments that you know are usually on the stack, they look like dynamic arrays, and in D most dynamic arrays are allocated on the heap (it's easy and useful to take a dynamic-array-slice of a stack allocated array, but in this case the code shows that the slice doesn't contain heap data).

If your function has a signature similar to this one:

void foo(int[3] arr...) {

It's not too much hard to think that 'arr' is on the stack. But dynamic arrays don't give that image:

void foo(int[] arr...) {

This is why I think it's better for the compiler to test if the arr data is on the stack, and dup it otherwise (unless a 'scope' is present, in this case both the test and allocation aren't present).

Bye,
bearophile


More information about the Digitalmars-d mailing list