github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/runtime/stack.h (about) 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 // StackSystem is a number of additional bytes to add 57 // to each stack below the usual guard area for OS-specific 58 // purposes like signal handling. Used on Windows and on 59 // Plan 9 because they do not use a separate stack. 60 #ifdef GOOS_windows 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 72 // The amount of extra stack to allocate beyond the size 73 // needed for the single frame that triggered the split. 74 StackExtra = 1024, 75 76 // The minimum stack segment size to allocate. 77 // If the amount needed for the splitting frame + StackExtra 78 // is less than this number, the stack will have this size instead. 79 StackMin = 4096, 80 FixedStack = StackMin + StackSystem, 81 82 // Functions that need frames bigger than this use an extra 83 // instruction to do the stack split check, to avoid overflow 84 // in case SP - framesize wraps below zero. 85 // This value can be no bigger than the size of the unmapped 86 // space at zero. 87 StackBig = 4096, 88 89 // The stack guard is a pointer this many bytes above the 90 // bottom of the stack. 91 StackGuard = 256 + StackSystem, 92 93 // After a stack split check the SP is allowed to be this 94 // many bytes below the stack guard. This saves an instruction 95 // in the checking sequence for tiny frames. 96 StackSmall = 128, 97 98 // The maximum number of bytes that a chain of NOSPLIT 99 // functions can use. 100 StackLimit = StackGuard - StackSystem - StackSmall, 101 102 // The assumed size of the top-of-stack data block. 103 // The actual size can be smaller than this but cannot be larger. 104 // Checked in proc.c's runtime.malg. 105 StackTop = 96, 106 }; 107 108 // Goroutine preemption request. 109 // Stored into g->stackguard0 to cause split stack check failure. 110 // Must be greater than any real sp. 111 // 0xfffffade in hex. 112 #define StackPreempt ((uint64)-1314)