]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: round stack size to power of 2.
authorShenghou Ma <minux.ma@gmail.com>
Fri, 7 Mar 2014 20:11:16 +0000 (15:11 -0500)
committerShenghou Ma <minux.ma@gmail.com>
Fri, 7 Mar 2014 20:11:16 +0000 (15:11 -0500)
Fixes build on windows/386 and plan9/386.
Fixes #7487.

LGTM=mattn.jp, dvyukov, rsc
R=golang-codereviews, mattn.jp, dvyukov, 0intro, rsc
CC=golang-codereviews
https://golang.org/cl/72360043

src/pkg/runtime/proc.c
src/pkg/runtime/runtime.c
src/pkg/runtime/runtime.h
src/pkg/runtime/stack.c
src/pkg/runtime/stack.h

index bf55912783d5c91bc7867a32e19f364e0499b05f..eb7dfe4f84d8530401571910947e3a212758cc00 100644 (file)
@@ -1751,12 +1751,13 @@ runtime·malg(int32 stacksize)
 
        newg = runtime·malloc(sizeof(G));
        if(stacksize >= 0) {
+               stacksize = runtime·round2(StackSystem + stacksize);
                if(g == m->g0) {
                        // running on scheduler stack already.
-                       stk = runtime·stackalloc(newg, StackSystem + stacksize);
+                       stk = runtime·stackalloc(newg, stacksize);
                } else {
                        // have to call stackalloc on scheduler stack.
-                       newg->stacksize = StackSystem + stacksize;
+                       newg->stacksize = stacksize;
                        g->param = newg;
                        runtime·mcall(mstackalloc);
                        stk = g->param;
@@ -1765,7 +1766,7 @@ runtime·malg(int32 stacksize)
                newg->stack0 = (uintptr)stk;
                newg->stackguard = (uintptr)stk + StackGuard;
                newg->stackguard0 = newg->stackguard;
-               newg->stackbase = (uintptr)stk + StackSystem + stacksize - sizeof(Stktop);
+               newg->stackbase = (uintptr)stk + stacksize - sizeof(Stktop);
        }
        return newg;
 }
index 08a395fbe29b3cde32ef851adbbbd4b34060be88..2198bc68507faa44cc364022fb077743de325c98 100644 (file)
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 #include "runtime.h"
+#include "stack.h"
 #include "arch_GOARCH.h"
 #include "../../cmd/ld/textflag.h"
 
@@ -256,6 +257,9 @@ runtime·check(void)
                runtime·throw("float32nan3");
 
        TestAtomic64();
+
+       if(FixedStack != runtime·round2(FixedStack))
+               runtime·throw("FixedStack is not power-of-2");
 }
 
 uint32
index 4415f550d4de792c77a2c4f5af93ba5869e8d5a3..716071eb83f98658069b54777072452097f68d15 100644 (file)
@@ -900,6 +900,7 @@ void        runtime·mcall(void(*)(G*));
 uint32 runtime·fastrand1(void);
 void   runtime·rewindmorestack(Gobuf*);
 int32  runtime·timediv(int64, int32, int32*);
+int32  runtime·round2(int32 x); // round x up to a power of 2.
 
 // atomic operations
 bool   runtime·cas(uint32*, uint32, uint32);
index d1ba2bfdb9bef86f0096d7567ba3ab80715819e2..ead9ba59c1f20c07533f285ec519e5754afdc431 100644 (file)
@@ -555,8 +555,8 @@ copystack(G *gp, uintptr nframes, uintptr newsize)
 }
 
 // round x up to a power of 2.
-static int32
-round2(int32 x)
+int32
+runtime·round2(int32 x)
 {
        int32 s;
 
@@ -683,7 +683,7 @@ runtime·newstack(void)
        if(framesize < StackMin)
                framesize = StackMin;
        framesize += StackSystem;
-       framesize = round2(framesize);
+       framesize = runtime·round2(framesize);
        stk = runtime·stackalloc(gp, framesize);
        if(gp->stacksize > runtime·maxstacksize) {
                runtime·printf("runtime: goroutine stack exceeds %D-byte limit\n", (uint64)runtime·maxstacksize);
index f2e4e43198da7df63d022352cfc9bdcd30d6456e..a3a5d83a64f879f86303f205e660fda94fb04bba 100644 (file)
@@ -57,15 +57,13 @@ enum {
        // to each stack below the usual guard area for OS-specific
        // purposes like signal handling. Used on Windows and on
        // Plan 9 because they do not use a separate stack.
-       // The new stack code requires stacks to be a power of two,
-       // and the default start size is 4k, so make StackSystem also 4k
-       // to keep the sum a power of two. StackSystem used to be
-       // 512*sizeof(uintptr) on Windows and 512 bytes on Plan 9.
 #ifdef GOOS_windows
-       StackSystem = 4096,
+       StackSystem = 512 * sizeof(uintptr),
 #else
 #ifdef GOOS_plan9
-       StackSystem = 4096,
+       // The size of the note handler frame varies among architectures,
+       // but 512 bytes should be enough for every implementation.
+       StackSystem = 512,
 #else
        StackSystem = 0,
 #endif // Plan 9
@@ -79,7 +77,8 @@ enum {
        // If the amount needed for the splitting frame + StackExtra
        // is less than this number, the stack will have this size instead.
        StackMin = 4096,
-       FixedStack = StackMin + StackSystem,
+       StackSystemRounded = StackSystem + (-StackSystem & (StackMin-1)),
+       FixedStack = StackMin + StackSystemRounded,
 
        // Functions that need frames bigger than this use an extra
        // instruction to do the stack split check, to avoid overflow