Jump to page: 1 2
Thread overview
Why are immutable array literals heap allocated?
Jul 04, 2019
Nick Treleaven
Jul 04, 2019
Eugene Wissner
Jul 05, 2019
Nick Treleaven
Jul 05, 2019
Max Haughton
Jul 05, 2019
Jonathan M Davis
Jul 06, 2019
Nick Treleaven
Jul 06, 2019
Era Scarecrow
Jul 04, 2019
a11e99z
Jul 05, 2019
Patrick Schluter
Jul 05, 2019
Patrick Schluter
Jul 06, 2019
ag0aep6g
Jul 07, 2019
Patrick Schluter
July 04, 2019
immutable(int[]) f() @nogc {
    return [1,2];
}

onlineapp.d(2): Error: array literal in `@nogc` function `onlineapp.f` may cause a GC allocation

This makes dynamic array literals unusable with @nogc, and adds to GC pressure for no reason. What code would break if dmd used only static data for [1,2]?
July 04, 2019
On Thursday, 4 July 2019 at 10:56:50 UTC, Nick Treleaven wrote:
> immutable(int[]) f() @nogc {
>     return [1,2];
> }
>
> onlineapp.d(2): Error: array literal in `@nogc` function `onlineapp.f` may cause a GC allocation
>
> This makes dynamic array literals unusable with @nogc, and adds to GC pressure for no reason. What code would break if dmd used only static data for [1,2]?

immutable(int[]) f() @nogc {
    static immutable arr = [1, 2];
    return arr;
}

You have to spell it out that the data is static.
July 04, 2019
On Thursday, 4 July 2019 at 10:56:50 UTC, Nick Treleaven wrote:
> immutable(int[]) f() @nogc {
>     return [1,2];
> }
>
> onlineapp.d(2): Error: array literal in `@nogc` function `onlineapp.f` may cause a GC allocation
>

specify the size of the static array:
immutable(int[ 2 /*HERE*/ ]) f() @nogc { return [1,2]; }
July 05, 2019
On Thursday, 4 July 2019 at 11:06:36 UTC, Eugene Wissner wrote:
>     static immutable arr = [1, 2];
>
> You have to spell it out that the data is static.

Yes, I was wondering why the compiler doesn't statically allocate it automatically as an optimization.
July 05, 2019
On Friday, 5 July 2019 at 16:25:10 UTC, Nick Treleaven wrote:
> On Thursday, 4 July 2019 at 11:06:36 UTC, Eugene Wissner wrote:
>>     static immutable arr = [1, 2];
>>
>> You have to spell it out that the data is static.
>
> Yes, I was wondering why the compiler doesn't statically allocate it automatically as an optimization.

LDC might be able to optimize it away but by default its heap allocated, I imagine for thread safety
July 05, 2019
On Friday, July 5, 2019 10:25:10 AM MDT Nick Treleaven via Digitalmars-d- learn wrote:
> On Thursday, 4 July 2019 at 11:06:36 UTC, Eugene Wissner wrote:
> >     static immutable arr = [1, 2];
> >
> > You have to spell it out that the data is static.
>
> Yes, I was wondering why the compiler doesn't statically allocate it automatically as an optimization.

It would have to be set up to store the literal somewhere else. Certainly, it can't just put it on the stack, because that risks it going out of scope and causing memory problems. It could theoretically be done with some types, but it's more than simply optimizing the code. As it stands, AFAIK, string literals are the only case where you avoid such allocations, and they get put in a particular place in memory for that to work. Something similar would have to be done with any other array literals where allocation was being avoided (save maybe for a case where scope is used and, and the compiler can statically verify that if it put it on the stack, it wouldn't escape the scope). And if I understand correctly what's being done with string literals, it requires that the value be known at compile time, in which case, any array literals with variables or function calls or the like couldn't work that way. Ultimately though, I think that what it comes down to is that rather than the compiler figuring out which array literals it can treat as special, it simply just knows that it can treat string literals that way and does it with them and nothing else.

Another thing to consider is that optimizations shouldn't affect the semantics. So, no matter what optimizations the compiler does with array literals, that shouldn't affect whether the function can be @nogc. For it to affect that, it would have to be something that was guaranteed by the language's semantics regardless of whether any optimizations were being done. So, even if an advanced optimizer really did figure out how to avoid the GC allocations, that wouldn't help with @nogc. Rather, it would have to be built into the semantics of the language.

- Jonathan M Davis



July 05, 2019
On Thursday, 4 July 2019 at 10:56:50 UTC, Nick Treleaven wrote:
> immutable(int[]) f() @nogc {
>     return [1,2];
> }
>
> onlineapp.d(2): Error: array literal in `@nogc` function `onlineapp.f` may cause a GC allocation
>
> This makes dynamic array literals unusable with @nogc, and adds to GC pressure for no reason. What code would break if dmd used only static data for [1,2]?

int[] in D is not an array but a fat pointer. When one realizes that then it become quite obvious why [1,2] was allocated. There is somewhere in the binary a static array [1,2] but as it is assigned to a pointer to mutable data, the compiler has no choice as to allocate a mutable copy of that immutable array.
July 05, 2019
On Friday, 5 July 2019 at 23:08:04 UTC, Patrick Schluter wrote:
> On Thursday, 4 July 2019 at 10:56:50 UTC, Nick Treleaven wrote:
>> immutable(int[]) f() @nogc {
>>     return [1,2];
>> }
>>
>> onlineapp.d(2): Error: array literal in `@nogc` function `onlineapp.f` may cause a GC allocation
>>
>> This makes dynamic array literals unusable with @nogc, and adds to GC pressure for no reason. What code would break if dmd used only static data for [1,2]?
>
> int[] in D is not an array but a fat pointer. When one realizes that then it become quite obvious why [1,2] was allocated. There is somewhere in the binary a static array [1,2] but as it is assigned to a pointer to mutable data, the compiler has no choice as to allocate a mutable copy of that immutable array.

and it cannot optimize it away because it doesn't know what the caller want to do with it. It might in another module invoke it and modify it, the compiler cannot tell. auto a=f(); a[0]++;
July 06, 2019
On Friday, 5 July 2019 at 16:25:10 UTC, Nick Treleaven wrote:
> Yes, I was wondering why the compiler doesn't statically allocate it automatically as an optimization.

 Which i would think it could, but silently adds .dup to the end as it points to a unnamed memory block of N size. Or if it's immutable i would point to the same shared data.
July 06, 2019
On 06.07.19 01:12, Patrick Schluter wrote:
> On Friday, 5 July 2019 at 23:08:04 UTC, Patrick Schluter wrote:
>> On Thursday, 4 July 2019 at 10:56:50 UTC, Nick Treleaven wrote:
>>> immutable(int[]) f() @nogc {
>>>     return [1,2];
>>> }
[...]
> 
> and it cannot optimize it away because it doesn't know what the caller want to do with it. It might in another module invoke it and modify it, the compiler cannot tell. auto a=f(); a[0]++;

f returns immutable. typeof(a) is immutable(int[]). You can't do a[0]++.
« First   ‹ Prev
1 2