www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why are immutable array literals heap allocated?

reply Nick Treleaven <nick geany.org> writes:
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]?
Jul 04 2019
next sibling parent reply Eugene Wissner <belka caraus.de> writes:
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.
Jul 04 2019
parent reply Nick Treleaven <nick geany.org> writes:
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.
Jul 05 2019
next sibling parent Max Haughton <maxhaton gmail.com> writes:
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
Jul 05 2019
prev sibling next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
Jul 05 2019
parent Nick Treleaven <nick geany.org> writes:
On Friday, 5 July 2019 at 23:05:32 UTC, Jonathan M Davis wrote:
 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.
I was thinking the read-only data segment.
 Certainly, it can't just put it on the stack, because that 
 risks it going out of scope and causing memory problems. It
It can do that with small-ish sized literals if they don't escape (-dip1000). I think Walter may have advocated something like this. This one can be done even with literals of mutable elements.
 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.
Yes, just like string literals I think static allocation can be part of the language for immutable data.
Jul 06 2019
prev sibling parent Era Scarecrow <rtcvb32 yahoo.com> writes:
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.
Jul 05 2019
prev sibling next sibling parent a11e99z <black80 bk.ru> writes:
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]; }
Jul 04 2019
prev sibling parent reply Patrick Schluter <Patrick.Schluter bbox.fr> writes:
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.
Jul 05 2019
parent reply Patrick Schluter <Patrick.Schluter bbox.fr> writes:
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]++;
Jul 05 2019
parent reply ag0aep6g <anonymous example.com> writes:
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]++.
Jul 06 2019
parent Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Saturday, 6 July 2019 at 09:56:57 UTC, ag0aep6g wrote:
 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]++.
You're right, I shouldn't post at 1 am.
Jul 07 2019