summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2013-08-08 13:46:30 -0400
committerRuss Cox <rsc@golang.org>2013-08-08 13:46:30 -0400
commitdfbe9bc5c8afd7681d5c09f61c1dc9e2e0906922 (patch)
treecf774a709822b84a9834c308a7a9489c1dfdc0a9
parent4f63263f9925f890aa8f55d704a0fae88a1c3b40 (diff)
downloadgo-dfbe9bc5c8afd7681d5c09f61c1dc9e2e0906922.tar.gz
cmd/gc: move large stack variables to heap
Individual variables bigger than 10 MB are now moved to the heap, as if they had escaped on their own. This avoids ridiculous stacks for programs that do things like x := [1<<30]byte{} ... use x ... If 10 MB is too small, we can raise the limit. Fixes issue 6077. R=ken2 CC=golang-dev https://codereview.appspot.com/12650045
-rw-r--r--src/cmd/gc/go.h3
-rw-r--r--src/cmd/gc/lex.c4
-rw-r--r--src/cmd/gc/pgen.c23
-rw-r--r--test/escape5.go7
-rw-r--r--test/fixedbugs/bug385_64.go217
5 files changed, 246 insertions, 8 deletions
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index e530e79dd..26ffabc68 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -63,6 +63,8 @@ enum
ACPLX128,
BADWIDTH = -1000000000,
+
+ MaxStackVarSize = 10*1024*1024,
};
extern vlong MAXWIDTH;
@@ -1470,6 +1472,7 @@ void ggloblnod(Node *nam);
void ggloblsym(Sym *s, int32 width, int dupok, int rodata);
Prog* gjmp(Prog*);
void gused(Node*);
+void movelarge(NodeList*);
int isfat(Type*);
void markautoused(Prog*);
Plist* newplist(void);
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
index 750b6aad6..281c1c9d6 100644
--- a/src/cmd/gc/lex.c
+++ b/src/cmd/gc/lex.c
@@ -418,6 +418,10 @@ main(int argc, char *argv[])
// Phase 5: Escape analysis.
if(!debug['N'])
escapes(xtop);
+
+ // Escape analysis moved escaped values off stack.
+ // Move large values off stack too.
+ movelarge(xtop);
// Phase 6: Compile top level functions.
for(l=xtop; l; l=l->next)
diff --git a/src/cmd/gc/pgen.c b/src/cmd/gc/pgen.c
index 8b268a218..237314ea1 100644
--- a/src/cmd/gc/pgen.c
+++ b/src/cmd/gc/pgen.c
@@ -447,3 +447,26 @@ allocauto(Prog* ptxt)
ll->n->stkdelta = 0;
}
}
+
+static void movelargefn(Node*);
+
+void
+movelarge(NodeList *l)
+{
+ for(; l; l=l->next)
+ if(l->n->op == ODCLFUNC)
+ movelargefn(l->n);
+}
+
+static void
+movelargefn(Node *fn)
+{
+ NodeList *l;
+ Node *n;
+
+ for(l=fn->dcl; l != nil; l=l->next) {
+ n = l->n;
+ if(n->class == PAUTO && n->type != T && n->type->width > MaxStackVarSize)
+ addrescapes(n);
+ }
+}
diff --git a/test/escape5.go b/test/escape5.go
index 6b327fe9e..c9646872d 100644
--- a/test/escape5.go
+++ b/test/escape5.go
@@ -142,3 +142,10 @@ func f9() {
var j T1 // ERROR "moved to heap: j"
f8(&j) // ERROR "&j escapes to heap"
}
+
+func f10() {
+ // These don't escape but are too big for the stack
+ var x [1<<30]byte // ERROR "moved to heap: x"
+ var y = make([]byte, 1<<30) // ERROR "does not escape"
+ _ = x[0] + y[0]
+}
diff --git a/test/fixedbugs/bug385_64.go b/test/fixedbugs/bug385_64.go
index b5621b210..aef03c389 100644
--- a/test/fixedbugs/bug385_64.go
+++ b/test/fixedbugs/bug385_64.go
@@ -10,13 +10,214 @@
package main
-func main() { // ERROR "stack frame too large"
- var arr [1000200030]int32
- arr_bkup := arr
- _ = arr_bkup
-}
+var z [10<<20]byte
-func F() { // ERROR "stack frame too large"
- var arr [1 << 30]int32
- _ = arr[42]
+func main() { // ERROR "stack frame too large"
+ // seq 1 206 | sed 's/.*/ var x& [10<<20]byte; z = x&/'
+ var x1 [10<<20]byte; z = x1
+ var x2 [10<<20]byte; z = x2
+ var x3 [10<<20]byte; z = x3
+ var x4 [10<<20]byte; z = x4
+ var x5 [10<<20]byte; z = x5
+ var x6 [10<<20]byte; z = x6
+ var x7 [10<<20]byte; z = x7
+ var x8 [10<<20]byte; z = x8
+ var x9 [10<<20]byte; z = x9
+ var x10 [10<<20]byte; z = x10
+ var x11 [10<<20]byte; z = x11
+ var x12 [10<<20]byte; z = x12
+ var x13 [10<<20]byte; z = x13
+ var x14 [10<<20]byte; z = x14
+ var x15 [10<<20]byte; z = x15
+ var x16 [10<<20]byte; z = x16
+ var x17 [10<<20]byte; z = x17
+ var x18 [10<<20]byte; z = x18
+ var x19 [10<<20]byte; z = x19
+ var x20 [10<<20]byte; z = x20
+ var x21 [10<<20]byte; z = x21
+ var x22 [10<<20]byte; z = x22
+ var x23 [10<<20]byte; z = x23
+ var x24 [10<<20]byte; z = x24
+ var x25 [10<<20]byte; z = x25
+ var x26 [10<<20]byte; z = x26
+ var x27 [10<<20]byte; z = x27
+ var x28 [10<<20]byte; z = x28
+ var x29 [10<<20]byte; z = x29
+ var x30 [10<<20]byte; z = x30
+ var x31 [10<<20]byte; z = x31
+ var x32 [10<<20]byte; z = x32
+ var x33 [10<<20]byte; z = x33
+ var x34 [10<<20]byte; z = x34
+ var x35 [10<<20]byte; z = x35
+ var x36 [10<<20]byte; z = x36
+ var x37 [10<<20]byte; z = x37
+ var x38 [10<<20]byte; z = x38
+ var x39 [10<<20]byte; z = x39
+ var x40 [10<<20]byte; z = x40
+ var x41 [10<<20]byte; z = x41
+ var x42 [10<<20]byte; z = x42
+ var x43 [10<<20]byte; z = x43
+ var x44 [10<<20]byte; z = x44
+ var x45 [10<<20]byte; z = x45
+ var x46 [10<<20]byte; z = x46
+ var x47 [10<<20]byte; z = x47
+ var x48 [10<<20]byte; z = x48
+ var x49 [10<<20]byte; z = x49
+ var x50 [10<<20]byte; z = x50
+ var x51 [10<<20]byte; z = x51
+ var x52 [10<<20]byte; z = x52
+ var x53 [10<<20]byte; z = x53
+ var x54 [10<<20]byte; z = x54
+ var x55 [10<<20]byte; z = x55
+ var x56 [10<<20]byte; z = x56
+ var x57 [10<<20]byte; z = x57
+ var x58 [10<<20]byte; z = x58
+ var x59 [10<<20]byte; z = x59
+ var x60 [10<<20]byte; z = x60
+ var x61 [10<<20]byte; z = x61
+ var x62 [10<<20]byte; z = x62
+ var x63 [10<<20]byte; z = x63
+ var x64 [10<<20]byte; z = x64
+ var x65 [10<<20]byte; z = x65
+ var x66 [10<<20]byte; z = x66
+ var x67 [10<<20]byte; z = x67
+ var x68 [10<<20]byte; z = x68
+ var x69 [10<<20]byte; z = x69
+ var x70 [10<<20]byte; z = x70
+ var x71 [10<<20]byte; z = x71
+ var x72 [10<<20]byte; z = x72
+ var x73 [10<<20]byte; z = x73
+ var x74 [10<<20]byte; z = x74
+ var x75 [10<<20]byte; z = x75
+ var x76 [10<<20]byte; z = x76
+ var x77 [10<<20]byte; z = x77
+ var x78 [10<<20]byte; z = x78
+ var x79 [10<<20]byte; z = x79
+ var x80 [10<<20]byte; z = x80
+ var x81 [10<<20]byte; z = x81
+ var x82 [10<<20]byte; z = x82
+ var x83 [10<<20]byte; z = x83
+ var x84 [10<<20]byte; z = x84
+ var x85 [10<<20]byte; z = x85
+ var x86 [10<<20]byte; z = x86
+ var x87 [10<<20]byte; z = x87
+ var x88 [10<<20]byte; z = x88
+ var x89 [10<<20]byte; z = x89
+ var x90 [10<<20]byte; z = x90
+ var x91 [10<<20]byte; z = x91
+ var x92 [10<<20]byte; z = x92
+ var x93 [10<<20]byte; z = x93
+ var x94 [10<<20]byte; z = x94
+ var x95 [10<<20]byte; z = x95
+ var x96 [10<<20]byte; z = x96
+ var x97 [10<<20]byte; z = x97
+ var x98 [10<<20]byte; z = x98
+ var x99 [10<<20]byte; z = x99
+ var x100 [10<<20]byte; z = x100
+ var x101 [10<<20]byte; z = x101
+ var x102 [10<<20]byte; z = x102
+ var x103 [10<<20]byte; z = x103
+ var x104 [10<<20]byte; z = x104
+ var x105 [10<<20]byte; z = x105
+ var x106 [10<<20]byte; z = x106
+ var x107 [10<<20]byte; z = x107
+ var x108 [10<<20]byte; z = x108
+ var x109 [10<<20]byte; z = x109
+ var x110 [10<<20]byte; z = x110
+ var x111 [10<<20]byte; z = x111
+ var x112 [10<<20]byte; z = x112
+ var x113 [10<<20]byte; z = x113
+ var x114 [10<<20]byte; z = x114
+ var x115 [10<<20]byte; z = x115
+ var x116 [10<<20]byte; z = x116
+ var x117 [10<<20]byte; z = x117
+ var x118 [10<<20]byte; z = x118
+ var x119 [10<<20]byte; z = x119
+ var x120 [10<<20]byte; z = x120
+ var x121 [10<<20]byte; z = x121
+ var x122 [10<<20]byte; z = x122
+ var x123 [10<<20]byte; z = x123
+ var x124 [10<<20]byte; z = x124
+ var x125 [10<<20]byte; z = x125
+ var x126 [10<<20]byte; z = x126
+ var x127 [10<<20]byte; z = x127
+ var x128 [10<<20]byte; z = x128
+ var x129 [10<<20]byte; z = x129
+ var x130 [10<<20]byte; z = x130
+ var x131 [10<<20]byte; z = x131
+ var x132 [10<<20]byte; z = x132
+ var x133 [10<<20]byte; z = x133
+ var x134 [10<<20]byte; z = x134
+ var x135 [10<<20]byte; z = x135
+ var x136 [10<<20]byte; z = x136
+ var x137 [10<<20]byte; z = x137
+ var x138 [10<<20]byte; z = x138
+ var x139 [10<<20]byte; z = x139
+ var x140 [10<<20]byte; z = x140
+ var x141 [10<<20]byte; z = x141
+ var x142 [10<<20]byte; z = x142
+ var x143 [10<<20]byte; z = x143
+ var x144 [10<<20]byte; z = x144
+ var x145 [10<<20]byte; z = x145
+ var x146 [10<<20]byte; z = x146
+ var x147 [10<<20]byte; z = x147
+ var x148 [10<<20]byte; z = x148
+ var x149 [10<<20]byte; z = x149
+ var x150 [10<<20]byte; z = x150
+ var x151 [10<<20]byte; z = x151
+ var x152 [10<<20]byte; z = x152
+ var x153 [10<<20]byte; z = x153
+ var x154 [10<<20]byte; z = x154
+ var x155 [10<<20]byte; z = x155
+ var x156 [10<<20]byte; z = x156
+ var x157 [10<<20]byte; z = x157
+ var x158 [10<<20]byte; z = x158
+ var x159 [10<<20]byte; z = x159
+ var x160 [10<<20]byte; z = x160
+ var x161 [10<<20]byte; z = x161
+ var x162 [10<<20]byte; z = x162
+ var x163 [10<<20]byte; z = x163
+ var x164 [10<<20]byte; z = x164
+ var x165 [10<<20]byte; z = x165
+ var x166 [10<<20]byte; z = x166
+ var x167 [10<<20]byte; z = x167
+ var x168 [10<<20]byte; z = x168
+ var x169 [10<<20]byte; z = x169
+ var x170 [10<<20]byte; z = x170
+ var x171 [10<<20]byte; z = x171
+ var x172 [10<<20]byte; z = x172
+ var x173 [10<<20]byte; z = x173
+ var x174 [10<<20]byte; z = x174
+ var x175 [10<<20]byte; z = x175
+ var x176 [10<<20]byte; z = x176
+ var x177 [10<<20]byte; z = x177
+ var x178 [10<<20]byte; z = x178
+ var x179 [10<<20]byte; z = x179
+ var x180 [10<<20]byte; z = x180
+ var x181 [10<<20]byte; z = x181
+ var x182 [10<<20]byte; z = x182
+ var x183 [10<<20]byte; z = x183
+ var x184 [10<<20]byte; z = x184
+ var x185 [10<<20]byte; z = x185
+ var x186 [10<<20]byte; z = x186
+ var x187 [10<<20]byte; z = x187
+ var x188 [10<<20]byte; z = x188
+ var x189 [10<<20]byte; z = x189
+ var x190 [10<<20]byte; z = x190
+ var x191 [10<<20]byte; z = x191
+ var x192 [10<<20]byte; z = x192
+ var x193 [10<<20]byte; z = x193
+ var x194 [10<<20]byte; z = x194
+ var x195 [10<<20]byte; z = x195
+ var x196 [10<<20]byte; z = x196
+ var x197 [10<<20]byte; z = x197
+ var x198 [10<<20]byte; z = x198
+ var x199 [10<<20]byte; z = x199
+ var x200 [10<<20]byte; z = x200
+ var x201 [10<<20]byte; z = x201
+ var x202 [10<<20]byte; z = x202
+ var x203 [10<<20]byte; z = x203
+ var x204 [10<<20]byte; z = x204
+ var x205 [10<<20]byte; z = x205
+ var x206 [10<<20]byte; z = x206
}