From 2386202283cf3daa799f87f01f30f4bafdca79c6 Mon Sep 17 00:00:00 2001 From: ian Date: Thu, 22 Jun 2017 14:44:30 +0000 Subject: [PATCH] runtime: change some stack fields to uintptr Because of how gccgo implements cgo calls, the code in dropm may not have any write barriers. As a step toward implementing that, change the gcstack, gcnextsegment, and gcnextsp fields of the g struct to uintptr, so that assignments to them do not require write barriers. The gcinitialsp field remains unsafe.Pointer, as on 32-bit systems that do not support split stack it points to a heap allocated space used for the goroutine stack. The test for this is runtime tests like TestCgoCallbackGC, which are not run today but will be run with a future gotools patch. Reviewed-on: https://go-review.googlesource.com/46396 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@249561 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/go/gofrontend/MERGE | 2 +- libgo/go/runtime/proc.go | 8 ++++---- libgo/go/runtime/runtime2.go | 6 +++--- libgo/runtime/proc.c | 26 ++++++++++++++------------ libgo/runtime/stack.c | 14 +++++++------- 5 files changed, 29 insertions(+), 27 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index a8dba3608d0..942752b1020 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -73b14da15ec731837ce2a45db658142bfbf5fe22 +b5c9fe259ec43f8079581c3bea0f1d12d85213a7 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go index 32bc14832b8..066d0e52de6 100644 --- a/libgo/go/runtime/proc.go +++ b/libgo/go/runtime/proc.go @@ -1460,8 +1460,8 @@ func dropm() { // gccgo sets the stack to Gdead here, because the splitstack // context is not initialized. atomic.Store(&mp.curg.atomicstatus, _Gdead) - mp.curg.gcstack = nil - mp.curg.gcnextsp = nil + mp.curg.gcstack = 0 + mp.curg.gcnextsp = 0 mnext := lockextra(true) mp.schedlink.set(mnext) @@ -2591,8 +2591,8 @@ func exitsyscallclear(gp *g) { // clear syscallsp. gp.syscallsp = 0 - gp.gcstack = nil - gp.gcnextsp = nil + gp.gcstack = 0 + gp.gcnextsp = 0 memclrNoHeapPointers(unsafe.Pointer(&gp.gcregs), unsafe.Sizeof(gp.gcregs)) } diff --git a/libgo/go/runtime/runtime2.go b/libgo/go/runtime/runtime2.go index f532a3b2ba9..96a4edb83d4 100644 --- a/libgo/go/runtime/runtime2.go +++ b/libgo/go/runtime/runtime2.go @@ -402,10 +402,10 @@ type g struct { isforeign bool // whether current exception is not from Go // Fields that hold stack and context information if status is Gsyscall - gcstack unsafe.Pointer + gcstack uintptr gcstacksize uintptr - gcnextsegment unsafe.Pointer - gcnextsp unsafe.Pointer + gcnextsegment uintptr + gcnextsp uintptr gcinitialsp unsafe.Pointer gcregs g_ucontext_t diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c index 14ee673dc47..303a1b580b3 100644 --- a/libgo/runtime/proc.c +++ b/libgo/runtime/proc.c @@ -316,7 +316,7 @@ runtime_mcall(FuncVal *fv) #else // We have to point to an address on the stack that is // below the saved registers. - gp->gcnextsp = &afterregs; + gp->gcnextsp = (uintptr)(&afterregs); #endif gp->fromgogo = false; getcontext(ucontext_arg(&gp->context[0])); @@ -489,7 +489,7 @@ runtime_mstart(void *arg) // Setting gcstacksize to 0 is a marker meaning that gcinitialsp // is the top of the stack, not the bottom. gp->gcstacksize = 0; - gp->gcnextsp = &arg; + gp->gcnextsp = (uintptr)(&arg); #endif // Save the currently active context. This will return @@ -558,9 +558,9 @@ setGContext() __splitstack_block_signals(&val, nil); #else gp->gcinitialsp = &val; - gp->gcstack = nil; + gp->gcstack = 0; gp->gcstacksize = 0; - gp->gcnextsp = &val; + gp->gcnextsp = (uintptr)(&val); #endif getcontext(ucontext_arg(&gp->context[0])); @@ -628,16 +628,17 @@ doentersyscall(uintptr pc, uintptr sp) #ifdef USING_SPLIT_STACK { size_t gcstacksize; - g->gcstack = __splitstack_find(nil, nil, &gcstacksize, - &g->gcnextsegment, &g->gcnextsp, - &g->gcinitialsp); + g->gcstack = (uintptr)(__splitstack_find(nil, nil, &gcstacksize, + (void**)(&g->gcnextsegment), + (void**)(&g->gcnextsp), + &g->gcinitialsp)); g->gcstacksize = (uintptr)gcstacksize; } #else { void *v; - g->gcnextsp = (byte *) &v; + g->gcnextsp = (uintptr)(&v); } #endif @@ -667,9 +668,10 @@ doentersyscallblock(uintptr pc, uintptr sp) #ifdef USING_SPLIT_STACK { size_t gcstacksize; - g->gcstack = __splitstack_find(nil, nil, &gcstacksize, - &g->gcnextsegment, &g->gcnextsp, - &g->gcinitialsp); + g->gcstack = (uintptr)(__splitstack_find(nil, nil, &gcstacksize, + (void**)(&g->gcnextsegment), + (void**)(&g->gcnextsp), + &g->gcinitialsp)); g->gcstacksize = (uintptr)gcstacksize; } #else @@ -765,7 +767,7 @@ resetNewG(G *newg, void **sp, uintptr *spsize) *spsize = newg->gcstacksize; if(*spsize == 0) runtime_throw("bad spsize in resetNewG"); - newg->gcnextsp = *sp; + newg->gcnextsp = (uintptr)(*sp); #endif } diff --git a/libgo/runtime/stack.c b/libgo/runtime/stack.c index 1ce30db00cd..900ca64b7f7 100644 --- a/libgo/runtime/stack.c +++ b/libgo/runtime/stack.c @@ -60,12 +60,12 @@ static void doscanstack1(G *gp, void *gcw) { // as schedlock and may have needed to start a new stack segment. // Use the stack segment and stack pointer at the time of // the system call instead, since that won't change underfoot. - if(gp->gcstack != nil) { - sp = gp->gcstack; + if(gp->gcstack != 0) { + sp = (void*)(gp->gcstack); spsize = gp->gcstacksize; - next_segment = gp->gcnextsegment; - next_sp = gp->gcnextsp; - initial_sp = gp->gcinitialsp; + next_segment = (void*)(gp->gcnextsegment); + next_sp = (void*)(gp->gcnextsp); + initial_sp = (void*)(gp->gcinitialsp); } else { sp = __splitstack_find_context((void**)(&gp->stackcontext[0]), &spsize, &next_segment, @@ -89,11 +89,11 @@ static void doscanstack1(G *gp, void *gcw) { } else { // Scanning another goroutine's stack. // The goroutine is usually asleep (the world is stopped). - bottom = (byte*)gp->gcnextsp; + bottom = (void*)gp->gcnextsp; if(bottom == nil) return; } - top = (byte*)gp->gcinitialsp + gp->gcstacksize; + top = (byte*)(void*)(gp->gcinitialsp) + gp->gcstacksize; if(top > bottom) scanstackblock(bottom, (uintptr)(top - bottom), gcw); else -- 2.11.4.GIT