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