mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: round stack size to power of 2.
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
This commit is contained in:
parent
3d5e219e02
commit
84570aa9a1
5 changed files with 18 additions and 13 deletions
|
|
@ -1751,12 +1751,13 @@ runtime·malg(int32 stacksize)
|
||||||
|
|
||||||
newg = runtime·malloc(sizeof(G));
|
newg = runtime·malloc(sizeof(G));
|
||||||
if(stacksize >= 0) {
|
if(stacksize >= 0) {
|
||||||
|
stacksize = runtime·round2(StackSystem + stacksize);
|
||||||
if(g == m->g0) {
|
if(g == m->g0) {
|
||||||
// running on scheduler stack already.
|
// running on scheduler stack already.
|
||||||
stk = runtime·stackalloc(newg, StackSystem + stacksize);
|
stk = runtime·stackalloc(newg, stacksize);
|
||||||
} else {
|
} else {
|
||||||
// have to call stackalloc on scheduler stack.
|
// have to call stackalloc on scheduler stack.
|
||||||
newg->stacksize = StackSystem + stacksize;
|
newg->stacksize = stacksize;
|
||||||
g->param = newg;
|
g->param = newg;
|
||||||
runtime·mcall(mstackalloc);
|
runtime·mcall(mstackalloc);
|
||||||
stk = g->param;
|
stk = g->param;
|
||||||
|
|
@ -1765,7 +1766,7 @@ runtime·malg(int32 stacksize)
|
||||||
newg->stack0 = (uintptr)stk;
|
newg->stack0 = (uintptr)stk;
|
||||||
newg->stackguard = (uintptr)stk + StackGuard;
|
newg->stackguard = (uintptr)stk + StackGuard;
|
||||||
newg->stackguard0 = newg->stackguard;
|
newg->stackguard0 = newg->stackguard;
|
||||||
newg->stackbase = (uintptr)stk + StackSystem + stacksize - sizeof(Stktop);
|
newg->stackbase = (uintptr)stk + stacksize - sizeof(Stktop);
|
||||||
}
|
}
|
||||||
return newg;
|
return newg;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
|
#include "stack.h"
|
||||||
#include "arch_GOARCH.h"
|
#include "arch_GOARCH.h"
|
||||||
#include "../../cmd/ld/textflag.h"
|
#include "../../cmd/ld/textflag.h"
|
||||||
|
|
||||||
|
|
@ -256,6 +257,9 @@ runtime·check(void)
|
||||||
runtime·throw("float32nan3");
|
runtime·throw("float32nan3");
|
||||||
|
|
||||||
TestAtomic64();
|
TestAtomic64();
|
||||||
|
|
||||||
|
if(FixedStack != runtime·round2(FixedStack))
|
||||||
|
runtime·throw("FixedStack is not power-of-2");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
|
|
|
||||||
|
|
@ -900,6 +900,7 @@ void runtime·mcall(void(*)(G*));
|
||||||
uint32 runtime·fastrand1(void);
|
uint32 runtime·fastrand1(void);
|
||||||
void runtime·rewindmorestack(Gobuf*);
|
void runtime·rewindmorestack(Gobuf*);
|
||||||
int32 runtime·timediv(int64, int32, int32*);
|
int32 runtime·timediv(int64, int32, int32*);
|
||||||
|
int32 runtime·round2(int32 x); // round x up to a power of 2.
|
||||||
|
|
||||||
// atomic operations
|
// atomic operations
|
||||||
bool runtime·cas(uint32*, uint32, uint32);
|
bool runtime·cas(uint32*, uint32, uint32);
|
||||||
|
|
|
||||||
|
|
@ -555,8 +555,8 @@ copystack(G *gp, uintptr nframes, uintptr newsize)
|
||||||
}
|
}
|
||||||
|
|
||||||
// round x up to a power of 2.
|
// round x up to a power of 2.
|
||||||
static int32
|
int32
|
||||||
round2(int32 x)
|
runtime·round2(int32 x)
|
||||||
{
|
{
|
||||||
int32 s;
|
int32 s;
|
||||||
|
|
||||||
|
|
@ -683,7 +683,7 @@ runtime·newstack(void)
|
||||||
if(framesize < StackMin)
|
if(framesize < StackMin)
|
||||||
framesize = StackMin;
|
framesize = StackMin;
|
||||||
framesize += StackSystem;
|
framesize += StackSystem;
|
||||||
framesize = round2(framesize);
|
framesize = runtime·round2(framesize);
|
||||||
stk = runtime·stackalloc(gp, framesize);
|
stk = runtime·stackalloc(gp, framesize);
|
||||||
if(gp->stacksize > runtime·maxstacksize) {
|
if(gp->stacksize > runtime·maxstacksize) {
|
||||||
runtime·printf("runtime: goroutine stack exceeds %D-byte limit\n", (uint64)runtime·maxstacksize);
|
runtime·printf("runtime: goroutine stack exceeds %D-byte limit\n", (uint64)runtime·maxstacksize);
|
||||||
|
|
|
||||||
|
|
@ -57,15 +57,13 @@ enum {
|
||||||
// to each stack below the usual guard area for OS-specific
|
// to each stack below the usual guard area for OS-specific
|
||||||
// purposes like signal handling. Used on Windows and on
|
// purposes like signal handling. Used on Windows and on
|
||||||
// Plan 9 because they do not use a separate stack.
|
// 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
|
#ifdef GOOS_windows
|
||||||
StackSystem = 4096,
|
StackSystem = 512 * sizeof(uintptr),
|
||||||
#else
|
#else
|
||||||
#ifdef GOOS_plan9
|
#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
|
#else
|
||||||
StackSystem = 0,
|
StackSystem = 0,
|
||||||
#endif // Plan 9
|
#endif // Plan 9
|
||||||
|
|
@ -79,7 +77,8 @@ enum {
|
||||||
// If the amount needed for the splitting frame + StackExtra
|
// If the amount needed for the splitting frame + StackExtra
|
||||||
// is less than this number, the stack will have this size instead.
|
// is less than this number, the stack will have this size instead.
|
||||||
StackMin = 4096,
|
StackMin = 4096,
|
||||||
FixedStack = StackMin + StackSystem,
|
StackSystemRounded = StackSystem + (-StackSystem & (StackMin-1)),
|
||||||
|
FixedStack = StackMin + StackSystemRounded,
|
||||||
|
|
||||||
// Functions that need frames bigger than this use an extra
|
// Functions that need frames bigger than this use an extra
|
||||||
// instruction to do the stack split check, to avoid overflow
|
// instruction to do the stack split check, to avoid overflow
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue