[Issue 14451] New: static-foreach uses huge stack for no reason
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Thu Apr 16 03:22:02 PDT 2015
https://issues.dlang.org/show_bug.cgi?id=14451
Issue ID: 14451
Summary: static-foreach uses huge stack for no reason
Product: D
Version: D2
Hardware: x86_64
OS: Linux
Status: NEW
Severity: major
Priority: P1
Component: DMD
Assignee: nobody at puremagic.com
Reporter: tomerfiliba at gmail.com
Using static foreach (on a compile-time known range) basically expands the code
block so many times. That's excellent, except that variables declared inside
the foreach-body are not scoped properly, which causes needless, huge stack
allocation.
Consider the following snippet:
================================================
import std.traits;
struct S {ubyte a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;}
string[] staticForeach1() {
string[] arr;
foreach(string name; __traits(allMembers, S)) {
ulong[100] x;
arr ~= name;
}
return arr;
}
string[] staticForeach2() {
string[] arr;
foreach(string name; __traits(allMembers, S)) {
(){
ulong[100] x;
arr ~= name;
}();
}
return arr;
}
================================================
The first version compiles to
Dump of assembler code for function staticForeach1:
0x0000000000426170 <+0>: push %rbp
0x0000000000426171 <+1>: mov %rsp,%rbp
0x0000000000426174 <+4>: sub $0x52f8,%rsp <<<<<
0x000000000042617b <+11>: push %rbx
0x000000000042617c <+12>: movq $0x0,-0x52f0(%rbp)
0x0000000000426187 <+23>: movq $0x0,-0x52e8(%rbp)
requiring over 20K of stack space. The second version compiles to
Dump of assembler code for function staticForeach2:
0x0000000000426c48 <+0>: push %rbp
0x0000000000426c49 <+1>: mov %rsp,%rbp
0x0000000000426c4c <+4>: sub $0x10,%rsp <<<<<
0x0000000000426c50 <+8>: movq $0x0,-0x10(%rbp)
0x0000000000426c58 <+16>: movq $0x0,-0x8(%rbp)
0x0000000000426c60 <+24>: mov %rbp,%rdi
0x0000000000426c63 <+27>: callq 0x426d40
<staticForeach2FZ9__lambda1MFNbNfZv>
0x0000000000426c68 <+32>: mov %rbp,%rdi
0x0000000000426c6b <+35>: callq 0x426db8
<staticForeach2FZ9__lambda2MFNbNfZv>
0x0000000000426c70 <+40>: mov %rbp,%rdi
requiring only 16 bytes. I tried adding more scoping braces inside the foreach,
e.g.,
foreach(string name; __traits(allMembers, S)) {
{
ulong[100] x;
arr ~= name;
}
}
but anything other than actually invoking a separate function does not work.
Since I'm using fibers with small stacks, this is a real issue for me. I can
usually find workarounds (as described here), but there's no reason why so much
stack be wasted here.
--
More information about the Digitalmars-d-bugs
mailing list