runtime: change some stack fields to uintptr
authorIan Lance Taylor <ian@gcc.gnu.org>
Thu, 22 Jun 2017 14:44:30 +0000 (14:44 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 22 Jun 2017 14:44:30 +0000 (14:44 +0000)
    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

gcc/go/gofrontend/MERGE
libgo/go/runtime/proc.go
libgo/go/runtime/runtime2.go
libgo/runtime/proc.c
libgo/runtime/stack.c

index a8dba3608d0660187ed59821d46690e105551cef..942752b10205c50d28bc72b0a9b681b6182e640b 100644 (file)
@@ -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.
index 32bc14832b8d4d5092fa9676267d2d7961393d95..066d0e52de6ee411e58eb61b44fc32352546f713 100644 (file)
@@ -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))
 }
 
index f532a3b2ba9d1ee5bf78649cf72c1a916c4846e5..96a4edb83d4445b57ebd2ffdd045d03009ed50fd 100644 (file)
@@ -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
 
index 14ee673dc47e94fd4e17ab3d012032e6c6898922..303a1b580b354069e0e5c38ff1917984f183afbe 100644 (file)
@@ -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
 }
 
index 1ce30db00cdc103e1ca80c069b85963f175b0849..900ca64b7f7d3f8b99faea92b3446c79b56ae2fc 100644 (file)
@@ -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