On Mon, 15 Nov 2010 17:02:27 -0500, bearophile <bearophileh...@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

Reply via email to