diff options
Diffstat (limited to 'src/runtime/stack.h')
-rw-r--r-- | src/runtime/stack.h | 97 |
1 files changed, 2 insertions, 95 deletions
diff --git a/src/runtime/stack.h b/src/runtime/stack.h index f97dc4ed8..0099d05c2 100644 --- a/src/runtime/stack.h +++ b/src/runtime/stack.h @@ -2,117 +2,24 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -/* -Stack layout parameters. -Included both by runtime (compiled via 6c) and linkers (compiled via gcc). - -The per-goroutine g->stackguard is set to point StackGuard bytes -above the bottom of the stack. Each function compares its stack -pointer against g->stackguard to check for overflow. To cut one -instruction from the check sequence for functions with tiny frames, -the stack is allowed to protrude StackSmall bytes below the stack -guard. Functions with large frames don't bother with the check and -always call morestack. The sequences are (for amd64, others are -similar): - - guard = g->stackguard - frame = function's stack frame size - argsize = size of function arguments (call + return) - - stack frame size <= StackSmall: - CMPQ guard, SP - JHI 3(PC) - MOVQ m->morearg, $(argsize << 32) - CALL morestack(SB) - - stack frame size > StackSmall but < StackBig - LEAQ (frame-StackSmall)(SP), R0 - CMPQ guard, R0 - JHI 3(PC) - MOVQ m->morearg, $(argsize << 32) - CALL morestack(SB) - - stack frame size >= StackBig: - MOVQ m->morearg, $((argsize << 32) | frame) - CALL morestack(SB) - -The bottom StackGuard - StackSmall bytes are important: there has -to be enough room to execute functions that refuse to check for -stack overflow, either because they need to be adjacent to the -actual caller's frame (deferproc) or because they handle the imminent -stack overflow (morestack). - -For example, deferproc might call malloc, which does one of the -above checks (without allocating a full frame), which might trigger -a call to morestack. This sequence needs to fit in the bottom -section of the stack. On amd64, morestack's frame is 40 bytes, and -deferproc's frame is 56 bytes. That fits well within the -StackGuard - StackSmall bytes at the bottom. -The linkers explore all possible call traces involving non-splitting -functions to make sure that this limit cannot be violated. - */ +// For the linkers. Must match Go definitions. +// TODO(rsc): Share Go definitions with linkers directly. enum { - // StackSystem is a number of additional bytes to add - // to each stack below the usual guard area for OS-specific - // purposes like signal handling. Used on Windows and on - // Plan 9 because they do not use a separate stack. #ifdef GOOS_windows StackSystem = 512 * sizeof(uintptr), #else #ifdef GOOS_plan9 - // The size of the note handler frame varies among architectures, - // but 512 bytes should be enough for every implementation. StackSystem = 512, #else StackSystem = 0, #endif // Plan 9 #endif // Windows - // The minimum size of stack used by Go code - StackMin = 2048, - - // The minimum stack size to allocate. - // The hackery here rounds FixedStack0 up to a power of 2. - FixedStack0 = StackMin + StackSystem, - FixedStack1 = FixedStack0 - 1, - FixedStack2 = FixedStack1 | (FixedStack1 >> 1), - FixedStack3 = FixedStack2 | (FixedStack2 >> 2), - FixedStack4 = FixedStack3 | (FixedStack3 >> 4), - FixedStack5 = FixedStack4 | (FixedStack4 >> 8), - FixedStack6 = FixedStack5 | (FixedStack5 >> 16), - FixedStack = FixedStack6 + 1, - - // Functions that need frames bigger than this use an extra - // instruction to do the stack split check, to avoid overflow - // in case SP - framesize wraps below zero. - // This value can be no bigger than the size of the unmapped - // space at zero. StackBig = 4096, - - // The stack guard is a pointer this many bytes above the - // bottom of the stack. StackGuard = 512 + StackSystem, - - // After a stack split check the SP is allowed to be this - // many bytes below the stack guard. This saves an instruction - // in the checking sequence for tiny frames. StackSmall = 128, - - // The maximum number of bytes that a chain of NOSPLIT - // functions can use. StackLimit = StackGuard - StackSystem - StackSmall, }; -// Goroutine preemption request. -// Stored into g->stackguard0 to cause split stack check failure. -// Must be greater than any real sp. -// 0xfffffade in hex. #define StackPreempt ((uint64)-1314) -/*c2go -enum -{ - StackPreempt = -1314, -}; -*/ -#define StackFork ((uint64)-1234) |