LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 /* | 5 /* |
6 * basic types | 6 * basic types |
7 */ | 7 */ |
8 typedef signed char int8; | 8 typedef signed char int8; |
9 typedef unsigned char uint8; | 9 typedef unsigned char uint8; |
10 typedef signed short int16; | 10 typedef signed short int16; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 // If you add to this list, add to the list | 96 // If you add to this list, add to the list |
97 // of "okay during garbage collection" status | 97 // of "okay during garbage collection" status |
98 // in mgc0.c too. | 98 // in mgc0.c too. |
99 Gidle, | 99 Gidle, |
100 Grunnable, | 100 Grunnable, |
101 Grunning, | 101 Grunning, |
102 Gsyscall, | 102 Gsyscall, |
103 Gwaiting, | 103 Gwaiting, |
104 Gmoribund, | 104 Gmoribund, |
105 Gdead, | 105 Gdead, |
106 Grecovery, | |
107 }; | 106 }; |
108 enum | 107 enum |
109 { | 108 { |
110 true = 1, | 109 true = 1, |
111 false = 0, | 110 false = 0, |
112 }; | 111 }; |
113 | 112 |
114 /* | 113 /* |
115 * structures | 114 * structures |
116 */ | 115 */ |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 byte* pc; | 176 byte* pc; |
178 G* g; | 177 G* g; |
179 }; | 178 }; |
180 struct G | 179 struct G |
181 { | 180 { |
182 byte* stackguard; // cannot move - also known to linker, libmach,
libcgo | 181 byte* stackguard; // cannot move - also known to linker, libmach,
libcgo |
183 byte* stackbase; // cannot move - also known to libmach, libcgo | 182 byte* stackbase; // cannot move - also known to libmach, libcgo |
184 Defer* defer; | 183 Defer* defer; |
185 Panic* panic; | 184 Panic* panic; |
186 Gobuf sched; | 185 Gobuf sched; |
| 186 byte* gcstack; // if status==Gsyscall, gcstack = stackb
ase to use during gc |
| 187 byte* gcsp; // if status==Gsyscall, gcsp = sched.sp to use d
uring gc |
| 188 byte* gcguard; // if status==Gsyscall, gcguard = stackg
uard to use during gc |
187 byte* stack0; | 189 byte* stack0; |
188 byte* entry; // initial function | 190 byte* entry; // initial function |
189 G* alllink; // on allg | 191 G* alllink; // on allg |
190 void* param; // passed parameter on wakeup | 192 void* param; // passed parameter on wakeup |
191 int16 status; | 193 int16 status; |
192 int32 goid; | 194 int32 goid; |
193 uint32 selgen; // valid sudog pointer | 195 uint32 selgen; // valid sudog pointer |
194 G* schedlink; | 196 G* schedlink; |
195 bool readyonstop; | 197 bool readyonstop; |
196 bool ispanic; | 198 bool ispanic; |
197 M* m; // for debuggers, but offset not hard-coded | 199 M* m; // for debuggers, but offset not hard-coded |
198 M* lockedm; | 200 M* lockedm; |
| 201 M* idlem; |
199 int32 sig; | 202 int32 sig; |
200 uintptr sigcode0; | 203 uintptr sigcode0; |
201 uintptr sigcode1; | 204 uintptr sigcode1; |
202 uintptr sigpc; | 205 uintptr sigpc; |
| 206 uintptr gopc; // pc of go statement that created this goroutine |
203 }; | 207 }; |
204 struct M | 208 struct M |
205 { | 209 { |
206 // The offsets of these fields are known to (hard-coded in) libmach. | 210 // The offsets of these fields are known to (hard-coded in) libmach. |
207 G* g0; // goroutine with scheduling stack | 211 G* g0; // goroutine with scheduling stack |
208 void (*morepc)(void); | 212 void (*morepc)(void); |
209 void* moreargp; // argument pointer for more stack | 213 void* moreargp; // argument pointer for more stack |
210 Gobuf morebuf; // gobuf arg to morestack | 214 Gobuf morebuf; // gobuf arg to morestack |
211 | 215 |
212 // Fields not known to debuggers. | 216 // Fields not known to debuggers. |
213 uint32 moreframesize; // size arguments to morestack | 217 uint32 moreframesize; // size arguments to morestack |
214 uint32 moreargsize; | 218 uint32 moreargsize; |
215 uintptr cret; // return value from C | 219 uintptr cret; // return value from C |
216 uint64 procid; // for debuggers, but offset not hard-coded | 220 uint64 procid; // for debuggers, but offset not hard-coded |
217 G* gsignal; // signal-handling G | 221 G* gsignal; // signal-handling G |
218 uint32 tls[8]; // thread-local storage (for 386 extern register
) | 222 uint32 tls[8]; // thread-local storage (for 386 extern register
) |
219 Gobuf sched; // scheduling stack | |
220 G* curg; // current running goroutine | 223 G* curg; // current running goroutine |
221 int32 id; | 224 int32 id; |
222 int32 mallocing; | 225 int32 mallocing; |
223 int32 gcing; | 226 int32 gcing; |
224 int32 locks; | 227 int32 locks; |
225 int32 nomemprof; | 228 int32 nomemprof; |
226 int32 waitnextg; | 229 int32 waitnextg; |
| 230 int32 dying; |
| 231 int32 profilehz; |
227 Note havenextg; | 232 Note havenextg; |
228 G* nextg; | 233 G* nextg; |
229 M* alllink; // on allm | 234 M* alllink; // on allm |
230 M* schedlink; | 235 M* schedlink; |
231 uint32 machport; // Return address for Mach IPC (OS X) | 236 uint32 machport; // Return address for Mach IPC (OS X) |
232 MCache *mcache; | 237 MCache *mcache; |
233 G* lockedg; | 238 G* lockedg; |
| 239 G* idleg; |
234 uint32 freglo[16]; // D[i] lsb and F[i] | 240 uint32 freglo[16]; // D[i] lsb and F[i] |
235 uint32 freghi[16]; // D[i] msb and F[i+16] | 241 uint32 freghi[16]; // D[i] msb and F[i+16] |
236 uint32 fflag; // floating point compare flags | 242 uint32 fflag; // floating point compare flags |
237 #ifdef __WINDOWS__ | 243 #ifdef __WINDOWS__ |
238 void* sehframe; | 244 void* sehframe; |
239 | 245 |
240 #ifdef _64BIT··· | 246 #ifdef _64BIT··· |
241 void* gostack; | 247 void* gostack; |
242 #endif | 248 #endif |
243 | 249 |
244 #endif | 250 #endif |
245 }; | 251 }; |
| 252 |
246 struct Stktop | 253 struct Stktop |
247 { | 254 { |
248 // The offsets of these fields are known to (hard-coded in) libmach. | 255 // The offsets of these fields are known to (hard-coded in) libmach. |
249 uint8* stackguard; | 256 uint8* stackguard; |
250 uint8* stackbase; | 257 uint8* stackbase; |
251 Gobuf gobuf; | 258 Gobuf gobuf; |
252 uint32 argsize; | 259 uint32 argsize; |
253 | 260 |
254 uint8* argp; // pointer to arguments in old frame | 261 uint8* argp; // pointer to arguments in old frame |
255 uintptr free; // if free>0, call stackfree using free as size | 262 uintptr free; // if free>0, call stackfree using free as size |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 Windows = 1 | 304 Windows = 1 |
298 }; | 305 }; |
299 #else | 306 #else |
300 enum { | 307 enum { |
301 Windows = 0 | 308 Windows = 0 |
302 }; | 309 }; |
303 #endif | 310 #endif |
304 | 311 |
305 /* | 312 /* |
306 * defined macros | 313 * defined macros |
307 * you need super-goru privilege | 314 * you need super-gopher-guru privilege |
308 * to add this list. | 315 * to add this list. |
309 */ | 316 */ |
310 #define nelem(x) (sizeof(x)/sizeof((x)[0])) | 317 #define nelem(x) (sizeof(x)/sizeof((x)[0])) |
311 #define nil ((void*)0) | 318 #define nil ((void*)0) |
312 #define offsetof(s,m) (uint32)(&(((s*)0)->m)) | 319 #define offsetof(s,m) (uint32)(&(((s*)0)->m)) |
313 | 320 |
314 /* | 321 /* |
315 * known to compiler | 322 * known to compiler |
316 */ | 323 */ |
317 enum | 324 enum |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 | 363 |
357 /* | 364 /* |
358 * external data | 365 * external data |
359 */ | 366 */ |
360 extern Alg runtime·algarray[Amax]; | 367 extern Alg runtime·algarray[Amax]; |
361 extern String runtime·emptystring; | 368 extern String runtime·emptystring; |
362 G* runtime·allg; | 369 G* runtime·allg; |
363 M* runtime·allm; | 370 M* runtime·allm; |
364 int32 runtime·goidgen; | 371 int32 runtime·goidgen; |
365 extern int32 runtime·gomaxprocs; | 372 extern int32 runtime·gomaxprocs; |
366 extern» int32» runtime·panicking; | 373 extern» uint32» runtime·panicking; |
367 extern int32 runtime·gcwaiting; // gc is waiting to run | 374 extern int32 runtime·gcwaiting; // gc is waiting to run |
368 int8* runtime·goos; | 375 int8* runtime·goos; |
369 extern bool runtime·iscgo; | 376 extern bool runtime·iscgo; |
370 | 377 |
371 /* | 378 /* |
372 * common functions and data | 379 * common functions and data |
373 */ | 380 */ |
374 int32 runtime·strcmp(byte*, byte*); | 381 int32 runtime·strcmp(byte*, byte*); |
375 int32 runtime·findnull(byte*); | 382 int32 runtime·findnull(byte*); |
376 int32 runtime·findnullw(uint16*); | 383 int32 runtime·findnullw(uint16*); |
377 void runtime·dump(byte*, int32); | 384 void runtime·dump(byte*, int32); |
378 int32 runtime·runetochar(byte*, int32); | 385 int32 runtime·runetochar(byte*, int32); |
379 int32 runtime·charntorune(int32*, uint8*, int32); | 386 int32 runtime·charntorune(int32*, uint8*, int32); |
380 | 387 |
381 /* | 388 /* |
382 * very low level c-called | 389 * very low level c-called |
383 */ | 390 */ |
384 #define FLUSH(x) USED(x) | 391 #define FLUSH(x) USED(x) |
385 | 392 |
386 void runtime·gogo(Gobuf*, uintptr); | 393 void runtime·gogo(Gobuf*, uintptr); |
387 void runtime·gogocall(Gobuf*, void(*)(void)); | 394 void runtime·gogocall(Gobuf*, void(*)(void)); |
388 uintptr»runtime·gosave(Gobuf*); | 395 void» runtime·gosave(Gobuf*); |
389 void runtime·lessstack(void); | 396 void runtime·lessstack(void); |
390 void runtime·goargs(void); | 397 void runtime·goargs(void); |
391 void runtime·goenvs(void); | 398 void runtime·goenvs(void); |
392 void runtime·goenvs_unix(void); | 399 void runtime·goenvs_unix(void); |
393 void* runtime·getu(void); | 400 void* runtime·getu(void); |
394 void runtime·throw(int8*); | 401 void runtime·throw(int8*); |
395 void runtime·panicstring(int8*); | 402 void runtime·panicstring(int8*); |
396 uint32 runtime·rnd(uint32, uint32); | 403 uint32 runtime·rnd(uint32, uint32); |
397 void runtime·prints(int8*); | 404 void runtime·prints(int8*); |
398 void runtime·printf(int8*, ...); | 405 void runtime·printf(int8*, ...); |
399 byte* runtime·mchr(byte*, byte, byte*); | 406 byte* runtime·mchr(byte*, byte, byte*); |
400 void runtime·mcpy(byte*, byte*, uint32); | 407 void runtime·mcpy(byte*, byte*, uint32); |
401 int32 runtime·mcmp(byte*, byte*, uint32); | 408 int32 runtime·mcmp(byte*, byte*, uint32); |
402 void runtime·memmove(void*, void*, uint32); | 409 void runtime·memmove(void*, void*, uint32); |
403 void* runtime·mal(uintptr); | 410 void* runtime·mal(uintptr); |
404 String runtime·catstring(String, String); | 411 String runtime·catstring(String, String); |
405 String runtime·gostring(byte*); | 412 String runtime·gostring(byte*); |
406 String runtime·gostringn(byte*, int32); | 413 String runtime·gostringn(byte*, int32); |
407 String runtime·gostringnocopy(byte*); | 414 String runtime·gostringnocopy(byte*); |
408 String runtime·gostringw(uint16*); | 415 String runtime·gostringw(uint16*); |
409 void runtime·initsig(int32); | 416 void runtime·initsig(int32); |
410 int32 runtime·gotraceback(void); | 417 int32 runtime·gotraceback(void); |
411 void runtime·traceback(uint8 *pc, uint8 *sp, uint8 *lr, G* gp); | 418 void runtime·traceback(uint8 *pc, uint8 *sp, uint8 *lr, G* gp); |
412 void runtime·tracebackothers(G*); | 419 void runtime·tracebackothers(G*); |
413 int32 runtime·write(int32, void*, int32); | 420 int32 runtime·write(int32, void*, int32); |
| 421 int32 runtime·mincore(void*, uintptr, byte*); |
414 bool runtime·cas(uint32*, uint32, uint32); | 422 bool runtime·cas(uint32*, uint32, uint32); |
415 bool runtime·casp(void**, void*, void*); | 423 bool runtime·casp(void**, void*, void*); |
416 uint32 runtime·xadd(uint32 volatile*, int32); | 424 uint32 runtime·xadd(uint32 volatile*, int32); |
417 void runtime·jmpdefer(byte*, void*); | 425 void runtime·jmpdefer(byte*, void*); |
418 void runtime·exit1(int32); | 426 void runtime·exit1(int32); |
419 void runtime·ready(G*); | 427 void runtime·ready(G*); |
420 byte* runtime·getenv(int8*); | 428 byte* runtime·getenv(int8*); |
421 int32 runtime·atoi(byte*); | 429 int32 runtime·atoi(byte*); |
422 void runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void)); | 430 void runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void)); |
423 void runtime·signalstack(byte*, int32); | 431 void runtime·signalstack(byte*, int32); |
(...skipping 11 matching lines...) Expand all Loading... |
435 uintptr runtime·efacehash(Eface); | 443 uintptr runtime·efacehash(Eface); |
436 uintptr runtime·nohash(uint32, void*); | 444 uintptr runtime·nohash(uint32, void*); |
437 uint32 runtime·noequal(uint32, void*, void*); | 445 uint32 runtime·noequal(uint32, void*, void*); |
438 void* runtime·malloc(uintptr size); | 446 void* runtime·malloc(uintptr size); |
439 void runtime·free(void *v); | 447 void runtime·free(void *v); |
440 void runtime·addfinalizer(void*, void(*fn)(void*), int32); | 448 void runtime·addfinalizer(void*, void(*fn)(void*), int32); |
441 void runtime·walkfintab(void (*fn)(void*)); | 449 void runtime·walkfintab(void (*fn)(void*)); |
442 void runtime·runpanic(Panic*); | 450 void runtime·runpanic(Panic*); |
443 void* runtime·getcallersp(void*); | 451 void* runtime·getcallersp(void*); |
444 int32 runtime·mcount(void); | 452 int32 runtime·mcount(void); |
| 453 void runtime·mcall(void(*)(G*)); |
445 | 454 |
446 void runtime·exit(int32); | 455 void runtime·exit(int32); |
447 void runtime·breakpoint(void); | 456 void runtime·breakpoint(void); |
448 void runtime·gosched(void); | 457 void runtime·gosched(void); |
449 void runtime·goexit(void); | 458 void runtime·goexit(void); |
450 void» runtime·runcgo(void (*fn)(void*), void*); | 459 void» runtime·asmcgocall(void (*fn)(void*), void*); |
451 void» runtime·runcgocallback(G*, void*, void (*fn)()); | |
452 void runtime·entersyscall(void); | 460 void runtime·entersyscall(void); |
453 void runtime·exitsyscall(void); | 461 void runtime·exitsyscall(void); |
454 void» runtime·startcgocallback(G*); | 462 G*» runtime·newproc1(byte*, byte*, int32, int32, void*); |
455 void» runtime·endcgocallback(G*); | |
456 G*» runtime·newproc1(byte*, byte*, int32, int32); | |
457 void runtime·siginit(void); | 463 void runtime·siginit(void); |
458 bool runtime·sigsend(int32 sig); | 464 bool runtime·sigsend(int32 sig); |
459 void runtime·gettime(int64*, int32*); | 465 void runtime·gettime(int64*, int32*); |
460 int32 runtime·callers(int32, uintptr*, int32); | 466 int32 runtime·callers(int32, uintptr*, int32); |
| 467 int32 runtime·gentraceback(byte*, byte*, byte*, G*, int32, uintptr*, int32); |
461 int64 runtime·nanotime(void); | 468 int64 runtime·nanotime(void); |
462 void runtime·dopanic(int32); | 469 void runtime·dopanic(int32); |
| 470 void runtime·startpanic(void); |
| 471 void runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp); |
| 472 void runtime·resetcpuprofiler(int32); |
| 473 void runtime·setcpuprofilerate(void(*)(uintptr*, int32), int32); |
463 | 474 |
464 #pragma varargck argpos runtime·printf 1 | 475 #pragma varargck argpos runtime·printf 1 |
465 #pragma varargck type "d" int32 | 476 #pragma varargck type "d" int32 |
466 #pragma varargck type "d" uint32 | 477 #pragma varargck type "d" uint32 |
467 #pragma varargck type "D" int64 | 478 #pragma varargck type "D" int64 |
468 #pragma varargck type "D" uint64 | 479 #pragma varargck type "D" uint64 |
469 #pragma varargck type "x" int32 | 480 #pragma varargck type "x" int32 |
470 #pragma varargck type "x" uint32 | 481 #pragma varargck type "x" uint32 |
471 #pragma varargck type "X" int64 | 482 #pragma varargck type "X" int64 |
472 #pragma varargck type "X" uint64 | 483 #pragma varargck type "X" uint64 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 bool runtime·isNaN(float64 f); | 583 bool runtime·isNaN(float64 f); |
573 float64 runtime·ldexp(float64 d, int32 e); | 584 float64 runtime·ldexp(float64 d, int32 e); |
574 float64 runtime·modf(float64 d, float64 *ip); | 585 float64 runtime·modf(float64 d, float64 *ip); |
575 void runtime·semacquire(uint32*); | 586 void runtime·semacquire(uint32*); |
576 void runtime·semrelease(uint32*); | 587 void runtime·semrelease(uint32*); |
577 String runtime·signame(int32 sig); | 588 String runtime·signame(int32 sig); |
578 int32 runtime·gomaxprocsfunc(int32 n); | 589 int32 runtime·gomaxprocsfunc(int32 n); |
579 | 590 |
580 void runtime·mapassign(Hmap*, byte*, byte*); | 591 void runtime·mapassign(Hmap*, byte*, byte*); |
581 void runtime·mapaccess(Hmap*, byte*, byte*, bool*); | 592 void runtime·mapaccess(Hmap*, byte*, byte*, bool*); |
582 struct hash_iter* runtime·newmapiterinit(Hmap*); | |
583 void runtime·mapiternext(struct hash_iter*); | 593 void runtime·mapiternext(struct hash_iter*); |
584 bool runtime·mapiterkey(struct hash_iter*, void*); | 594 bool runtime·mapiterkey(struct hash_iter*, void*); |
585 void runtime·mapiterkeyvalue(struct hash_iter*, void*, void*); | 595 void runtime·mapiterkeyvalue(struct hash_iter*, void*, void*); |
586 Hmap* runtime·makemap_c(Type*, Type*, int64); | 596 Hmap* runtime·makemap_c(Type*, Type*, int64); |
587 | 597 |
588 Hchan* runtime·makechan_c(Type*, int64); | 598 Hchan* runtime·makechan_c(Type*, int64); |
589 void runtime·chansend(Hchan*, void*, bool*); | 599 void runtime·chansend(Hchan*, void*, bool*); |
590 void runtime·chanrecv(Hchan*, void*, bool*, bool*); | 600 void runtime·chanrecv(Hchan*, void*, bool*, bool*); |
591 void runtime·chanclose(Hchan*); | |
592 bool runtime·chanclosed(Hchan*); | |
593 int32 runtime·chanlen(Hchan*); | 601 int32 runtime·chanlen(Hchan*); |
594 int32 runtime·chancap(Hchan*); | 602 int32 runtime·chancap(Hchan*); |
595 | 603 |
596 void runtime·ifaceE2I(struct InterfaceType*, Eface, Iface*); | 604 void runtime·ifaceE2I(struct InterfaceType*, Eface, Iface*); |
597 | 605 |
598 /* | |
599 * Stack layout parameters. | |
600 * Known to linkers. | |
601 * | |
602 * The per-goroutine g->stackguard is set to point | |
603 * StackGuard bytes above the bottom of the stack. | |
604 * Each function compares its stack pointer against | |
605 * g->stackguard to check for overflow. To cut one | |
606 * instruction from the check sequence for functions | |
607 * with tiny frames, the stack is allowed to protrude | |
608 * StackSmall bytes below the stack guard. Functions | |
609 * with large frames don't bother with the check and | |
610 * always call morestack. The sequences are | |
611 * (for amd64, others are similar): | |
612 * | |
613 * guard = g->stackguard | |
614 * frame = function's stack frame size | |
615 * argsize = size of function arguments (call + return) | |
616 * | |
617 * stack frame size <= StackSmall: | |
618 * CMPQ guard, SP | |
619 * JHI 3(PC) | |
620 * MOVQ m->morearg, $(argsize << 32) | |
621 * CALL morestack(SB) | |
622 * | |
623 * stack frame size > StackSmall but < StackBig | |
624 * LEAQ (frame-StackSmall)(SP), R0 | |
625 * CMPQ guard, R0 | |
626 * JHI 3(PC) | |
627 * MOVQ m->morearg, $(argsize << 32) | |
628 * CALL morestack(SB) | |
629 * | |
630 * stack frame size >= StackBig: | |
631 * MOVQ m->morearg, $((argsize << 32) | frame) | |
632 * CALL morestack(SB) | |
633 * | |
634 * The bottom StackGuard - StackSmall bytes are important: | |
635 * there has to be enough room to execute functions that | |
636 * refuse to check for stack overflow, either because they | |
637 * need to be adjacent to the actual caller's frame (deferproc) | |
638 * or because they handle the imminent stack overflow (morestack). | |
639 * | |
640 * For example, deferproc might call malloc, which does one | |
641 * of the above checks (without allocating a full frame), | |
642 * which might trigger a call to morestack. This sequence | |
643 * needs to fit in the bottom section of the stack. On amd64, | |
644 * morestack's frame is 40 bytes, and deferproc's frame is 56 bytes. | |
645 * That fits well within the StackGuard - StackSmall = 128 bytes | |
646 * at the bottom. There may be other sequences lurking or yet to | |
647 * be written that require more stack. Morestack checks to make | |
648 * sure the stack has not completely overflowed and should catch | |
649 * such sequences. | |
650 */ | |
651 enum | |
652 { | |
653 #ifdef __WINDOWS__ | |
654 // need enough room in guard area for exception handler. | |
655 // use larger stacks to compensate for larger stack guard. | |
656 StackSmall = 256, | |
657 StackGuard = 2048, | |
658 StackBig = 8192, | |
659 StackExtra = StackGuard, | |
660 #else | |
661 // byte offset of stack guard (g->stackguard) above bottom of stack. | |
662 StackGuard = 256, | |
663 | |
664 // checked frames are allowed to protrude below the guard by | |
665 // this many bytes. this saves an instruction in the checking | |
666 // sequence when the stack frame is tiny. | |
667 StackSmall = 128, | |
668 | |
669 // extra space in the frame (beyond the function for which | |
670 // the frame is allocated) is assumed not to be much bigger | |
671 // than this amount. it may not be used efficiently if it is. | |
672 StackBig = 4096, | |
673 | |
674 // extra room over frame size when allocating a stack. | |
675 StackExtra = 1024, | |
676 #endif | |
677 }; | |
LEFT | RIGHT |