aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime
diff options
context:
space:
mode:
authorDmitriy Vyukov <dvyukov@google.com>2011-12-07 16:53:17 +0300
committerDmitriy Vyukov <dvyukov@google.com>2011-12-07 16:53:17 +0300
commit428062da4e5e35ce75178d993dd6d8ef5e3ecb5d (patch)
treeba42071e9fce2013704374474713b920249a2c23 /src/pkg/runtime
parent5e43527336e056b9c5a51bf0e23e790c86e3affa (diff)
downloadgo-428062da4e5e35ce75178d993dd6d8ef5e3ecb5d.tar.xz
ld: increase default stack size on Windows for cgo
Fixes #2437. R=rsc, hectorchu, mattn.jp, alex.brainman, jdpoirier, snaury, n13m3y3r CC=golang-dev https://golang.org/cl/5371049
Diffstat (limited to 'src/pkg/runtime')
-rw-r--r--src/pkg/runtime/386/asm.s21
-rw-r--r--src/pkg/runtime/amd64/asm.s20
-rw-r--r--src/pkg/runtime/cgo/windows_386.c17
-rw-r--r--src/pkg/runtime/cgo/windows_amd64.c17
-rw-r--r--src/pkg/runtime/windows/thread.c5
5 files changed, 33 insertions, 47 deletions
diff --git a/src/pkg/runtime/386/asm.s b/src/pkg/runtime/386/asm.s
index 470463925e..04d4e214c3 100644
--- a/src/pkg/runtime/386/asm.s
+++ b/src/pkg/runtime/386/asm.s
@@ -21,15 +21,22 @@ TEXT _rt0_386(SB),7,$0
MOVL AX, 120(SP) // save argc, argv away
MOVL BX, 124(SP)
+ // set default stack bounds.
+ // initcgo may update stackguard.
+ MOVL $runtime·g0(SB), BP
+ LEAL (-64*1024+104)(SP), BX
+ MOVL BX, g_stackguard(BP)
+ MOVL SP, g_stackbase(BP)
+
// if there is an initcgo, call it to let it
// initialize and to set up GS. if not,
// we set up GS ourselves.
MOVL initcgo(SB), AX
TESTL AX, AX
JZ needtls
- PUSHL $runtime·g0(SB)
+ PUSHL BP
CALL AX
- POPL AX
+ POPL BP
// skip runtime·ldt0setup(SB) and tls test after initcgo for non-windows
CMPL runtime·iswindows(SB), $0
JEQ ok
@@ -59,16 +66,6 @@ ok:
// save m->g0 = g0
MOVL CX, m_g0(AX)
- // create istack out of the OS stack
- // if there is an initcgo, it had setup stackguard for us
- MOVL initcgo(SB), AX
- TESTL AX, AX
- JNZ stackok
- LEAL (-64*1024+104)(SP), AX // TODO: 104?
- MOVL AX, g_stackguard(CX)
-stackok:
- MOVL SP, g_stackbase(CX)
-
CALL runtime·emptyfunc(SB) // fault if stack check is wrong
// convention is D is always cleared
diff --git a/src/pkg/runtime/amd64/asm.s b/src/pkg/runtime/amd64/asm.s
index 109b95eba8..18cdefb83d 100644
--- a/src/pkg/runtime/amd64/asm.s
+++ b/src/pkg/runtime/amd64/asm.s
@@ -12,13 +12,19 @@ TEXT _rt0_amd64(SB),7,$-8
ANDQ $~15, SP
MOVQ AX, 16(SP)
MOVQ BX, 24(SP)
+
+ // create istack out of the given (operating system) stack.
+ // initcgo may update stackguard.
+ MOVQ $runtime·g0(SB), DI
+ LEAQ (-8192+104)(SP), BX
+ MOVQ BX, g_stackguard(DI)
+ MOVQ SP, g_stackbase(DI)
// if there is an initcgo, call it.
MOVQ initcgo(SB), AX
TESTQ AX, AX
JZ needtls
- LEAQ runtime·g0(SB), DI
- CALL AX
+ CALL AX // g0 already in DI
CMPL runtime·iswindows(SB), $0
JEQ ok
@@ -44,16 +50,6 @@ ok:
// save m->g0 = g0
MOVQ CX, m_g0(AX)
- // create istack out of the given (operating system) stack
- // if there is an initcgo, it had setup stackguard for us
- MOVQ initcgo(SB), AX
- TESTQ AX, AX
- JNZ stackok
- LEAQ (-8192+104)(SP), AX
- MOVQ AX, g_stackguard(CX)
-stackok:
- MOVQ SP, g_stackbase(CX)
-
CLD // convention is D is always left cleared
CALL runtime·check(SB)
diff --git a/src/pkg/runtime/cgo/windows_386.c b/src/pkg/runtime/cgo/windows_386.c
index 96aea07128..4f34323929 100644
--- a/src/pkg/runtime/cgo/windows_386.c
+++ b/src/pkg/runtime/cgo/windows_386.c
@@ -8,15 +8,16 @@
static void *threadentry(void*);
-/* From what I've read 1MB is default for 32-bit Linux.
- Allocation granularity on Windows is typically 64 KB. */
+/* 1MB is default stack size for 32-bit Windows.
+ Allocation granularity on Windows is typically 64 KB.
+ The constant is also hardcoded in cmd/ld/pe.c (keep synchronized). */
#define STACKSIZE (1*1024*1024)
static void
xinitcgo(G *g)
{
int tmp;
- g->stackguard = (uintptr)&tmp - STACKSIZE + 4096;
+ g->stackguard = (uintptr)&tmp - STACKSIZE + 8*1024;
}
void (*initcgo)(G*) = xinitcgo;
@@ -24,8 +25,7 @@ void (*initcgo)(G*) = xinitcgo;
void
libcgo_sys_thread_start(ThreadStart *ts)
{
- ts->g->stackguard = STACKSIZE;
- _beginthread(threadentry, STACKSIZE, ts);
+ _beginthread(threadentry, 0, ts);
}
static void*
@@ -38,12 +38,7 @@ threadentry(void *v)
free(v);
ts.g->stackbase = (uintptr)&ts;
-
- /*
- * libcgo_sys_thread_start set stackguard to stack size;
- * change to actual guard pointer.
- */
- ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
+ ts.g->stackguard = (uintptr)&ts - STACKSIZE + 8*1024;
/*
* Set specific keys in thread local storage.
diff --git a/src/pkg/runtime/cgo/windows_amd64.c b/src/pkg/runtime/cgo/windows_amd64.c
index 6d31845ce6..2abc30b892 100644
--- a/src/pkg/runtime/cgo/windows_amd64.c
+++ b/src/pkg/runtime/cgo/windows_amd64.c
@@ -8,15 +8,16 @@
static void *threadentry(void*);
-/* From what I've read 2MB is default for 64-bit Linux.
- Allocation granularity on Windows is typically 64 KB. */
+/* 2MB is default stack size for 64-bit Windows.
+ Allocation granularity on Windows is typically 64 KB.
+ The constant is also hardcoded in cmd/ld/pe.c (keep synchronized). */
#define STACKSIZE (2*1024*1024)
static void
xinitcgo(G *g)
{
int tmp;
- g->stackguard = (uintptr)&tmp - STACKSIZE + 4096;
+ g->stackguard = (uintptr)&tmp - STACKSIZE + 8*1024;
}
void (*initcgo)(G*) = xinitcgo;
@@ -24,8 +25,7 @@ void (*initcgo)(G*) = xinitcgo;
void
libcgo_sys_thread_start(ThreadStart *ts)
{
- ts->g->stackguard = STACKSIZE;
- _beginthread(threadentry, STACKSIZE, ts);
+ _beginthread(threadentry, 0, ts);
}
static void*
@@ -38,12 +38,7 @@ threadentry(void *v)
free(v);
ts.g->stackbase = (uintptr)&ts;
-
- /*
- * libcgo_sys_thread_start set stackguard to stack size;
- * change to actual guard pointer.
- */
- ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
+ ts.g->stackguard = (uintptr)&ts - STACKSIZE + 8*1024;
/*
* Set specific keys in thread local storage.
diff --git a/src/pkg/runtime/windows/thread.c b/src/pkg/runtime/windows/thread.c
index 4b963f374e..dc7e06cd33 100644
--- a/src/pkg/runtime/windows/thread.c
+++ b/src/pkg/runtime/windows/thread.c
@@ -183,6 +183,8 @@ runtime·semacreate(void)
return (uintptr)runtime·stdcall(runtime·CreateEvent, 4, (uintptr)0, (uintptr)0, (uintptr)0, (uintptr)0);
}
+#define STACK_SIZE_PARAM_IS_A_RESERVATION ((uintptr)0x00010000)
+
void
runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
{
@@ -193,7 +195,8 @@ runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
USED(fn); // assuming fn = mstart
thandle = runtime·stdcall(runtime·CreateThread, 6,
- nil, nil, runtime·tstart_stdcall, m, nil, nil);
+ nil, (uintptr)0x20000, runtime·tstart_stdcall, m,
+ STACK_SIZE_PARAM_IS_A_RESERVATION, nil);
if(thandle == nil) {
runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), runtime·getlasterror());
runtime·throw("runtime.newosproc");