runtime: add stackguard0 to G This is part of preemptive scheduler. stackguard0 is checked in split stack checks and can be set to StackPreempt. stackguard is not set to StackPreempt (holds the original value). R=golang-dev, daniel.morsing, iant CC=golang-dev https://golang.org/cl/9875043
diff --git a/src/pkg/runtime/asm_386.s b/src/pkg/runtime/asm_386.s index 58fa6d6..85b5008 100644 --- a/src/pkg/runtime/asm_386.s +++ b/src/pkg/runtime/asm_386.s
@@ -18,6 +18,7 @@ MOVL $runtime·g0(SB), BP LEAL (-64*1024+104)(SP), BX MOVL BX, g_stackguard(BP) + MOVL BX, g_stackguard0(BP) MOVL SP, g_stackbase(BP) // find out information about the processor we're on @@ -41,6 +42,10 @@ MOVL BX, 4(SP) MOVL BP, 0(SP) CALL AX + // update stackguard after _cgo_init + MOVL $runtime·g0(SB), CX + MOVL g_stackguard0(CX), AX + MOVL AX, g_stackguard(CX) // skip runtime·ldt0setup(SB) and tls test after _cgo_init for non-windows CMPL runtime·iswindows(SB), $0 JEQ ok
diff --git a/src/pkg/runtime/asm_amd64.s b/src/pkg/runtime/asm_amd64.s index f779b94..af83c03 100644 --- a/src/pkg/runtime/asm_amd64.s +++ b/src/pkg/runtime/asm_amd64.s
@@ -18,6 +18,7 @@ MOVQ $runtime·g0(SB), DI LEAQ (-64*1024+104)(SP), BX MOVQ BX, g_stackguard(DI) + MOVQ BX, g_stackguard0(DI) MOVQ SP, g_stackbase(DI) // find out information about the processor we're on @@ -39,6 +40,10 @@ MOVQ DI, CX // Win64 uses CX for first parameter MOVQ $setmg_gcc<>(SB), SI CALL AX + // update stackguard after _cgo_init + MOVQ $runtime·g0(SB), CX + MOVQ g_stackguard0(CX), AX + MOVQ AX, g_stackguard(CX) CMPL runtime·iswindows(SB), $0 JEQ ok
diff --git a/src/pkg/runtime/asm_arm.s b/src/pkg/runtime/asm_arm.s index fed9b30..d4bcbd5 100644 --- a/src/pkg/runtime/asm_arm.s +++ b/src/pkg/runtime/asm_arm.s
@@ -28,6 +28,7 @@ // create istack out of the OS stack MOVW $(-8192+104)(R13), R0 MOVW R0, g_stackguard(g) // (w 104b guard) + MOVW R0, g_stackguard0(g) MOVW R13, g_stackbase(g) BL runtime·emptyfunc(SB) // fault if stack check is wrong @@ -36,6 +37,9 @@ CMP $0, R2 MOVW.NE g, R0 // first argument of _cgo_init is g BL.NE (R2) // will clobber R0-R3 + // update stackguard after _cgo_init + MOVW g_stackguard0(g), R0 + MOVW R0, g_stackguard(g) BL runtime·checkgoarm(SB) BL runtime·check(SB)
diff --git a/src/pkg/runtime/panic.c b/src/pkg/runtime/panic.c index ecce93f..18e4779 100644 --- a/src/pkg/runtime/panic.c +++ b/src/pkg/runtime/panic.c
@@ -298,6 +298,7 @@ break; gp->stackbase = (uintptr)top->stackbase; gp->stackguard = (uintptr)top->stackguard; + gp->stackguard0 = gp->stackguard; if(top->free != 0) runtime·stackfree(stk, top->free); }
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c index c7a8d24..206a3cb 100644 --- a/src/pkg/runtime/proc.c +++ b/src/pkg/runtime/proc.c
@@ -468,6 +468,7 @@ // so other calls can reuse this stack space. runtime·gosave(&m->g0->sched); m->g0->sched.pc = (void*)-1; // make sure it is never used + m->g0->stackguard = m->g0->stackguard0; // cgo sets only stackguard0, copy it to stackguard m->seh = &seh; runtime·asminit(); runtime·minit(); @@ -615,6 +616,7 @@ runtime·setmg(mp, mp->g0); g->stackbase = (uintptr)(&x + 1024); g->stackguard = (uintptr)(&x - 32*1024); + g->stackguard0 = g->stackguard; // On windows/386, we need to put an SEH frame (two words) // somewhere on the current stack. We are called @@ -979,6 +981,7 @@ runtime·throw("execute: bad g status"); } gp->status = Grunning; + gp->stackguard0 = gp->stackguard; m->p->tick++; m->curg = gp; gp->m = m; @@ -1465,6 +1468,7 @@ } newg->stack0 = (uintptr)stk; newg->stackguard = (uintptr)stk + StackGuard; + newg->stackguard0 = newg->stackguard; newg->stackbase = (uintptr)stk + StackSystem + stacksize - sizeof(Stktop); runtime·memclr((byte*)newg->stackbase, sizeof(Stktop)); }
diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h index 2d918f4..e616990 100644 --- a/src/pkg/runtime/runtime.h +++ b/src/pkg/runtime/runtime.h
@@ -226,7 +226,8 @@ }; struct G { - uintptr stackguard; // cannot move - also known to linker, libmach, runtime/cgo + // stackguard0 can be set to StackPreempt as opposed to stackguard + uintptr stackguard0; // cannot move - also known to linker, libmach, runtime/cgo uintptr stackbase; // cannot move - also known to libmach, runtime/cgo Defer* defer; Panic* panic; @@ -235,6 +236,7 @@ uintptr gcsp; // if status==Gsyscall, gcsp = sched.sp to use during gc byte* gcpc; // if status==Gsyscall, gcpc = sched.pc to use during gc uintptr gcguard; // if status==Gsyscall, gcguard = stackguard to use during gc + uintptr stackguard; // same as stackguard0, but not set to StackPreempt uintptr stack0; FuncVal* fnstart; // initial function G* alllink; // on allg
diff --git a/src/pkg/runtime/stack.c b/src/pkg/runtime/stack.c index b6f64aa..a033d6b 100644 --- a/src/pkg/runtime/stack.c +++ b/src/pkg/runtime/stack.c
@@ -157,6 +157,7 @@ label = top->gobuf; gp->stackbase = (uintptr)top->stackbase; gp->stackguard = (uintptr)top->stackguard; + gp->stackguard0 = gp->stackguard; if(top->free != 0) runtime·stackfree(old, top->free); @@ -249,6 +250,7 @@ gp->stackbase = (uintptr)top; gp->stackguard = (uintptr)stk + StackGuard; + gp->stackguard0 = gp->stackguard; sp = (byte*)top; if(argsize > 0) {