Skip to content

Commit db2e73f

Browse files
nodirtbradfitz
authored andcommitted
runtime: merge stack{1,2}.go -> stack.go
* rename stack1.go -> stack.go * prepend contents of stack2.go to stack.go Updates #12952 Change-Id: I60d409af37162a5a7596c678dfebc2cea89564ff Reviewed-on: https://go-review.googlesource.com/16008 Reviewed-by: Austin Clements <austin@google.com> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
1 parent 69a99cc commit db2e73f

File tree

2 files changed

+101
-106
lines changed

2 files changed

+101
-106
lines changed

src/runtime/stack1.go renamed to src/runtime/stack.go

+101
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,107 @@ package runtime
66

77
import "unsafe"
88

9+
/*
10+
Stack layout parameters.
11+
Included both by runtime (compiled via 6c) and linkers (compiled via gcc).
12+
13+
The per-goroutine g->stackguard is set to point StackGuard bytes
14+
above the bottom of the stack. Each function compares its stack
15+
pointer against g->stackguard to check for overflow. To cut one
16+
instruction from the check sequence for functions with tiny frames,
17+
the stack is allowed to protrude StackSmall bytes below the stack
18+
guard. Functions with large frames don't bother with the check and
19+
always call morestack. The sequences are (for amd64, others are
20+
similar):
21+
22+
guard = g->stackguard
23+
frame = function's stack frame size
24+
argsize = size of function arguments (call + return)
25+
26+
stack frame size <= StackSmall:
27+
CMPQ guard, SP
28+
JHI 3(PC)
29+
MOVQ m->morearg, $(argsize << 32)
30+
CALL morestack(SB)
31+
32+
stack frame size > StackSmall but < StackBig
33+
LEAQ (frame-StackSmall)(SP), R0
34+
CMPQ guard, R0
35+
JHI 3(PC)
36+
MOVQ m->morearg, $(argsize << 32)
37+
CALL morestack(SB)
38+
39+
stack frame size >= StackBig:
40+
MOVQ m->morearg, $((argsize << 32) | frame)
41+
CALL morestack(SB)
42+
43+
The bottom StackGuard - StackSmall bytes are important: there has
44+
to be enough room to execute functions that refuse to check for
45+
stack overflow, either because they need to be adjacent to the
46+
actual caller's frame (deferproc) or because they handle the imminent
47+
stack overflow (morestack).
48+
49+
For example, deferproc might call malloc, which does one of the
50+
above checks (without allocating a full frame), which might trigger
51+
a call to morestack. This sequence needs to fit in the bottom
52+
section of the stack. On amd64, morestack's frame is 40 bytes, and
53+
deferproc's frame is 56 bytes. That fits well within the
54+
StackGuard - StackSmall bytes at the bottom.
55+
The linkers explore all possible call traces involving non-splitting
56+
functions to make sure that this limit cannot be violated.
57+
*/
58+
59+
const (
60+
// StackSystem is a number of additional bytes to add
61+
// to each stack below the usual guard area for OS-specific
62+
// purposes like signal handling. Used on Windows, Plan 9,
63+
// and Darwin/ARM because they do not use a separate stack.
64+
_StackSystem = goos_windows*512*ptrSize + goos_plan9*512 + goos_darwin*goarch_arm*1024
65+
66+
// The minimum size of stack used by Go code
67+
_StackMin = 2048
68+
69+
// The minimum stack size to allocate.
70+
// The hackery here rounds FixedStack0 up to a power of 2.
71+
_FixedStack0 = _StackMin + _StackSystem
72+
_FixedStack1 = _FixedStack0 - 1
73+
_FixedStack2 = _FixedStack1 | (_FixedStack1 >> 1)
74+
_FixedStack3 = _FixedStack2 | (_FixedStack2 >> 2)
75+
_FixedStack4 = _FixedStack3 | (_FixedStack3 >> 4)
76+
_FixedStack5 = _FixedStack4 | (_FixedStack4 >> 8)
77+
_FixedStack6 = _FixedStack5 | (_FixedStack5 >> 16)
78+
_FixedStack = _FixedStack6 + 1
79+
80+
// Functions that need frames bigger than this use an extra
81+
// instruction to do the stack split check, to avoid overflow
82+
// in case SP - framesize wraps below zero.
83+
// This value can be no bigger than the size of the unmapped
84+
// space at zero.
85+
_StackBig = 4096
86+
87+
// The stack guard is a pointer this many bytes above the
88+
// bottom of the stack.
89+
_StackGuard = 640*stackGuardMultiplier + _StackSystem
90+
91+
// After a stack split check the SP is allowed to be this
92+
// many bytes below the stack guard. This saves an instruction
93+
// in the checking sequence for tiny frames.
94+
_StackSmall = 128
95+
96+
// The maximum number of bytes that a chain of NOSPLIT
97+
// functions can use.
98+
_StackLimit = _StackGuard - _StackSystem - _StackSmall
99+
)
100+
101+
// Goroutine preemption request.
102+
// Stored into g->stackguard0 to cause split stack check failure.
103+
// Must be greater than any real sp.
104+
// 0xfffffade in hex.
105+
const (
106+
_StackPreempt = uintptrMask & -1314
107+
_StackFork = uintptrMask & -1234
108+
)
109+
9110
const (
10111
// stackDebug == 0: no logging
11112
// == 1: logging of per-stack operations

src/runtime/stack2.go

-106
This file was deleted.

0 commit comments

Comments
 (0)