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.
Change-Id: I1c9ff83829802f011d143e97b5060e1dd9432d6a
Reviewed-on: https://go-review.googlesource.com/46396
Reviewed-by: Than McIntosh <thanm@google.com>
diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go
index 32bc148..066d0e5 100644
--- a/libgo/go/runtime/proc.go
+++ b/libgo/go/runtime/proc.go
@@ -1460,8 +1460,8 @@
// 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 @@
// 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 f532a3b..96a4edb 100644
--- a/libgo/go/runtime/runtime2.go
+++ b/libgo/go/runtime/runtime2.go
@@ -402,10 +402,10 @@
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 14ee673..303a1b5 100644
--- a/libgo/runtime/proc.c
+++ b/libgo/runtime/proc.c
@@ -316,7 +316,7 @@
#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 @@
// 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 @@
__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 @@
#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 @@
#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 @@
*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 1ce30db..900ca64 100644
--- a/libgo/runtime/stack.c
+++ b/libgo/runtime/stack.c
@@ -60,12 +60,12 @@
// 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 @@
} 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