mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
5l, 6l, 8l: fix stack split logic for stacks near default segment size
Fixes #3310. R=golang-dev, r CC=golang-dev https://golang.org/cl/5823051
This commit is contained in:
parent
b7b3652414
commit
9e5db8c90a
10 changed files with 1587 additions and 8 deletions
|
|
@ -226,8 +226,7 @@ noops(void)
|
|||
p->as = AMOVW;
|
||||
p->scond = C_SCOND_LO;
|
||||
p->from.type = D_CONST;
|
||||
/* 160 comes from 3 calls (3*8) 4 safes (4*8) and 104 guard */
|
||||
p->from.offset = autosize+160;
|
||||
p->from.offset = autosize;
|
||||
p->to.type = D_REG;
|
||||
p->to.reg = 1;
|
||||
|
||||
|
|
|
|||
|
|
@ -501,10 +501,17 @@ dostkoff(void)
|
|||
q = p;
|
||||
}
|
||||
|
||||
/* 160 comes from 3 calls (3*8) 4 safes (4*8) and 104 guard */
|
||||
// If we ask for more stack, we'll get a minimum of StackMin bytes.
|
||||
// We need a stack frame large enough to hold the top-of-stack data,
|
||||
// the function arguments+results, our caller's PC, our frame,
|
||||
// a word for the return PC of the next call, and then the StackLimit bytes
|
||||
// that must be available on entry to any function called from a function
|
||||
// that did a stack check. If StackMin is enough, don't ask for a specific
|
||||
// amount: then we can use the custom functions and save a few
|
||||
// instructions.
|
||||
moreconst1 = 0;
|
||||
if(autoffset+160+textarg > 4096)
|
||||
moreconst1 = (autoffset+160) & ~7LL;
|
||||
if(StackTop + textarg + PtrSize + autoffset + PtrSize + StackLimit >= StackMin)
|
||||
moreconst1 = autoffset;
|
||||
moreconst2 = textarg;
|
||||
|
||||
// 4 varieties varieties (const1==0 cross const2==0)
|
||||
|
|
|
|||
|
|
@ -527,10 +527,18 @@ dostkoff(void)
|
|||
p = appendp(p); // save frame size in DX
|
||||
p->as = AMOVL;
|
||||
p->to.type = D_DX;
|
||||
/* 160 comes from 3 calls (3*8) 4 safes (4*8) and 104 guard */
|
||||
p->from.type = D_CONST;
|
||||
if(autoffset+160+cursym->text->to.offset2 > 4096)
|
||||
p->from.offset = (autoffset+160) & ~7LL;
|
||||
|
||||
// If we ask for more stack, we'll get a minimum of StackMin bytes.
|
||||
// We need a stack frame large enough to hold the top-of-stack data,
|
||||
// the function arguments+results, our caller's PC, our frame,
|
||||
// a word for the return PC of the next call, and then the StackLimit bytes
|
||||
// that must be available on entry to any function called from a function
|
||||
// that did a stack check. If StackMin is enough, don't ask for a specific
|
||||
// amount: then we can use the custom functions and save a few
|
||||
// instructions.
|
||||
if(StackTop + cursym->text->to.offset2 + PtrSize + autoffset + PtrSize + StackLimit >= StackMin)
|
||||
p->from.offset = (autoffset+7) & ~7LL;
|
||||
|
||||
p = appendp(p); // save arg size in AX
|
||||
p->as = AMOVL;
|
||||
|
|
|
|||
|
|
@ -560,4 +560,13 @@ TEXT runtime·emptyfunc(SB),0,$0
|
|||
TEXT runtime·abort(SB),7,$0
|
||||
INT $0x3
|
||||
|
||||
TEXT runtime·stackguard(SB),7,$0
|
||||
MOVL SP, DX
|
||||
MOVL DX, sp+0(FP)
|
||||
get_tls(CX)
|
||||
MOVL g(CX), BX
|
||||
MOVL g_stackguard(BX), DX
|
||||
MOVL DX, guard+4(FP)
|
||||
RET
|
||||
|
||||
GLOBL runtime·tls0(SB), $32
|
||||
|
|
|
|||
|
|
@ -587,4 +587,13 @@ TEXT runtime·cputicks(SB),7,$0
|
|||
ADDQ DX, AX
|
||||
RET
|
||||
|
||||
TEXT runtime·stackguard(SB),7,$0
|
||||
MOVQ SP, DX
|
||||
MOVQ DX, sp+0(FP)
|
||||
get_tls(CX)
|
||||
MOVQ g(CX), BX
|
||||
MOVQ g_stackguard(BX), DX
|
||||
MOVQ DX, guard+8(FP)
|
||||
RET
|
||||
|
||||
GLOBL runtime·tls0(SB), $64
|
||||
|
|
|
|||
|
|
@ -313,3 +313,10 @@ casl:
|
|||
casfail:
|
||||
MOVW $0, R0
|
||||
RET
|
||||
|
||||
TEXT runtime·stackguard(SB),7,$0
|
||||
MOVL R13, R1
|
||||
MOVL g_stackguard(g), R2
|
||||
MOVL R1, sp+0(FP)
|
||||
MOVL R2, limit+4(FP)
|
||||
RET
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@ var F64toint = f64toint
|
|||
func entersyscall()
|
||||
func exitsyscall()
|
||||
func golockedOSThread() bool
|
||||
func stackguard() (sp, limit uintptr)
|
||||
|
||||
var Entersyscall = entersyscall
|
||||
var Exitsyscall = exitsyscall
|
||||
var LockedOSThread = golockedOSThread
|
||||
var Stackguard = stackguard
|
||||
|
|
|
|||
|
|
@ -1161,6 +1161,11 @@ runtime·malg(int32 stacksize)
|
|||
{
|
||||
G *newg;
|
||||
byte *stk;
|
||||
|
||||
if(StackTop < sizeof(Stktop)) {
|
||||
runtime·printf("runtime: SizeofStktop=%d, should be >=%d\n", (int32)StackTop, (int32)sizeof(Stktop));
|
||||
runtime·throw("runtime: bad stack.h");
|
||||
}
|
||||
|
||||
newg = runtime·malloc(sizeof(G));
|
||||
if(stacksize >= 0) {
|
||||
|
|
|
|||
|
|
@ -94,4 +94,9 @@ enum {
|
|||
// The maximum number of bytes that a chain of NOSPLIT
|
||||
// functions can use.
|
||||
StackLimit = StackGuard - StackSystem - StackSmall,
|
||||
|
||||
// The assumed size of the top-of-stack data block.
|
||||
// The actual size can be smaller than this but cannot be larger.
|
||||
// Checked in proc.c's runtime.malg.
|
||||
StackTop = 72,
|
||||
};
|
||||
|
|
|
|||
1528
src/pkg/runtime/stack_test.go
Normal file
1528
src/pkg/runtime/stack_test.go
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue