LEFT | RIGHT |
(no file at all) | |
| 1 // Copyright 2011 The Go Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style |
| 3 // license that can be found in the LICENSE file. |
| 4 |
| 5 /* |
| 6 Stack layout parameters. |
| 7 Included both by runtime (compiled via 6c) and linkers (compiled via gcc). |
| 8 |
| 9 The per-goroutine g->stackguard is set to point StackGuard bytes |
| 10 above the bottom of the stack. Each function compares its stack |
| 11 pointer against g->stackguard to check for overflow. To cut one |
| 12 instruction from the check sequence for functions with tiny frames, |
| 13 the stack is allowed to protrude StackSmall bytes below the stack |
| 14 guard. Functions with large frames don't bother with the check and |
| 15 always call morestack. The sequences are (for amd64, others are |
| 16 similar): |
| 17 · |
| 18 guard = g->stackguard |
| 19 frame = function's stack frame size |
| 20 argsize = size of function arguments (call + return) |
| 21 |
| 22 stack frame size <= StackSmall: |
| 23 CMPQ guard, SP |
| 24 JHI 3(PC) |
| 25 MOVQ m->morearg, $(argsize << 32) |
| 26 CALL morestack(SB) |
| 27 |
| 28 stack frame size > StackSmall but < StackBig |
| 29 LEAQ (frame-StackSmall)(SP), R0 |
| 30 CMPQ guard, R0 |
| 31 JHI 3(PC) |
| 32 MOVQ m->morearg, $(argsize << 32) |
| 33 CALL morestack(SB) |
| 34 |
| 35 stack frame size >= StackBig: |
| 36 MOVQ m->morearg, $((argsize << 32) | frame) |
| 37 CALL morestack(SB) |
| 38 |
| 39 The bottom StackGuard - StackSmall bytes are important: there has |
| 40 to be enough room to execute functions that refuse to check for |
| 41 stack overflow, either because they need to be adjacent to the |
| 42 actual caller's frame (deferproc) or because they handle the imminent |
| 43 stack overflow (morestack). |
| 44 |
| 45 For example, deferproc might call malloc, which does one of the |
| 46 above checks (without allocating a full frame), which might trigger |
| 47 a call to morestack. This sequence needs to fit in the bottom |
| 48 section of the stack. On amd64, morestack's frame is 40 bytes, and |
| 49 deferproc's frame is 56 bytes. That fits well within the |
| 50 StackGuard - StackSmall = 128 bytes at the bottom.·· |
| 51 The linkers explore all possible call traces involving non-splitting |
| 52 functions to make sure that this limit cannot be violated. |
| 53 */ |
| 54 |
| 55 enum { |
| 56 // The amount of extra stack to allocate beyond the size |
| 57 // needed for the single frame that triggered the split. |
| 58 StackExtra = 1024, |
| 59 |
| 60 // The minimum stack segment size to allocate. |
| 61 // If the amount needed for the splitting frame + StackExtra |
| 62 // is less than this number, the stack will have this size instead. |
| 63 StackMin = 4096, |
| 64 |
| 65 // Functions that need frames bigger than this call morestack |
| 66 // unconditionally. That is, on entry to a function it is assumed |
| 67 // that the amount of space available in the current stack segment |
| 68 // couldn't possibly be bigger than StackBig. If stack segments |
| 69 // do run with more space than StackBig, the space may not be |
| 70 // used efficiently. As a result, StackBig should not be significantly |
| 71 // smaller than StackMin or StackExtra. |
| 72 StackBig = 4096, |
| 73 |
| 74 // The stack guard is a pointer this many bytes above the |
| 75 // bottom of the stack. |
| 76 StackGuard = 256, |
| 77 |
| 78 // After a stack split check the SP is allowed to be this |
| 79 // many bytes below the stack guard. This saves an instruction |
| 80 // in the checking sequence for tiny frames. |
| 81 StackSmall = 128, |
| 82 |
| 83 // The maximum number of bytes that a chain of NOSPLIT |
| 84 // functions can use. |
| 85 StackLimit = StackGuard - StackSmall, |
| 86 }; |
LEFT | RIGHT |