From: Dmitriy Vyukov Date: Wed, 7 Dec 2011 13:53:17 +0000 (+0300) Subject: ld: increase default stack size on Windows for cgo X-Git-Tag: weekly.2011-12-14~165 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=428062da4e5e35ce75178d993dd6d8ef5e3ecb5d;p=gostls13.git 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 --- diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c index 82f3f007f4..5a4d752892 100644 --- a/src/cmd/ld/lib.c +++ b/src/cmd/ld/lib.c @@ -274,6 +274,7 @@ loadlib(void) for(i=0; ig0 = 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");