Commit 3b0ddadf by Ian Lance Taylor

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

From-SVN: r249561
parent a055692a
73b14da15ec731837ce2a45db658142bfbf5fe22 b5c9fe259ec43f8079581c3bea0f1d12d85213a7
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -1460,8 +1460,8 @@ func dropm() { ...@@ -1460,8 +1460,8 @@ func dropm() {
// gccgo sets the stack to Gdead here, because the splitstack // gccgo sets the stack to Gdead here, because the splitstack
// context is not initialized. // context is not initialized.
atomic.Store(&mp.curg.atomicstatus, _Gdead) atomic.Store(&mp.curg.atomicstatus, _Gdead)
mp.curg.gcstack = nil mp.curg.gcstack = 0
mp.curg.gcnextsp = nil mp.curg.gcnextsp = 0
mnext := lockextra(true) mnext := lockextra(true)
mp.schedlink.set(mnext) mp.schedlink.set(mnext)
...@@ -2591,8 +2591,8 @@ func exitsyscallclear(gp *g) { ...@@ -2591,8 +2591,8 @@ func exitsyscallclear(gp *g) {
// clear syscallsp. // clear syscallsp.
gp.syscallsp = 0 gp.syscallsp = 0
gp.gcstack = nil gp.gcstack = 0
gp.gcnextsp = nil gp.gcnextsp = 0
memclrNoHeapPointers(unsafe.Pointer(&gp.gcregs), unsafe.Sizeof(gp.gcregs)) memclrNoHeapPointers(unsafe.Pointer(&gp.gcregs), unsafe.Sizeof(gp.gcregs))
} }
......
...@@ -402,10 +402,10 @@ type g struct { ...@@ -402,10 +402,10 @@ type g struct {
isforeign bool // whether current exception is not from Go isforeign bool // whether current exception is not from Go
// Fields that hold stack and context information if status is Gsyscall // Fields that hold stack and context information if status is Gsyscall
gcstack unsafe.Pointer gcstack uintptr
gcstacksize uintptr gcstacksize uintptr
gcnextsegment unsafe.Pointer gcnextsegment uintptr
gcnextsp unsafe.Pointer gcnextsp uintptr
gcinitialsp unsafe.Pointer gcinitialsp unsafe.Pointer
gcregs g_ucontext_t gcregs g_ucontext_t
......
...@@ -316,7 +316,7 @@ runtime_mcall(FuncVal *fv) ...@@ -316,7 +316,7 @@ runtime_mcall(FuncVal *fv)
#else #else
// We have to point to an address on the stack that is // We have to point to an address on the stack that is
// below the saved registers. // below the saved registers.
gp->gcnextsp = &afterregs; gp->gcnextsp = (uintptr)(&afterregs);
#endif #endif
gp->fromgogo = false; gp->fromgogo = false;
getcontext(ucontext_arg(&gp->context[0])); getcontext(ucontext_arg(&gp->context[0]));
...@@ -489,7 +489,7 @@ runtime_mstart(void *arg) ...@@ -489,7 +489,7 @@ runtime_mstart(void *arg)
// Setting gcstacksize to 0 is a marker meaning that gcinitialsp // Setting gcstacksize to 0 is a marker meaning that gcinitialsp
// is the top of the stack, not the bottom. // is the top of the stack, not the bottom.
gp->gcstacksize = 0; gp->gcstacksize = 0;
gp->gcnextsp = &arg; gp->gcnextsp = (uintptr)(&arg);
#endif #endif
// Save the currently active context. This will return // Save the currently active context. This will return
...@@ -558,9 +558,9 @@ setGContext() ...@@ -558,9 +558,9 @@ setGContext()
__splitstack_block_signals(&val, nil); __splitstack_block_signals(&val, nil);
#else #else
gp->gcinitialsp = &val; gp->gcinitialsp = &val;
gp->gcstack = nil; gp->gcstack = 0;
gp->gcstacksize = 0; gp->gcstacksize = 0;
gp->gcnextsp = &val; gp->gcnextsp = (uintptr)(&val);
#endif #endif
getcontext(ucontext_arg(&gp->context[0])); getcontext(ucontext_arg(&gp->context[0]));
...@@ -628,16 +628,17 @@ doentersyscall(uintptr pc, uintptr sp) ...@@ -628,16 +628,17 @@ doentersyscall(uintptr pc, uintptr sp)
#ifdef USING_SPLIT_STACK #ifdef USING_SPLIT_STACK
{ {
size_t gcstacksize; size_t gcstacksize;
g->gcstack = __splitstack_find(nil, nil, &gcstacksize, g->gcstack = (uintptr)(__splitstack_find(nil, nil, &gcstacksize,
&g->gcnextsegment, &g->gcnextsp, (void**)(&g->gcnextsegment),
&g->gcinitialsp); (void**)(&g->gcnextsp),
&g->gcinitialsp));
g->gcstacksize = (uintptr)gcstacksize; g->gcstacksize = (uintptr)gcstacksize;
} }
#else #else
{ {
void *v; void *v;
g->gcnextsp = (byte *) &v; g->gcnextsp = (uintptr)(&v);
} }
#endif #endif
...@@ -667,9 +668,10 @@ doentersyscallblock(uintptr pc, uintptr sp) ...@@ -667,9 +668,10 @@ doentersyscallblock(uintptr pc, uintptr sp)
#ifdef USING_SPLIT_STACK #ifdef USING_SPLIT_STACK
{ {
size_t gcstacksize; size_t gcstacksize;
g->gcstack = __splitstack_find(nil, nil, &gcstacksize, g->gcstack = (uintptr)(__splitstack_find(nil, nil, &gcstacksize,
&g->gcnextsegment, &g->gcnextsp, (void**)(&g->gcnextsegment),
&g->gcinitialsp); (void**)(&g->gcnextsp),
&g->gcinitialsp));
g->gcstacksize = (uintptr)gcstacksize; g->gcstacksize = (uintptr)gcstacksize;
} }
#else #else
...@@ -765,7 +767,7 @@ resetNewG(G *newg, void **sp, uintptr *spsize) ...@@ -765,7 +767,7 @@ resetNewG(G *newg, void **sp, uintptr *spsize)
*spsize = newg->gcstacksize; *spsize = newg->gcstacksize;
if(*spsize == 0) if(*spsize == 0)
runtime_throw("bad spsize in resetNewG"); runtime_throw("bad spsize in resetNewG");
newg->gcnextsp = *sp; newg->gcnextsp = (uintptr)(*sp);
#endif #endif
} }
......
...@@ -60,12 +60,12 @@ static void doscanstack1(G *gp, void *gcw) { ...@@ -60,12 +60,12 @@ static void doscanstack1(G *gp, void *gcw) {
// as schedlock and may have needed to start a new stack segment. // as schedlock and may have needed to start a new stack segment.
// Use the stack segment and stack pointer at the time of // Use the stack segment and stack pointer at the time of
// the system call instead, since that won't change underfoot. // the system call instead, since that won't change underfoot.
if(gp->gcstack != nil) { if(gp->gcstack != 0) {
sp = gp->gcstack; sp = (void*)(gp->gcstack);
spsize = gp->gcstacksize; spsize = gp->gcstacksize;
next_segment = gp->gcnextsegment; next_segment = (void*)(gp->gcnextsegment);
next_sp = gp->gcnextsp; next_sp = (void*)(gp->gcnextsp);
initial_sp = gp->gcinitialsp; initial_sp = (void*)(gp->gcinitialsp);
} else { } else {
sp = __splitstack_find_context((void**)(&gp->stackcontext[0]), sp = __splitstack_find_context((void**)(&gp->stackcontext[0]),
&spsize, &next_segment, &spsize, &next_segment,
...@@ -89,11 +89,11 @@ static void doscanstack1(G *gp, void *gcw) { ...@@ -89,11 +89,11 @@ static void doscanstack1(G *gp, void *gcw) {
} else { } else {
// Scanning another goroutine's stack. // Scanning another goroutine's stack.
// The goroutine is usually asleep (the world is stopped). // The goroutine is usually asleep (the world is stopped).
bottom = (byte*)gp->gcnextsp; bottom = (void*)gp->gcnextsp;
if(bottom == nil) if(bottom == nil)
return; return;
} }
top = (byte*)gp->gcinitialsp + gp->gcstacksize; top = (byte*)(void*)(gp->gcinitialsp) + gp->gcstacksize;
if(top > bottom) if(top > bottom)
scanstackblock(bottom, (uintptr)(top - bottom), gcw); scanstackblock(bottom, (uintptr)(top - bottom), gcw);
else else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment