LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 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 |
| 5 package runtime |
4 | 6 |
5 /* | 7 /* |
6 Stack layout parameters. | 8 Stack layout parameters. |
7 Included both by runtime (compiled via 6c) and linkers (compiled via gcc). | 9 Included both by runtime (compiled via 6c) and linkers (compiled via gcc). |
8 | 10 |
9 The per-goroutine g->stackguard is set to point StackGuard bytes | 11 The per-goroutine g->stackguard is set to point stackGuard bytes |
10 above the bottom of the stack. Each function compares its stack | 12 above the bottom of the stack. Each function compares its stack |
11 pointer against g->stackguard to check for overflow. To cut one | 13 pointer against g->stackguard to check for overflow. To cut one |
12 instruction from the check sequence for functions with tiny frames, | 14 instruction from the check sequence for functions with tiny frames, |
13 the stack is allowed to protrude StackSmall bytes below the stack | 15 the stack is allowed to protrude stackSmall bytes below the stack |
14 guard. Functions with large frames don't bother with the check and | 16 guard. Functions with large frames don't bother with the check and |
15 always call morestack. The sequences are (for amd64, others are | 17 always call morestack. The sequences are (for amd64, others are |
16 similar): | 18 similar): |
17 | 19 |
18 guard = g->stackguard | 20 guard = g->stackguard |
19 frame = function's stack frame size | 21 frame = function's stack frame size |
20 argsize = size of function arguments (call + return) | 22 argsize = size of function arguments (call + return) |
21 | 23 |
22 » stack frame size <= StackSmall: | 24 » stack frame size <= stackSmall: |
23 CMPQ guard, SP | 25 CMPQ guard, SP |
24 JHI 3(PC) | 26 JHI 3(PC) |
25 MOVQ m->morearg, $(argsize << 32) | 27 MOVQ m->morearg, $(argsize << 32) |
26 CALL morestack(SB) | 28 CALL morestack(SB) |
27 | 29 |
28 » stack frame size > StackSmall but < StackBig | 30 » stack frame size > stackSmall but < stackBig |
29 » » LEAQ (frame-StackSmall)(SP), R0 | 31 » » LEAQ (frame-stackSmall)(SP), R0 |
30 CMPQ guard, R0 | 32 CMPQ guard, R0 |
31 JHI 3(PC) | 33 JHI 3(PC) |
32 MOVQ m->morearg, $(argsize << 32) | 34 MOVQ m->morearg, $(argsize << 32) |
33 CALL morestack(SB) | 35 CALL morestack(SB) |
34 | 36 |
35 » stack frame size >= StackBig: | 37 » stack frame size >= stackBig: |
36 MOVQ m->morearg, $((argsize << 32) | frame) | 38 MOVQ m->morearg, $((argsize << 32) | frame) |
37 CALL morestack(SB) | 39 CALL morestack(SB) |
38 | 40 |
39 The bottom StackGuard - StackSmall bytes are important: there has | 41 The bottom stackGuard - stackSmall bytes are important: there has |
40 to be enough room to execute functions that refuse to check for | 42 to be enough room to execute functions that refuse to check for |
41 stack overflow, either because they need to be adjacent to the | 43 stack overflow, either because they need to be adjacent to the |
42 actual caller's frame (deferproc) or because they handle the imminent | 44 actual caller's frame (deferproc) or because they handle the imminent |
43 stack overflow (morestack). | 45 stack overflow (morestack). |
44 | 46 |
45 For example, deferproc might call malloc, which does one of the | 47 For example, deferproc might call malloc, which does one of the |
46 above checks (without allocating a full frame), which might trigger | 48 above checks (without allocating a full frame), which might trigger |
47 a call to morestack. This sequence needs to fit in the bottom | 49 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 | 50 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 | 51 deferproc's frame is 56 bytes. That fits well within the |
50 StackGuard - StackSmall = 128 bytes at the bottom. | 52 stackGuard - stackSmall = 128 bytes at the bottom. |
51 The linkers explore all possible call traces involving non-splitting | 53 The linkers explore all possible call traces involving non-splitting |
52 functions to make sure that this limit cannot be violated. | 54 functions to make sure that this limit cannot be violated. |
53 */ | 55 */ |
54 | 56 |
55 enum { | 57 const ( |
56 » // StackSystem is a number of additional bytes to add | 58 » // stackSystem is a number of additional bytes to add |
57 // to each stack below the usual guard area for OS-specific | 59 // to each stack below the usual guard area for OS-specific |
58 // purposes like signal handling. Used on Windows and on | 60 // purposes like signal handling. Used on Windows and on |
59 // Plan 9 because they do not use a separate stack. | 61 // Plan 9 because they do not use a separate stack. |
60 #ifdef GOOS_windows | 62 » // Defined in os_*.go. |
61 » StackSystem = 512 * sizeof(uintptr), | |
62 #else | |
63 #ifdef GOOS_plan9 | |
64 » // The size of the note handler frame varies among architectures, | |
65 » // but 512 bytes should be enough for every implementation. | |
66 » StackSystem = 512, | |
67 #else | |
68 » StackSystem = 0, | |
69 #endif» // Plan 9 | |
70 #endif» // Windows | |
71 | 63 |
72 // The amount of extra stack to allocate beyond the size | 64 // The amount of extra stack to allocate beyond the size |
73 // needed for the single frame that triggered the split. | 65 // needed for the single frame that triggered the split. |
74 » StackExtra = 2048, | 66 » stackExtra = 2048 |
75 | 67 |
76 // The minimum stack segment size to allocate. | 68 // The minimum stack segment size to allocate. |
77 » // If the amount needed for the splitting frame + StackExtra | 69 » // If the amount needed for the splitting frame + stackExtra |
78 // is less than this number, the stack will have this size instead. | 70 // is less than this number, the stack will have this size instead. |
79 » StackMin = 8192, | 71 » stackMin = 8192 |
80 » StackSystemRounded = StackSystem + (-StackSystem & (StackMin-1)), | 72 » stackSystemRounded = stackSystem + (-stackSystem & (stackMin - 1)) |
81 » FixedStack = StackMin + StackSystemRounded, | 73 » Fixedstack = stackMin + stackSystemRounded |
82 | 74 |
83 // Functions that need frames bigger than this use an extra | 75 // Functions that need frames bigger than this use an extra |
84 // instruction to do the stack split check, to avoid overflow | 76 // instruction to do the stack split check, to avoid overflow |
85 // in case SP - framesize wraps below zero. | 77 // in case SP - framesize wraps below zero. |
86 // This value can be no bigger than the size of the unmapped | 78 // This value can be no bigger than the size of the unmapped |
87 // space at zero. | 79 // space at zero. |
88 » StackBig = 4096, | 80 » stackBig = 4096 |
89 | 81 |
90 // The stack guard is a pointer this many bytes above the | 82 // The stack guard is a pointer this many bytes above the |
91 // bottom of the stack. | 83 // bottom of the stack. |
92 » StackGuard = 256 + StackSystem, | 84 » stackGuard = 256 + stackSystem |
93 | 85 |
94 // After a stack split check the SP is allowed to be this | 86 // After a stack split check the SP is allowed to be this |
95 // many bytes below the stack guard. This saves an instruction | 87 // many bytes below the stack guard. This saves an instruction |
96 // in the checking sequence for tiny frames. | 88 // in the checking sequence for tiny frames. |
97 » StackSmall = 96, | 89 » stackSmall = 96 |
98 | 90 |
99 // The maximum number of bytes that a chain of NOSPLIT | 91 // The maximum number of bytes that a chain of NOSPLIT |
100 // functions can use. | 92 // functions can use. |
101 » StackLimit = StackGuard - StackSystem - StackSmall, | 93 » stackLimit = stackGuard - stackSystem - stackSmall |
102 » | 94 |
103 // The assumed size of the top-of-stack data block. | 95 // The assumed size of the top-of-stack data block. |
104 // The actual size can be smaller than this but cannot be larger. | 96 // The actual size can be smaller than this but cannot be larger. |
105 // Checked in proc.c's runtime.malg. | 97 // Checked in proc.c's runtime.malg. |
106 » StackTop = 88, | 98 » stackTop = 88 |
107 }; | |
108 | 99 |
109 // Goroutine preemption request. | 100 » // Goroutine preemption request. |
110 // Stored into g->stackguard0 to cause split stack check failure. | 101 » // Stored into g->stackguard0 to cause split stack check failure. |
111 // Must be greater than any real sp. | 102 » // Must be greater than any real sp. |
112 // 0xfffffade in hex. | 103 » // 0xfffffade in hex. |
113 #define StackPreempt ((uint64)-1314) | 104 » stackPreempt = ^uintptr(1313) |
114 /*c2go | 105 ) |
115 enum | |
116 { | |
117 » StackPreempt = -1314, | |
118 }; | |
119 */ | |
LEFT | RIGHT |