From 89f185fe8a036b0fabce30b20c480cf1c832bdd7 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 26 Jun 2014 11:54:39 -0400 Subject: [PATCH] all: remove 'extern register M *m' from runtime MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The runtime has historically held two dedicated values g (current goroutine) and m (current thread) in 'extern register' slots (TLS on x86, real registers backed by TLS on ARM). This CL removes the extern register m; code now uses g->m. On ARM, this frees up the register that formerly held m (R9). This is important for NaCl, because NaCl ARM code cannot use R9 at all. The Go 1 macrobenchmarks (those with per-op times >= 10 µs) are unaffected: BenchmarkBinaryTree17 5491374955 5471024381 -0.37% BenchmarkFannkuch11 4357101311 4275174828 -1.88% BenchmarkGobDecode 11029957 11364184 +3.03% BenchmarkGobEncode 6852205 6784822 -0.98% BenchmarkGzip 650795967 650152275 -0.10% BenchmarkGunzip 140962363 141041670 +0.06% BenchmarkHTTPClientServer 71581 73081 +2.10% BenchmarkJSONEncode 31928079 31913356 -0.05% BenchmarkJSONDecode 117470065 113689916 -3.22% BenchmarkMandelbrot200 6008923 5998712 -0.17% BenchmarkGoParse 6310917 6327487 +0.26% BenchmarkRegexpMatchMedium_1K 114568 114763 +0.17% BenchmarkRegexpMatchHard_1K 168977 169244 +0.16% BenchmarkRevcomp 935294971 914060918 -2.27% BenchmarkTemplate 145917123 148186096 +1.55% Minux previous reported larger variations, but these were caused by run-to-run noise, not repeatable slowdowns. Actual code changes by Minux. I only did the docs and the benchmarking. LGTM=dvyukov, iant, minux R=minux, josharian, iant, dave, bradfitz, dvyukov CC=golang-codereviews https://golang.org/cl/109050043 --- doc/asm.html | 24 +- include/link.h | 2 +- src/cmd/5a/lex.c | 4 +- src/cmd/dist/buildruntime.c | 3 - src/cmd/ld/data.c | 12 +- src/cmd/ld/lib.c | 14 +- src/cmd/ld/symtab.c | 4 +- src/liblink/asm5.c | 8 +- src/liblink/obj5.c | 12 +- src/liblink/obj6.c | 4 +- src/pkg/runtime/asm_386.s | 63 ++-- src/pkg/runtime/asm_amd64.s | 71 +++-- src/pkg/runtime/asm_amd64p32.s | 31 +- src/pkg/runtime/asm_arm.s | 127 ++++---- src/pkg/runtime/cgo/asm_arm.s | 8 +- src/pkg/runtime/cgo/callbacks.c | 4 +- src/pkg/runtime/cgo/gcc_arm.S | 9 +- src/pkg/runtime/cgo/gcc_darwin_386.c | 60 ++-- src/pkg/runtime/cgo/gcc_darwin_amd64.c | 49 ++-- src/pkg/runtime/cgo/gcc_dragonfly_386.c | 8 +- src/pkg/runtime/cgo/gcc_dragonfly_amd64.c | 8 +- src/pkg/runtime/cgo/gcc_freebsd_386.c | 8 +- src/pkg/runtime/cgo/gcc_freebsd_amd64.c | 8 +- src/pkg/runtime/cgo/gcc_freebsd_arm.c | 10 +- src/pkg/runtime/cgo/gcc_linux_386.c | 8 +- src/pkg/runtime/cgo/gcc_linux_amd64.c | 8 +- src/pkg/runtime/cgo/gcc_linux_arm.c | 10 +- src/pkg/runtime/cgo/gcc_netbsd_386.c | 8 +- src/pkg/runtime/cgo/gcc_netbsd_amd64.c | 8 +- src/pkg/runtime/cgo/gcc_netbsd_arm.c | 10 +- src/pkg/runtime/cgo/gcc_openbsd_386.c | 8 +- src/pkg/runtime/cgo/gcc_openbsd_amd64.c | 8 +- src/pkg/runtime/cgo/gcc_windows_386.c | 3 +- src/pkg/runtime/cgo/gcc_windows_amd64.c | 3 +- src/pkg/runtime/cgo/libcgo.h | 1 - src/pkg/runtime/cgocall.c | 26 +- src/pkg/runtime/heapdump.c | 8 +- src/pkg/runtime/lock_futex.c | 24 +- src/pkg/runtime/lock_sema.c | 56 ++-- src/pkg/runtime/malloc.goc | 38 +-- src/pkg/runtime/mcache.c | 4 +- src/pkg/runtime/mgc0.c | 68 ++--- src/pkg/runtime/mheap.c | 20 +- src/pkg/runtime/mprof.goc | 26 +- src/pkg/runtime/netpoll_solaris.c | 2 +- src/pkg/runtime/netpoll_windows.c | 12 +- src/pkg/runtime/os_darwin.c | 11 +- src/pkg/runtime/os_dragonfly.c | 3 +- src/pkg/runtime/os_freebsd.c | 3 +- src/pkg/runtime/os_linux.c | 3 +- src/pkg/runtime/os_nacl.c | 29 +- src/pkg/runtime/os_netbsd.c | 27 +- src/pkg/runtime/os_openbsd.c | 21 +- src/pkg/runtime/os_plan9.c | 12 +- src/pkg/runtime/os_plan9_386.c | 8 +- src/pkg/runtime/os_plan9_amd64.c | 8 +- src/pkg/runtime/os_solaris.c | 34 ++- src/pkg/runtime/os_windows.c | 26 +- src/pkg/runtime/os_windows_386.c | 4 +- src/pkg/runtime/os_windows_amd64.c | 4 +- src/pkg/runtime/panic.c | 51 ++-- src/pkg/runtime/proc.c | 334 +++++++++++----------- src/pkg/runtime/race_amd64.s | 8 +- src/pkg/runtime/runtime.c | 8 +- src/pkg/runtime/runtime.h | 5 +- src/pkg/runtime/runtime1.goc | 4 +- src/pkg/runtime/signal_386.c | 12 +- src/pkg/runtime/signal_amd64x.c | 10 +- src/pkg/runtime/signal_arm.c | 12 +- src/pkg/runtime/signal_unix.c | 2 +- src/pkg/runtime/softfloat_arm.c | 14 +- src/pkg/runtime/stack.c | 94 +++--- src/pkg/runtime/symtab.goc | 2 +- src/pkg/runtime/sys_darwin_386.s | 10 +- src/pkg/runtime/sys_darwin_amd64.s | 10 +- src/pkg/runtime/sys_dragonfly_386.s | 10 +- src/pkg/runtime/sys_dragonfly_amd64.s | 10 +- src/pkg/runtime/sys_freebsd_386.s | 10 +- src/pkg/runtime/sys_freebsd_amd64.s | 10 +- src/pkg/runtime/sys_freebsd_arm.s | 16 +- src/pkg/runtime/sys_linux_386.s | 11 +- src/pkg/runtime/sys_linux_amd64.s | 10 +- src/pkg/runtime/sys_linux_arm.s | 19 +- src/pkg/runtime/sys_nacl_386.s | 10 +- src/pkg/runtime/sys_nacl_amd64p32.s | 12 +- src/pkg/runtime/sys_netbsd_386.s | 10 +- src/pkg/runtime/sys_netbsd_amd64.s | 10 +- src/pkg/runtime/sys_netbsd_arm.s | 13 +- src/pkg/runtime/sys_openbsd_386.s | 10 +- src/pkg/runtime/sys_openbsd_amd64.s | 10 +- src/pkg/runtime/sys_plan9_386.s | 10 +- src/pkg/runtime/sys_plan9_amd64.s | 10 +- src/pkg/runtime/sys_solaris_amd64.s | 22 +- src/pkg/runtime/sys_windows_386.s | 16 +- src/pkg/runtime/sys_windows_amd64.s | 14 +- src/pkg/runtime/traceback_arm.c | 2 +- src/pkg/runtime/traceback_x86.c | 2 +- src/pkg/runtime/vlop_arm.s | 25 +- 98 files changed, 994 insertions(+), 957 deletions(-) diff --git a/doc/asm.html b/doc/asm.html index d44cb799d4..f4ef1e62f2 100644 --- a/doc/asm.html +++ b/doc/asm.html @@ -149,7 +149,7 @@ hardware's SP register.

Instructions, registers, and assembler directives are always in UPPER CASE to remind you that assembly programming is a fraught endeavor. -(Exceptions: the m and g register renamings on ARM.) +(Exception: the g register renaming on ARM.)

@@ -344,7 +344,7 @@ Here follows some descriptions of key Go-specific details for the supported arch

32-bit Intel 386

-The runtime pointers to the m and g structures are maintained +The runtime pointer to the g structure is maintained through the value of an otherwise unused (as far as Go is concerned) register in the MMU. A OS-dependent macro get_tls is defined for the assembler if the source includes an architecture-dependent header file, like this: @@ -356,14 +356,15 @@ an architecture-dependent header file, like this:

Within the runtime, the get_tls macro loads its argument register -with a pointer to a pair of words representing the g and m pointers. +with a pointer to the g pointer, and the g struct +contains the m pointer. The sequence to load g and m using CX looks like this:

 get_tls(CX)
-MOVL	g(CX), AX	// Move g into AX.
-MOVL	m(CX), BX	// Move m into BX.
+MOVL	g(CX), AX     // Move g into AX.
+MOVL	g_m(AX), BX   // Move g->m into BX.
 

64-bit Intel 386 (a.k.a. amd64)

@@ -376,22 +377,21 @@ pointers is the same as on the 386, except it uses MOVQ rather than
 get_tls(CX)
-MOVQ	g(CX), AX	// Move g into AX.
-MOVQ	m(CX), BX	// Move m into BX.
+MOVQ	g(CX), AX     // Move g into AX.
+MOVQ	g_m(AX), BX   // Move g->m into BX.
 

ARM

-The registers R9, R10, and R11 +The registers R10 and R11 are reserved by the compiler and linker.

-R9 and R10 point to the m (machine) and g -(goroutine) structures, respectively. -Within assembler source code, these pointers must be referred to as m and g; -the names R9 and R10 are not recognized. +R10 points to the g (goroutine) structure. +Within assembler source code, this pointer must be referred to as g; +the name R10 is not recognized.

diff --git a/include/link.h b/include/link.h index 248497888e..2067bec089 100644 --- a/include/link.h +++ b/include/link.h @@ -390,7 +390,7 @@ struct Link LSym* sym_mod; LSym* sym_modu; LSym* symmorestack[20]; - LSym* gmsym; + LSym* tlsg; LSym* plan9tos; Prog* curp; Prog* printp; diff --git a/src/cmd/5a/lex.c b/src/cmd/5a/lex.c index 571fdf7f26..84a17d1557 100644 --- a/src/cmd/5a/lex.c +++ b/src/cmd/5a/lex.c @@ -199,8 +199,8 @@ struct "R6", LREG, 6, "R7", LREG, 7, "R8", LREG, 8, - "m", LREG, 9, // avoid unintentionally clobber m/g using R9/R10 - "g", LREG, 10, + "R9", LREG, 9, + "g", LREG, 10, // avoid unintentionally clobber g using R10 "R11", LREG, 11, "R12", LREG, 12, "R13", LREG, 13, diff --git a/src/cmd/dist/buildruntime.c b/src/cmd/dist/buildruntime.c index ba5993b2fc..008554d549 100644 --- a/src/cmd/dist/buildruntime.c +++ b/src/cmd/dist/buildruntime.c @@ -130,17 +130,14 @@ static struct { {"386", "", "#define get_tls(r) MOVL TLS, r\n" "#define g(r) 0(r)(TLS*1)\n" - "#define m(r) 4(r)(TLS*1)\n" }, {"amd64p32", "", "#define get_tls(r) MOVL TLS, r\n" "#define g(r) 0(r)(TLS*1)\n" - "#define m(r) 4(r)(TLS*1)\n" }, {"amd64", "", "#define get_tls(r) MOVQ TLS, r\n" "#define g(r) 0(r)(TLS*1)\n" - "#define m(r) 8(r)(TLS*1)\n" }, {"arm", "", diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c index 55d020710e..03b93c77ce 100644 --- a/src/cmd/ld/data.c +++ b/src/cmd/ld/data.c @@ -186,8 +186,8 @@ relocsym(LSym *s) case R_TLS_LE: if(linkmode == LinkExternal && iself && HEADTYPE != Hopenbsd) { r->done = 0; - r->sym = ctxt->gmsym; - r->xsym = ctxt->gmsym; + r->sym = ctxt->tlsg; + r->xsym = ctxt->tlsg; r->xadd = r->add; o = 0; if(thechar != '6') @@ -200,8 +200,8 @@ relocsym(LSym *s) case R_TLS_IE: if(linkmode == LinkExternal && iself && HEADTYPE != Hopenbsd) { r->done = 0; - r->sym = ctxt->gmsym; - r->xsym = ctxt->gmsym; + r->sym = ctxt->tlsg; + r->xsym = ctxt->tlsg; r->xadd = r->add; o = 0; if(thechar != '6') @@ -951,9 +951,9 @@ dodata(void) sect->len = datsize; } else { // Might be internal linking but still using cgo. - // In that case, the only possible STLSBSS symbol is tlsgm. + // In that case, the only possible STLSBSS symbol is runtime.tlsg. // Give it offset 0, because it's the only thing here. - if(s != nil && s->type == STLSBSS && strcmp(s->name, "runtime.tlsgm") == 0) { + if(s != nil && s->type == STLSBSS && strcmp(s->name, "runtime.tlsg") == 0) { s->value = 0; s = s->next; } diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c index da6194e4ff..ef638a66a6 100644 --- a/src/cmd/ld/lib.c +++ b/src/cmd/ld/lib.c @@ -177,7 +177,7 @@ void loadlib(void) { int i, w, x; - LSym *s, *gmsym; + LSym *s, *tlsg; char* cgostrsym; if(flag_shared) { @@ -244,12 +244,12 @@ loadlib(void) } } - gmsym = linklookup(ctxt, "runtime.tlsgm", 0); - gmsym->type = STLSBSS; - gmsym->size = 2*PtrSize; - gmsym->hide = 1; - gmsym->reachable = 1; - ctxt->gmsym = gmsym; + tlsg = linklookup(ctxt, "runtime.tlsg", 0); + tlsg->type = STLSBSS; + tlsg->size = PtrSize; + tlsg->hide = 1; + tlsg->reachable = 1; + ctxt->tlsg = tlsg; // Now that we know the link mode, trim the dynexp list. x = CgoExportDynamic; diff --git a/src/cmd/ld/symtab.c b/src/cmd/ld/symtab.c index 6d321c0bb9..1bc384e805 100644 --- a/src/cmd/ld/symtab.c +++ b/src/cmd/ld/symtab.c @@ -198,13 +198,13 @@ asmelfsym(void) genasmsym(putelfsym); if(linkmode == LinkExternal && HEADTYPE != Hopenbsd) { - s = linklookup(ctxt, "runtime.tlsgm", 0); + s = linklookup(ctxt, "runtime.tlsg", 0); if(s->sect == nil) { ctxt->cursym = nil; diag("missing section for %s", s->name); errorexit(); } - putelfsyment(putelfstr(s->name), 0, 2*PtrSize, (STB_LOCAL<<4)|STT_TLS, s->sect->elfsect->shnum, 0); + putelfsyment(putelfstr(s->name), 0, s->size, (STB_LOCAL<<4)|STT_TLS, s->sect->elfsect->shnum, 0); s->elfsym = numelfsym++; } diff --git a/src/liblink/asm5.c b/src/liblink/asm5.c index 465b645b27..2d084801f1 100644 --- a/src/liblink/asm5.c +++ b/src/liblink/asm5.c @@ -572,8 +572,8 @@ span5(Link *ctxt, LSym *cursym) * code references to be relocated too, and then * perhaps we'd be able to parallelize the span loop above. */ - if(ctxt->gmsym == nil) - ctxt->gmsym = linklookup(ctxt, "runtime.tlsgm", 0); + if(ctxt->tlsg == nil) + ctxt->tlsg = linklookup(ctxt, "runtime.tlsg", 0); p = cursym->text; ctxt->autosize = p->to.offset + 4; @@ -1377,11 +1377,11 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na rel->sym = p->to.sym; rel->add = p->to.offset; - // runtime.tlsgm (aka gmsym) is special. + // runtime.tlsg is special. // Its "address" is the offset from the TLS thread pointer // to the thread-local g and m pointers. // Emit a TLS relocation instead of a standard one. - if(rel->sym == ctxt->gmsym) { + if(rel->sym == ctxt->tlsg) { rel->type = R_TLS; if(ctxt->flag_shared) rel->add += ctxt->pc - p->pcrel->pc - 8 - rel->siz; diff --git a/src/liblink/obj5.c b/src/liblink/obj5.c index ccd4c81c79..d473cb7c6a 100644 --- a/src/liblink/obj5.c +++ b/src/liblink/obj5.c @@ -173,15 +173,15 @@ progedit(Link *ctxt, Prog *p) if(ctxt->flag_shared) { // Shared libraries use R_ARM_TLS_IE32 instead of // R_ARM_TLS_LE32, replacing the link time constant TLS offset in - // runtime.tlsgm with an address to a GOT entry containing the - // offset. Rewrite $runtime.tlsgm(SB) to runtime.tlsgm(SB) to + // runtime.tlsg with an address to a GOT entry containing the + // offset. Rewrite $runtime.tlsg(SB) to runtime.tlsg(SB) to // compensate. - if(ctxt->gmsym == nil) - ctxt->gmsym = linklookup(ctxt, "runtime.tlsgm", 0); + if(ctxt->tlsg == nil) + ctxt->tlsg = linklookup(ctxt, "runtime.tlsg", 0); - if(p->from.type == D_CONST && p->from.name == D_EXTERN && p->from.sym == ctxt->gmsym) + if(p->from.type == D_CONST && p->from.name == D_EXTERN && p->from.sym == ctxt->tlsg) p->from.type = D_OREG; - if(p->to.type == D_CONST && p->to.name == D_EXTERN && p->to.sym == ctxt->gmsym) + if(p->to.type == D_CONST && p->to.name == D_EXTERN && p->to.sym == ctxt->tlsg) p->to.type = D_OREG; } } diff --git a/src/liblink/obj6.c b/src/liblink/obj6.c index b1bcd0dc08..d83f847851 100644 --- a/src/liblink/obj6.c +++ b/src/liblink/obj6.c @@ -394,8 +394,8 @@ addstacksplit(Link *ctxt, LSym *cursym) uint32 i; vlong textstksiz, textarg; - if(ctxt->gmsym == nil) - ctxt->gmsym = linklookup(ctxt, "runtime.tlsgm", 0); + if(ctxt->tlsg == nil) + ctxt->tlsg = linklookup(ctxt, "runtime.tlsg", 0); if(ctxt->symmorestack[0] == nil) { if(nelem(morename) > nelem(ctxt->symmorestack)) sysfatal("Link.symmorestack needs at least %d elements", nelem(morename)); diff --git a/src/pkg/runtime/asm_386.s b/src/pkg/runtime/asm_386.s index 8ba72eb1fc..0b093588cb 100644 --- a/src/pkg/runtime/asm_386.s +++ b/src/pkg/runtime/asm_386.s @@ -40,7 +40,7 @@ nocpuinfo: MOVL _cgo_init(SB), AX TESTL AX, AX JZ needtls - MOVL $setmg_gcc<>(SB), BX + MOVL $setg_gcc<>(SB), BX MOVL BX, 4(SP) MOVL BP, 0(SP) CALL AX @@ -72,10 +72,11 @@ ok: LEAL runtime·g0(SB), CX MOVL CX, g(BX) LEAL runtime·m0(SB), AX - MOVL AX, m(BX) // save m->g0 = g0 MOVL CX, m_g0(AX) + // save g0->m = m0 + MOVL AX, g_m(CX) CALL runtime·emptyfunc(SB) // fault if stack check is wrong @@ -178,7 +179,8 @@ TEXT runtime·mcall(SB), NOSPLIT, $0-4 MOVL AX, (g_sched+gobuf_g)(AX) // switch to m->g0 & its stack, call fn - MOVL m(CX), BX + MOVL g(CX), BX + MOVL g_m(BX), BX MOVL m_g0(BX), SI CMPL SI, AX // if g == m->g0 call badmcall JNE 3(PC) @@ -206,7 +208,8 @@ TEXT runtime·mcall(SB), NOSPLIT, $0-4 TEXT runtime·morestack(SB),NOSPLIT,$0-0 // Cannot grow scheduler stack (m->g0). get_tls(CX) - MOVL m(CX), BX + MOVL g(CX), BX + MOVL g_m(BX), BX MOVL m_g0(BX), SI CMPL g(CX), SI JNE 2(PC) @@ -258,7 +261,8 @@ TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0-0 // func call(fn *byte, arg *byte, argsize uint32). TEXT runtime·newstackcall(SB), NOSPLIT, $0-12 get_tls(CX) - MOVL m(CX), BX + MOVL g(CX), BX + MOVL g_m(BX), BX // Save our caller's state as the PC and SP to // restore when returning from f. @@ -415,7 +419,8 @@ CALLFN(call1073741824, 1073741824) TEXT runtime·lessstack(SB), NOSPLIT, $0-0 // Save return value in m->cret get_tls(CX) - MOVL m(CX), BX + MOVL g(CX), BX + MOVL g_m(BX), BX MOVL AX, m_cret(BX) // Call oldstack on m->g0's stack. @@ -606,7 +611,8 @@ TEXT runtime·asmcgocall(SB),NOSPLIT,$0-8 // We get called to create new OS threads too, and those // come in on the m->g0 stack already. get_tls(CX) - MOVL m(CX), BP + MOVL g(CX), BP + MOVL g_m(BP), BP MOVL m_g0(BP), SI MOVL g(CX), DI CMPL SI, DI @@ -647,7 +653,7 @@ TEXT runtime·cgocallback(SB),NOSPLIT,$12-12 // cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize) // See cgocall.c for more details. TEXT runtime·cgocallback_gofunc(SB),NOSPLIT,$12-12 - // If m is nil, Go did not create the current thread. + // If g is nil, Go did not create the current thread. // Call needm to obtain one for temporary use. // In this case, we're running on the thread stack, so there's // lots of space, but the linker doesn't know. Hide the call from @@ -656,19 +662,22 @@ TEXT runtime·cgocallback_gofunc(SB),NOSPLIT,$12-12 #ifdef GOOS_windows MOVL $0, BP CMPL CX, $0 - JEQ 2(PC) + JEQ 2(PC) // TODO #endif - MOVL m(CX), BP - MOVL BP, DX // saved copy of oldm + MOVL g(CX), BP CMPL BP, $0 - JNE havem + JEQ needm + MOVL g_m(BP), BP + MOVL BP, DX // saved copy of oldm + JMP havem needm: - MOVL DX, 0(SP) + MOVL $0, 0(SP) MOVL $runtime·needm(SB), AX CALL AX MOVL 0(SP), DX get_tls(CX) - MOVL m(CX), BP + MOVL g(CX), BP + MOVL g_m(BP), BP havem: // Now there's a valid m, and we're running on its m->g0. @@ -718,7 +727,8 @@ havem: // Switch back to m->g0's stack and restore m->g0->sched.sp. // (Unlike m->curg, the g0 goroutine never uses sched.pc, // so we do not have to restore it.) - MOVL m(CX), BP + MOVL g(CX), BP + MOVL g_m(BP), BP MOVL m_g0(BP), SI MOVL SI, g(CX) MOVL (g_sched+gobuf_sp)(SI), SP @@ -735,33 +745,28 @@ havem: // Done! RET -// void setmg(M*, G*); set m and g. for use by needm. -TEXT runtime·setmg(SB), NOSPLIT, $0-8 +// void setg(G*); set g. for use by needm. +TEXT runtime·setg(SB), NOSPLIT, $0-8 + MOVL gg+0(FP), BX #ifdef GOOS_windows - MOVL mm+0(FP), AX - CMPL AX, $0 + CMPL BX, $0 JNE settls MOVL $0, 0x14(FS) RET settls: + MOVL g_m(BX), AX LEAL m_tls(AX), AX MOVL AX, 0x14(FS) #endif - MOVL mm+0(FP), AX get_tls(CX) - MOVL mm+0(FP), AX - MOVL AX, m(CX) - MOVL gg+4(FP), BX MOVL BX, g(CX) RET -// void setmg_gcc(M*, G*); set m and g. for use by gcc -TEXT setmg_gcc<>(SB), NOSPLIT, $0 +// void setg_gcc(G*); set g. for use by gcc +TEXT setg_gcc<>(SB), NOSPLIT, $0 get_tls(AX) - MOVL mm+0(FP), DX - MOVL DX, m(AX) - MOVL gg+4(FP), DX - MOVL DX,g (AX) + MOVL gg+0(FP), DX + MOVL DX, g(AX) RET // check that SP is in range [g->stackbase, g->stackguard) diff --git a/src/pkg/runtime/asm_amd64.s b/src/pkg/runtime/asm_amd64.s index b712e3415a..4057f77761 100644 --- a/src/pkg/runtime/asm_amd64.s +++ b/src/pkg/runtime/asm_amd64.s @@ -40,7 +40,7 @@ nocpuinfo: JZ needtls // g0 already in DI MOVQ DI, CX // Win64 uses CX for first parameter - MOVQ $setmg_gcc<>(SB), SI + MOVQ $setg_gcc<>(SB), SI CALL AX // update stackguard after _cgo_init MOVQ $runtime·g0(SB), CX @@ -73,10 +73,11 @@ ok: LEAQ runtime·g0(SB), CX MOVQ CX, g(BX) LEAQ runtime·m0(SB), AX - MOVQ AX, m(BX) // save m->g0 = g0 MOVQ CX, m_g0(AX) + // save m0 to g0->m + MOVQ AX, g_m(CX) CLD // convention is D is always left cleared CALL runtime·check(SB) @@ -168,7 +169,8 @@ TEXT runtime·mcall(SB), NOSPLIT, $0-8 MOVQ AX, (g_sched+gobuf_g)(AX) // switch to m->g0 & its stack, call fn - MOVQ m(CX), BX + MOVQ g(CX), BX + MOVQ g_m(BX), BX MOVQ m_g0(BX), SI CMPQ SI, AX // if g == m->g0 call badmcall JNE 3(PC) @@ -236,7 +238,8 @@ TEXT runtime·morestack(SB),NOSPLIT,$0-0 // func call(fn *byte, arg *byte, argsize uint32). TEXT runtime·newstackcall(SB), NOSPLIT, $0-20 get_tls(CX) - MOVQ m(CX), BX + MOVQ g(CX), BX + MOVQ g_m(BX), BX // Save our caller's state as the PC and SP to // restore when returning from f. @@ -392,7 +395,8 @@ CALLFN(call1073741824, 1073741824) TEXT runtime·lessstack(SB), NOSPLIT, $0-0 // Save return value in m->cret get_tls(CX) - MOVQ m(CX), BX + MOVQ g(CX), BX + MOVQ g_m(BX), BX MOVQ AX, m_cret(BX) // Call oldstack on m->g0's stack. @@ -406,7 +410,8 @@ TEXT runtime·lessstack(SB), NOSPLIT, $0-0 // morestack trampolines TEXT runtime·morestack00(SB),NOSPLIT,$0 get_tls(CX) - MOVQ m(CX), BX + MOVQ g(CX), BX + MOVQ g_m(BX), BX MOVQ $0, AX MOVQ AX, m_moreframesize(BX) MOVQ $runtime·morestack(SB), AX @@ -414,7 +419,8 @@ TEXT runtime·morestack00(SB),NOSPLIT,$0 TEXT runtime·morestack01(SB),NOSPLIT,$0 get_tls(CX) - MOVQ m(CX), BX + MOVQ g(CX), BX + MOVQ g_m(BX), BX SHLQ $32, AX MOVQ AX, m_moreframesize(BX) MOVQ $runtime·morestack(SB), AX @@ -422,7 +428,8 @@ TEXT runtime·morestack01(SB),NOSPLIT,$0 TEXT runtime·morestack10(SB),NOSPLIT,$0 get_tls(CX) - MOVQ m(CX), BX + MOVQ g(CX), BX + MOVQ g_m(BX), BX MOVLQZX AX, AX MOVQ AX, m_moreframesize(BX) MOVQ $runtime·morestack(SB), AX @@ -430,7 +437,8 @@ TEXT runtime·morestack10(SB),NOSPLIT,$0 TEXT runtime·morestack11(SB),NOSPLIT,$0 get_tls(CX) - MOVQ m(CX), BX + MOVQ g(CX), BX + MOVQ g_m(BX), BX MOVQ AX, m_moreframesize(BX) MOVQ $runtime·morestack(SB), AX JMP AX @@ -469,7 +477,8 @@ TEXT runtime·morestack48(SB),NOSPLIT,$0 TEXT morestack<>(SB),NOSPLIT,$0 get_tls(CX) - MOVQ m(CX), BX + MOVQ g(CX), BX + MOVQ g_m(BX), BX SHLQ $35, R8 MOVQ R8, m_moreframesize(BX) MOVQ $runtime·morestack(SB), AX @@ -678,7 +687,8 @@ TEXT runtime·asmcgocall(SB),NOSPLIT,$0-16 // We get called to create new OS threads too, and those // come in on the m->g0 stack already. get_tls(CX) - MOVQ m(CX), BP + MOVQ g(CX), BP + MOVQ g_m(BP), BP MOVQ m_g0(BP), SI MOVQ g(CX), DI CMPQ SI, DI @@ -728,8 +738,8 @@ TEXT runtime·cgocallback(SB),NOSPLIT,$24-24 // cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize) // See cgocall.c for more details. TEXT runtime·cgocallback_gofunc(SB),NOSPLIT,$8-24 - // If m is nil, Go did not create the current thread. - // Call needm to obtain one for temporary use. + // If g is nil, Go did not create the current thread. + // Call needm to obtain one m for temporary use. // In this case, we're running on the thread stack, so there's // lots of space, but the linker doesn't know. Hide the call from // the linker analysis by using an indirect call through AX. @@ -739,17 +749,20 @@ TEXT runtime·cgocallback_gofunc(SB),NOSPLIT,$8-24 CMPQ CX, $0 JEQ 2(PC) #endif - MOVQ m(CX), BP - MOVQ BP, R8 // holds oldm until end of function + MOVQ g(CX), BP CMPQ BP, $0 - JNE havem + JEQ needm + MOVQ g_m(BP), BP + MOVQ BP, R8 // holds oldm until end of function + JMP havem needm: - MOVQ R8, 0(SP) + MOVQ $0, 0(SP) MOVQ $runtime·needm(SB), AX CALL AX MOVQ 0(SP), R8 get_tls(CX) - MOVQ m(CX), BP + MOVQ g(CX), BP + MOVQ g_m(BP), BP havem: // Now there's a valid m, and we're running on its m->g0. @@ -798,7 +811,8 @@ havem: // Switch back to m->g0's stack and restore m->g0->sched.sp. // (Unlike m->curg, the g0 goroutine never uses sched.pc, // so we do not have to restore it.) - MOVQ m(CX), BP + MOVQ g(CX), BP + MOVQ g_m(BP), BP MOVQ m_g0(BP), SI MOVQ SI, g(CX) MOVQ (g_sched+gobuf_sp)(SI), SP @@ -815,30 +829,27 @@ havem: // Done! RET -// void setmg(M*, G*); set m and g. for use by needm. -TEXT runtime·setmg(SB), NOSPLIT, $0-16 - MOVQ mm+0(FP), AX +// void setg(G*); set g. for use by needm. +TEXT runtime·setg(SB), NOSPLIT, $0-16 + MOVQ gg+0(FP), BX #ifdef GOOS_windows - CMPQ AX, $0 + CMPQ BX, $0 JNE settls MOVQ $0, 0x28(GS) RET settls: + MOVQ g_m(BX), AX LEAQ m_tls(AX), AX MOVQ AX, 0x28(GS) #endif get_tls(CX) - MOVQ mm+0(FP), AX - MOVQ AX, m(CX) - MOVQ gg+8(FP), BX MOVQ BX, g(CX) RET -// void setmg_gcc(M*, G*); set m and g called from gcc. -TEXT setmg_gcc<>(SB),NOSPLIT,$0 +// void setg_gcc(G*); set g called from gcc. +TEXT setg_gcc<>(SB),NOSPLIT,$0 get_tls(AX) - MOVQ DI, m(AX) - MOVQ SI, g(AX) + MOVQ DI, g(AX) RET // check that SP is in range [g->stackbase, g->stackguard) diff --git a/src/pkg/runtime/asm_amd64p32.s b/src/pkg/runtime/asm_amd64p32.s index b70ab698af..a1cc631e05 100644 --- a/src/pkg/runtime/asm_amd64p32.s +++ b/src/pkg/runtime/asm_amd64p32.s @@ -53,10 +53,11 @@ ok: LEAL runtime·g0(SB), CX MOVL CX, g(BX) LEAL runtime·m0(SB), AX - MOVL AX, m(BX) // save m->g0 = g0 MOVL CX, m_g0(AX) + // save m0 to g0->m + MOVL AX, g_m(CX) CLD // convention is D is always left cleared CALL runtime·check(SB) @@ -147,7 +148,8 @@ TEXT runtime·mcall(SB), NOSPLIT, $0-4 MOVL AX, (g_sched+gobuf_g)(AX) // switch to m->g0 & its stack, call fn - MOVL m(CX), BX + MOVL g(CX), BX + MOVL g_m(BX), BX MOVL m_g0(BX), SI CMPL SI, AX // if g == m->g0 call badmcall JNE 3(PC) @@ -215,7 +217,8 @@ TEXT runtime·morestack(SB),NOSPLIT,$0-0 // func call(fn *byte, arg *byte, argsize uint32). TEXT runtime·newstackcall(SB), NOSPLIT, $0-20 get_tls(CX) - MOVL m(CX), BX + MOVL g(CX), BX + MOVL g_m(BX), BX // Save our caller's state as the PC and SP to // restore when returning from f. @@ -358,7 +361,8 @@ CALLFN(call1073741824, 1073741824) TEXT runtime·lessstack(SB), NOSPLIT, $0-0 // Save return value in m->cret get_tls(CX) - MOVL m(CX), BX + MOVL g(CX), BX + MOVL g_m(BX), BX MOVQ AX, m_cret(BX) // MOVQ, to save all 64 bits // Call oldstack on m->g0's stack. @@ -372,7 +376,8 @@ TEXT runtime·lessstack(SB), NOSPLIT, $0-0 // morestack trampolines TEXT runtime·morestack00(SB),NOSPLIT,$0 get_tls(CX) - MOVL m(CX), BX + MOVL g(CX), BX + MOVL g_m(BX), BX MOVQ $0, AX MOVQ AX, m_moreframesize(BX) MOVL $runtime·morestack(SB), AX @@ -380,7 +385,8 @@ TEXT runtime·morestack00(SB),NOSPLIT,$0 TEXT runtime·morestack01(SB),NOSPLIT,$0 get_tls(CX) - MOVL m(CX), BX + MOVL g(CX), BX + MOVL g_m(BX), BX SHLQ $32, AX MOVQ AX, m_moreframesize(BX) MOVL $runtime·morestack(SB), AX @@ -388,7 +394,8 @@ TEXT runtime·morestack01(SB),NOSPLIT,$0 TEXT runtime·morestack10(SB),NOSPLIT,$0 get_tls(CX) - MOVL m(CX), BX + MOVL g(CX), BX + MOVL g_m(BX), BX MOVLQZX AX, AX MOVQ AX, m_moreframesize(BX) MOVL $runtime·morestack(SB), AX @@ -396,7 +403,8 @@ TEXT runtime·morestack10(SB),NOSPLIT,$0 TEXT runtime·morestack11(SB),NOSPLIT,$0 get_tls(CX) - MOVL m(CX), BX + MOVL g(CX), BX + MOVL g_m(BX), BX MOVQ AX, m_moreframesize(BX) MOVL $runtime·morestack(SB), AX JMP AX @@ -435,7 +443,8 @@ TEXT runtime·morestack48(SB),NOSPLIT,$0 TEXT morestack<>(SB),NOSPLIT,$0 get_tls(CX) - MOVL m(CX), BX + MOVL g(CX), BX + MOVL g_m(BX), BX SHLQ $35, R8 MOVQ R8, m_moreframesize(BX) MOVL $runtime·morestack(SB), AX @@ -625,9 +634,9 @@ TEXT runtime·cgocallback(SB),NOSPLIT,$0-12 MOVL 0, AX RET -// void setmg(M*, G*); set m and g. for use by needm. +// void setg(G*); set g. for use by needm. // Not implemented. -TEXT runtime·setmg(SB), NOSPLIT, $0-8 +TEXT runtime·setg(SB), NOSPLIT, $0-8 MOVL 0, AX RET diff --git a/src/pkg/runtime/asm_arm.s b/src/pkg/runtime/asm_arm.s index bc0dd3ca7c..7564e96b1e 100644 --- a/src/pkg/runtime/asm_arm.s +++ b/src/pkg/runtime/asm_arm.s @@ -19,13 +19,15 @@ TEXT _rt0_go(SB),NOSPLIT,$-4 MOVW R0, 60(R13) // save argc, argv away MOVW R1, 64(R13) - // set up m and g registers - // g is R10, m is R9 + // set up g register + // g is R10 MOVW $runtime·g0(SB), g - MOVW $runtime·m0(SB), m + MOVW $runtime·m0(SB), R8 // save m->g0 = g0 - MOVW g, m_g0(m) + MOVW g, m_g0(R8) + // save g->m = m0 + MOVW R8, g_m(g) // create istack out of the OS stack MOVW $(-8192+104)(R13), R0 @@ -38,9 +40,9 @@ TEXT _rt0_go(SB),NOSPLIT,$-4 MOVW _cgo_init(SB), R4 CMP $0, R4 B.EQ nocgo - BL runtime·save_gm(SB); + BL runtime·save_g(SB); MOVW g, R0 // first argument of _cgo_init is g - MOVW $setmg_gcc<>(SB), R1 // second argument is address of save_gm + MOVW $setg_gcc<>(SB), R1 // second argument is address of save_g BL (R4) // will clobber R0-R3 nocgo: @@ -124,7 +126,7 @@ TEXT runtime·gogo(SB), NOSPLIT, $-4-4 MOVW 0(g), R2 // make sure g != nil MOVB runtime·iscgo(SB), R2 CMP $0, R2 // if in Cgo, we have to save g and m - BL.NE runtime·save_gm(SB) // this call will clobber R0 + BL.NE runtime·save_g(SB) // this call will clobber R0 MOVW gobuf_sp(R1), SP // restore SP MOVW gobuf_lr(R1), LR MOVW gobuf_ret(R1), R0 @@ -142,8 +144,6 @@ TEXT runtime·gogo(SB), NOSPLIT, $-4-4 // Fn must never return. It should gogo(&g->sched) // to keep running g. TEXT runtime·mcall(SB), NOSPLIT, $-4-4 - MOVW fn+0(FP), R0 - // Save caller state in g->sched. MOVW SP, (g_sched+gobuf_sp)(g) MOVW LR, (g_sched+gobuf_pc)(g) @@ -153,10 +153,15 @@ TEXT runtime·mcall(SB), NOSPLIT, $-4-4 // Switch to m->g0 & its stack, call fn. MOVW g, R1 - MOVW m_g0(m), g + MOVW g_m(g), R8 + MOVW m_g0(R8), g CMP g, R1 B.NE 2(PC) B runtime·badmcall(SB) + MOVB runtime·iscgo(SB), R11 + CMP $0, R11 + BL.NE runtime·save_g(SB) + MOVW fn+0(FP), R0 MOVW (g_sched+gobuf_sp)(g), SP SUB $8, SP MOVW R1, 4(SP) @@ -182,12 +187,13 @@ TEXT runtime·mcall(SB), NOSPLIT, $-4-4 // record an argument size. For that purpose, it has no arguments. TEXT runtime·morestack(SB),NOSPLIT,$-4-0 // Cannot grow scheduler stack (m->g0). - MOVW m_g0(m), R4 + MOVW g_m(g), R8 + MOVW m_g0(R8), R4 CMP g, R4 BL.EQ runtime·abort(SB) - MOVW R1, m_moreframesize(m) - MOVW R2, m_moreargsize(m) + MOVW R1, m_moreframesize(R8) + MOVW R2, m_moreargsize(R8) // Called from f. // Set g->sched to context in f. @@ -198,14 +204,14 @@ TEXT runtime·morestack(SB),NOSPLIT,$-4-0 // Called from f. // Set m->morebuf to f's caller. - MOVW R3, (m_morebuf+gobuf_pc)(m) // f's caller's PC - MOVW SP, (m_morebuf+gobuf_sp)(m) // f's caller's SP + MOVW R3, (m_morebuf+gobuf_pc)(R8) // f's caller's PC + MOVW SP, (m_morebuf+gobuf_sp)(R8) // f's caller's SP MOVW $4(SP), R3 // f's argument pointer - MOVW R3, m_moreargp(m) - MOVW g, (m_morebuf+gobuf_g)(m) + MOVW R3, m_moreargp(R8) + MOVW g, (m_morebuf+gobuf_g)(R8) // Call newstack on m->g0's stack. - MOVW m_g0(m), g + MOVW m_g0(R8), g MOVW (g_sched+gobuf_sp)(g), SP BL runtime·newstack(SB) @@ -225,9 +231,10 @@ TEXT runtime·morestack_noctxt(SB),NOSPLIT,$-4-0 TEXT runtime·newstackcall(SB), NOSPLIT, $-4-12 // Save our caller's state as the PC and SP to // restore when returning from f. - MOVW LR, (m_morebuf+gobuf_pc)(m) // our caller's PC - MOVW SP, (m_morebuf+gobuf_sp)(m) // our caller's SP - MOVW g, (m_morebuf+gobuf_g)(m) + MOVW g_m(g), R8 + MOVW LR, (m_morebuf+gobuf_pc)(R8) // our caller's PC + MOVW SP, (m_morebuf+gobuf_sp)(R8) // our caller's SP + MOVW g, (m_morebuf+gobuf_g)(R8) // Save our own state as the PC and SP to restore // if this goroutine needs to be restarted. @@ -246,14 +253,14 @@ TEXT runtime·newstackcall(SB), NOSPLIT, $-4-12 MOVW 8(SP), R1 // arg frame MOVW 12(SP), R2 // arg size - MOVW R0, m_cret(m) // f's PC - MOVW R1, m_moreargp(m) // f's argument pointer - MOVW R2, m_moreargsize(m) // f's argument size + MOVW R0, m_cret(R8) // f's PC + MOVW R1, m_moreargp(R8) // f's argument pointer + MOVW R2, m_moreargsize(R8) // f's argument size MOVW $1, R3 - MOVW R3, m_moreframesize(m) // f's frame size + MOVW R3, m_moreframesize(R8) // f's frame size // Call newstack on m->g0's stack. - MOVW m_g0(m), g + MOVW m_g0(R8), g MOVW (g_sched+gobuf_sp)(g), SP B runtime·newstack(SB) @@ -382,10 +389,11 @@ CALLFN(call1073741824, 1073741824) // as morestack; in that context, it has 0 arguments. TEXT runtime·lessstack(SB), NOSPLIT, $-4-0 // Save return value in m->cret - MOVW R0, m_cret(m) + MOVW g_m(g), R8 + MOVW R0, m_cret(R8) // Call oldstack on m->g0's stack. - MOVW m_g0(m), g + MOVW m_g0(R8), g MOVW (g_sched+gobuf_sp)(g), SP BL runtime·oldstack(SB) @@ -430,7 +438,8 @@ TEXT runtime·asmcgocall(SB),NOSPLIT,$0-8 // Figure out if we need to switch to m->g0 stack. // We get called to create new OS threads too, and those // come in on the m->g0 stack already. - MOVW m_g0(m), R3 + MOVW g_m(g), R8 + MOVW m_g0(R8), R3 CMP R3, g BEQ 4(PC) BL gosave<>(SB) @@ -470,26 +479,28 @@ TEXT runtime·cgocallback_gofunc(SB),NOSPLIT,$8-12 // Load m and g from thread-local storage. MOVB runtime·iscgo(SB), R0 CMP $0, R0 - BL.NE runtime·load_gm(SB) + BL.NE runtime·load_g(SB) - // If m is nil, Go did not create the current thread. + // If g is nil, Go did not create the current thread. // Call needm to obtain one for temporary use. // In this case, we're running on the thread stack, so there's // lots of space, but the linker doesn't know. Hide the call from // the linker analysis by using an indirect call. - MOVW m, savedm-4(SP) - CMP $0, m + CMP $0, g B.NE havem + MOVW g, savedm-4(SP) // g is zero, so is m. MOVW $runtime·needm(SB), R0 BL (R0) havem: + MOVW g_m(g), R8 + MOVW R8, savedm-4(SP) // Now there's a valid m, and we're running on its m->g0. // Save current m->g0->sched.sp on stack and then set it to SP. // Save current sp in m->g0->sched.sp in preparation for // switch back to m->curg stack. // NOTE: unwindm knows that the saved g->sched.sp is at 4(R13) aka savedsp-8(SP). - MOVW m_g0(m), R3 + MOVW m_g0(R8), R3 MOVW (g_sched+gobuf_sp)(R3), R4 MOVW R4, savedsp-8(SP) MOVW R13, (g_sched+gobuf_sp)(R3) @@ -512,7 +523,7 @@ havem: MOVW fn+4(FP), R0 MOVW frame+8(FP), R1 MOVW framesize+12(FP), R2 - MOVW m_curg(m), g + MOVW m_curg(R8), g MOVW (g_sched+gobuf_sp)(g), R4 // prepare stack as R4 MOVW (g_sched+gobuf_pc)(g), R5 MOVW R5, -12(R4) @@ -528,7 +539,8 @@ havem: // Switch back to m->g0's stack and restore m->g0->sched.sp. // (Unlike m->curg, the g0 goroutine never uses sched.pc, // so we do not have to restore it.) - MOVW m_g0(m), g + MOVW g_m(g), R8 + MOVW m_g0(R8), g MOVW (g_sched+gobuf_sp)(g), R13 MOVW savedsp-8(SP), R4 MOVW R4, (g_sched+gobuf_sp)(g) @@ -544,15 +556,14 @@ havem: // Done! RET -// void setmg(M*, G*); set m and g. for use by needm. -TEXT runtime·setmg(SB), NOSPLIT, $0-8 - MOVW mm+0(FP), m - MOVW gg+4(FP), g +// void setg(G*); set g. for use by needm. +TEXT runtime·setg(SB), NOSPLIT, $0-8 + MOVW gg+0(FP), g - // Save m and g to thread-local storage. + // Save g to thread-local storage. MOVB runtime·iscgo(SB), R0 CMP $0, R0 - BL.NE runtime·save_gm(SB) + BL.NE runtime·save_g(SB) RET @@ -685,40 +696,38 @@ _eqnext: // Note: all three functions will clobber R0, and the last // two can be called from 5c ABI code. -// save_gm saves the g and m registers into pthread-provided +// save_g saves the g register into pthread-provided // thread-local memory, so that we can call externally compiled // ARM code that will overwrite those registers. // NOTE: runtime.gogo assumes that R1 is preserved by this function. -TEXT runtime·save_gm(SB),NOSPLIT,$0 +// runtime.mcall assumes this function only clobbers R0 and R11. +TEXT runtime·save_g(SB),NOSPLIT,$0 MRC 15, 0, R0, C13, C0, 3 // fetch TLS base pointer - // $runtime.tlsgm(SB) is a special linker symbol. + // $runtime.tlsg(SB) is a special linker symbol. // It is the offset from the TLS base pointer to our - // thread-local storage for g and m. - MOVW $runtime·tlsgm(SB), R11 + // thread-local storage for g. + MOVW $runtime·tlsg(SB), R11 ADD R11, R0 MOVW g, 0(R0) - MOVW m, 4(R0) RET -// load_gm loads the g and m registers from pthread-provided +// load_g loads the g register from pthread-provided // thread-local memory, for use after calling externally compiled // ARM code that overwrote those registers. -TEXT runtime·load_gm(SB),NOSPLIT,$0 +TEXT runtime·load_g(SB),NOSPLIT,$0 MRC 15, 0, R0, C13, C0, 3 // fetch TLS base pointer - // $runtime.tlsgm(SB) is a special linker symbol. + // $runtime.tlsg(SB) is a special linker symbol. // It is the offset from the TLS base pointer to our - // thread-local storage for g and m. - MOVW $runtime·tlsgm(SB), R11 + // thread-local storage for g. + MOVW $runtime·tlsg(SB), R11 ADD R11, R0 MOVW 0(R0), g - MOVW 4(R0), m RET -// void setmg_gcc(M*, G*); set m and g called from gcc. -TEXT setmg_gcc<>(SB),NOSPLIT,$0 - MOVW R0, m - MOVW R1, g - B runtime·save_gm(SB) +// void setg_gcc(M*, G*); set m and g called from gcc. +TEXT setg_gcc<>(SB),NOSPLIT,$0 + MOVW R0, g + B runtime·save_g(SB) // TODO: share code with memeq? TEXT bytes·Equal(SB),NOSPLIT,$0 diff --git a/src/pkg/runtime/cgo/asm_arm.s b/src/pkg/runtime/cgo/asm_arm.s index 850b1c6b61..b989ab9330 100644 --- a/src/pkg/runtime/cgo/asm_arm.s +++ b/src/pkg/runtime/cgo/asm_arm.s @@ -14,11 +14,11 @@ TEXT crosscall2(SB),NOSPLIT,$-4 * push 2 args for fn (R1 and R2). * Also note that at procedure entry in 5c/5g world, 4(R13) will be the * first arg, so we must push another dummy reg (R0) for 0(R13). - * Additionally, runtime·load_gm will clobber R0, so we need to save R0 + * Additionally, runtime·load_g will clobber R0, so we need to save R0 * nevertheless. */ - MOVM.WP [R0, R1, R2, R4, R5, R6, R7, R8, m, g, R11, R12, R14], (R13) - BL runtime·load_gm(SB) + MOVM.WP [R0, R1, R2, R4, R5, R6, R7, R8, R9, g, R11, R12, R14], (R13) + BL runtime·load_g(SB) MOVW PC, R14 MOVW 0(R13), PC - MOVM.IAW (R13), [R0, R1, R2, R4, R5, R6, R7, R8, m, g, R11, R12, PC] + MOVM.IAW (R13), [R0, R1, R2, R4, R5, R6, R7, R8, R9, g, R11, R12, PC] diff --git a/src/pkg/runtime/cgo/callbacks.c b/src/pkg/runtime/cgo/callbacks.c index e91c8bf8a3..5a4889c9b3 100644 --- a/src/pkg/runtime/cgo/callbacks.c +++ b/src/pkg/runtime/cgo/callbacks.c @@ -40,9 +40,9 @@ _cgo_allocate_internal(uintptr len, byte *ret) ret = runtime·mal(len); c = runtime·mal(sizeof(*c)); - c->next = m->cgomal; + c->next = g->m->cgomal; c->alloc = ret; - m->cgomal = c; + g->m->cgomal = c; FLUSH(&ret); } diff --git a/src/pkg/runtime/cgo/gcc_arm.S b/src/pkg/runtime/cgo/gcc_arm.S index 17e98d91f6..336f8ca62c 100644 --- a/src/pkg/runtime/cgo/gcc_arm.S +++ b/src/pkg/runtime/cgo/gcc_arm.S @@ -19,20 +19,19 @@ .arch armv5t /* - * void crosscall_arm2(void (*fn)(void), void (*setmg_gcc)(void *m, void *g), void *m, void *g) + * void crosscall_arm1(void (*fn)(void), void (*setg_gcc)(void *g), void *g) * * Calling into the 5c tool chain, where all registers are caller save. * Called from standard ARM EABI, where r4-r11 are callee-save, so they * must be saved explicitly. */ -.globl EXT(crosscall_arm2) -EXT(crosscall_arm2): +.globl EXT(crosscall_arm1) +EXT(crosscall_arm1): push {r4, r5, r6, r7, r8, r9, r10, r11, ip, lr} mov r4, r0 mov r5, r1 mov r0, r2 - mov r1, r3 - blx r5 // setmg(m, g) + blx r5 // setmg(g) blx r4 // fn() pop {r4, r5, r6, r7, r8, r9, r10, r11, ip, pc} diff --git a/src/pkg/runtime/cgo/gcc_darwin_386.c b/src/pkg/runtime/cgo/gcc_darwin_386.c index ad9fb5abf6..d1ef31ed4e 100644 --- a/src/pkg/runtime/cgo/gcc_darwin_386.c +++ b/src/pkg/runtime/cgo/gcc_darwin_386.c @@ -8,46 +8,44 @@ #include "libcgo.h" static void* threadentry(void*); -static pthread_key_t k1, k2; +static pthread_key_t k1; #define magic1 (0x23581321U) static void inittls(void) { - uint32 x, y; + uint32 x; pthread_key_t tofree[128], k; int i, ntofree; - int havek1, havek2; /* - * Allocate thread-local storage slots for m, g. + * Allocate thread-local storage slot for g. * The key numbers start at 0x100, and we expect to be * one of the early calls to pthread_key_create, so we - * should be able to get pretty low numbers. + * should be able to get a pretty low number. * * In Darwin/386 pthreads, %gs points at the thread * structure, and each key is an index into the thread-local * storage array that begins at offset 0x48 within in that structure. * It may happen that we are not quite the first function to try * to allocate thread-local storage keys, so instead of depending - * on getting 0x100 and 0x101, we try for 0x108 and 0x109, - * allocating keys until we get the ones we want and then freeing - * the ones we didn't want. + * on getting 0x100, we try for 0x108, allocating keys until + * we get the one we want and then freeing the ones we didn't want. * - * Thus the final offsets to use in %gs references are - * 0x48+4*0x108 = 0x468 and 0x48+4*0x109 = 0x46c. + * Thus the final offset to use in %gs references is + * 0x48+4*0x108 = 0x468. * - * The linker and runtime hard-code these constant offsets - * from %gs where we expect to find m and g. - * Known to ../../../cmd/8l/obj.c:/468 + * The linker and runtime hard-code this constant offset + * from %gs where we expect to find g. + * Known to ../../../liblink/sym.c:/468 * and to ../sys_darwin_386.s:/468 * * This is truly disgusting and a bit fragile, but taking care * of it here protects the rest of the system from damage. * The alternative would be to use a global variable that * held the offset and refer to that variable each time we - * need a %gs variable (m or g). That approach would + * need a %gs variable (g). That approach would * require an extra instruction and memory reference in * every stack growth prolog and would also require * rewriting the code that 8c generates for extern registers. @@ -63,39 +61,32 @@ inittls(void) * storage until we find a key that writes to the memory location * we want. Then keep that key. */ - havek1 = 0; - havek2 = 0; ntofree = 0; - while(!havek1 || !havek2) { + for(;;) { if(pthread_key_create(&k, nil) < 0) { fprintf(stderr, "runtime/cgo: pthread_key_create failed\n"); abort(); } pthread_setspecific(k, (void*)magic1); asm volatile("movl %%gs:0x468, %0" : "=r"(x)); - asm volatile("movl %%gs:0x46c, %0" : "=r"(y)); + pthread_setspecific(k, 0); if(x == magic1) { - havek1 = 1; k1 = k; - } else if(y == magic1) { - havek2 = 1; - k2 = k; - } else { - if(ntofree >= nelem(tofree)) { - fprintf(stderr, "runtime/cgo: could not obtain pthread_keys\n"); - fprintf(stderr, "\ttried"); - for(i=0; i= nelem(tofree)) { + fprintf(stderr, "runtime/cgo: could not obtain pthread_keys\n"); + fprintf(stderr, "\ttried"); + for(i=0; istackguard = (uintptr)&ts - ts.g->stackguard + 4096; pthread_setspecific(k1, (void*)ts.g); - pthread_setspecific(k2, (void*)ts.m); crosscall_386(ts.fn); return nil; diff --git a/src/pkg/runtime/cgo/gcc_darwin_amd64.c b/src/pkg/runtime/cgo/gcc_darwin_amd64.c index 65d381633d..358a2816a3 100644 --- a/src/pkg/runtime/cgo/gcc_darwin_amd64.c +++ b/src/pkg/runtime/cgo/gcc_darwin_amd64.c @@ -8,64 +8,56 @@ #include "libcgo.h" static void* threadentry(void*); -static pthread_key_t k1, k2; +static pthread_key_t k1; #define magic1 (0x23581321345589ULL) static void inittls(void) { - uint64 x, y; + uint64 x; pthread_key_t tofree[128], k; int i, ntofree; - int havek1, havek2; /* * Same logic, code as darwin_386.c:/inittls, except that words * are 8 bytes long now, and the thread-local storage starts - * at 0x60 on Leopard / Snow Leopard. So the offsets are - * 0x60+8*0x108 = 0x8a0 and 0x60+8*0x109 = 0x8a8. + * at 0x60 on Leopard / Snow Leopard. So the offset is + * 0x60+8*0x108 = 0x8a0. * - * The linker and runtime hard-code these constant offsets - * from %gs where we expect to find m and g. - * Known to ../../../cmd/6l/obj.c:/8a0 + * The linker and runtime hard-code this constant offset + * from %gs where we expect to find g. + * Known to ../../../liblink/sym.c:/8a0 * and to ../sys_darwin_amd64.s:/8a0 * * As disgusting as on the 386; same justification. */ - havek1 = 0; - havek2 = 0; ntofree = 0; - while(!havek1 || !havek2) { + for(;;) { if(pthread_key_create(&k, nil) < 0) { fprintf(stderr, "runtime/cgo: pthread_key_create failed\n"); abort(); } pthread_setspecific(k, (void*)magic1); asm volatile("movq %%gs:0x8a0, %0" : "=r"(x)); - asm volatile("movq %%gs:0x8a8, %0" : "=r"(y)); + pthread_setspecific(k, 0); if(x == magic1) { - havek1 = 1; k1 = k; - } else if(y == magic1) { - havek2 = 1; - k2 = k; - } else { - if(ntofree >= nelem(tofree)) { - fprintf(stderr, "runtime/cgo: could not obtain pthread_keys\n"); - fprintf(stderr, "\ttried"); - for(i=0; i= nelem(tofree)) { + fprintf(stderr, "runtime/cgo: could not obtain pthread_keys\n"); + fprintf(stderr, "\ttried"); + for(i=0; istackguard = (uintptr)&ts - ts.g->stackguard + 4096; pthread_setspecific(k1, (void*)ts.g); - pthread_setspecific(k2, (void*)ts.m); crosscall_amd64(ts.fn); return nil; diff --git a/src/pkg/runtime/cgo/gcc_dragonfly_386.c b/src/pkg/runtime/cgo/gcc_dragonfly_386.c index 695c16634b..6af61ac495 100644 --- a/src/pkg/runtime/cgo/gcc_dragonfly_386.c +++ b/src/pkg/runtime/cgo/gcc_dragonfly_386.c @@ -10,15 +10,15 @@ #include "libcgo.h" static void* threadentry(void*); -static void (*setmg_gcc)(void*, void*); +static void (*setg_gcc)(void*); void -x_cgo_init(G *g, void (*setmg)(void*, void*)) +x_cgo_init(G *g, void (*setg)(void*)) { pthread_attr_t attr; size_t size; - setmg_gcc = setmg; + setg_gcc = setg; pthread_attr_init(&attr); pthread_attr_getstacksize(&attr, &size); g->stackguard = (uintptr)&attr - size + 4096; @@ -70,7 +70,7 @@ threadentry(void *v) /* * Set specific keys. */ - setmg_gcc((void*)ts.m, (void*)ts.g); + setg_gcc((void*)ts.g); crosscall_386(ts.fn); return nil; diff --git a/src/pkg/runtime/cgo/gcc_dragonfly_amd64.c b/src/pkg/runtime/cgo/gcc_dragonfly_amd64.c index a46c121ad9..a29d522946 100644 --- a/src/pkg/runtime/cgo/gcc_dragonfly_amd64.c +++ b/src/pkg/runtime/cgo/gcc_dragonfly_amd64.c @@ -10,15 +10,15 @@ #include "libcgo.h" static void* threadentry(void*); -static void (*setmg_gcc)(void*, void*); +static void (*setg_gcc)(void*); void -x_cgo_init(G *g, void (*setmg)(void*, void*)) +x_cgo_init(G *g, void (*setg)(void*)) { pthread_attr_t attr; size_t size; - setmg_gcc = setmg; + setg_gcc = setg; pthread_attr_init(&attr); pthread_attr_getstacksize(&attr, &size); g->stackguard = (uintptr)&attr - size + 4096; @@ -70,7 +70,7 @@ threadentry(void *v) /* * Set specific keys. */ - setmg_gcc((void*)ts.m, (void*)ts.g); + setg_gcc((void*)ts.g); crosscall_amd64(ts.fn); return nil; diff --git a/src/pkg/runtime/cgo/gcc_freebsd_386.c b/src/pkg/runtime/cgo/gcc_freebsd_386.c index 695c16634b..6af61ac495 100644 --- a/src/pkg/runtime/cgo/gcc_freebsd_386.c +++ b/src/pkg/runtime/cgo/gcc_freebsd_386.c @@ -10,15 +10,15 @@ #include "libcgo.h" static void* threadentry(void*); -static void (*setmg_gcc)(void*, void*); +static void (*setg_gcc)(void*); void -x_cgo_init(G *g, void (*setmg)(void*, void*)) +x_cgo_init(G *g, void (*setg)(void*)) { pthread_attr_t attr; size_t size; - setmg_gcc = setmg; + setg_gcc = setg; pthread_attr_init(&attr); pthread_attr_getstacksize(&attr, &size); g->stackguard = (uintptr)&attr - size + 4096; @@ -70,7 +70,7 @@ threadentry(void *v) /* * Set specific keys. */ - setmg_gcc((void*)ts.m, (void*)ts.g); + setg_gcc((void*)ts.g); crosscall_386(ts.fn); return nil; diff --git a/src/pkg/runtime/cgo/gcc_freebsd_amd64.c b/src/pkg/runtime/cgo/gcc_freebsd_amd64.c index a46c121ad9..a29d522946 100644 --- a/src/pkg/runtime/cgo/gcc_freebsd_amd64.c +++ b/src/pkg/runtime/cgo/gcc_freebsd_amd64.c @@ -10,15 +10,15 @@ #include "libcgo.h" static void* threadentry(void*); -static void (*setmg_gcc)(void*, void*); +static void (*setg_gcc)(void*); void -x_cgo_init(G *g, void (*setmg)(void*, void*)) +x_cgo_init(G *g, void (*setg)(void*)) { pthread_attr_t attr; size_t size; - setmg_gcc = setmg; + setg_gcc = setg; pthread_attr_init(&attr); pthread_attr_getstacksize(&attr, &size); g->stackguard = (uintptr)&attr - size + 4096; @@ -70,7 +70,7 @@ threadentry(void *v) /* * Set specific keys. */ - setmg_gcc((void*)ts.m, (void*)ts.g); + setg_gcc((void*)ts.g); crosscall_amd64(ts.fn); return nil; diff --git a/src/pkg/runtime/cgo/gcc_freebsd_arm.c b/src/pkg/runtime/cgo/gcc_freebsd_arm.c index 6175e1d9cc..16530f0200 100644 --- a/src/pkg/runtime/cgo/gcc_freebsd_arm.c +++ b/src/pkg/runtime/cgo/gcc_freebsd_arm.c @@ -21,15 +21,15 @@ static void *threadentry(void*); -static void (*setmg_gcc)(void*, void*); +static void (*setg_gcc)(void*); void -x_cgo_init(G *g, void (*setmg)(void*, void*)) +x_cgo_init(G *g, void (*setg)(void*)) { pthread_attr_t attr; size_t size; - setmg_gcc = setmg; + setg_gcc = setg; pthread_attr_init(&attr); pthread_attr_getstacksize(&attr, &size); g->stackguard = (uintptr)&attr - size + 4096; @@ -67,7 +67,7 @@ _cgo_sys_thread_start(ThreadStart *ts) } } -extern void crosscall_arm2(void (*fn)(void), void (*setmg_gcc)(void*, void*), void *g, void *m); +extern void crosscall_arm1(void (*fn)(void), void (*setg_gcc)(void*), void *g); static void* threadentry(void *v) { @@ -84,6 +84,6 @@ threadentry(void *v) */ ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096 * 2; - crosscall_arm2(ts.fn, setmg_gcc, (void*)ts.m, (void*)ts.g); + crosscall_arm1(ts.fn, setg_gcc, (void*)ts.g); return nil; } diff --git a/src/pkg/runtime/cgo/gcc_linux_386.c b/src/pkg/runtime/cgo/gcc_linux_386.c index 0a46c9b7a2..5b282c9b8e 100644 --- a/src/pkg/runtime/cgo/gcc_linux_386.c +++ b/src/pkg/runtime/cgo/gcc_linux_386.c @@ -8,15 +8,15 @@ #include "libcgo.h" static void *threadentry(void*); -static void (*setmg_gcc)(void*, void*); +static void (*setg_gcc)(void*); void -x_cgo_init(G *g, void (*setmg)(void*, void*)) +x_cgo_init(G *g, void (*setg)(void*)) { pthread_attr_t attr; size_t size; - setmg_gcc = setmg; + setg_gcc = setg; pthread_attr_init(&attr); pthread_attr_getstacksize(&attr, &size); g->stackguard = (uintptr)&attr - size + 4096; @@ -73,7 +73,7 @@ threadentry(void *v) /* * Set specific keys. */ - setmg_gcc((void*)ts.m, (void*)ts.g); + setg_gcc((void*)ts.g); crosscall_386(ts.fn); return nil; diff --git a/src/pkg/runtime/cgo/gcc_linux_amd64.c b/src/pkg/runtime/cgo/gcc_linux_amd64.c index c530183b73..19ca580b7f 100644 --- a/src/pkg/runtime/cgo/gcc_linux_amd64.c +++ b/src/pkg/runtime/cgo/gcc_linux_amd64.c @@ -8,15 +8,15 @@ #include "libcgo.h" static void* threadentry(void*); -static void (*setmg_gcc)(void*, void*); +static void (*setg_gcc)(void*); void -x_cgo_init(G* g, void (*setmg)(void*, void*)) +x_cgo_init(G* g, void (*setg)(void*)) { pthread_attr_t attr; size_t size; - setmg_gcc = setmg; + setg_gcc = setg; pthread_attr_init(&attr); pthread_attr_getstacksize(&attr, &size); g->stackguard = (uintptr)&attr - size + 4096; @@ -68,7 +68,7 @@ threadentry(void *v) /* * Set specific keys. */ - setmg_gcc((void*)ts.m, (void*)ts.g); + setg_gcc((void*)ts.g); crosscall_amd64(ts.fn); return nil; diff --git a/src/pkg/runtime/cgo/gcc_linux_arm.c b/src/pkg/runtime/cgo/gcc_linux_arm.c index 0325681556..3b108fec22 100644 --- a/src/pkg/runtime/cgo/gcc_linux_arm.c +++ b/src/pkg/runtime/cgo/gcc_linux_arm.c @@ -9,15 +9,15 @@ static void *threadentry(void*); -static void (*setmg_gcc)(void*, void*); +static void (*setg_gcc)(void*); void -x_cgo_init(G *g, void (*setmg)(void*, void*)) +x_cgo_init(G *g, void (*setg)(void*)) { pthread_attr_t attr; size_t size; - setmg_gcc = setmg; + setg_gcc = setg; pthread_attr_init(&attr); pthread_attr_getstacksize(&attr, &size); g->stackguard = (uintptr)&attr - size + 4096; @@ -55,7 +55,7 @@ _cgo_sys_thread_start(ThreadStart *ts) } } -extern void crosscall_arm2(void (*fn)(void), void (*setmg_gcc)(void*, void*), void*, void*); +extern void crosscall_arm1(void (*fn)(void), void (*setg_gcc)(void*), void *g); static void* threadentry(void *v) { @@ -72,6 +72,6 @@ threadentry(void *v) */ ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096 * 2; - crosscall_arm2(ts.fn, setmg_gcc, (void*)ts.m, (void*)ts.g); + crosscall_arm1(ts.fn, setg_gcc, (void*)ts.g); return nil; } diff --git a/src/pkg/runtime/cgo/gcc_netbsd_386.c b/src/pkg/runtime/cgo/gcc_netbsd_386.c index 28690ccbdf..a2b7ef3fc5 100644 --- a/src/pkg/runtime/cgo/gcc_netbsd_386.c +++ b/src/pkg/runtime/cgo/gcc_netbsd_386.c @@ -9,15 +9,15 @@ #include "libcgo.h" static void* threadentry(void*); -static void (*setmg_gcc)(void*, void*); +static void (*setg_gcc)(void*); void -x_cgo_init(G *g, void (*setmg)(void*, void*)) +x_cgo_init(G *g, void (*setg)(void*)) { pthread_attr_t attr; size_t size; - setmg_gcc = setmg; + setg_gcc = setg; pthread_attr_init(&attr); pthread_attr_getstacksize(&attr, &size); g->stackguard = (uintptr)&attr - size + 4096; @@ -69,7 +69,7 @@ threadentry(void *v) /* * Set specific keys. */ - setmg_gcc((void*)ts.m, (void*)ts.g); + setg_gcc((void*)ts.g); crosscall_386(ts.fn); return nil; diff --git a/src/pkg/runtime/cgo/gcc_netbsd_amd64.c b/src/pkg/runtime/cgo/gcc_netbsd_amd64.c index 6e0482d5b1..ccd08b73ce 100644 --- a/src/pkg/runtime/cgo/gcc_netbsd_amd64.c +++ b/src/pkg/runtime/cgo/gcc_netbsd_amd64.c @@ -9,15 +9,15 @@ #include "libcgo.h" static void* threadentry(void*); -static void (*setmg_gcc)(void*, void*); +static void (*setg_gcc)(void*); void -x_cgo_init(G *g, void (*setmg)(void*, void*)) +x_cgo_init(G *g, void (*setg)(void*)) { pthread_attr_t attr; size_t size; - setmg_gcc = setmg; + setg_gcc = setg; pthread_attr_init(&attr); pthread_attr_getstacksize(&attr, &size); g->stackguard = (uintptr)&attr - size + 4096; @@ -70,7 +70,7 @@ threadentry(void *v) /* * Set specific keys. */ - setmg_gcc((void*)ts.m, (void*)ts.g); + setg_gcc((void*)ts.g); crosscall_amd64(ts.fn); return nil; diff --git a/src/pkg/runtime/cgo/gcc_netbsd_arm.c b/src/pkg/runtime/cgo/gcc_netbsd_arm.c index ba2ae2568c..5c0603dc6e 100644 --- a/src/pkg/runtime/cgo/gcc_netbsd_arm.c +++ b/src/pkg/runtime/cgo/gcc_netbsd_arm.c @@ -10,15 +10,15 @@ static void *threadentry(void*); -static void (*setmg_gcc)(void*, void*); +static void (*setg_gcc)(void*); void -x_cgo_init(G *g, void (*setmg)(void*, void*)) +x_cgo_init(G *g, void (*setg)(void*)) { pthread_attr_t attr; size_t size; - setmg_gcc = setmg; + setg_gcc = setg; pthread_attr_init(&attr); pthread_attr_getstacksize(&attr, &size); g->stackguard = (uintptr)&attr - size + 4096; @@ -51,7 +51,7 @@ _cgo_sys_thread_start(ThreadStart *ts) } } -extern void crosscall_arm2(void (*fn)(void), void (*setmg_gcc)(void*, void*), void *g, void *m); +extern void crosscall_arm1(void (*fn)(void), void (*setg_gcc)(void*), void *g); static void* threadentry(void *v) { @@ -68,6 +68,6 @@ threadentry(void *v) */ ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096 * 2; - crosscall_arm2(ts.fn, setmg_gcc, (void*)ts.m, (void*)ts.g); + crosscall_arm1(ts.fn, setg_gcc, (void*)ts.g); return nil; } diff --git a/src/pkg/runtime/cgo/gcc_openbsd_386.c b/src/pkg/runtime/cgo/gcc_openbsd_386.c index e682c37251..48b4bc7393 100644 --- a/src/pkg/runtime/cgo/gcc_openbsd_386.c +++ b/src/pkg/runtime/cgo/gcc_openbsd_386.c @@ -11,7 +11,7 @@ #include "libcgo.h" static void* threadentry(void*); -static void (*setmg_gcc)(void*, void*); +static void (*setg_gcc)(void*); // TCB_SIZE is sizeof(struct thread_control_block), // as defined in /usr/src/lib/librthread/tcb.h @@ -83,13 +83,13 @@ pthread_create(pthread_t *thread, const pthread_attr_t *attr, } void -x_cgo_init(G *g, void (*setmg)(void*, void*)) +x_cgo_init(G *g, void (*setg)(void*)) { pthread_attr_t attr; size_t size; void *handle; - setmg_gcc = setmg; + setg_gcc = setg; pthread_attr_init(&attr); pthread_attr_getstacksize(&attr, &size); g->stackguard = (uintptr)&attr - size + 4096; @@ -158,7 +158,7 @@ threadentry(void *v) /* * Set specific keys. */ - setmg_gcc((void*)ts.m, (void*)ts.g); + setg_gcc((void*)ts.g); crosscall_386(ts.fn); return nil; diff --git a/src/pkg/runtime/cgo/gcc_openbsd_amd64.c b/src/pkg/runtime/cgo/gcc_openbsd_amd64.c index 64d29a935b..5f0d3bb453 100644 --- a/src/pkg/runtime/cgo/gcc_openbsd_amd64.c +++ b/src/pkg/runtime/cgo/gcc_openbsd_amd64.c @@ -11,7 +11,7 @@ #include "libcgo.h" static void* threadentry(void*); -static void (*setmg_gcc)(void*, void*); +static void (*setg_gcc)(void*); // TCB_SIZE is sizeof(struct thread_control_block), // as defined in /usr/src/lib/librthread/tcb.h @@ -83,13 +83,13 @@ pthread_create(pthread_t *thread, const pthread_attr_t *attr, } void -x_cgo_init(G *g, void (*setmg)(void*, void*)) +x_cgo_init(G *g, void (*setg)(void*)) { pthread_attr_t attr; size_t size; void *handle; - setmg_gcc = setmg; + setg_gcc = setg; pthread_attr_init(&attr); pthread_attr_getstacksize(&attr, &size); g->stackguard = (uintptr)&attr - size + 4096; @@ -159,7 +159,7 @@ threadentry(void *v) /* * Set specific keys. */ - setmg_gcc((void*)ts.m, (void*)ts.g); + setg_gcc((void*)ts.g); crosscall_amd64(ts.fn); return nil; diff --git a/src/pkg/runtime/cgo/gcc_windows_386.c b/src/pkg/runtime/cgo/gcc_windows_386.c index cdc866468f..0935b74f22 100644 --- a/src/pkg/runtime/cgo/gcc_windows_386.c +++ b/src/pkg/runtime/cgo/gcc_windows_386.c @@ -54,8 +54,7 @@ threadentry(void *v) "movl %0, %%fs:0x14\n" // MOVL tls0, 0x14(FS) "movl %%fs:0x14, %%eax\n" // MOVL 0x14(FS), tmp "movl %1, 0(%%eax)\n" // MOVL g, 0(FS) - "movl %2, 4(%%eax)\n" // MOVL m, 4(FS) - :: "r"(ts.tls), "r"(ts.g), "r"(ts.m) : "%eax" + :: "r"(ts.tls), "r"(ts.g) : "%eax" ); crosscall_386(ts.fn); diff --git a/src/pkg/runtime/cgo/gcc_windows_amd64.c b/src/pkg/runtime/cgo/gcc_windows_amd64.c index d8dd69b4a7..4a2540a352 100644 --- a/src/pkg/runtime/cgo/gcc_windows_amd64.c +++ b/src/pkg/runtime/cgo/gcc_windows_amd64.c @@ -54,8 +54,7 @@ threadentry(void *v) "movq %0, %%gs:0x28\n" // MOVL tls0, 0x28(GS) "movq %%gs:0x28, %%rax\n" // MOVQ 0x28(GS), tmp "movq %1, 0(%%rax)\n" // MOVQ g, 0(GS) - "movq %2, 8(%%rax)\n" // MOVQ m, 8(GS) - :: "r"(ts.tls), "r"(ts.g), "r"(ts.m) : "%rax" + :: "r"(ts.tls), "r"(ts.g) : "%rax" ); crosscall_amd64(ts.fn); diff --git a/src/pkg/runtime/cgo/libcgo.h b/src/pkg/runtime/cgo/libcgo.h index 65ea3f3726..251fb4c68e 100644 --- a/src/pkg/runtime/cgo/libcgo.h +++ b/src/pkg/runtime/cgo/libcgo.h @@ -32,7 +32,6 @@ struct G typedef struct ThreadStart ThreadStart; struct ThreadStart { - uintptr m; G *g; uintptr *tls; void (*fn)(void); diff --git a/src/pkg/runtime/cgocall.c b/src/pkg/runtime/cgocall.c index 7b2ec26f3c..aa4cf5ee52 100644 --- a/src/pkg/runtime/cgocall.c +++ b/src/pkg/runtime/cgocall.c @@ -112,7 +112,7 @@ runtime·cgocall(void (*fn)(void*), void *arg) if(runtime·needextram && runtime·cas(&runtime·needextram, 1, 0)) runtime·newextram(); - m->ncgocall++; + g->m->ncgocall++; /* * Lock g to m to ensure we stay on the same stack if we do a @@ -126,7 +126,7 @@ runtime·cgocall(void (*fn)(void*), void *arg) d.special = true; g->defer = &d; - m->ncgo++; + g->m->ncgo++; /* * Announce we are entering a system call @@ -153,12 +153,12 @@ static void endcgo(void) { runtime·unlockOSThread(); - m->ncgo--; - if(m->ncgo == 0) { + g->m->ncgo--; + if(g->m->ncgo == 0) { // We are going back to Go and are not in a recursive // call. Let the GC collect any memory allocated via // _cgo_allocate that is no longer referenced. - m->cgomal = nil; + g->m->cgomal = nil; } if(raceenabled) @@ -210,12 +210,12 @@ struct CallbackArgs // On arm, stack frame is two words and there's a saved LR between // SP and the stack frame and between the stack frame and the arguments. #ifdef GOARCH_arm -#define CBARGS (CallbackArgs*)((byte*)m->g0->sched.sp+4*sizeof(void*)) +#define CBARGS (CallbackArgs*)((byte*)g->m->g0->sched.sp+4*sizeof(void*)) #endif // On amd64, stack frame is one word, plus caller PC. #ifdef GOARCH_amd64 -#define CBARGS (CallbackArgs*)((byte*)m->g0->sched.sp+2*sizeof(void*)) +#define CBARGS (CallbackArgs*)((byte*)g->m->g0->sched.sp+2*sizeof(void*)) #endif // Unimplemented on amd64p32 @@ -225,7 +225,7 @@ struct CallbackArgs // On 386, stack frame is three words, plus caller PC. #ifdef GOARCH_386 -#define CBARGS (CallbackArgs*)((byte*)m->g0->sched.sp+4*sizeof(void*)) +#define CBARGS (CallbackArgs*)((byte*)g->m->g0->sched.sp+4*sizeof(void*)) #endif void runtime·cgocallbackg1(void); @@ -234,7 +234,7 @@ void runtime·cgocallbackg1(void); void runtime·cgocallbackg(void) { - if(g != m->curg) { + if(g != g->m->curg) { runtime·prints("runtime: bad g in cgocallback"); runtime·exit(2); } @@ -250,8 +250,8 @@ runtime·cgocallbackg1(void) CallbackArgs *cb; Defer d; - if(m->needextram) { - m->needextram = 0; + if(g->m->needextram) { + g->m->needextram = 0; runtime·newextram(); } @@ -291,10 +291,10 @@ unwindm(void) runtime·throw("runtime: unwindm not implemented"); case '8': case '6': - m->g0->sched.sp = *(uintptr*)m->g0->sched.sp; + g->m->g0->sched.sp = *(uintptr*)g->m->g0->sched.sp; break; case '5': - m->g0->sched.sp = *(uintptr*)((byte*)m->g0->sched.sp + 4); + g->m->g0->sched.sp = *(uintptr*)((byte*)g->m->g0->sched.sp + 4); break; } } diff --git a/src/pkg/runtime/heapdump.c b/src/pkg/runtime/heapdump.c index 744c59f9bc..868f239301 100644 --- a/src/pkg/runtime/heapdump.c +++ b/src/pkg/runtime/heapdump.c @@ -800,8 +800,8 @@ runtime∕debug·WriteHeapDump(uintptr fd) { // Stop the world. runtime·semacquire(&runtime·worldsema, false); - m->gcing = 1; - m->locks++; + g->m->gcing = 1; + g->m->locks++; runtime·stoptheworld(); // Update stats so we can dump them. @@ -821,10 +821,10 @@ runtime∕debug·WriteHeapDump(uintptr fd) dumpfd = 0; // Start up the world again. - m->gcing = 0; + g->m->gcing = 0; runtime·semrelease(&runtime·worldsema); runtime·starttheworld(); - m->locks--; + g->m->locks--; } // Runs the specified gc program. Calls the callback for every diff --git a/src/pkg/runtime/lock_futex.c b/src/pkg/runtime/lock_futex.c index c16ac905dd..7fc2d5547d 100644 --- a/src/pkg/runtime/lock_futex.c +++ b/src/pkg/runtime/lock_futex.c @@ -39,7 +39,7 @@ runtime·lock(Lock *l) { uint32 i, v, wait, spin; - if(m->locks++ < 0) + if(g->m->locks++ < 0) runtime·throw("runtime·lock: lock count"); // Speculative grab for lock. @@ -99,9 +99,9 @@ runtime·unlock(Lock *l) if(v == MUTEX_SLEEPING) runtime·futexwakeup((uint32*)&l->key, 1); - if(--m->locks < 0) + if(--g->m->locks < 0) runtime·throw("runtime·unlock: lock count"); - if(m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack + if(g->m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack g->stackguard0 = StackPreempt; } @@ -128,12 +128,12 @@ runtime·notewakeup(Note *n) void runtime·notesleep(Note *n) { - if(g != m->g0) + if(g != g->m->g0) runtime·throw("notesleep not on g0"); while(runtime·atomicload((uint32*)&n->key) == 0) { - m->blocked = true; + g->m->blocked = true; runtime·futexsleep((uint32*)&n->key, 0, -1); - m->blocked = false; + g->m->blocked = false; } } @@ -147,9 +147,9 @@ notetsleep(Note *n, int64 ns, int64 deadline, int64 now) if(ns < 0) { while(runtime·atomicload((uint32*)&n->key) == 0) { - m->blocked = true; + g->m->blocked = true; runtime·futexsleep((uint32*)&n->key, 0, -1); - m->blocked = false; + g->m->blocked = false; } return true; } @@ -159,9 +159,9 @@ notetsleep(Note *n, int64 ns, int64 deadline, int64 now) deadline = runtime·nanotime() + ns; for(;;) { - m->blocked = true; + g->m->blocked = true; runtime·futexsleep((uint32*)&n->key, 0, ns); - m->blocked = false; + g->m->blocked = false; if(runtime·atomicload((uint32*)&n->key) != 0) break; now = runtime·nanotime(); @@ -177,7 +177,7 @@ runtime·notetsleep(Note *n, int64 ns) { bool res; - if(g != m->g0 && !m->gcing) + if(g != g->m->g0 && !g->m->gcing) runtime·throw("notetsleep not on g0"); res = notetsleep(n, ns, 0, 0); @@ -191,7 +191,7 @@ runtime·notetsleepg(Note *n, int64 ns) { bool res; - if(g == m->g0) + if(g == g->m->g0) runtime·throw("notetsleepg on g0"); runtime·entersyscallblock(); diff --git a/src/pkg/runtime/lock_sema.c b/src/pkg/runtime/lock_sema.c index ff8fdfd423..a4274e6555 100644 --- a/src/pkg/runtime/lock_sema.c +++ b/src/pkg/runtime/lock_sema.c @@ -39,15 +39,15 @@ runtime·lock(Lock *l) uintptr v; uint32 i, spin; - if(m->locks++ < 0) + if(g->m->locks++ < 0) runtime·throw("runtime·lock: lock count"); // Speculative grab for lock. if(runtime·casp((void**)&l->key, nil, (void*)LOCKED)) return; - if(m->waitsema == 0) - m->waitsema = runtime·semacreate(); + if(g->m->waitsema == 0) + g->m->waitsema = runtime·semacreate(); // On uniprocessor's, no point spinning. // On multiprocessors, spin for ACTIVE_SPIN attempts. @@ -73,8 +73,8 @@ unlocked: // for this lock, chained through m->nextwaitm. // Queue this M. for(;;) { - m->nextwaitm = (void*)(v&~LOCKED); - if(runtime·casp((void**)&l->key, (void*)v, (void*)((uintptr)m|LOCKED))) + g->m->nextwaitm = (void*)(v&~LOCKED); + if(runtime·casp((void**)&l->key, (void*)v, (void*)((uintptr)g->m|LOCKED))) break; v = (uintptr)runtime·atomicloadp((void**)&l->key); if((v&LOCKED) == 0) @@ -112,9 +112,9 @@ runtime·unlock(Lock *l) } } - if(--m->locks < 0) + if(--g->m->locks < 0) runtime·throw("runtime·unlock: lock count"); - if(m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack + if(g->m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack g->stackguard0 = StackPreempt; } @@ -150,20 +150,20 @@ runtime·notewakeup(Note *n) void runtime·notesleep(Note *n) { - if(g != m->g0) + if(g != g->m->g0) runtime·throw("notesleep not on g0"); - if(m->waitsema == 0) - m->waitsema = runtime·semacreate(); - if(!runtime·casp((void**)&n->key, nil, m)) { // must be LOCKED (got wakeup) + if(g->m->waitsema == 0) + g->m->waitsema = runtime·semacreate(); + if(!runtime·casp((void**)&n->key, nil, g->m)) { // must be LOCKED (got wakeup) if(n->key != LOCKED) runtime·throw("notesleep - waitm out of sync"); return; } // Queued. Sleep. - m->blocked = true; + g->m->blocked = true; runtime·semasleep(-1); - m->blocked = false; + g->m->blocked = false; } #pragma textflag NOSPLIT @@ -175,7 +175,7 @@ notetsleep(Note *n, int64 ns, int64 deadline, M *mp) // does not count against our nosplit stack sequence. // Register for wakeup on n->waitm. - if(!runtime·casp((void**)&n->key, nil, m)) { // must be LOCKED (got wakeup already) + if(!runtime·casp((void**)&n->key, nil, g->m)) { // must be LOCKED (got wakeup already) if(n->key != LOCKED) runtime·throw("notetsleep - waitm out of sync"); return true; @@ -183,23 +183,23 @@ notetsleep(Note *n, int64 ns, int64 deadline, M *mp) if(ns < 0) { // Queued. Sleep. - m->blocked = true; + g->m->blocked = true; runtime·semasleep(-1); - m->blocked = false; + g->m->blocked = false; return true; } deadline = runtime·nanotime() + ns; for(;;) { // Registered. Sleep. - m->blocked = true; + g->m->blocked = true; if(runtime·semasleep(ns) >= 0) { - m->blocked = false; + g->m->blocked = false; // Acquired semaphore, semawakeup unregistered us. // Done. return true; } - m->blocked = false; + g->m->blocked = false; // Interrupted or timed out. Still registered. Semaphore not acquired. ns = deadline - runtime·nanotime(); @@ -214,17 +214,17 @@ notetsleep(Note *n, int64 ns, int64 deadline, M *mp) // try to grant us the semaphore when we don't expect it. for(;;) { mp = runtime·atomicloadp((void**)&n->key); - if(mp == m) { + if(mp == g->m) { // No wakeup yet; unregister if possible. if(runtime·casp((void**)&n->key, mp, nil)) return false; } else if(mp == (M*)LOCKED) { // Wakeup happened so semaphore is available. // Grab it to avoid getting out of sync. - m->blocked = true; + g->m->blocked = true; if(runtime·semasleep(-1) < 0) runtime·throw("runtime: unable to acquire - semaphore out of sync"); - m->blocked = false; + g->m->blocked = false; return true; } else runtime·throw("runtime: unexpected waitm - semaphore out of sync"); @@ -236,11 +236,11 @@ runtime·notetsleep(Note *n, int64 ns) { bool res; - if(g != m->g0 && !m->gcing) + if(g != g->m->g0 && !g->m->gcing) runtime·throw("notetsleep not on g0"); - if(m->waitsema == 0) - m->waitsema = runtime·semacreate(); + if(g->m->waitsema == 0) + g->m->waitsema = runtime·semacreate(); res = notetsleep(n, ns, 0, nil); return res; @@ -253,11 +253,11 @@ runtime·notetsleepg(Note *n, int64 ns) { bool res; - if(g == m->g0) + if(g == g->m->g0) runtime·throw("notetsleepg on g0"); - if(m->waitsema == 0) - m->waitsema = runtime·semacreate(); + if(g->m->waitsema == 0) + g->m->waitsema = runtime·semacreate(); runtime·entersyscallblock(); res = notetsleep(n, ns, 0, nil); diff --git a/src/pkg/runtime/malloc.goc b/src/pkg/runtime/malloc.goc index 7b7e350d8d..0b56d1fdb0 100644 --- a/src/pkg/runtime/malloc.goc +++ b/src/pkg/runtime/malloc.goc @@ -53,17 +53,17 @@ runtime·mallocgc(uintptr size, uintptr typ, uint32 flag) // have distinct values. return &runtime·zerobase; } - if(m->mallocing) + if(g->m->mallocing) runtime·throw("malloc/free - deadlock"); // Disable preemption during settype. // We can not use m->mallocing for this, because settype calls mallocgc. - m->locks++; - m->mallocing = 1; + g->m->locks++; + g->m->mallocing = 1; if(DebugTypeAtBlockEnd) size += sizeof(uintptr); - c = m->mcache; + c = g->m->mcache; if(!runtime·debug.efence && size <= MaxSmallSize) { if((flag&(FlagNoScan|FlagNoGC)) == FlagNoScan && size < TinySize) { // Tiny allocator. @@ -112,9 +112,9 @@ runtime·mallocgc(uintptr size, uintptr typ, uint32 flag) v = (MLink*)tiny; c->tiny += size1; c->tinysize -= size1; - m->mallocing = 0; - m->locks--; - if(m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack + g->m->mallocing = 0; + g->m->locks--; + if(g->m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack g->stackguard0 = StackPreempt; return v; } @@ -178,7 +178,7 @@ runtime·mallocgc(uintptr size, uintptr typ, uint32 flag) if(DebugTypeAtBlockEnd) *(uintptr*)((uintptr)v+size-sizeof(uintptr)) = typ; - m->mallocing = 0; + g->m->mallocing = 0; // TODO: save type even if FlagNoScan? Potentially expensive but might help // heap profiling/tracing. if(UseSpanType && !(flag & FlagNoScan) && typ != 0) @@ -197,8 +197,8 @@ runtime·mallocgc(uintptr size, uintptr typ, uint32 flag) profilealloc(v, size); } - m->locks--; - if(m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack + g->m->locks--; + if(g->m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack g->stackguard0 = StackPreempt; if(!(flag & FlagNoInvokeGC) && mstats.heap_alloc >= mstats.next_gc) @@ -239,7 +239,7 @@ profilealloc(void *v, uintptr size) int32 next; MCache *c; - c = m->mcache; + c = g->m->mcache; rate = runtime·MemProfileRate; if(size < rate) { // pick next profile time @@ -279,9 +279,9 @@ runtime·free(void *v) // If you change this also change mgc0.c:/^sweep, // which has a copy of the guts of free. - if(m->mallocing) + if(g->m->mallocing) runtime·throw("malloc/free - deadlock"); - m->mallocing = 1; + g->m->mallocing = 1; if(!runtime·mlookup(v, nil, nil, &s)) { runtime·printf("free %p: not an allocated block\n", v); @@ -304,7 +304,7 @@ runtime·free(void *v) if(s->specials != nil) runtime·freeallspecials(s, v, size); - c = m->mcache; + c = g->m->mcache; if(sizeclass == 0) { // Large object. s->needzero = 1; @@ -354,7 +354,7 @@ runtime·free(void *v) runtime·MCache_Free(c, v, sizeclass, size); } } - m->mallocing = 0; + g->m->mallocing = 0; } int32 @@ -364,11 +364,11 @@ runtime·mlookup(void *v, byte **base, uintptr *size, MSpan **sp) byte *p; MSpan *s; - m->mcache->local_nlookup++; - if (sizeof(void*) == 4 && m->mcache->local_nlookup >= (1<<30)) { + g->m->mcache->local_nlookup++; + if (sizeof(void*) == 4 && g->m->mcache->local_nlookup >= (1<<30)) { // purge cache stats to prevent overflow runtime·lock(&runtime·mheap); - runtime·purgecachedstats(m->mcache); + runtime·purgecachedstats(g->m->mcache); runtime·unlock(&runtime·mheap); } @@ -569,7 +569,7 @@ runtime·mallocinit(void) // Initialize the rest of the allocator. runtime·MHeap_Init(&runtime·mheap); - m->mcache = runtime·allocmcache(); + g->m->mcache = runtime·allocmcache(); // See if it works. runtime·free(runtime·malloc(TinySize)); diff --git a/src/pkg/runtime/mcache.c b/src/pkg/runtime/mcache.c index 26e3db2dca..13437a50cd 100644 --- a/src/pkg/runtime/mcache.c +++ b/src/pkg/runtime/mcache.c @@ -57,7 +57,7 @@ runtime·MCache_Refill(MCache *c, int32 sizeclass) MCacheList *l; MSpan *s; - m->locks++; + g->m->locks++; // Return the current cached span to the central lists. s = c->alloc[sizeclass]; if(s->freelist != nil) @@ -83,7 +83,7 @@ runtime·MCache_Refill(MCache *c, int32 sizeclass) runtime·throw("empty span"); } c->alloc[sizeclass] = s; - m->locks--; + g->m->locks--; return s; } diff --git a/src/pkg/runtime/mgc0.c b/src/pkg/runtime/mgc0.c index 50d9feabd0..51c765eaac 100644 --- a/src/pkg/runtime/mgc0.c +++ b/src/pkg/runtime/mgc0.c @@ -757,7 +757,7 @@ scanblock(Workbuf *wbuf, bool keepworking) } // Initialize sbuf - scanbuffers = &bufferList[m->helpgc]; + scanbuffers = &bufferList[g->m->helpgc]; sbuf.ptr.begin = sbuf.ptr.pos = &scanbuffers->ptrtarget[0]; sbuf.ptr.end = sbuf.ptr.begin + nelem(scanbuffers->ptrtarget); @@ -1389,13 +1389,13 @@ getfull(Workbuf *b) if(work.nwait == work.nproc) return nil; if(i < 10) { - m->gcstats.nprocyield++; + g->m->gcstats.nprocyield++; runtime·procyield(20); } else if(i < 20) { - m->gcstats.nosyield++; + g->m->gcstats.nosyield++; runtime·osyield(); } else { - m->gcstats.nsleep++; + g->m->gcstats.nsleep++; runtime·usleep(100); } } @@ -1413,8 +1413,8 @@ handoff(Workbuf *b) b->nobj -= n; b1->nobj = n; runtime·memmove(b1->obj, b->obj+b->nobj, n*sizeof b1->obj[0]); - m->gcstats.nhandoff++; - m->gcstats.nhandoffcnt += n; + g->m->gcstats.nhandoff++; + g->m->gcstats.nhandoffcnt += n; // Put b on full list - let first half of b get stolen. runtime·lfstackpush(&work.full, &b->node); @@ -1487,7 +1487,7 @@ scanbitvector(Func *f, bool precise, byte *scanp, BitVector *bv, void *wbufp) if(precise && (p < (byte*)PageSize || (uintptr)p == PoisonGC || (uintptr)p == PoisonStack)) { // Looks like a junk value in a pointer slot. // Liveness analysis wrong? - m->traceback = 2; + g->m->traceback = 2; runtime·printf("bad pointer in frame %s at %p: %p\n", runtime·funcname(f), scanp, p); runtime·throw("bad pointer in scanbitvector"); } @@ -1533,7 +1533,7 @@ scanbitvector(Func *f, bool precise, byte *scanp, BitVector *bv, void *wbufp) if(Debug > 2) runtime·printf("frame %s @%p: slice %p/%D/%D\n", runtime·funcname(f), p, ((Slice*)p)->array, (int64)((Slice*)p)->len, (int64)((Slice*)p)->cap); if(((Slice*)p)->cap < ((Slice*)p)->len) { - m->traceback = 2; + g->m->traceback = 2; runtime·printf("bad slice in frame %s at %p: %p/%p/%p\n", runtime·funcname(f), p, ((byte**)p)[0], ((byte**)p)[1], ((byte**)p)[2]); runtime·throw("slice capacity smaller than length"); } @@ -1757,7 +1757,7 @@ runtime·MSpan_EnsureSwept(MSpan *s) // Caller must disable preemption. // Otherwise when this function returns the span can become unswept again // (if GC is triggered on another goroutine). - if(m->locks == 0 && m->mallocing == 0 && g != m->g0) + if(g->m->locks == 0 && g->m->mallocing == 0 && g != g->m->g0) runtime·throw("MSpan_EnsureSwept: m is not locked"); sg = runtime·mheap.sweepgen; @@ -1794,7 +1794,7 @@ runtime·MSpan_Sweep(MSpan *s) // It's critical that we enter this function with preemption disabled, // GC must not start while we are in the middle of this function. - if(m->locks == 0 && m->mallocing == 0 && g != m->g0) + if(g->m->locks == 0 && g->m->mallocing == 0 && g != g->m->g0) runtime·throw("MSpan_Sweep: m is not locked"); sweepgen = runtime·mheap.sweepgen; if(s->state != MSpanInUse || s->sweepgen != sweepgen-1) { @@ -1815,7 +1815,7 @@ runtime·MSpan_Sweep(MSpan *s) res = false; nfree = 0; end = &head; - c = m->mcache; + c = g->m->mcache; sweepgenset = false; // mark any free objects in this span so we don't collect them @@ -2002,13 +2002,13 @@ runtime·sweepone(void) // increment locks to ensure that the goroutine is not preempted // in the middle of sweep thus leaving the span in an inconsistent state for next GC - m->locks++; + g->m->locks++; sg = runtime·mheap.sweepgen; for(;;) { idx = runtime·xadd(&sweep.spanidx, 1) - 1; if(idx >= sweep.nspan) { runtime·mheap.sweepdone = true; - m->locks--; + g->m->locks--; return -1; } s = sweep.spans[idx]; @@ -2023,7 +2023,7 @@ runtime·sweepone(void) npages = s->npages; if(!runtime·MSpan_Sweep(s)) npages = 0; - m->locks--; + g->m->locks--; return npages; } } @@ -2107,7 +2107,7 @@ runtime·gchelper(void) { uint32 nproc; - m->traceback = 2; + g->m->traceback = 2; gchelperstart(); // parallel mark for over gc roots @@ -2116,11 +2116,11 @@ runtime·gchelper(void) // help other threads scan secondary blocks scanblock(nil, true); - bufferList[m->helpgc].busy = 0; + bufferList[g->m->helpgc].busy = 0; nproc = work.nproc; // work.nproc can change right after we increment work.ndone if(runtime·xadd(&work.ndone, +1) == nproc-1) runtime·notewakeup(&work.alldone); - m->traceback = 0; + g->m->traceback = 0; } static void @@ -2282,7 +2282,7 @@ runtime·gc(int32 force) // problems, don't bother trying to run gc // while holding a lock. The next mallocgc // without a lock will do the gc instead. - if(!mstats.enablegc || g == m->g0 || m->locks > 0 || runtime·panicking) + if(!mstats.enablegc || g == g->m->g0 || g->m->locks > 0 || runtime·panicking) return; if(gcpercent == GcpercentUnknown) { // first time through @@ -2305,7 +2305,7 @@ runtime·gc(int32 force) // Ok, we're doing it! Stop everybody else a.start_time = runtime·nanotime(); a.eagersweep = force >= 2; - m->gcing = 1; + g->m->gcing = 1; runtime·stoptheworld(); clearpools(); @@ -2326,11 +2326,11 @@ runtime·gc(int32 force) } // all done - m->gcing = 0; - m->locks++; + g->m->gcing = 0; + g->m->locks++; runtime·semrelease(&runtime·worldsema); runtime·starttheworld(); - m->locks--; + g->m->locks--; // now that gc is done, kick off finalizer thread if needed if(!ConcurrentSweep) { @@ -2360,17 +2360,17 @@ gc(struct gc_args *args) if(runtime·debug.allocfreetrace) runtime·tracegc(); - m->traceback = 2; + g->m->traceback = 2; t0 = args->start_time; work.tstart = args->start_time; if(CollectStats) runtime·memclr((byte*)&gcstats, sizeof(gcstats)); - m->locks++; // disable gc during mallocs in parforalloc + g->m->locks++; // disable gc during mallocs in parforalloc if(work.markfor == nil) work.markfor = runtime·parforalloc(MaxGcproc); - m->locks--; + g->m->locks--; if(itabtype == nil) { // get C pointer to the Go type "itab" @@ -2407,7 +2407,7 @@ gc(struct gc_args *args) if(runtime·debug.gctrace) t3 = runtime·nanotime(); - bufferList[m->helpgc].busy = 0; + bufferList[g->m->helpgc].busy = 0; if(work.nproc > 1) runtime·notesleep(&work.alldone); @@ -2515,7 +2515,7 @@ gc(struct gc_args *args) runtime·shrinkstack(runtime·allg[i]); runtime·MProf_GC(); - m->traceback = 0; + g->m->traceback = 0; } extern uintptr runtime·sizeof_C_MStats; @@ -2528,17 +2528,17 @@ runtime·ReadMemStats(MStats *stats) // one goroutine at a time, and there might be // a pending garbage collection already calling it. runtime·semacquire(&runtime·worldsema, false); - m->gcing = 1; + g->m->gcing = 1; runtime·stoptheworld(); runtime·updatememstats(nil); // Size of the trailing by_size array differs between Go and C, // NumSizeClasses was changed, but we can not change Go struct because of backward compatibility. runtime·memcopy(runtime·sizeof_C_MStats, stats, &mstats); - m->gcing = 0; - m->locks++; + g->m->gcing = 0; + g->m->locks++; runtime·semrelease(&runtime·worldsema); runtime·starttheworld(); - m->locks--; + g->m->locks--; } void @@ -2590,11 +2590,11 @@ runtime·setgcpercent(int32 in) { static void gchelperstart(void) { - if(m->helpgc < 0 || m->helpgc >= MaxGcproc) + if(g->m->helpgc < 0 || g->m->helpgc >= MaxGcproc) runtime·throw("gchelperstart: bad m->helpgc"); - if(runtime·xchg(&bufferList[m->helpgc].busy, 1)) + if(runtime·xchg(&bufferList[g->m->helpgc].busy, 1)) runtime·throw("gchelperstart: already busy"); - if(g != m->g0) + if(g != g->m->g0) runtime·throw("gchelper not running on g0 stack"); } diff --git a/src/pkg/runtime/mheap.c b/src/pkg/runtime/mheap.c index 7e83eb2833..961b32e504 100644 --- a/src/pkg/runtime/mheap.c +++ b/src/pkg/runtime/mheap.c @@ -173,8 +173,8 @@ runtime·MHeap_Alloc(MHeap *h, uintptr npage, int32 sizeclass, bool large, bool MSpan *s; runtime·lock(h); - mstats.heap_alloc += m->mcache->local_cachealloc; - m->mcache->local_cachealloc = 0; + mstats.heap_alloc += g->m->mcache->local_cachealloc; + g->m->mcache->local_cachealloc = 0; s = MHeap_AllocLocked(h, npage, sizeclass); if(s != nil) { mstats.heap_inuse += npage<mcache->local_cachealloc; - m->mcache->local_cachealloc = 0; + mstats.heap_alloc += g->m->mcache->local_cachealloc; + g->m->mcache->local_cachealloc = 0; mstats.heap_inuse -= s->npages<npages<locks++; + g->m->locks++; runtime·MSpan_EnsureSwept(span); offset = (uintptr)p - (span->start << PageShift); @@ -669,7 +669,7 @@ addspecial(void *p, Special *s) while((x = *t) != nil) { if(offset == x->offset && kind == x->kind) { runtime·unlock(&span->specialLock); - m->locks--; + g->m->locks--; return false; // already exists } if(offset < x->offset || (offset == x->offset && kind < x->kind)) @@ -681,7 +681,7 @@ addspecial(void *p, Special *s) s->next = x; *t = s; runtime·unlock(&span->specialLock); - m->locks--; + g->m->locks--; return true; } @@ -701,7 +701,7 @@ removespecial(void *p, byte kind) // Ensure that the span is swept. // GC accesses specials list w/o locks. And it's just much safer. - m->locks++; + g->m->locks++; runtime·MSpan_EnsureSwept(span); offset = (uintptr)p - (span->start << PageShift); @@ -714,13 +714,13 @@ removespecial(void *p, byte kind) if(offset == s->offset && kind == s->kind) { *t = s->next; runtime·unlock(&span->specialLock); - m->locks--; + g->m->locks--; return s; } t = &s->next; } runtime·unlock(&span->specialLock); - m->locks--; + g->m->locks--; return nil; } diff --git a/src/pkg/runtime/mprof.goc b/src/pkg/runtime/mprof.goc index 9c23a16f88..0aea545b4e 100644 --- a/src/pkg/runtime/mprof.goc +++ b/src/pkg/runtime/mprof.goc @@ -387,7 +387,7 @@ func Stack(b Slice, all bool) (n int) { if(all) { runtime·semacquire(&runtime·worldsema, false); - m->gcing = 1; + g->m->gcing = 1; runtime·stoptheworld(); } @@ -406,7 +406,7 @@ func Stack(b Slice, all bool) (n int) { } if(all) { - m->gcing = 0; + g->m->gcing = 0; runtime·semrelease(&runtime·worldsema); runtime·starttheworld(); } @@ -434,7 +434,7 @@ func GoroutineProfile(b Slice) (n int, ok bool) { n = runtime·gcount(); if(n <= b.len) { runtime·semacquire(&runtime·worldsema, false); - m->gcing = 1; + g->m->gcing = 1; runtime·stoptheworld(); n = runtime·gcount(); @@ -450,7 +450,7 @@ func GoroutineProfile(b Slice) (n int, ok bool) { } } - m->gcing = 0; + g->m->gcing = 0; runtime·semrelease(&runtime·worldsema); runtime·starttheworld(); } @@ -480,22 +480,22 @@ runtime·tracealloc(void *p, uintptr size, uintptr typ) Type *type; runtime·lock(&tracelock); - m->traceback = 2; + g->m->traceback = 2; type = (Type*)(typ & ~3); name = typeinfoname(typ & 3); if(type == nil) runtime·printf("tracealloc(%p, %p, %s)\n", p, size, name); else runtime·printf("tracealloc(%p, %p, %s of %S)\n", p, size, name, *type->string); - if(m->curg == nil || g == m->curg) { + if(g->m->curg == nil || g == g->m->curg) { runtime·goroutineheader(g); runtime·traceback((uintptr)runtime·getcallerpc(&p), (uintptr)runtime·getcallersp(&p), 0, g); } else { - runtime·goroutineheader(m->curg); - runtime·traceback(~(uintptr)0, ~(uintptr)0, 0, m->curg); + runtime·goroutineheader(g->m->curg); + runtime·traceback(~(uintptr)0, ~(uintptr)0, 0, g->m->curg); } runtime·printf("\n"); - m->traceback = 0; + g->m->traceback = 0; runtime·unlock(&tracelock); } @@ -503,12 +503,12 @@ void runtime·tracefree(void *p, uintptr size) { runtime·lock(&tracelock); - m->traceback = 2; + g->m->traceback = 2; runtime·printf("tracefree(%p, %p)\n", p, size); runtime·goroutineheader(g); runtime·traceback((uintptr)runtime·getcallerpc(&p), (uintptr)runtime·getcallersp(&p), 0, g); runtime·printf("\n"); - m->traceback = 0; + g->m->traceback = 0; runtime·unlock(&tracelock); } @@ -516,12 +516,12 @@ void runtime·tracegc(void) { runtime·lock(&tracelock); - m->traceback = 2; + g->m->traceback = 2; runtime·printf("tracegc()\n"); // running on m->g0 stack; show all non-g0 goroutines runtime·tracebackothers(g); runtime·printf("end tracegc\n"); runtime·printf("\n"); - m->traceback = 0; + g->m->traceback = 0; runtime·unlock(&tracelock); } diff --git a/src/pkg/runtime/netpoll_solaris.c b/src/pkg/runtime/netpoll_solaris.c index a2631a8ab9..569aee52d4 100644 --- a/src/pkg/runtime/netpoll_solaris.c +++ b/src/pkg/runtime/netpoll_solaris.c @@ -79,7 +79,7 @@ extern uintptr libc·port_associate; extern uintptr libc·port_dissociate; extern uintptr libc·port_getn; -#define errno (*m->perrno) +#define errno (*g->m->perrno) int32 runtime·fcntl(int32 fd, int32 cmd, uintptr arg) diff --git a/src/pkg/runtime/netpoll_windows.c b/src/pkg/runtime/netpoll_windows.c index f3cd15c7a9..4528292125 100644 --- a/src/pkg/runtime/netpoll_windows.c +++ b/src/pkg/runtime/netpoll_windows.c @@ -102,16 +102,16 @@ retry: if(n < 8) n = 8; if(block) - m->blocked = true; + g->m->blocked = true; if(runtime·stdcall(runtime·GetQueuedCompletionStatusEx, 6, iocphandle, entries, (uintptr)n, &n, (uintptr)wait, (uintptr)0) == 0) { - m->blocked = false; + g->m->blocked = false; errno = runtime·getlasterror(); if(!block && errno == WAIT_TIMEOUT) return nil; runtime·printf("netpoll: GetQueuedCompletionStatusEx failed (errno=%d)\n", errno); runtime·throw("netpoll: GetQueuedCompletionStatusEx failed"); } - m->blocked = false; + g->m->blocked = false; for(i = 0; i < n; i++) { op = entries[i].op; errno = 0; @@ -125,9 +125,9 @@ retry: errno = 0; qty = 0; if(block) - m->blocked = true; + g->m->blocked = true; if(runtime·stdcall(runtime·GetQueuedCompletionStatus, 5, iocphandle, &qty, &key, &op, (uintptr)wait) == 0) { - m->blocked = false; + g->m->blocked = false; errno = runtime·getlasterror(); if(!block && errno == WAIT_TIMEOUT) return nil; @@ -137,7 +137,7 @@ retry: } // dequeued failed IO packet, so report that } - m->blocked = false; + g->m->blocked = false; handlecompletion(&gp, op, errno, qty); } if(block && gp == nil) diff --git a/src/pkg/runtime/os_darwin.c b/src/pkg/runtime/os_darwin.c index 33a2df958f..c660fb8c10 100644 --- a/src/pkg/runtime/os_darwin.c +++ b/src/pkg/runtime/os_darwin.c @@ -119,6 +119,7 @@ void runtime·mpreinit(M *mp) { mp->gsignal = runtime·malg(32*1024); // OS X wants >=8K, Linux >=2K + mp->gsignal->m = mp; } // Called to initialize a new m (including the bootstrap m). @@ -127,7 +128,7 @@ void runtime·minit(void) { // Initialize signal handling. - runtime·signalstack((byte*)m->gsignal->stackguard - StackGuard, 32*1024); + runtime·signalstack((byte*)g->m->gsignal->stackguard - StackGuard, 32*1024); runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil); } @@ -202,9 +203,9 @@ machcall(MachHeader *h, int32 maxsize, int32 rxsize) uint32 port; CodeMsg *c; - if((port = m->machport) == 0){ + if((port = g->m->machport) == 0){ port = runtime·mach_reply_port(); - m->machport = port; + g->m->machport = port; } h->msgh_bits |= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE); @@ -405,14 +406,14 @@ runtime·semasleep(int64 ns) if(ns >= 0) { secs = runtime·timediv(ns, 1000000000, &nsecs); - r = runtime·mach_semaphore_timedwait(m->waitsema, secs, nsecs); + r = runtime·mach_semaphore_timedwait(g->m->waitsema, secs, nsecs); if(r == KERN_ABORTED || r == KERN_OPERATION_TIMED_OUT) return -1; if(r != 0) macherror(r, "semaphore_wait"); return 0; } - while((r = runtime·mach_semaphore_wait(m->waitsema)) != 0) { + while((r = runtime·mach_semaphore_wait(g->m->waitsema)) != 0) { if(r == KERN_ABORTED) // interrupted continue; macherror(r, "semaphore_wait"); diff --git a/src/pkg/runtime/os_dragonfly.c b/src/pkg/runtime/os_dragonfly.c index e7fd2cc06f..b8c967a07a 100644 --- a/src/pkg/runtime/os_dragonfly.c +++ b/src/pkg/runtime/os_dragonfly.c @@ -148,6 +148,7 @@ void runtime·mpreinit(M *mp) { mp->gsignal = runtime·malg(32*1024); + mp->gsignal->m = mp; } // Called to initialize a new m (including the bootstrap m). @@ -156,7 +157,7 @@ void runtime·minit(void) { // Initialize signal handling - runtime·signalstack((byte*)m->gsignal->stackguard - StackGuard, 32*1024); + runtime·signalstack((byte*)g->m->gsignal->stackguard - StackGuard, 32*1024); runtime·sigprocmask(&sigset_none, nil); } diff --git a/src/pkg/runtime/os_freebsd.c b/src/pkg/runtime/os_freebsd.c index 02b13472c8..9299dbdc04 100644 --- a/src/pkg/runtime/os_freebsd.c +++ b/src/pkg/runtime/os_freebsd.c @@ -156,6 +156,7 @@ void runtime·mpreinit(M *mp) { mp->gsignal = runtime·malg(32*1024); + mp->gsignal->m = mp; } // Called to initialize a new m (including the bootstrap m). @@ -164,7 +165,7 @@ void runtime·minit(void) { // Initialize signal handling - runtime·signalstack((byte*)m->gsignal->stackguard - StackGuard, 32*1024); + runtime·signalstack((byte*)g->m->gsignal->stackguard - StackGuard, 32*1024); runtime·sigprocmask(&sigset_none, nil); } diff --git a/src/pkg/runtime/os_linux.c b/src/pkg/runtime/os_linux.c index 8a945242b9..31cbdb0ad5 100644 --- a/src/pkg/runtime/os_linux.c +++ b/src/pkg/runtime/os_linux.c @@ -196,6 +196,7 @@ void runtime·mpreinit(M *mp) { mp->gsignal = runtime·malg(32*1024); // OS X wants >=8K, Linux >=2K + mp->gsignal->m = mp; } // Called to initialize a new m (including the bootstrap m). @@ -204,7 +205,7 @@ void runtime·minit(void) { // Initialize signal handling. - runtime·signalstack((byte*)m->gsignal->stackguard - StackGuard, 32*1024); + runtime·signalstack((byte*)g->m->gsignal->stackguard - StackGuard, 32*1024); runtime·rtsigprocmask(SIG_SETMASK, &sigset_none, nil, sizeof(Sigset)); } diff --git a/src/pkg/runtime/os_nacl.c b/src/pkg/runtime/os_nacl.c index 3196e2ce32..b3e0fc6636 100644 --- a/src/pkg/runtime/os_nacl.c +++ b/src/pkg/runtime/os_nacl.c @@ -20,6 +20,7 @@ void runtime·mpreinit(M *mp) { mp->gsignal = runtime·malg(32*1024); // OS X wants >=8K, Linux >=2K + mp->gsignal->m = mp; } // Called to initialize a new m (including the bootstrap m). @@ -30,7 +31,7 @@ runtime·minit(void) int32 ret; // Initialize signal handling - ret = runtime·nacl_exception_stack((byte*)m->gsignal->stackguard - StackGuard, 32*1024); + ret = runtime·nacl_exception_stack((byte*)g->m->gsignal->stackguard - StackGuard, 32*1024); if(ret < 0) runtime·printf("runtime: nacl_exception_stack: error %d\n", -ret); @@ -54,7 +55,7 @@ void runtime·osinit(void) { runtime·ncpu = 1; - m->procid = 2; + g->m->procid = 2; //runtime·nacl_exception_handler(runtime·sigtramp, nil); } @@ -126,7 +127,7 @@ runtime·semacreate(void) runtime·printf("nacl_cond_create: error %d\n", -cond); runtime·throw("semacreate"); } - m->waitsemalock = mu; + g->m->waitsemalock = mu; return cond; // assigned to m->waitsema } @@ -136,20 +137,20 @@ runtime·semasleep(int64 ns) { int32 ret; - ret = runtime·nacl_mutex_lock(m->waitsemalock); + ret = runtime·nacl_mutex_lock(g->m->waitsemalock); if(ret < 0) { //runtime·printf("nacl_mutex_lock: error %d\n", -ret); runtime·throw("semasleep"); } - if(m->waitsemacount > 0) { - m->waitsemacount = 0; - runtime·nacl_mutex_unlock(m->waitsemalock); + if(g->m->waitsemacount > 0) { + g->m->waitsemacount = 0; + runtime·nacl_mutex_unlock(g->m->waitsemalock); return 0; } - while(m->waitsemacount == 0) { + while(g->m->waitsemacount == 0) { if(ns < 0) { - ret = runtime·nacl_cond_wait(m->waitsema, m->waitsemalock); + ret = runtime·nacl_cond_wait(g->m->waitsema, g->m->waitsemalock); if(ret < 0) { //runtime·printf("nacl_cond_wait: error %d\n", -ret); runtime·throw("semasleep"); @@ -159,9 +160,9 @@ runtime·semasleep(int64 ns) ns += runtime·nanotime(); ts.tv_sec = runtime·timediv(ns, 1000000000, (int32*)&ts.tv_nsec); - ret = runtime·nacl_cond_timed_wait_abs(m->waitsema, m->waitsemalock, &ts); + ret = runtime·nacl_cond_timed_wait_abs(g->m->waitsema, g->m->waitsemalock, &ts); if(ret == -ETIMEDOUT) { - runtime·nacl_mutex_unlock(m->waitsemalock); + runtime·nacl_mutex_unlock(g->m->waitsemalock); return -1; } if(ret < 0) { @@ -171,8 +172,8 @@ runtime·semasleep(int64 ns) } } - m->waitsemacount = 0; - runtime·nacl_mutex_unlock(m->waitsemalock); + g->m->waitsemacount = 0; + runtime·nacl_mutex_unlock(g->m->waitsemalock); return 0; } @@ -275,4 +276,4 @@ int32 runtime·nacl_irt_memory_v0_3_size = sizeof(runtime·nacl_irt_memory_v0_3) int8 runtime·nacl_irt_thread_v0_1_str[] = "nacl-irt-thread-0.1"; void *runtime·nacl_irt_thread_v0_1[3]; // thread_create, thread_exit, thread_nice int32 runtime·nacl_irt_thread_v0_1_size = sizeof(runtime·nacl_irt_thread_v0_1); -*/ \ No newline at end of file +*/ diff --git a/src/pkg/runtime/os_netbsd.c b/src/pkg/runtime/os_netbsd.c index 93229bffeb..0889181a81 100644 --- a/src/pkg/runtime/os_netbsd.c +++ b/src/pkg/runtime/os_netbsd.c @@ -70,12 +70,12 @@ runtime·semasleep(int64 ns) Timespec ts; // spin-mutex lock - while(runtime·xchg(&m->waitsemalock, 1)) + while(runtime·xchg(&g->m->waitsemalock, 1)) runtime·osyield(); for(;;) { // lock held - if(m->waitsemacount == 0) { + if(g->m->waitsemacount == 0) { // sleep until semaphore != 0 or timeout. // thrsleep unlocks m->waitsemalock. if(ns < 0) { @@ -92,8 +92,8 @@ runtime·semasleep(int64 ns) // the NetBSD kernel does not appear to provide // a mechanism for unlocking the userspace // mutex once the thread is actually parked. - runtime·atomicstore(&m->waitsemalock, 0); - runtime·lwp_park(nil, 0, &m->waitsemacount, nil); + runtime·atomicstore(&g->m->waitsemalock, 0); + runtime·lwp_park(nil, 0, &g->m->waitsemacount, nil); } else { ns = ns + runtime·nanotime(); // NOTE: tv_nsec is int64 on amd64, so this assumes a little-endian system. @@ -101,20 +101,20 @@ runtime·semasleep(int64 ns) ts.tv_sec = runtime·timediv(ns, 1000000000, (int32*)&ts.tv_nsec); // TODO(jsing) - potential deadlock! // See above for details. - runtime·atomicstore(&m->waitsemalock, 0); - runtime·lwp_park(&ts, 0, &m->waitsemacount, nil); + runtime·atomicstore(&g->m->waitsemalock, 0); + runtime·lwp_park(&ts, 0, &g->m->waitsemacount, nil); } // reacquire lock - while(runtime·xchg(&m->waitsemalock, 1)) + while(runtime·xchg(&g->m->waitsemalock, 1)) runtime·osyield(); } // lock held (again) - if(m->waitsemacount != 0) { + if(g->m->waitsemacount != 0) { // semaphore is available. - m->waitsemacount--; + g->m->waitsemacount--; // spin-mutex unlock - runtime·atomicstore(&m->waitsemalock, 0); + runtime·atomicstore(&g->m->waitsemalock, 0); return 0; // semaphore acquired } @@ -127,7 +127,7 @@ runtime·semasleep(int64 ns) // lock held but giving up // spin-mutex unlock - runtime·atomicstore(&m->waitsemalock, 0); + runtime·atomicstore(&g->m->waitsemalock, 0); return -1; } @@ -214,6 +214,7 @@ void runtime·mpreinit(M *mp) { mp->gsignal = runtime·malg(32*1024); + mp->gsignal->m = mp; } // Called to initialize a new m (including the bootstrap m). @@ -221,10 +222,10 @@ runtime·mpreinit(M *mp) void runtime·minit(void) { - m->procid = runtime·lwp_self(); + g->m->procid = runtime·lwp_self(); // Initialize signal handling - runtime·signalstack((byte*)m->gsignal->stackguard - StackGuard, 32*1024); + runtime·signalstack((byte*)g->m->gsignal->stackguard - StackGuard, 32*1024); runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil); } diff --git a/src/pkg/runtime/os_openbsd.c b/src/pkg/runtime/os_openbsd.c index 08a290a055..220091535d 100644 --- a/src/pkg/runtime/os_openbsd.c +++ b/src/pkg/runtime/os_openbsd.c @@ -67,34 +67,34 @@ runtime·semasleep(int64 ns) Timespec ts; // spin-mutex lock - while(runtime·xchg(&m->waitsemalock, 1)) + while(runtime·xchg(&g->m->waitsemalock, 1)) runtime·osyield(); for(;;) { // lock held - if(m->waitsemacount == 0) { + if(g->m->waitsemacount == 0) { // sleep until semaphore != 0 or timeout. // thrsleep unlocks m->waitsemalock. if(ns < 0) - runtime·thrsleep(&m->waitsemacount, 0, nil, &m->waitsemalock, nil); + runtime·thrsleep(&g->m->waitsemacount, 0, nil, &g->m->waitsemalock, nil); else { ns += runtime·nanotime(); // NOTE: tv_nsec is int64 on amd64, so this assumes a little-endian system. ts.tv_nsec = 0; ts.tv_sec = runtime·timediv(ns, 1000000000, (int32*)&ts.tv_nsec); - runtime·thrsleep(&m->waitsemacount, CLOCK_MONOTONIC, &ts, &m->waitsemalock, nil); + runtime·thrsleep(&g->m->waitsemacount, CLOCK_MONOTONIC, &ts, &g->m->waitsemalock, nil); } // reacquire lock - while(runtime·xchg(&m->waitsemalock, 1)) + while(runtime·xchg(&g->m->waitsemalock, 1)) runtime·osyield(); } // lock held (again) - if(m->waitsemacount != 0) { + if(g->m->waitsemacount != 0) { // semaphore is available. - m->waitsemacount--; + g->m->waitsemacount--; // spin-mutex unlock - runtime·atomicstore(&m->waitsemalock, 0); + runtime·atomicstore(&g->m->waitsemalock, 0); return 0; // semaphore acquired } @@ -107,7 +107,7 @@ runtime·semasleep(int64 ns) // lock held but giving up // spin-mutex unlock - runtime·atomicstore(&m->waitsemalock, 0); + runtime·atomicstore(&g->m->waitsemalock, 0); return -1; } @@ -193,6 +193,7 @@ void runtime·mpreinit(M *mp) { mp->gsignal = runtime·malg(32*1024); + mp->gsignal->m = mp; } // Called to initialize a new m (including the bootstrap m). @@ -201,7 +202,7 @@ void runtime·minit(void) { // Initialize signal handling - runtime·signalstack((byte*)m->gsignal->stackguard - StackGuard, 32*1024); + runtime·signalstack((byte*)g->m->gsignal->stackguard - StackGuard, 32*1024); runtime·sigprocmask(SIG_SETMASK, sigset_none); } diff --git a/src/pkg/runtime/os_plan9.c b/src/pkg/runtime/os_plan9.c index 14d4fae486..61f315a6c6 100644 --- a/src/pkg/runtime/os_plan9.c +++ b/src/pkg/runtime/os_plan9.c @@ -88,7 +88,7 @@ void runtime·osinit(void) { runtime·ncpu = getproccount(); - m->procid = getpid(); + g->m->procid = getpid(); runtime·notify(runtime·sigtramp); } @@ -285,13 +285,13 @@ runtime·semasleep(int64 ns) ms = runtime·timediv(ns, 1000000, nil); if(ms == 0) ms = 1; - ret = runtime·plan9_tsemacquire(&m->waitsemacount, ms); + ret = runtime·plan9_tsemacquire(&g->m->waitsemacount, ms); if(ret == 1) return 0; // success return -1; // timeout or interrupted } - while(runtime·plan9_semacquire(&m->waitsemacount, 1) < 0) { + while(runtime·plan9_semacquire(&g->m->waitsemacount, 1) < 0) { /* interrupted; try again (c.f. lock_sema.c) */ } return 0; // success @@ -360,7 +360,7 @@ runtime·sigpanic(void) switch(g->sig) { case SIGRFAULT: case SIGWFAULT: - p = runtime·strstr((byte*)m->notesig, (byte*)"addr=")+5; + p = runtime·strstr((byte*)g->m->notesig, (byte*)"addr=")+5; g->sigcode1 = atolwhex(p); if(g->sigcode1 < 0x1000 || g->paniconfault) { if(g->sigpc == 0) @@ -373,7 +373,7 @@ runtime·sigpanic(void) case SIGTRAP: if(g->paniconfault) runtime·panicstring("invalid memory address or nil pointer dereference"); - runtime·throw(m->notesig); + runtime·throw(g->m->notesig); break; case SIGINTDIV: runtime·panicstring("integer divide by zero"); @@ -382,7 +382,7 @@ runtime·sigpanic(void) runtime·panicstring("floating point error"); break; default: - runtime·panicstring(m->notesig); + runtime·panicstring(g->m->notesig); break; } } diff --git a/src/pkg/runtime/os_plan9_386.c b/src/pkg/runtime/os_plan9_386.c index 80d711f338..3490862244 100644 --- a/src/pkg/runtime/os_plan9_386.c +++ b/src/pkg/runtime/os_plan9_386.c @@ -73,7 +73,7 @@ runtime·sighandler(void *v, int8 *note, G *gp) if(flags & SigPanic) { // Copy the error string from sigtramp's stack into m->notesig so // we can reliably access it from the panic routines. - runtime·memmove(m->notesig, note, len+1); + runtime·memmove(g->m->notesig, note, len+1); gp->sig = sig; gp->sigpc = ureg->pc; @@ -104,8 +104,8 @@ runtime·sighandler(void *v, int8 *note, G *gp) return NCONT; Throw: - m->throwing = 1; - m->caughtsig = gp; + g->m->throwing = 1; + g->m->caughtsig = gp; runtime·startpanic(); runtime·printf("%s\n", note); @@ -146,5 +146,5 @@ runtime·resetcpuprofiler(int32 hz) { // TODO: Enable profiling interrupts. - m->profilehz = hz; + g->m->profilehz = hz; } diff --git a/src/pkg/runtime/os_plan9_amd64.c b/src/pkg/runtime/os_plan9_amd64.c index a4e5ba8194..6b0f8ae3a2 100644 --- a/src/pkg/runtime/os_plan9_amd64.c +++ b/src/pkg/runtime/os_plan9_amd64.c @@ -81,7 +81,7 @@ runtime·sighandler(void *v, int8 *note, G *gp) if(flags & SigPanic) { // Copy the error string from sigtramp's stack into m->notesig so // we can reliably access it from the panic routines. - runtime·memmove(m->notesig, note, len+1); + runtime·memmove(g->m->notesig, note, len+1); gp->sig = sig; gp->sigpc = ureg->ip; @@ -112,8 +112,8 @@ runtime·sighandler(void *v, int8 *note, G *gp) return NCONT; Throw: - m->throwing = 1; - m->caughtsig = gp; + g->m->throwing = 1; + g->m->caughtsig = gp; runtime·startpanic(); runtime·printf("%s\n", note); @@ -154,5 +154,5 @@ runtime·resetcpuprofiler(int32 hz) { // TODO: Enable profiling interrupts. - m->profilehz = hz; + g->m->profilehz = hz; } diff --git a/src/pkg/runtime/os_solaris.c b/src/pkg/runtime/os_solaris.c index c6bbea3116..4ef17f9021 100644 --- a/src/pkg/runtime/os_solaris.c +++ b/src/pkg/runtime/os_solaris.c @@ -102,14 +102,14 @@ static Sigset sigset_all = { ~(uint32)0, ~(uint32)0, ~(uint32)0, ~(uint32)0, }; uintptr runtime·sysvicall6(uintptr fn, int32 count, ...) { - runtime·memclr((byte*)&m->scratch, sizeof(m->scratch)); - m->libcall.fn = (void*)fn; - m->libcall.n = (uintptr)count; + runtime·memclr((byte*)&g->m->scratch, sizeof(g->m->scratch)); + g->m->libcall.fn = (void*)fn; + g->m->libcall.n = (uintptr)count; for(;count; count--) - m->scratch.v[count - 1] = *((uintptr*)&count + count); - m->libcall.args = (uintptr*)&m->scratch.v[0]; - runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall); - return m->libcall.r1; + g->m->scratch.v[count - 1] = *((uintptr*)&count + count); + g->m->libcall.args = (uintptr*)&g->m->scratch.v[0]; + runtime·asmcgocall(runtime·asmsysvicall6, &g->m->libcall); + return g->m->libcall.r1; } static int32 @@ -187,6 +187,7 @@ void runtime·mpreinit(M *mp) { mp->gsignal = runtime·malg(32*1024); + mp->gsignal->m = mp; } // Called to initialize a new m (including the bootstrap m). @@ -196,7 +197,7 @@ runtime·minit(void) { runtime·asmcgocall(runtime·miniterrno, (void *)libc·___errno); // Initialize signal handling - runtime·signalstack((byte*)m->gsignal->stackguard - StackGuard, 32*1024); + runtime·signalstack((byte*)g->m->gsignal->stackguard - StackGuard, 32*1024); runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil); } @@ -337,13 +338,13 @@ runtime·semacreate(void) // Call libc's malloc rather than runtime·malloc. This will // allocate space on the C heap. We can't call runtime·malloc // here because it could cause a deadlock. - m->libcall.fn = (void*)libc·malloc; - m->libcall.n = 1; - runtime·memclr((byte*)&m->scratch, sizeof(m->scratch)); - m->scratch.v[0] = (uintptr)sizeof(*sem); - m->libcall.args = (uintptr*)&m->scratch; - runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall); - sem = (void*)m->libcall.r1; + g->m->libcall.fn = (void*)libc·malloc; + g->m->libcall.n = 1; + runtime·memclr((byte*)&g->m->scratch, sizeof(g->m->scratch)); + g->m->scratch.v[0] = (uintptr)sizeof(*sem); + g->m->libcall.args = (uintptr*)&g->m->scratch; + runtime·asmcgocall(runtime·asmsysvicall6, &g->m->libcall); + sem = (void*)g->m->libcall.r1; if(runtime·sem_init(sem, 0, 0) != 0) runtime·throw("sem_init"); return (uintptr)sem; @@ -353,6 +354,9 @@ runtime·semacreate(void) int32 runtime·semasleep(int64 ns) { + M *m; + + m = g->m; if(ns >= 0) { m->ts.tv_sec = ns / 1000000000LL; m->ts.tv_nsec = ns % 1000000000LL; diff --git a/src/pkg/runtime/os_windows.c b/src/pkg/runtime/os_windows.c index 0dd44ed1b9..159af048f6 100644 --- a/src/pkg/runtime/os_windows.c +++ b/src/pkg/runtime/os_windows.c @@ -202,7 +202,7 @@ runtime·semasleep(int64 ns) if(ns == 0) ns = 1; } - if(runtime·stdcall(runtime·WaitForSingleObject, 2, m->waitsema, (uintptr)ns) != 0) + if(runtime·stdcall(runtime·WaitForSingleObject, 2, g->m->waitsema, (uintptr)ns) != 0) return -1; // timeout return 0; } @@ -256,7 +256,7 @@ runtime·minit(void) runtime·stdcall(runtime·DuplicateHandle, 7, (uintptr)-1, (uintptr)-2, (uintptr)-1, &thandle, (uintptr)0, (uintptr)0, (uintptr)DUPLICATE_SAME_ACCESS); - runtime·atomicstorep(&m->thread, thandle); + runtime·atomicstorep(&g->m->thread, thandle); } // Called from dropm to undo the effect of an minit. @@ -295,20 +295,20 @@ time·now(int64 sec, int32 usec) void * runtime·stdcall(void *fn, int32 count, ...) { - m->libcall.fn = fn; - m->libcall.n = count; - m->libcall.args = (uintptr*)&count + 1; - if(m->profilehz != 0) { + g->m->libcall.fn = fn; + g->m->libcall.n = count; + g->m->libcall.args = (uintptr*)&count + 1; + if(g->m->profilehz != 0) { // leave pc/sp for cpu profiler - m->libcallg = g; - m->libcallpc = (uintptr)runtime·getcallerpc(&fn); + g->m->libcallg = g; + g->m->libcallpc = (uintptr)runtime·getcallerpc(&fn); // sp must be the last, because once async cpu profiler finds // all three values to be non-zero, it will use them - m->libcallsp = (uintptr)runtime·getcallersp(&fn); + g->m->libcallsp = (uintptr)runtime·getcallersp(&fn); } - runtime·asmcgocall(runtime·asmstdcall, &m->libcall); - m->libcallsp = 0; - return (void*)m->libcall.r1; + runtime·asmcgocall(runtime·asmstdcall, &g->m->libcall); + g->m->libcallsp = 0; + return (void*)g->m->libcall.r1; } extern void runtime·usleep1(uint32); @@ -484,7 +484,7 @@ runtime·resetcpuprofiler(int32 hz) } runtime·stdcall(runtime·SetWaitableTimer, 6, profiletimer, &due, (uintptr)ms, nil, nil, nil); - runtime·atomicstore((uint32*)&m->profilehz, hz); + runtime·atomicstore((uint32*)&g->m->profilehz, hz); } void diff --git a/src/pkg/runtime/os_windows_386.c b/src/pkg/runtime/os_windows_386.c index c36a001140..7ee7dedc1f 100644 --- a/src/pkg/runtime/os_windows_386.c +++ b/src/pkg/runtime/os_windows_386.c @@ -100,9 +100,9 @@ runtime·sighandler(ExceptionRecord *info, Context *r, G *gp) info->ExceptionInformation[0], info->ExceptionInformation[1], r->Eip); runtime·printf("PC=%x\n", r->Eip); - if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) { + if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) { runtime·printf("signal arrived during cgo execution\n"); - gp = m->lockedg; + gp = g->m->lockedg; } runtime·printf("\n"); diff --git a/src/pkg/runtime/os_windows_amd64.c b/src/pkg/runtime/os_windows_amd64.c index 7fb973cde4..a7acf1d786 100644 --- a/src/pkg/runtime/os_windows_amd64.c +++ b/src/pkg/runtime/os_windows_amd64.c @@ -106,9 +106,9 @@ runtime·sighandler(ExceptionRecord *info, Context *r, G *gp) runtime·printf("PC=%X\n", r->Rip); - if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) { + if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) { runtime·printf("signal arrived during cgo execution\n"); - gp = m->lockedg; + gp = g->m->lockedg; } runtime·printf("\n"); diff --git a/src/pkg/runtime/panic.c b/src/pkg/runtime/panic.c index f577b37b58..8225df7db7 100644 --- a/src/pkg/runtime/panic.c +++ b/src/pkg/runtime/panic.c @@ -34,7 +34,7 @@ newdefer(int32 siz) d = nil; sc = DEFERCLASS(siz); if(sc < nelem(p->deferpool)) { - p = m->p; + p = g->m->p; d = p->deferpool[sc]; if(d) p->deferpool[sc] = d->link; @@ -63,7 +63,7 @@ freedefer(Defer *d) return; sc = DEFERCLASS(d->siz); if(sc < nelem(p->deferpool)) { - p = m->p; + p = g->m->p; d->link = p->deferpool[sc]; p->deferpool[sc] = d; // No need to wipe out pointers in argp/pc/fn/args, @@ -134,13 +134,13 @@ runtime·deferreturn(uintptr arg0) // Do not allow preemption here, because the garbage collector // won't know the form of the arguments until the jmpdefer can // flip the PC over to fn. - m->locks++; + g->m->locks++; runtime·memmove(argp, d->args, d->siz); fn = d->fn; g->defer = d->link; freedefer(d); - m->locks--; - if(m->locks == 0 && g->preempt) + g->m->locks--; + if(g->m->locks == 0 && g->preempt) g->stackguard0 = StackPreempt; runtime·jmpdefer(fn, argp); } @@ -385,12 +385,12 @@ runtime·startpanic(void) { if(runtime·mheap.cachealloc.size == 0) { // very early runtime·printf("runtime: panic before malloc heap initialized\n"); - m->mallocing = 1; // tell rest of panic not to try to malloc - } else if(m->mcache == nil) // can happen if called from signal handler or throw - m->mcache = runtime·allocmcache(); - switch(m->dying) { + g->m->mallocing = 1; // tell rest of panic not to try to malloc + } else if(g->m->mcache == nil) // can happen if called from signal handler or throw + g->m->mcache = runtime·allocmcache(); + switch(g->m->dying) { case 0: - m->dying = 1; + g->m->dying = 1; if(g != nil) g->writebuf = nil; runtime·xadd(&runtime·panicking, 1); @@ -402,14 +402,14 @@ runtime·startpanic(void) case 1: // Something failed while panicing, probably the print of the // argument to panic(). Just print a stack trace and exit. - m->dying = 2; + g->m->dying = 2; runtime·printf("panic during panic\n"); runtime·dopanic(0); runtime·exit(3); case 2: // This is a genuine bug in the runtime, we couldn't even // print the stack trace successfully. - m->dying = 3; + g->m->dying = 3; runtime·printf("stack trace unavailable\n"); runtime·exit(4); default: @@ -430,11 +430,11 @@ runtime·dopanic(int32 unused) g->sig, g->sigcode0, g->sigcode1, g->sigpc); if((t = runtime·gotraceback(&crash)) > 0){ - if(g != m->g0) { + if(g != g->m->g0) { runtime·printf("\n"); runtime·goroutineheader(g); runtime·traceback((uintptr)runtime·getcallerpc(&unused), (uintptr)runtime·getcallersp(&unused), 0, g); - } else if(t >= 2 || m->throwing > 0) { + } else if(t >= 2 || g->m->throwing > 0) { runtime·printf("\nruntime stack:\n"); runtime·traceback((uintptr)runtime·getcallerpc(&unused), (uintptr)runtime·getcallersp(&unused), 0, g); } @@ -489,9 +489,12 @@ runtime·throwinit(void) bool runtime·canpanic(G *gp) { - byte g; + M *m; - USED(&g); // don't use global g, it points to gsignal + // Note that g is m->gsignal, different from gp. + // Note also that g->m can change at preemption, so m can go stale + // if this function ever makes a function call. + m = g->m; // Is it okay for gp to panic instead of crashing the program? // Yes, as long as it is running Go code, not runtime code, @@ -512,8 +515,8 @@ runtime·canpanic(G *gp) void runtime·throw(int8 *s) { - if(m->throwing == 0) - m->throwing = 1; + if(g->m->throwing == 0) + g->m->throwing = 1; runtime·startpanic(); runtime·printf("fatal error: %s\n", s); runtime·dopanic(0); @@ -531,20 +534,20 @@ runtime·panicstring(int8 *s) // It increments m->locks to avoid preemption. // If we're panicking, the software floating point frames // will be unwound, so decrement m->locks as they would. - if(m->softfloat) { - m->locks--; - m->softfloat = 0; + if(g->m->softfloat) { + g->m->locks--; + g->m->softfloat = 0; } - if(m->mallocing) { + if(g->m->mallocing) { runtime·printf("panic: %s\n", s); runtime·throw("panic during malloc"); } - if(m->gcing) { + if(g->m->gcing) { runtime·printf("panic: %s\n", s); runtime·throw("panic during gc"); } - if(m->locks) { + if(g->m->locks) { runtime·printf("panic: %s\n", s); runtime·throw("panic holding locks"); } diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c index b81267210b..7467e9fa16 100644 --- a/src/pkg/runtime/proc.c +++ b/src/pkg/runtime/proc.c @@ -153,7 +153,7 @@ runtime·schedinit(void) runtime·symtabinit(); runtime·mallocinit(); - mcommoninit(m); + mcommoninit(g->m); // Initialize the itable value for newErrorCString, // so that the next time it gets called, possibly @@ -236,7 +236,7 @@ runtime·main(void) d.special = true; g->defer = &d; - if(m != &runtime·m0) + if(g->m != &runtime·m0) runtime·throw("runtime·main not on m0"); runtime·newproc1(&scavenger, nil, 0, 0, runtime·main); main·init(); @@ -313,7 +313,7 @@ runtime·tracebackothers(G *me) traceback = runtime·gotraceback(nil); // Show the current goroutine first, if we haven't already. - if((gp = m->curg) != nil && gp != me) { + if((gp = g->m->curg) != nil && gp != me) { runtime·printf("\n"); runtime·goroutineheader(gp); runtime·traceback(~(uintptr)0, ~(uintptr)0, 0, gp); @@ -322,7 +322,7 @@ runtime·tracebackothers(G *me) runtime·lock(&allglock); for(i = 0; i < runtime·allglen; i++) { gp = runtime·allg[i]; - if(gp == me || gp == m->curg || gp->status == Gdead) + if(gp == me || gp == g->m->curg || gp->status == Gdead) continue; if(gp->issystem && traceback < 2) continue; @@ -352,7 +352,7 @@ mcommoninit(M *mp) { // If there is no mcache runtime·callers() will crash, // and we are most likely in sysmon thread so the stack is senseless anyway. - if(m->mcache) + if(g->m->mcache) runtime·callers(1, mp->createstack, nelem(mp->createstack)); mp->fastrand = 0x49f6428aUL + mp->id + runtime·cputicks(); @@ -362,7 +362,7 @@ mcommoninit(M *mp) checkmcount(); runtime·mpreinit(mp); - // Add to runtime·allm so garbage collector doesn't free m + // Add to runtime·allm so garbage collector doesn't free g->m // when it is just in a register or thread-local storage. mp->alllink = runtime·allm; // runtime·NumCgoCall() iterates over allm w/o schedlock, @@ -376,17 +376,17 @@ void runtime·ready(G *gp) { // Mark runnable. - m->locks++; // disable preemption because it can be holding p in a local var + g->m->locks++; // disable preemption because it can be holding p in a local var if(gp->status != Gwaiting) { runtime·printf("goroutine %D has status %d\n", gp->goid, gp->status); runtime·throw("bad g->status in ready"); } gp->status = Grunnable; - runqput(m->p, gp); + runqput(g->m->p, gp); if(runtime·atomicload(&runtime·sched.npidle) != 0 && runtime·atomicload(&runtime·sched.nmspinning) == 0) // TODO: fast atomic wakep(); - m->locks--; - if(m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack + g->m->locks--; + if(g->m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack g->stackguard0 = StackPreempt; } @@ -434,7 +434,7 @@ runtime·helpgc(int32 nproc) runtime·lock(&runtime·sched); pos = 0; for(n = 1; n < nproc; n++) { // one M is currently running - if(runtime·allp[pos]->mcache == m->mcache) + if(runtime·allp[pos]->mcache == g->m->mcache) pos++; mp = mget(); if(mp == nil) @@ -488,7 +488,7 @@ runtime·stoptheworld(void) runtime·atomicstore((uint32*)&runtime·sched.gcwaiting, 1); preemptall(); // stop current P - m->p->status = Pgcstop; + g->m->p->status = Pgcstop; runtime·sched.stopwait--; // try to retake all P's in Psyscall status for(i = 0; i < runtime·gomaxprocs; i++) { @@ -528,7 +528,7 @@ runtime·stoptheworld(void) static void mhelpgc(void) { - m->helpgc = -1; + g->m->helpgc = -1; } void @@ -539,7 +539,7 @@ runtime·starttheworld(void) G *gp; bool add; - m->locks++; // disable preemption because it can be holding p in a local var + g->m->locks++; // disable preemption because it can be holding p in a local var gp = runtime·netpoll(false); // non-blocking injectglist(gp); add = needaddgcproc(); @@ -596,8 +596,8 @@ runtime·starttheworld(void) // the maximum number of procs. newm(mhelpgc, nil); } - m->locks--; - if(m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack + g->m->locks--; + if(g->m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack g->stackguard0 = StackPreempt; } @@ -605,32 +605,32 @@ runtime·starttheworld(void) void runtime·mstart(void) { - if(g != m->g0) + if(g != g->m->g0) runtime·throw("bad runtime·mstart"); // Record top of stack for use by mcall. // Once we call schedule we're never coming back, // so other calls can reuse this stack space. - runtime·gosave(&m->g0->sched); - m->g0->sched.pc = (uintptr)-1; // make sure it is never used - m->g0->stackguard = m->g0->stackguard0; // cgo sets only stackguard0, copy it to stackguard + runtime·gosave(&g->m->g0->sched); + g->m->g0->sched.pc = (uintptr)-1; // make sure it is never used + g->m->g0->stackguard = g->m->g0->stackguard0; // cgo sets only stackguard0, copy it to stackguard runtime·asminit(); runtime·minit(); // Install signal handlers; after minit so that minit can // prepare the thread to be able to handle the signals. - if(m == &runtime·m0) + if(g->m == &runtime·m0) runtime·initsig(); - if(m->mstartfn) - m->mstartfn(); + if(g->m->mstartfn) + g->m->mstartfn(); - if(m->helpgc) { - m->helpgc = 0; + if(g->m->helpgc) { + g->m->helpgc = 0; stopm(); - } else if(m != &runtime·m0) { - acquirep(m->nextp); - m->nextp = nil; + } else if(g->m != &runtime·m0) { + acquirep(g->m->nextp); + g->m->nextp = nil; } schedule(); @@ -647,7 +647,6 @@ void (*_cgo_thread_start)(void*); typedef struct CgoThreadStart CgoThreadStart; struct CgoThreadStart { - M *m; G *g; uintptr *tls; void (*fn)(void); @@ -661,8 +660,8 @@ runtime·allocm(P *p) M *mp; static Type *mtype; // The Go type M - m->locks++; // disable GC because it can be called from sysmon - if(m->p == nil) + g->m->locks++; // disable GC because it can be called from sysmon + if(g->m->p == nil) acquirep(p); // temporarily borrow p for mallocs in this function if(mtype == nil) { Eface e; @@ -679,11 +678,12 @@ runtime·allocm(P *p) mp->g0 = runtime·malg(-1); else mp->g0 = runtime·malg(8192); + mp->g0->m = mp; - if(p == m->p) + if(p == g->m->p) releasep(); - m->locks--; - if(m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack + g->m->locks--; + if(g->m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack g->stackguard0 = StackPreempt; return mp; @@ -770,12 +770,12 @@ runtime·needm(byte x) mp->needextram = mp->schedlink == nil; unlockextra(mp->schedlink); - // Install m and g (= m->g0) and set the stack bounds + // Install g (= m->g0) and set the stack bounds // to match the current stack. We don't actually know // how big the stack is, like we don't know how big any // scheduling stack is, but we assume there's at least 32 kB, // which is more than enough for us. - runtime·setmg(mp, mp->g0); + runtime·setg(mp->g0); g->stackbase = (uintptr)(&x + 1024); g->stackguard = (uintptr)(&x - 32*1024); g->stackguard0 = g->stackguard; @@ -810,6 +810,7 @@ runtime·newextram(void) gp->syscallstack = gp->stackbase; gp->syscallguard = gp->stackguard; gp->status = Gsyscall; + gp->m = mp; mp->curg = gp; mp->locked = LockInternal; mp->lockedg = gp; @@ -859,8 +860,8 @@ runtime·dropm(void) // Clear m and g, and return m to the extra list. // After the call to setmg we can only call nosplit functions. - mp = m; - runtime·setmg(nil, nil); + mp = g->m; + runtime·setg(nil); mnext = lockextra(true); mp->schedlink = mnext; @@ -925,7 +926,6 @@ newm(void(*fn)(void), P *p) if(_cgo_thread_start == nil) runtime·throw("_cgo_thread_start missing"); - ts.m = mp; ts.g = mp->g0; ts.tls = mp->tls; ts.fn = runtime·mstart; @@ -940,35 +940,35 @@ newm(void(*fn)(void), P *p) static void stopm(void) { - if(m->locks) + if(g->m->locks) runtime·throw("stopm holding locks"); - if(m->p) + if(g->m->p) runtime·throw("stopm holding p"); - if(m->spinning) { - m->spinning = false; + if(g->m->spinning) { + g->m->spinning = false; runtime·xadd(&runtime·sched.nmspinning, -1); } retry: runtime·lock(&runtime·sched); - mput(m); + mput(g->m); runtime·unlock(&runtime·sched); - runtime·notesleep(&m->park); - runtime·noteclear(&m->park); - if(m->helpgc) { + runtime·notesleep(&g->m->park); + runtime·noteclear(&g->m->park); + if(g->m->helpgc) { runtime·gchelper(); - m->helpgc = 0; - m->mcache = nil; + g->m->helpgc = 0; + g->m->mcache = nil; goto retry; } - acquirep(m->nextp); - m->nextp = nil; + acquirep(g->m->nextp); + g->m->nextp = nil; } static void mspinning(void) { - m->spinning = true; + g->m->spinning = true; } // Schedules some M to run the p (creates an M if necessary). @@ -1065,21 +1065,21 @@ stoplockedm(void) { P *p; - if(m->lockedg == nil || m->lockedg->lockedm != m) + if(g->m->lockedg == nil || g->m->lockedg->lockedm != g->m) runtime·throw("stoplockedm: inconsistent locking"); - if(m->p) { + if(g->m->p) { // Schedule another M to run this p. p = releasep(); handoffp(p); } incidlelocked(1); // Wait until another thread schedules lockedg again. - runtime·notesleep(&m->park); - runtime·noteclear(&m->park); - if(m->lockedg->status != Grunnable) + runtime·notesleep(&g->m->park); + runtime·noteclear(&g->m->park); + if(g->m->lockedg->status != Grunnable) runtime·throw("stoplockedm: not runnable"); - acquirep(m->nextp); - m->nextp = nil; + acquirep(g->m->nextp); + g->m->nextp = nil; } // Schedules the locked m to run the locked gp. @@ -1090,7 +1090,7 @@ startlockedm(G *gp) P *p; mp = gp->lockedm; - if(mp == m) + if(mp == g->m) runtime·throw("startlockedm: locked to me"); if(mp->nextp) runtime·throw("startlockedm: m has p"); @@ -1111,8 +1111,8 @@ gcstopm(void) if(!runtime·sched.gcwaiting) runtime·throw("gcstopm: not waiting for gc"); - if(m->spinning) { - m->spinning = false; + if(g->m->spinning) { + g->m->spinning = false; runtime·xadd(&runtime·sched.nmspinning, -1); } p = releasep(); @@ -1139,13 +1139,13 @@ execute(G *gp) gp->waitsince = 0; gp->preempt = false; gp->stackguard0 = gp->stackguard; - m->p->schedtick++; - m->curg = gp; - gp->m = m; + g->m->p->schedtick++; + g->m->curg = gp; + gp->m = g->m; // Check whether the profiler needs to be turned on or off. hz = runtime·sched.profilehz; - if(m->profilehz != hz) + if(g->m->profilehz != hz) runtime·resetcpuprofiler(hz); runtime·gogo(&gp->sched); @@ -1168,13 +1168,13 @@ top: if(runtime·fingwait && runtime·fingwake && (gp = runtime·wakefing()) != nil) runtime·ready(gp); // local runq - gp = runqget(m->p); + gp = runqget(g->m->p); if(gp) return gp; // global runq if(runtime·sched.runqsize) { runtime·lock(&runtime·sched); - gp = globrunqget(m->p, 0); + gp = globrunqget(g->m->p, 0); runtime·unlock(&runtime·sched); if(gp) return gp; @@ -1189,10 +1189,10 @@ top: // If number of spinning M's >= number of busy P's, block. // This is necessary to prevent excessive CPU consumption // when GOMAXPROCS>>1 but the program parallelism is low. - if(!m->spinning && 2 * runtime·atomicload(&runtime·sched.nmspinning) >= runtime·gomaxprocs - runtime·atomicload(&runtime·sched.npidle)) // TODO: fast atomic + if(!g->m->spinning && 2 * runtime·atomicload(&runtime·sched.nmspinning) >= runtime·gomaxprocs - runtime·atomicload(&runtime·sched.npidle)) // TODO: fast atomic goto stop; - if(!m->spinning) { - m->spinning = true; + if(!g->m->spinning) { + g->m->spinning = true; runtime·xadd(&runtime·sched.nmspinning, 1); } // random steal from other P's @@ -1200,10 +1200,10 @@ top: if(runtime·sched.gcwaiting) goto top; p = runtime·allp[runtime·fastrand1()%runtime·gomaxprocs]; - if(p == m->p) + if(p == g->m->p) gp = runqget(p); else - gp = runqsteal(m->p, p); + gp = runqsteal(g->m->p, p); if(gp) return gp; } @@ -1215,15 +1215,15 @@ stop: goto top; } if(runtime·sched.runqsize) { - gp = globrunqget(m->p, 0); + gp = globrunqget(g->m->p, 0); runtime·unlock(&runtime·sched); return gp; } p = releasep(); pidleput(p); runtime·unlock(&runtime·sched); - if(m->spinning) { - m->spinning = false; + if(g->m->spinning) { + g->m->spinning = false; runtime·xadd(&runtime·sched.nmspinning, -1); } // check all runqueues once again @@ -1242,9 +1242,9 @@ stop: } // poll network if(runtime·xchg64(&runtime·sched.lastpoll, 0) != 0) { - if(m->p) + if(g->m->p) runtime·throw("findrunnable: netpoll with p"); - if(m->spinning) + if(g->m->spinning) runtime·throw("findrunnable: netpoll with spinning"); gp = runtime·netpoll(true); // block until new work is available runtime·atomicstore64(&runtime·sched.lastpoll, runtime·nanotime()); @@ -1270,8 +1270,8 @@ resetspinning(void) { int32 nmspinning; - if(m->spinning) { - m->spinning = false; + if(g->m->spinning) { + g->m->spinning = false; nmspinning = runtime·xadd(&runtime·sched.nmspinning, -1); if(nmspinning < 0) runtime·throw("findrunnable: negative nmspinning"); @@ -1315,7 +1315,7 @@ schedule(void) G *gp; uint32 tick; - if(m->locks) + if(g->m->locks) runtime·throw("schedule: holding locks"); top: @@ -1328,19 +1328,19 @@ top: // Check the global runnable queue once in a while to ensure fairness. // Otherwise two goroutines can completely occupy the local runqueue // by constantly respawning each other. - tick = m->p->schedtick; + tick = g->m->p->schedtick; // This is a fancy way to say tick%61==0, // it uses 2 MUL instructions instead of a single DIV and so is faster on modern processors. if(tick - (((uint64)tick*0x4325c53fu)>>36)*61 == 0 && runtime·sched.runqsize > 0) { runtime·lock(&runtime·sched); - gp = globrunqget(m->p, 1); + gp = globrunqget(g->m->p, 1); runtime·unlock(&runtime·sched); if(gp) resetspinning(); } if(gp == nil) { - gp = runqget(m->p); - if(gp && m->spinning) + gp = runqget(g->m->p); + if(gp && g->m->spinning) runtime·throw("schedule: spinning with local work"); } if(gp == nil) { @@ -1365,8 +1365,8 @@ runtime·park(bool(*unlockf)(G*, void*), void *lock, int8 *reason) { if(g->status != Grunning) runtime·throw("bad g status"); - m->waitlock = lock; - m->waitunlockf = unlockf; + g->m->waitlock = lock; + g->m->waitunlockf = unlockf; g->waitreason = reason; runtime·mcall(park0); } @@ -1395,17 +1395,17 @@ park0(G *gp) gp->status = Gwaiting; gp->m = nil; - m->curg = nil; - if(m->waitunlockf) { - ok = m->waitunlockf(gp, m->waitlock); - m->waitunlockf = nil; - m->waitlock = nil; + g->m->curg = nil; + if(g->m->waitunlockf) { + ok = g->m->waitunlockf(gp, g->m->waitlock); + g->m->waitunlockf = nil; + g->m->waitlock = nil; if(!ok) { gp->status = Grunnable; execute(gp); // Schedule it back, never returns. } } - if(m->lockedg) { + if(g->m->lockedg) { stoplockedm(); execute(gp); // Never returns. } @@ -1427,11 +1427,11 @@ runtime·gosched0(G *gp) { gp->status = Grunnable; gp->m = nil; - m->curg = nil; + g->m->curg = nil; runtime·lock(&runtime·sched); globrunqput(gp); runtime·unlock(&runtime·sched); - if(m->lockedg) { + if(g->m->lockedg) { stoplockedm(); execute(gp); // Never returns. } @@ -1467,15 +1467,15 @@ goexit0(G *gp) gp->writebuf = nil; gp->waitreason = nil; gp->param = nil; - m->curg = nil; - m->lockedg = nil; - if(m->locked & ~LockExternal) { - runtime·printf("invalid m->locked = %d\n", m->locked); + g->m->curg = nil; + g->m->lockedg = nil; + if(g->m->locked & ~LockExternal) { + runtime·printf("invalid m->locked = %d\n", g->m->locked); runtime·throw("internal lockOSThread error"); } - m->locked = 0; + g->m->locked = 0; runtime·unwindstack(gp, nil); - gfput(m->p, gp); + gfput(g->m->p, gp); schedule(); } @@ -1505,7 +1505,7 @@ void { // Disable preemption because during this function g is in Gsyscall status, // but can have inconsistent g->sched, do not let GC observe it. - m->locks++; + g->m->locks++; // Leave SP around for GC and traceback. save(runtime·getcallerpc(&dummy), runtime·getcallersp(&dummy)); @@ -1530,12 +1530,12 @@ void save(runtime·getcallerpc(&dummy), runtime·getcallersp(&dummy)); } - m->mcache = nil; - m->p->m = nil; - runtime·atomicstore(&m->p->status, Psyscall); + g->m->mcache = nil; + g->m->p->m = nil; + runtime·atomicstore(&g->m->p->status, Psyscall); if(runtime·sched.gcwaiting) { runtime·lock(&runtime·sched); - if (runtime·sched.stopwait > 0 && runtime·cas(&m->p->status, Psyscall, Pgcstop)) { + if (runtime·sched.stopwait > 0 && runtime·cas(&g->m->p->status, Psyscall, Pgcstop)) { if(--runtime·sched.stopwait == 0) runtime·notewakeup(&runtime·sched.stopnote); } @@ -1547,7 +1547,7 @@ void // We set stackguard to StackPreempt so that first split stack check calls morestack. // Morestack detects this case and throws. g->stackguard0 = StackPreempt; - m->locks--; + g->m->locks--; } // The same as runtime·entersyscall(), but with a hint that the syscall is blocking. @@ -1557,7 +1557,7 @@ void { P *p; - m->locks++; // see comment in entersyscall + g->m->locks++; // see comment in entersyscall // Leave SP around for GC and traceback. save(runtime·getcallerpc(&dummy), runtime·getcallersp(&dummy)); @@ -1581,7 +1581,7 @@ void save(runtime·getcallerpc(&dummy), runtime·getcallersp(&dummy)); g->stackguard0 = StackPreempt; // see comment in entersyscall - m->locks--; + g->m->locks--; } // The goroutine g exited its system call. @@ -1592,7 +1592,7 @@ void void runtime·exitsyscall(void) { - m->locks++; // see comment in entersyscall + g->m->locks++; // see comment in entersyscall if(g->isbackground) // do not consider blocked scavenger for deadlock detection incidlelocked(-1); @@ -1600,13 +1600,13 @@ runtime·exitsyscall(void) g->waitsince = 0; if(exitsyscallfast()) { // There's a cpu for us, so we can run. - m->p->syscalltick++; + g->m->p->syscalltick++; g->status = Grunning; // Garbage collector isn't running (since we are), // so okay to clear gcstack and gcsp. g->syscallstack = (uintptr)nil; g->syscallsp = (uintptr)nil; - m->locks--; + g->m->locks--; if(g->preempt) { // restore the preemption request in case we've cleared it in newstack g->stackguard0 = StackPreempt; @@ -1617,7 +1617,7 @@ runtime·exitsyscall(void) return; } - m->locks--; + g->m->locks--; // Call the scheduler. runtime·mcall(exitsyscall0); @@ -1630,7 +1630,7 @@ runtime·exitsyscall(void) // is not running. g->syscallstack = (uintptr)nil; g->syscallsp = (uintptr)nil; - m->p->syscalltick++; + g->m->p->syscalltick++; } #pragma textflag NOSPLIT @@ -1641,19 +1641,19 @@ exitsyscallfast(void) // Freezetheworld sets stopwait but does not retake P's. if(runtime·sched.stopwait) { - m->p = nil; + g->m->p = nil; return false; } // Try to re-acquire the last P. - if(m->p && m->p->status == Psyscall && runtime·cas(&m->p->status, Psyscall, Prunning)) { + if(g->m->p && g->m->p->status == Psyscall && runtime·cas(&g->m->p->status, Psyscall, Prunning)) { // There's a cpu for us, so we can run. - m->mcache = m->p->mcache; - m->p->m = m; + g->m->mcache = g->m->p->mcache; + g->m->p->m = g->m; return true; } // Try to get any other idle P. - m->p = nil; + g->m->p = nil; if(runtime·sched.pidle) { runtime·lock(&runtime·sched); p = pidleget(); @@ -1679,7 +1679,7 @@ exitsyscall0(G *gp) gp->status = Grunnable; gp->m = nil; - m->curg = nil; + g->m->curg = nil; runtime·lock(&runtime·sched); p = pidleget(); if(p == nil) @@ -1693,7 +1693,7 @@ exitsyscall0(G *gp) acquirep(p); execute(gp); // Never returns. } - if(m->lockedg) { + if(g->m->lockedg) { // Wait until another thread schedules gp and so m again. stoplockedm(); execute(gp); // Never returns. @@ -1709,15 +1709,15 @@ syscall·runtime_BeforeFork(void) { // Fork can hang if preempted with signals frequently enough (see issue 5517). // Ensure that we stay on the same M where we disable profiling. - m->locks++; - if(m->profilehz != 0) + g->m->locks++; + if(g->m->profilehz != 0) runtime·resetcpuprofiler(0); // This function is called before fork in syscall package. // Code between fork and exec must not allocate memory nor even try to grow stack. // Here we spoil g->stackguard to reliably detect any attempts to grow stack. // runtime_AfterFork will undo this in parent process, but not in child. - m->forkstackguard = g->stackguard; + g->m->forkstackguard = g->stackguard; g->stackguard0 = StackPreempt-1; g->stackguard = StackPreempt-1; } @@ -1730,14 +1730,14 @@ syscall·runtime_AfterFork(void) int32 hz; // See the comment in runtime_BeforeFork. - g->stackguard0 = m->forkstackguard; - g->stackguard = m->forkstackguard; - m->forkstackguard = 0; + g->stackguard0 = g->m->forkstackguard; + g->stackguard = g->m->forkstackguard; + g->m->forkstackguard = 0; hz = runtime·sched.profilehz; if(hz != 0) runtime·resetcpuprofiler(hz); - m->locks--; + g->m->locks--; } // Hook used by runtime·malg to call runtime·stackalloc on the @@ -1772,7 +1772,7 @@ runtime·malg(int32 stacksize) newg = allocg(); if(stacksize >= 0) { stacksize = runtime·round2(StackSystem + stacksize); - if(g == m->g0) { + if(g == g->m->g0) { // running on scheduler stack already. stk = runtime·stackalloc(newg, stacksize); } else { @@ -1825,10 +1825,10 @@ runtime·newproc1(FuncVal *fn, byte *argp, int32 narg, int32 nret, void *callerp //runtime·printf("newproc1 %p %p narg=%d nret=%d\n", fn->fn, argp, narg, nret); if(fn == nil) { - m->throwing = -1; // do not dump full stacks + g->m->throwing = -1; // do not dump full stacks runtime·throw("go of nil func value"); } - m->locks++; // disable preemption because it can be holding p in a local var + g->m->locks++; // disable preemption because it can be holding p in a local var siz = narg + nret; siz = (siz+7) & ~7; @@ -1839,7 +1839,7 @@ runtime·newproc1(FuncVal *fn, byte *argp, int32 narg, int32 nret, void *callerp if(siz > StackMin - 1024) runtime·throw("runtime.newproc: function arguments too large for new goroutine"); - p = m->p; + p = g->m->p; if((newg = gfget(p)) != nil) { if(newg->stackguard - StackGuard != newg->stack0) runtime·throw("invalid stack in newg"); @@ -1876,8 +1876,8 @@ runtime·newproc1(FuncVal *fn, byte *argp, int32 narg, int32 nret, void *callerp if(runtime·atomicload(&runtime·sched.npidle) != 0 && runtime·atomicload(&runtime·sched.nmspinning) == 0 && fn->fn != runtime·main) // TODO: fast atomic wakep(); - m->locks--; - if(m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack + g->m->locks--; + if(g->m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack g->stackguard0 = StackPreempt; return newg; } @@ -1976,7 +1976,7 @@ retry: if(gp->stack0 == 0) { // Stack was deallocated in gfput. Allocate a new one. - if(g == m->g0) { + if(g == g->m->g0) { stk = runtime·stackalloc(gp, FixedStack); } else { gp->stacksize = FixedStack; @@ -2041,10 +2041,10 @@ runtime·gomaxprocsfunc(int32 n) runtime·unlock(&runtime·sched); runtime·semacquire(&runtime·worldsema, false); - m->gcing = 1; + g->m->gcing = 1; runtime·stoptheworld(); newprocs = n; - m->gcing = 0; + g->m->gcing = 0; runtime·semrelease(&runtime·worldsema); runtime·starttheworld(); @@ -2058,21 +2058,21 @@ runtime·gomaxprocsfunc(int32 n) static void lockOSThread(void) { - m->lockedg = g; - g->lockedm = m; + g->m->lockedg = g; + g->lockedm = g->m; } void runtime·LockOSThread(void) { - m->locked |= LockExternal; + g->m->locked |= LockExternal; lockOSThread(); } void runtime·lockOSThread(void) { - m->locked += LockInternal; + g->m->locked += LockInternal; lockOSThread(); } @@ -2084,32 +2084,32 @@ runtime·lockOSThread(void) static void unlockOSThread(void) { - if(m->locked != 0) + if(g->m->locked != 0) return; - m->lockedg = nil; + g->m->lockedg = nil; g->lockedm = nil; } void runtime·UnlockOSThread(void) { - m->locked &= ~LockExternal; + g->m->locked &= ~LockExternal; unlockOSThread(); } void runtime·unlockOSThread(void) { - if(m->locked < LockInternal) + if(g->m->locked < LockInternal) runtime·throw("runtime: internal error: misuse of lockOSThread/unlockOSThread"); - m->locked -= LockInternal; + g->m->locked -= LockInternal; unlockOSThread(); } bool runtime·lockedOSThread(void) { - return g->lockedm != nil && m->lockedg != nil; + return g->lockedm != nil && g->m->lockedg != nil; } int32 @@ -2329,7 +2329,7 @@ runtime·setcpuprofilerate(void (*fn)(uintptr*, int32), int32 hz) // Disable preemption, otherwise we can be rescheduled to another thread // that has profiling enabled. - m->locks++; + g->m->locks++; // Stop profiler on this thread so that it is safe to lock prof. // if a profiling signal came in while we had prof locked, @@ -2347,7 +2347,7 @@ runtime·setcpuprofilerate(void (*fn)(uintptr*, int32), int32 hz) if(hz != 0) runtime·resetcpuprofiler(hz); - m->locks--; + g->m->locks--; } // Change number of processors. The world is stopped, sched is locked. @@ -2373,7 +2373,7 @@ procresize(int32 new) } if(p->mcache == nil) { if(old==0 && i==0) - p->mcache = m->mcache; // bootstrap + p->mcache = g->m->mcache; // bootstrap else p->mcache = runtime·allocmcache(); } @@ -2424,10 +2424,10 @@ procresize(int32 new) // can't free P itself because it can be referenced by an M in syscall } - if(m->p) - m->p->m = nil; - m->p = nil; - m->mcache = nil; + if(g->m->p) + g->m->p->m = nil; + g->m->p = nil; + g->m->mcache = nil; p = runtime·allp[0]; p->m = nil; p->status = Pidle; @@ -2444,15 +2444,15 @@ procresize(int32 new) static void acquirep(P *p) { - if(m->p || m->mcache) + if(g->m->p || g->m->mcache) runtime·throw("acquirep: already in go"); if(p->m || p->status != Pidle) { runtime·printf("acquirep: p->m=%p(%d) p->status=%d\n", p->m, p->m ? p->m->id : 0, p->status); runtime·throw("acquirep: invalid p state"); } - m->mcache = p->mcache; - m->p = p; - p->m = m; + g->m->mcache = p->mcache; + g->m->p = p; + p->m = g->m; p->status = Prunning; } @@ -2462,16 +2462,16 @@ releasep(void) { P *p; - if(m->p == nil || m->mcache == nil) + if(g->m->p == nil || g->m->mcache == nil) runtime·throw("releasep: invalid arg"); - p = m->p; - if(p->m != m || p->mcache != m->mcache || p->status != Prunning) { + p = g->m->p; + if(p->m != g->m || p->mcache != g->m->mcache || p->status != Prunning) { runtime·printf("releasep: m=%p m->p=%p p->m=%p m->mcache=%p p->mcache=%p p->status=%d\n", - m, m->p, p->m, m->mcache, p->mcache, p->status); + g->m, g->m->p, p->m, g->m->mcache, p->mcache, p->status); runtime·throw("releasep: invalid p state"); } - m->p = nil; - m->mcache = nil; + g->m->p = nil; + g->m->mcache = nil; p->m = nil; p->status = Pidle; return p; @@ -2529,7 +2529,7 @@ checkdead(void) runtime·unlock(&allglock); if(grunning == 0) // possible if main goroutine calls runtime·Goexit() runtime·throw("no goroutines (main called runtime.Goexit) - deadlock!"); - m->throwing = -1; // do not dump full stacks + g->m->throwing = -1; // do not dump full stacks runtime·throw("all goroutines are asleep - deadlock!"); } @@ -2700,7 +2700,7 @@ preemptone(P *p) G *gp; mp = p->m; - if(mp == nil || mp == m) + if(mp == nil || mp == g->m) return false; gp = mp->curg; if(gp == nil || gp == mp->g0) @@ -2783,7 +2783,7 @@ runtime·schedtrace(bool detailed) " locks=%d dying=%d helpgc=%d spinning=%d blocked=%d lockedg=%D\n", mp->id, id1, id2, mp->mallocing, mp->throwing, mp->gcing, mp->locks, mp->dying, mp->helpgc, - mp->spinning, m->blocked, id3); + mp->spinning, g->m->blocked, id3); } runtime·lock(&allglock); for(gi = 0; gi < runtime·allglen; gi++) { diff --git a/src/pkg/runtime/race_amd64.s b/src/pkg/runtime/race_amd64.s index d60cf899b8..210f5d4ad7 100644 --- a/src/pkg/runtime/race_amd64.s +++ b/src/pkg/runtime/race_amd64.s @@ -192,8 +192,8 @@ TEXT runtime·racecall(SB), NOSPLIT, $0-0 // Switches SP to g0 stack and calls (AX). Arguments already set. TEXT racecall<>(SB), NOSPLIT, $0-0 get_tls(R12) - MOVQ m(R12), R13 MOVQ g(R12), R14 + MOVQ g_m(R14), R13 // Switch to g0 stack. MOVQ SP, R12 // callee-saved, preserved across the CALL MOVQ m_g0(R13), R10 @@ -222,14 +222,16 @@ TEXT runtime·racesymbolizethunk(SB), NOSPLIT, $56-8 PUSHQ R15 // Set g = g0. get_tls(R12) - MOVQ m(R12), R13 + MOVQ g(R12), R13 + MOVQ g_m(R13), R13 MOVQ m_g0(R13), R14 MOVQ R14, g(R12) // g = m->g0 MOVQ RARG0, 0(SP) // func arg CALL runtime·racesymbolize(SB) // All registers are smashed after Go code, reload. get_tls(R12) - MOVQ m(R12), R13 + MOVQ g(R12), R13 + MOVQ g_m(R13), R13 MOVQ m_curg(R13), R14 MOVQ R14, g(R12) // g = m->curg // Restore callee-saved registers. diff --git a/src/pkg/runtime/runtime.c b/src/pkg/runtime/runtime.c index 3a4f7199ed..26dbbbd3e2 100644 --- a/src/pkg/runtime/runtime.c +++ b/src/pkg/runtime/runtime.c @@ -32,8 +32,8 @@ runtime·gotraceback(bool *crash) if(crash != nil) *crash = false; - if(m->traceback != 0) - return m->traceback; + if(g->m->traceback != 0) + return g->m->traceback; x = runtime·atomicload(&traceback_cache); if(x == ~(uint32)0) { p = runtime·getenv("GOTRACEBACK"); @@ -286,11 +286,11 @@ runtime·fastrand1(void) { uint32 x; - x = m->fastrand; + x = g->m->fastrand; x += x; if(x & 0x80000000L) x ^= 0x88888eefUL; - m->fastrand = x; + g->m->fastrand = x; return x; } diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h index 5115503789..0f630abbf2 100644 --- a/src/pkg/runtime/runtime.h +++ b/src/pkg/runtime/runtime.h @@ -102,14 +102,13 @@ typedef struct DebugVars DebugVars; * local storage indexed by a pseudo-register TLS. See zasmhdr in * src/cmd/dist/buildruntime.c for details, and be aware that the linker may * make further OS-specific changes to the compiler's output. For example, - * 6l/linux rewrites 0(TLS) as -16(FS). + * 6l/linux rewrites 0(TLS) as -8(FS). * * Every C file linked into a Go program must include runtime.h so that the * C compiler (6c, 8c, etc.) knows to avoid other uses of these dedicated * registers. The Go compiler (6g, 8g, etc.) knows to avoid them. */ extern register G* g; -extern register M* m; /* * defined constants @@ -907,7 +906,7 @@ uint64 runtime·atomicload64(uint64 volatile*); void* runtime·atomicloadp(void* volatile*); void runtime·atomicstorep(void* volatile*, void*); -void runtime·setmg(M*, G*); +void runtime·setg(G*); void runtime·newextram(void); void runtime·exit(int32); void runtime·breakpoint(void); diff --git a/src/pkg/runtime/runtime1.goc b/src/pkg/runtime/runtime1.goc index c6f6b626a7..a95a4f944d 100644 --- a/src/pkg/runtime/runtime1.goc +++ b/src/pkg/runtime/runtime1.goc @@ -117,12 +117,12 @@ func runtime∕pprof·runtime_cyclesPerSecond() (res int64) { func sync·runtime_procPin() (p int) { M *mp; - mp = m; + mp = g->m; // Disable preemption. mp->locks++; p = mp->p->id; } func sync·runtime_procUnpin() { - m->locks--; + g->m->locks--; } diff --git a/src/pkg/runtime/signal_386.c b/src/pkg/runtime/signal_386.c index 70fcc6a636..d55e304528 100644 --- a/src/pkg/runtime/signal_386.c +++ b/src/pkg/runtime/signal_386.c @@ -39,7 +39,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp) bool crash; if(sig == SIGPROF) { - runtime·sigprof((byte*)SIG_EIP(info, ctxt), (byte*)SIG_ESP(info, ctxt), nil, gp, m); + runtime·sigprof((byte*)SIG_EIP(info, ctxt), (byte*)SIG_ESP(info, ctxt), nil, gp, g->m); return; } @@ -91,8 +91,8 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp) if(!(t->flags & SigThrow)) return; - m->throwing = 1; - m->caughtsig = gp; + g->m->throwing = 1; + g->m->caughtsig = gp; runtime·startpanic(); if(sig < 0 || sig >= NSIG) @@ -101,10 +101,10 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp) runtime·printf("%s\n", runtime·sigtab[sig].name); runtime·printf("PC=%x\n", SIG_EIP(info, ctxt)); - if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) { + if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) { runtime·printf("signal arrived during cgo execution\n"); - gp = m->lockedg; - } + gp = g->m->lockedg; + } runtime·printf("\n"); if(runtime·gotraceback(&crash)){ diff --git a/src/pkg/runtime/signal_amd64x.c b/src/pkg/runtime/signal_amd64x.c index 04026f32f6..44e68cecfc 100644 --- a/src/pkg/runtime/signal_amd64x.c +++ b/src/pkg/runtime/signal_amd64x.c @@ -48,7 +48,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp) bool crash; if(sig == SIGPROF) { - runtime·sigprof((byte*)SIG_RIP(info, ctxt), (byte*)SIG_RSP(info, ctxt), nil, gp, m); + runtime·sigprof((byte*)SIG_RIP(info, ctxt), (byte*)SIG_RSP(info, ctxt), nil, gp, g->m); return; } @@ -125,8 +125,8 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp) if(!(t->flags & SigThrow)) return; - m->throwing = 1; - m->caughtsig = gp; + g->m->throwing = 1; + g->m->caughtsig = gp; runtime·startpanic(); if(sig < 0 || sig >= NSIG) @@ -135,9 +135,9 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp) runtime·printf("%s\n", runtime·sigtab[sig].name); runtime·printf("PC=%X\n", SIG_RIP(info, ctxt)); - if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) { + if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) { runtime·printf("signal arrived during cgo execution\n"); - gp = m->lockedg; + gp = g->m->lockedg; } runtime·printf("\n"); diff --git a/src/pkg/runtime/signal_arm.c b/src/pkg/runtime/signal_arm.c index 9b2a43d9ba..1e8636846d 100644 --- a/src/pkg/runtime/signal_arm.c +++ b/src/pkg/runtime/signal_arm.c @@ -46,7 +46,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp) bool crash; if(sig == SIGPROF) { - runtime·sigprof((uint8*)SIG_PC(info, ctxt), (uint8*)SIG_SP(info, ctxt), (uint8*)SIG_LR(info, ctxt), gp, m); + runtime·sigprof((uint8*)SIG_PC(info, ctxt), (uint8*)SIG_SP(info, ctxt), (uint8*)SIG_LR(info, ctxt), gp, g->m); return; } @@ -76,7 +76,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp) SIG_LR(info, ctxt) = gp->sigpc; // In case we are panicking from external C code SIG_R10(info, ctxt) = (uintptr)gp; - SIG_R9(info, ctxt) = (uintptr)m; + SIG_R9(info, ctxt) = (uintptr)g->m; SIG_PC(info, ctxt) = (uintptr)runtime·sigpanic; return; } @@ -89,8 +89,8 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp) if(!(t->flags & SigThrow)) return; - m->throwing = 1; - m->caughtsig = gp; + g->m->throwing = 1; + g->m->caughtsig = gp; if(runtime·panicking) // traceback already printed runtime·exit(2); runtime·panicking = 1; @@ -101,9 +101,9 @@ runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp) runtime·printf("%s\n", runtime·sigtab[sig].name); runtime·printf("PC=%x\n", SIG_PC(info, ctxt)); - if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) { + if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) { runtime·printf("signal arrived during cgo execution\n"); - gp = m->lockedg; + gp = g->m->lockedg; } runtime·printf("\n"); diff --git a/src/pkg/runtime/signal_unix.c b/src/pkg/runtime/signal_unix.c index 246a1eb258..4d582d3f8c 100644 --- a/src/pkg/runtime/signal_unix.c +++ b/src/pkg/runtime/signal_unix.c @@ -89,7 +89,7 @@ runtime·resetcpuprofiler(int32 hz) it.it_value = it.it_interval; runtime·setitimer(ITIMER_PROF, &it, nil); } - m->profilehz = hz; + g->m->profilehz = hz; } void diff --git a/src/pkg/runtime/softfloat_arm.c b/src/pkg/runtime/softfloat_arm.c index 29a52bd0e4..41ce8bd753 100644 --- a/src/pkg/runtime/softfloat_arm.c +++ b/src/pkg/runtime/softfloat_arm.c @@ -32,20 +32,20 @@ fabort(void) static void putf(uint32 reg, uint32 val) { - m->freglo[reg] = val; + g->m->freglo[reg] = val; } static void putd(uint32 reg, uint64 val) { - m->freglo[reg] = (uint32)val; - m->freghi[reg] = (uint32)(val>>32); + g->m->freglo[reg] = (uint32)val; + g->m->freghi[reg] = (uint32)(val>>32); } static uint64 getd(uint32 reg) { - return (uint64)m->freglo[reg] | ((uint64)m->freghi[reg]<<32); + return (uint64)g->m->freglo[reg] | ((uint64)g->m->freghi[reg]<<32); } static void @@ -53,7 +53,7 @@ fprint(void) { uint32 i; for (i = 0; i < 16; i++) { - runtime·printf("\tf%d:\t%X %X\n", i, m->freghi[i], m->freglo[i]); + runtime·printf("\tf%d:\t%X %X\n", i, g->m->freghi[i], g->m->freglo[i]); } } @@ -111,7 +111,11 @@ stepflt(uint32 *pc, uint32 *regs) int64 sval; bool nan, ok; int32 cmp; + M *m; + // m is locked in vlop_arm.s, so g->m cannot change during this function call, + // so caching it in a local variable is safe. + m = g->m; i = *pc; if(trace) diff --git a/src/pkg/runtime/stack.c b/src/pkg/runtime/stack.c index 1680f004eb..a07042111e 100644 --- a/src/pkg/runtime/stack.c +++ b/src/pkg/runtime/stack.c @@ -53,15 +53,15 @@ stackcacherefill(void) for(i = 0; i < StackCacheBatch-1; i++) n->batch[i] = (byte*)n + (i+1)*FixedStack; } - pos = m->stackcachepos; + pos = g->m->stackcachepos; for(i = 0; i < StackCacheBatch-1; i++) { - m->stackcache[pos] = n->batch[i]; + g->m->stackcache[pos] = n->batch[i]; pos = (pos + 1) % StackCacheSize; } - m->stackcache[pos] = n; + g->m->stackcache[pos] = n; pos = (pos + 1) % StackCacheSize; - m->stackcachepos = pos; - m->stackcachecnt += StackCacheBatch; + g->m->stackcachepos = pos; + g->m->stackcachecnt += StackCacheBatch; } static void @@ -70,14 +70,14 @@ stackcacherelease(void) StackCacheNode *n; uint32 i, pos; - pos = (m->stackcachepos - m->stackcachecnt) % StackCacheSize; - n = (StackCacheNode*)m->stackcache[pos]; + pos = (g->m->stackcachepos - g->m->stackcachecnt) % StackCacheSize; + n = (StackCacheNode*)g->m->stackcache[pos]; pos = (pos + 1) % StackCacheSize; for(i = 0; i < StackCacheBatch-1; i++) { - n->batch[i] = m->stackcache[pos]; + n->batch[i] = g->m->stackcache[pos]; pos = (pos + 1) % StackCacheSize; } - m->stackcachecnt -= StackCacheBatch; + g->m->stackcachecnt -= StackCacheBatch; runtime·lock(&stackcachemu); n->next = stackcache; stackcache = n; @@ -95,7 +95,7 @@ runtime·stackalloc(G *gp, uint32 n) // Stackalloc must be called on scheduler stack, so that we // never try to grow the stack during the code that stackalloc runs. // Doing so would cause a deadlock (issue 1547). - if(g != m->g0) + if(g != g->m->g0) runtime·throw("stackalloc not on scheduler stack"); if((n & (n-1)) != 0) runtime·throw("stack size not a power of 2"); @@ -115,19 +115,19 @@ runtime·stackalloc(G *gp, uint32 n) // (assuming that inside malloc all the stack frames are small, // so that we do not deadlock). malloced = true; - if(n == FixedStack || m->mallocing) { + if(n == FixedStack || g->m->mallocing) { if(n != FixedStack) { runtime·printf("stackalloc: in malloc, size=%d want %d\n", FixedStack, n); runtime·throw("stackalloc"); } - if(m->stackcachecnt == 0) + if(g->m->stackcachecnt == 0) stackcacherefill(); - pos = m->stackcachepos; + pos = g->m->stackcachepos; pos = (pos - 1) % StackCacheSize; - v = m->stackcache[pos]; - m->stackcachepos = pos; - m->stackcachecnt--; - m->stackinuse++; + v = g->m->stackcache[pos]; + g->m->stackcachepos = pos; + g->m->stackcachecnt--; + g->m->stackinuse++; malloced = false; } else v = runtime·mallocgc(n, 0, FlagNoProfiling|FlagNoGC|FlagNoZero|FlagNoInvokeGC); @@ -161,13 +161,13 @@ runtime·stackfree(G *gp, void *v, Stktop *top) } if(n != FixedStack) runtime·throw("stackfree: bad fixed size"); - if(m->stackcachecnt == StackCacheSize) + if(g->m->stackcachecnt == StackCacheSize) stackcacherelease(); - pos = m->stackcachepos; - m->stackcache[pos] = v; - m->stackcachepos = (pos + 1) % StackCacheSize; - m->stackcachecnt++; - m->stackinuse--; + pos = g->m->stackcachepos; + g->m->stackcache[pos] = v; + g->m->stackcachepos = (pos + 1) % StackCacheSize; + g->m->stackcachecnt++; + g->m->stackinuse--; } // Called from runtime·lessstack when returning from a function which @@ -184,7 +184,7 @@ runtime·oldstack(void) int64 goid; int32 oldstatus; - gp = m->curg; + gp = g->m->curg; top = (Stktop*)gp->stackbase; old = (byte*)gp->stackguard - StackGuard; sp = (byte*)top; @@ -192,7 +192,7 @@ runtime·oldstack(void) if(StackDebug >= 1) { runtime·printf("runtime: oldstack gobuf={pc:%p sp:%p lr:%p} cret=%p argsize=%p\n", - top->gobuf.pc, top->gobuf.sp, top->gobuf.lr, (uintptr)m->cret, (uintptr)argsize); + top->gobuf.pc, top->gobuf.sp, top->gobuf.lr, (uintptr)g->m->cret, (uintptr)argsize); } // gp->status is usually Grunning, but it could be Gsyscall if a stack overflow @@ -200,8 +200,8 @@ runtime·oldstack(void) oldstatus = gp->status; gp->sched = top->gobuf; - gp->sched.ret = m->cret; - m->cret = 0; // drop reference + gp->sched.ret = g->m->cret; + g->m->cret = 0; // drop reference gp->status = Gwaiting; gp->waitreason = "stack unsplit"; @@ -416,7 +416,7 @@ adjustpointers(byte **scanp, BitVector *bv, AdjustInfo *adjinfo, Func *f) if(f != nil && (byte*)0 < p && (p < (byte*)PageSize || (uintptr)p == PoisonGC || (uintptr)p == PoisonStack)) { // Looks like a junk value in a pointer slot. // Live analysis wrong? - m->traceback = 2; + g->m->traceback = 2; runtime·printf("runtime: bad pointer in frame %s at %p: %p\n", runtime·funcname(f), &scanp[i], p); runtime·throw("bad pointer!"); } @@ -675,28 +675,28 @@ runtime·newstack(void) void *moreargp; bool newstackcall; - if(m->forkstackguard) + if(g->m->forkstackguard) runtime·throw("split stack after fork"); - if(m->morebuf.g != m->curg) { + if(g->m->morebuf.g != g->m->curg) { runtime·printf("runtime: newstack called from g=%p\n" "\tm=%p m->curg=%p m->g0=%p m->gsignal=%p\n", - m->morebuf.g, m, m->curg, m->g0, m->gsignal); + g->m->morebuf.g, g->m, g->m->curg, g->m->g0, g->m->gsignal); runtime·throw("runtime: wrong goroutine in newstack"); } // gp->status is usually Grunning, but it could be Gsyscall if a stack overflow // happens during a function call inside entersyscall. - gp = m->curg; + gp = g->m->curg; oldstatus = gp->status; - framesize = m->moreframesize; - argsize = m->moreargsize; - moreargp = m->moreargp; - m->moreargp = nil; - morebuf = m->morebuf; - m->morebuf.pc = (uintptr)nil; - m->morebuf.lr = (uintptr)nil; - m->morebuf.sp = (uintptr)nil; + framesize = g->m->moreframesize; + argsize = g->m->moreargsize; + moreargp = g->m->moreargp; + g->m->moreargp = nil; + morebuf = g->m->morebuf; + g->m->morebuf.pc = (uintptr)nil; + g->m->morebuf.lr = (uintptr)nil; + g->m->morebuf.sp = (uintptr)nil; gp->status = Gwaiting; gp->waitreason = "stack growth"; newstackcall = framesize==1; @@ -717,7 +717,7 @@ runtime·newstack(void) "\tmorebuf={pc:%p sp:%p lr:%p}\n" "\tsched={pc:%p sp:%p lr:%p ctxt:%p}\n", (uintptr)framesize, (uintptr)argsize, sp, gp->stackguard - StackGuard, gp->stackbase, - m->morebuf.pc, m->morebuf.sp, m->morebuf.lr, + g->m->morebuf.pc, g->m->morebuf.sp, g->m->morebuf.lr, gp->sched.pc, gp->sched.sp, gp->sched.lr, gp->sched.ctxt); } if(sp < gp->stackguard - StackGuard) { @@ -731,15 +731,15 @@ runtime·newstack(void) } if(gp->stackguard0 == (uintptr)StackPreempt) { - if(gp == m->g0) + if(gp == g->m->g0) runtime·throw("runtime: preempt g0"); - if(oldstatus == Grunning && m->p == nil && m->locks == 0) + if(oldstatus == Grunning && g->m->p == nil && g->m->locks == 0) runtime·throw("runtime: g is running but p is not"); - if(oldstatus == Gsyscall && m->locks == 0) + if(oldstatus == Gsyscall && g->m->locks == 0) runtime·throw("runtime: stack growth during syscall"); // Be conservative about where we preempt. // We are interested in preempting user Go code, not runtime code. - if(oldstatus != Grunning || m->locks || m->mallocing || m->gcing || m->p->status != Prunning) { + if(oldstatus != Grunning || g->m->locks || g->m->mallocing || g->m->gcing || g->m->p->status != Prunning) { // Let the goroutine keep running for now. // gp->preempt is set, so it will be preempted next time. gp->stackguard0 = gp->stackguard; @@ -839,9 +839,9 @@ runtime·newstack(void) runtime·memclr((byte*)&label, sizeof label); label.sp = sp; label.pc = (uintptr)runtime·lessstack; - label.g = m->curg; + label.g = g->m->curg; if(newstackcall) - runtime·gostartcallfn(&label, (FuncVal*)m->cret); + runtime·gostartcallfn(&label, (FuncVal*)g->m->cret); else { runtime·gostartcall(&label, (void(*)(void))gp->sched.pc, gp->sched.ctxt); gp->sched.ctxt = nil; diff --git a/src/pkg/runtime/symtab.goc b/src/pkg/runtime/symtab.goc index 15e1d28fab..961b78d5fc 100644 --- a/src/pkg/runtime/symtab.goc +++ b/src/pkg/runtime/symtab.goc @@ -316,7 +316,7 @@ runtime·showframe(Func *f, G *gp) static int32 traceback = -1; String name; - if(m->throwing > 0 && gp != nil && (gp == m->curg || gp == m->caughtsig)) + if(g->m->throwing > 0 && gp != nil && (gp == g->m->curg || gp == g->m->caughtsig)) return 1; if(traceback < 0) traceback = runtime·gotraceback(nil); diff --git a/src/pkg/runtime/sys_darwin_386.s b/src/pkg/runtime/sys_darwin_386.s index bfaaa00a7e..a702d9bfa1 100644 --- a/src/pkg/runtime/sys_darwin_386.s +++ b/src/pkg/runtime/sys_darwin_386.s @@ -236,9 +236,9 @@ TEXT runtime·sigaction(SB),NOSPLIT,$0 TEXT runtime·sigtramp(SB),NOSPLIT,$40 get_tls(CX) - // check that m exists - MOVL m(CX), BP - CMPL BP, $0 + // check that g exists + MOVL g(CX), DI + CMPL DI, $0 JNE 6(PC) MOVL sig+8(FP), BX MOVL BX, 0(SP) @@ -247,10 +247,10 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$40 JMP sigtramp_ret // save g - MOVL g(CX), DI MOVL DI, 20(SP) // g = m->gsignal + MOVL g_m(DI), BP MOVL m_gsignal(BP), BP MOVL BP, g(CX) @@ -362,7 +362,7 @@ TEXT runtime·bsdthread_start(SB),NOSPLIT,$0 // Now segment is established. Initialize m, g. get_tls(BP) MOVL AX, g(BP) - MOVL DX, m(BP) + MOVL DX, g_m(AX) MOVL BX, m_procid(DX) // m->procid = thread port (for debuggers) CALL runtime·stackcheck(SB) // smashes AX CALL CX // fn() diff --git a/src/pkg/runtime/sys_darwin_amd64.s b/src/pkg/runtime/sys_darwin_amd64.s index a0c81b5d28..23995db7a8 100644 --- a/src/pkg/runtime/sys_darwin_amd64.s +++ b/src/pkg/runtime/sys_darwin_amd64.s @@ -196,9 +196,9 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$64 MOVQ R8, 32(SP) // save ucontext MOVQ SI, 40(SP) // save infostyle - // check that m exists - MOVQ m(BX), BP - CMPQ BP, $0 + // check that g exists + MOVQ g(BX), R10 + CMPQ R10, $0 JNE 5(PC) MOVL DX, 0(SP) MOVQ $runtime·badsignal(SB), AX @@ -206,10 +206,10 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$64 JMP sigtramp_ret // save g - MOVQ g(BX), R10 MOVQ R10, 48(SP) // g = m->gsignal + MOVQ g_m(R10), BP MOVQ m_gsignal(BP), BP MOVQ BP, g(BX) @@ -325,10 +325,10 @@ TEXT runtime·bsdthread_start(SB),NOSPLIT,$0 POPQ DX get_tls(BX) - MOVQ CX, m(BX) MOVQ SI, m_procid(CX) // thread port is m->procid MOVQ m_g0(CX), AX MOVQ AX, g(BX) + MOVQ CX, g_m(AX) CALL runtime·stackcheck(SB) // smashes AX, CX CALL DX // fn CALL runtime·exit1(SB) diff --git a/src/pkg/runtime/sys_dragonfly_386.s b/src/pkg/runtime/sys_dragonfly_386.s index 20e6999668..0b8d219112 100644 --- a/src/pkg/runtime/sys_dragonfly_386.s +++ b/src/pkg/runtime/sys_dragonfly_386.s @@ -42,7 +42,7 @@ TEXT runtime·lwp_start(SB),NOSPLIT,$0 // Now segment is established. Initialize m, g. get_tls(CX) - MOVL BX, m(CX) + MOVL BX, g_m(DX) MOVL DX, g(CX) CALL runtime·stackcheck(SB) // smashes AX, CX @@ -201,9 +201,9 @@ TEXT runtime·sigaction(SB),NOSPLIT,$-4 TEXT runtime·sigtramp(SB),NOSPLIT,$44 get_tls(CX) - // check that m exists - MOVL m(CX), BX - CMPL BX, $0 + // check that g exists + MOVL g(CX), DI + CMPL DI, $0 JNE 6(PC) MOVL signo+0(FP), BX MOVL BX, 0(SP) @@ -212,10 +212,10 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$44 JMP sigtramp_ret // save g - MOVL g(CX), DI MOVL DI, 20(SP) // g = m->gsignal + MOVL g_m(DI), BX MOVL m_gsignal(BX), BX MOVL BX, g(CX) diff --git a/src/pkg/runtime/sys_dragonfly_amd64.s b/src/pkg/runtime/sys_dragonfly_amd64.s index d70d2e80cd..25d2be3ad8 100644 --- a/src/pkg/runtime/sys_dragonfly_amd64.s +++ b/src/pkg/runtime/sys_dragonfly_amd64.s @@ -43,8 +43,8 @@ TEXT runtime·lwp_start(SB),NOSPLIT,$0 // set up m, g get_tls(CX) - MOVQ R13, m(CX) MOVQ m_g0(R13), DI + MOVQ R13, g_m(DI) MOVQ DI, g(CX) CALL runtime·stackcheck(SB) @@ -163,9 +163,9 @@ TEXT runtime·sigaction(SB),NOSPLIT,$-8 TEXT runtime·sigtramp(SB),NOSPLIT,$64 get_tls(BX) - // check that m exists - MOVQ m(BX), BP - CMPQ BP, $0 + // check that g exists + MOVQ g(BX), R10 + CMPQ R10, $0 JNE 5(PC) MOVQ DI, 0(SP) MOVQ $runtime·badsignal(SB), AX @@ -173,10 +173,10 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$64 RET // save g - MOVQ g(BX), R10 MOVQ R10, 40(SP) // g = m->signal + MOVQ g_m(R10), BP MOVQ m_gsignal(BP), BP MOVQ BP, g(BX) diff --git a/src/pkg/runtime/sys_freebsd_386.s b/src/pkg/runtime/sys_freebsd_386.s index 4c97eec7b1..d2ce25f994 100644 --- a/src/pkg/runtime/sys_freebsd_386.s +++ b/src/pkg/runtime/sys_freebsd_386.s @@ -37,7 +37,7 @@ TEXT runtime·thr_start(SB),NOSPLIT,$0 get_tls(CX) MOVL BX, g(CX) - MOVL AX, m(CX) + MOVL AX, g_m(BX) CALL runtime·stackcheck(SB) // smashes AX CALL runtime·mstart(SB) @@ -183,9 +183,9 @@ TEXT runtime·sigaction(SB),NOSPLIT,$-4 TEXT runtime·sigtramp(SB),NOSPLIT,$44 get_tls(CX) - // check that m exists - MOVL m(CX), BX - CMPL BX, $0 + // check that g exists + MOVL g(CX), DI + CMPL DI, $0 JNE 6(PC) MOVL signo+0(FP), BX MOVL BX, 0(SP) @@ -194,10 +194,10 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$44 JMP sigtramp_ret // save g - MOVL g(CX), DI MOVL DI, 20(SP) // g = m->gsignal + MOVL g_m(DI), BX MOVL m_gsignal(BX), BX MOVL BX, g(CX) diff --git a/src/pkg/runtime/sys_freebsd_amd64.s b/src/pkg/runtime/sys_freebsd_amd64.s index 4c5b325043..2c6e33590f 100644 --- a/src/pkg/runtime/sys_freebsd_amd64.s +++ b/src/pkg/runtime/sys_freebsd_amd64.s @@ -60,8 +60,8 @@ TEXT runtime·thr_start(SB),NOSPLIT,$0 // set up m, g get_tls(CX) - MOVQ R13, m(CX) MOVQ m_g0(R13), DI + MOVQ R13, g_m(DI) MOVQ DI, g(CX) CALL runtime·stackcheck(SB) @@ -184,9 +184,9 @@ TEXT runtime·sigaction(SB),NOSPLIT,$-8 TEXT runtime·sigtramp(SB),NOSPLIT,$64 get_tls(BX) - // check that m exists - MOVQ m(BX), BP - CMPQ BP, $0 + // check that g exists + MOVQ g(BX), R10 + CMPQ R10, $0 JNE 5(PC) MOVQ DI, 0(SP) MOVQ $runtime·badsignal(SB), AX @@ -194,10 +194,10 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$64 RET // save g - MOVQ g(BX), R10 MOVQ R10, 40(SP) // g = m->signal + MOVQ g_m(R10), BP MOVQ m_gsignal(BP), BP MOVQ BP, g(BX) diff --git a/src/pkg/runtime/sys_freebsd_arm.s b/src/pkg/runtime/sys_freebsd_arm.s index 3ec95a6518..dbb2583b00 100644 --- a/src/pkg/runtime/sys_freebsd_arm.s +++ b/src/pkg/runtime/sys_freebsd_arm.s @@ -58,10 +58,9 @@ TEXT runtime·thr_new(SB),NOSPLIT,$0 RET TEXT runtime·thr_start(SB),NOSPLIT,$0 - MOVW R0, m - // set up g - MOVW m_g0(m), g + MOVW m_g0(R0), g + MOVW R0, g_m(g) BL runtime·emptyfunc(SB) // fault if stack check is wrong BL runtime·mstart(SB) @@ -196,14 +195,14 @@ TEXT runtime·sigaction(SB),NOSPLIT,$-8 TEXT runtime·sigtramp(SB),NOSPLIT,$24 // this might be called in external code context, - // where g and m are not set. - // first save R0, because runtime·load_gm will clobber it + // where g is not set. + // first save R0, because runtime·load_g will clobber it MOVW R0, 4(R13) // signum MOVB runtime·iscgo(SB), R0 CMP $0, R0 - BL.NE runtime·load_gm(SB) + BL.NE runtime·load_g(SB) - CMP $0, m + CMP $0, g BNE 4(PC) // signal number is already prepared in 4(R13) MOVW $runtime·badsignal(SB), R11 @@ -215,7 +214,8 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$24 MOVW g, 20(R13) // g = m->signal - MOVW m_gsignal(m), g + MOVW g_m(g), R8 + MOVW m_gsignal(R8), g // R0 is already saved MOVW R1, 8(R13) // info diff --git a/src/pkg/runtime/sys_linux_386.s b/src/pkg/runtime/sys_linux_386.s index b7896f1786..3a8371cdd4 100644 --- a/src/pkg/runtime/sys_linux_386.s +++ b/src/pkg/runtime/sys_linux_386.s @@ -166,9 +166,9 @@ TEXT runtime·rt_sigaction(SB),NOSPLIT,$0 TEXT runtime·sigtramp(SB),NOSPLIT,$44 get_tls(CX) - // check that m exists - MOVL m(CX), BX - CMPL BX, $0 + // check that g exists + MOVL g(CX), DI + CMPL DI, $0 JNE 6(PC) MOVL sig+0(FP), BX MOVL BX, 0(SP) @@ -177,11 +177,10 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$44 RET // save g - MOVL g(CX), DI MOVL DI, 20(SP) // g = m->gsignal - MOVL m(CX), BX + MOVL g_m(DI), BX MOVL m_gsignal(BX), BX MOVL BX, g(CX) @@ -324,7 +323,7 @@ TEXT runtime·clone(SB),NOSPLIT,$0 // Now segment is established. Initialize m, g. get_tls(AX) MOVL DX, g(AX) - MOVL BX, m(AX) + MOVL BX, g_m(DX) CALL runtime·stackcheck(SB) // smashes AX, CX MOVL 0(DX), DX // paranoia; check they are not nil diff --git a/src/pkg/runtime/sys_linux_amd64.s b/src/pkg/runtime/sys_linux_amd64.s index b340c4f2cc..03b9d6a7c4 100644 --- a/src/pkg/runtime/sys_linux_amd64.s +++ b/src/pkg/runtime/sys_linux_amd64.s @@ -184,9 +184,9 @@ TEXT runtime·rt_sigaction(SB),NOSPLIT,$0-32 TEXT runtime·sigtramp(SB),NOSPLIT,$64 get_tls(BX) - // check that m exists - MOVQ m(BX), BP - CMPQ BP, $0 + // check that g exists + MOVQ g(BX), R10 + CMPQ R10, $0 JNE 5(PC) MOVQ DI, 0(SP) MOVQ $runtime·badsignal(SB), AX @@ -194,10 +194,10 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$64 RET // save g - MOVQ g(BX), R10 MOVQ R10, 40(SP) // g = m->gsignal + MOVQ g_m(R10), BP MOVQ m_gsignal(BP), BP MOVQ BP, g(BX) @@ -301,7 +301,7 @@ TEXT runtime·clone(SB),NOSPLIT,$0 // In child, set up new stack get_tls(CX) - MOVQ R8, m(CX) + MOVQ R8, g_m(R9) MOVQ R9, g(CX) CALL runtime·stackcheck(SB) diff --git a/src/pkg/runtime/sys_linux_arm.s b/src/pkg/runtime/sys_linux_arm.s index c537a87223..8bfc72b571 100644 --- a/src/pkg/runtime/sys_linux_arm.s +++ b/src/pkg/runtime/sys_linux_arm.s @@ -244,11 +244,12 @@ TEXT runtime·clone(SB),NOSPLIT,$0 BEQ 2(PC) BL runtime·abort(SB) - MOVW 0(R13), m MOVW 4(R13), g + MOVW 0(R13), R8 + MOVW R8, g_m(g) // paranoia; check they are not nil - MOVW 0(m), R0 + MOVW 0(R8), R0 MOVW 0(g), R0 BL runtime·emptyfunc(SB) // fault if stack check is wrong @@ -256,7 +257,8 @@ TEXT runtime·clone(SB),NOSPLIT,$0 // Initialize m->procid to Linux tid MOVW $SYS_gettid, R7 SWI $0 - MOVW R0, m_procid(m) + MOVW g_m(g), R8 + MOVW R0, m_procid(R8) // Call fn MOVW 8(R13), R0 @@ -285,14 +287,14 @@ TEXT runtime·sigaltstack(SB),NOSPLIT,$0 TEXT runtime·sigtramp(SB),NOSPLIT,$24 // this might be called in external code context, - // where g and m are not set. - // first save R0, because runtime·load_gm will clobber it + // where g is not set. + // first save R0, because runtime·load_g will clobber it MOVW R0, 4(R13) MOVB runtime·iscgo(SB), R0 CMP $0, R0 - BL.NE runtime·load_gm(SB) + BL.NE runtime·load_g(SB) - CMP $0, m + CMP $0, g BNE 4(PC) // signal number is already prepared in 4(R13) MOVW $runtime·badsignal(SB), R11 @@ -304,7 +306,8 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$24 MOVW g, 20(R13) // g = m->gsignal - MOVW m_gsignal(m), g + MOVW g_m(g), R8 + MOVW m_gsignal(R8), g // copy arguments for call to sighandler // R0 is already saved above diff --git a/src/pkg/runtime/sys_nacl_386.s b/src/pkg/runtime/sys_nacl_386.s index 42ba0e0edf..50dca316df 100644 --- a/src/pkg/runtime/sys_nacl_386.s +++ b/src/pkg/runtime/sys_nacl_386.s @@ -165,21 +165,21 @@ TEXT runtime·setldt(SB),NOSPLIT,$8 TEXT runtime·sigtramp(SB),NOSPLIT,$0 get_tls(CX) - // check that m exists - MOVL m(CX), BX - CMPL BX, $0 + // check that g exists + MOVL g(CX), DI + CMPL DI, $0 JNE 6(PC) MOVL $11, BX - MOVL BX, 0(SP) + MOVL $0, 0(SP) MOVL $runtime·badsignal(SB), AX CALL AX JMP sigtramp_ret // save g - MOVL g(CX), DI MOVL DI, 20(SP) // g = m->gsignal + MOVL g_m(DI), BX MOVL m_gsignal(BX), BX MOVL BX, g(CX) diff --git a/src/pkg/runtime/sys_nacl_amd64p32.s b/src/pkg/runtime/sys_nacl_amd64p32.s index 43c1723721..d4e32ffe39 100644 --- a/src/pkg/runtime/sys_nacl_amd64p32.s +++ b/src/pkg/runtime/sys_nacl_amd64p32.s @@ -261,18 +261,18 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$80 MOVL (16*4+5*8)(AX), AX MOVL AX, TLS - // check that m exists + // check that g exists get_tls(CX) - MOVL m(CX), BX + MOVL g(CX), DI - CMPL BX, $0 - JEQ nom + CMPL DI, $0 + JEQ nog // save g - MOVL g(CX), DI MOVL DI, 20(SP) // g = m->gsignal + MOVL g_m(DI), BX MOVL m_gsignal(BX), BX MOVL BX, g(CX) @@ -359,7 +359,7 @@ notls: MOVL 0, AX RET -nom: +nog: MOVL 0, AX RET diff --git a/src/pkg/runtime/sys_netbsd_386.s b/src/pkg/runtime/sys_netbsd_386.s index 05de55e93a..4a78cb9d2e 100644 --- a/src/pkg/runtime/sys_netbsd_386.s +++ b/src/pkg/runtime/sys_netbsd_386.s @@ -194,9 +194,9 @@ TEXT runtime·sigaction(SB),NOSPLIT,$24 TEXT runtime·sigtramp(SB),NOSPLIT,$44 get_tls(CX) - // check that m exists - MOVL m(CX), BX - CMPL BX, $0 + // check that g exists + MOVL g(CX), DI + CMPL DI, $0 JNE 6(PC) MOVL signo+0(FP), BX MOVL BX, 0(SP) @@ -205,10 +205,10 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$44 RET // save g - MOVL g(CX), DI MOVL DI, 20(SP) // g = m->gsignal + MOVL g_m(DI), BX MOVL m_gsignal(BX), BX MOVL BX, g(CX) @@ -257,7 +257,7 @@ TEXT runtime·lwp_tramp(SB),NOSPLIT,$0 // Now segment is established. Initialize m, g. get_tls(AX) MOVL DX, g(AX) - MOVL BX, m(AX) + MOVL BX, g_m(DX) CALL runtime·stackcheck(SB) // smashes AX, CX MOVL 0(DX), DX // paranoia; check they are not nil diff --git a/src/pkg/runtime/sys_netbsd_amd64.s b/src/pkg/runtime/sys_netbsd_amd64.s index fcbced548f..13b1cdc2f7 100644 --- a/src/pkg/runtime/sys_netbsd_amd64.s +++ b/src/pkg/runtime/sys_netbsd_amd64.s @@ -28,7 +28,7 @@ TEXT runtime·lwp_tramp(SB),NOSPLIT,$0 // Set up new stack. get_tls(CX) - MOVQ R8, m(CX) + MOVQ R8, g_m(R9) MOVQ R9, g(CX) CALL runtime·stackcheck(SB) @@ -213,9 +213,9 @@ TEXT runtime·sigaction(SB),NOSPLIT,$-8 TEXT runtime·sigtramp(SB),NOSPLIT,$64 get_tls(BX) - // check that m exists - MOVQ m(BX), BP - CMPQ BP, $0 + // check that g exists + MOVQ g(BX), R10 + CMPQ R10, $0 JNE 5(PC) MOVQ DI, 0(SP) MOVQ $runtime·badsignal(SB), AX @@ -223,10 +223,10 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$64 RET // save g - MOVQ g(BX), R10 MOVQ R10, 40(SP) // g = m->signal + MOVQ g_m(R10), BP MOVQ m_gsignal(BP), BP MOVQ BP, g(BX) diff --git a/src/pkg/runtime/sys_netbsd_arm.s b/src/pkg/runtime/sys_netbsd_arm.s index b2eb74ee33..acf01cf3bb 100644 --- a/src/pkg/runtime/sys_netbsd_arm.s +++ b/src/pkg/runtime/sys_netbsd_arm.s @@ -80,7 +80,7 @@ TEXT runtime·lwp_self(SB),NOSPLIT,$0 RET TEXT runtime·lwp_tramp(SB),NOSPLIT,$0 - MOVW R0, m + MOVW R0, g_m(R1) MOVW R1, g BL runtime·emptyfunc(SB) // fault if stack check is wrong @@ -200,14 +200,14 @@ TEXT runtime·sigaction(SB),NOSPLIT,$4 TEXT runtime·sigtramp(SB),NOSPLIT,$24 // this might be called in external code context, - // where g and m are not set. - // first save R0, because runtime·load_gm will clobber it + // where g is not set. + // first save R0, because runtime·load_g will clobber it MOVW R0, 4(R13) // signum MOVB runtime·iscgo(SB), R0 CMP $0, R0 - BL.NE runtime·load_gm(SB) + BL.NE runtime·load_g(SB) - CMP $0, m + CMP $0, g BNE 4(PC) // signal number is already prepared in 4(R13) MOVW $runtime·badsignal(SB), R11 @@ -219,7 +219,8 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$24 MOVW g, 20(R13) // g = m->signal - MOVW m_gsignal(m), g + MOVW g_m(g), R8 + MOVW m_gsignal(R8), g // R0 is already saved MOVW R1, 8(R13) // info diff --git a/src/pkg/runtime/sys_openbsd_386.s b/src/pkg/runtime/sys_openbsd_386.s index 8f0da5c0ee..a94c4e4a8f 100644 --- a/src/pkg/runtime/sys_openbsd_386.s +++ b/src/pkg/runtime/sys_openbsd_386.s @@ -174,9 +174,9 @@ TEXT runtime·sigprocmask(SB),NOSPLIT,$-4 TEXT runtime·sigtramp(SB),NOSPLIT,$44 get_tls(CX) - // check that m exists - MOVL m(CX), BX - CMPL BX, $0 + // check that g exists + MOVL g(CX), DI + CMPL DI, $0 JNE 6(PC) MOVL signo+0(FP), BX MOVL BX, 0(SP) @@ -185,10 +185,10 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$44 JMP sigtramp_ret // save g - MOVL g(CX), DI MOVL DI, 20(SP) // g = m->gsignal + MOVL g_m(DI), BX MOVL m_gsignal(BX), BX MOVL BX, g(CX) @@ -278,7 +278,7 @@ TEXT runtime·tfork(SB),NOSPLIT,$12 // Now segment is established. Initialize m, g. get_tls(AX) MOVL DX, g(AX) - MOVL BX, m(AX) + MOVL BX, g_m(DX) CALL runtime·stackcheck(SB) // smashes AX, CX MOVL 0(DX), DX // paranoia; check they are not nil diff --git a/src/pkg/runtime/sys_openbsd_amd64.s b/src/pkg/runtime/sys_openbsd_amd64.s index b2a61820a0..dac90eae10 100644 --- a/src/pkg/runtime/sys_openbsd_amd64.s +++ b/src/pkg/runtime/sys_openbsd_amd64.s @@ -40,7 +40,7 @@ TEXT runtime·tfork(SB),NOSPLIT,$32 // In child, set up new stack. get_tls(CX) - MOVQ R8, m(CX) + MOVQ R8, g_m(R9) MOVQ R9, g(CX) CALL runtime·stackcheck(SB) @@ -204,9 +204,9 @@ TEXT runtime·sigprocmask(SB),NOSPLIT,$0 TEXT runtime·sigtramp(SB),NOSPLIT,$64 get_tls(BX) - // check that m exists - MOVQ m(BX), BP - CMPQ BP, $0 + // check that g exists + MOVQ g(BX), R10 + CMPQ R10, $0 JNE 5(PC) MOVQ DI, 0(SP) MOVQ $runtime·badsignal(SB), AX @@ -214,10 +214,10 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$64 RET // save g - MOVQ g(BX), R10 MOVQ R10, 40(SP) // g = m->signal + MOVQ g_m(R10), BP MOVQ m_gsignal(BP), BP MOVQ BP, g(BX) diff --git a/src/pkg/runtime/sys_plan9_386.s b/src/pkg/runtime/sys_plan9_386.s index 143cd2e498..5a652abaed 100644 --- a/src/pkg/runtime/sys_plan9_386.s +++ b/src/pkg/runtime/sys_plan9_386.s @@ -98,7 +98,7 @@ TEXT runtime·rfork(SB),NOSPLIT,$0 // Initialize m, g. get_tls(AX) MOVL DX, g(AX) - MOVL BX, m(AX) + MOVL BX, g_m(DX) // Initialize procid from TOS struct. // TODO: Be explicit and insert a new MOVL _tos(SB), AX here. @@ -123,8 +123,8 @@ TEXT runtime·rfork(SB),NOSPLIT,$0 TEXT runtime·sigtramp(SB),NOSPLIT,$0 get_tls(AX) - // check that m exists - MOVL m(AX), BX + // check that g exists + MOVL g(AX), BX CMPL BX, $0 JNE 3(PC) CALL runtime·badsignal2(SB) // will exit @@ -135,6 +135,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0 MOVL note+8(SP), DX // change stack + MOVL g_m(BX), BX MOVL m_gsignal(BX), BP MOVL g_stackbase(BP), BP MOVL BP, SP @@ -181,7 +182,8 @@ TEXT runtime·setfpmasks(SB),NOSPLIT,$0 // See ../syscall/asm_plan9_386.s:/·Syscall/ TEXT runtime·errstr(SB),NOSPLIT,$0 get_tls(AX) - MOVL m(AX), BX + MOVL g(AX), BX + MOVL g_m(BX), BX MOVL m_errstr(BX), CX MOVL CX, 4(SP) MOVL $ERRMAX, 8(SP) diff --git a/src/pkg/runtime/sys_plan9_amd64.s b/src/pkg/runtime/sys_plan9_amd64.s index e60459cb8e..7e8e59393b 100644 --- a/src/pkg/runtime/sys_plan9_amd64.s +++ b/src/pkg/runtime/sys_plan9_amd64.s @@ -133,7 +133,7 @@ TEXT runtime·rfork(SB),NOSPLIT,$0 // Initialize m, g. get_tls(AX) MOVQ DX, g(AX) - MOVQ BX, m(AX) + MOVQ BX, g_m(DX) // Initialize AX from pid in TLS. MOVQ 0(FS), AX @@ -156,8 +156,8 @@ TEXT runtime·settls(SB),NOSPLIT,$0 TEXT runtime·sigtramp(SB),NOSPLIT,$0 get_tls(AX) - // check that m exists - MOVQ m(AX), BX + // check that g exists + MOVQ g(AX), BX CMPQ BX, $0 JNE 3(PC) CALL runtime·badsignal2(SB) // will exit @@ -168,6 +168,7 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0 MOVQ note+16(SP), DX // change stack + MOVQ g_m(BX), BX MOVQ m_gsignal(BX), R10 MOVQ g_stackbase(R10), BP MOVQ BP, SP @@ -218,7 +219,8 @@ TEXT runtime·setfpmasks(SB),NOSPLIT,$8 // See ../syscall/asm_plan9_386.s:/·Syscall/ TEXT runtime·errstr(SB),NOSPLIT,$0 get_tls(AX) - MOVQ m(AX), BX + MOVQ g(AX), BX + MOVQ g_m(BX), BX MOVQ m_errstr(BX), CX MOVQ CX, 8(SP) MOVQ $ERRMAX, 16(SP) diff --git a/src/pkg/runtime/sys_solaris_amd64.s b/src/pkg/runtime/sys_solaris_amd64.s index 21517693b2..dd34e24d01 100644 --- a/src/pkg/runtime/sys_solaris_amd64.s +++ b/src/pkg/runtime/sys_solaris_amd64.s @@ -22,7 +22,8 @@ TEXT runtime·miniterrno(SB),NOSPLIT,$0 // asmcgocall will put first argument into DI. CALL DI // SysV ABI so returns in AX get_tls(CX) - MOVQ m(CX), BX + MOVQ g(CX), BX + MOVQ g_m(BX), BX MOVQ AX, m_perrno(BX) RET @@ -73,7 +74,8 @@ TEXT runtime·asmsysvicall6(SB),NOSPLIT,$0 MOVQ libcall_n(DI), R10 get_tls(CX) - MOVQ m(CX), BX + MOVQ g(CX), BX + MOVQ g_m(BX), BX MOVQ m_perrno(BX), DX CMPQ DX, $0 JEQ skiperrno1 @@ -100,7 +102,8 @@ skipargs: MOVQ DX, libcall_r2(DI) get_tls(CX) - MOVQ m(CX), BX + MOVQ g(CX), BX + MOVQ g_m(BX), BX MOVQ m_perrno(BX), AX CMPQ AX, $0 JEQ skiperrno2 @@ -118,7 +121,7 @@ TEXT runtime·tstart_sysvicall(SB),NOSPLIT,$0 // Make TLS entries point at g and m. get_tls(BX) MOVQ DX, g(BX) - MOVQ DI, m(BX) + MOVQ DI, g_m(DX) // Layout new m scheduler stack on os stack. MOVQ SP, AX @@ -154,9 +157,9 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0 MOVQ R15, 72(SP) get_tls(BX) - // check that m exists - MOVQ m(BX), BP - CMPQ BP, $0 + // check that g exists + MOVQ g(BX), R10 + CMPQ R10, $0 JNE allgood MOVQ DI, 0(SP) MOVQ $runtime·badsignal(SB), AX @@ -165,13 +168,13 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0 allgood: // save g - MOVQ g(BX), R10 MOVQ R10, 80(SP) // Save m->libcall and m->scratch. We need to do this because we // might get interrupted by a signal in runtime·asmcgocall. // save m->libcall + MOVQ g_m(R10), BP LEAQ m_libcall(BP), R11 MOVQ libcall_fn(R11), R10 MOVQ R10, 88(SP) @@ -217,7 +220,8 @@ allgood: CALL runtime·sighandler(SB) get_tls(BX) - MOVQ m(BX), BP + MOVQ g(BX), BP + MOVQ g_m(BP), BP // restore libcall LEAQ m_libcall(BP), R11 MOVQ 88(SP), R10 diff --git a/src/pkg/runtime/sys_windows_386.s b/src/pkg/runtime/sys_windows_386.s index e0c0631cfc..dc6fc39ddb 100644 --- a/src/pkg/runtime/sys_windows_386.s +++ b/src/pkg/runtime/sys_windows_386.s @@ -88,11 +88,10 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0-0 // fetch g get_tls(DX) - MOVL m(DX), AX - CMPL AX, $0 + MOVL g(DX), DX + CMPL DX, $0 JNE 2(PC) CALL runtime·badsignal2(SB) - MOVL g(DX), DX // call sighandler(ExceptionRecord*, Context*, G*) MOVL BX, 0(SP) MOVL CX, 4(SP) @@ -142,7 +141,6 @@ TEXT runtime·externalthreadhandler(SB),NOSPLIT,$0 LEAL m_tls(SP), CX MOVL CX, 0x14(FS) - MOVL SP, m(CX) MOVL SP, BX SUBL $g_end, SP // space for G MOVL SP, g(CX) @@ -151,6 +149,8 @@ TEXT runtime·externalthreadhandler(SB),NOSPLIT,$0 MOVL SP, 0(SP) MOVL $g_end, 4(SP) CALL runtime·memclr(SB) // smashes AX,BX,CX + LEAL g_end(SP), BX + MOVL BX, g_m(SP) LEAL -4096(SP), CX MOVL CX, g_stackguard(SP) MOVL DX, g_stackbase(SP) @@ -260,7 +260,7 @@ TEXT runtime·tstart(SB),NOSPLIT,$0 // Set up tls. LEAL m_tls(CX), SI MOVL SI, 0x14(FS) - MOVL CX, m(SI) + MOVL CX, g_m(DX) MOVL DX, g(SI) // Someday the convention will be D is always cleared. @@ -308,7 +308,8 @@ TEXT runtime·usleep1(SB),NOSPLIT,$0 CALL AX RET - MOVL m(CX), BP + MOVL g(CX), BP + MOVL g_m(BP), BP // leave pc/sp for cpu profiler MOVL (SP), SI @@ -337,7 +338,8 @@ usleep1_switch: usleep1_ret: get_tls(CX) - MOVL m(CX), BP + MOVL g(CX), BP + MOVL g_m(BP), BP MOVL $0, m_libcallsp(BP) RET diff --git a/src/pkg/runtime/sys_windows_amd64.s b/src/pkg/runtime/sys_windows_amd64.s index 94845903ed..c3db2c1f83 100644 --- a/src/pkg/runtime/sys_windows_amd64.s +++ b/src/pkg/runtime/sys_windows_amd64.s @@ -120,11 +120,10 @@ TEXT runtime·sigtramp(SB),NOSPLIT,$0-0 // fetch g get_tls(DX) - MOVQ m(DX), AX - CMPQ AX, $0 + MOVQ g(DX), DX + CMPQ DX, $0 JNE 2(PC) CALL runtime·badsignal2(SB) - MOVQ g(DX), DX // call sighandler(ExceptionRecord*, Context*, G*) MOVQ BX, 0(SP) MOVQ CX, 8(SP) @@ -176,7 +175,6 @@ TEXT runtime·externalthreadhandler(SB),NOSPLIT,$0 LEAQ m_tls(SP), CX MOVQ CX, 0x28(GS) - MOVQ SP, m(CX) MOVQ SP, BX SUBQ $g_end, SP // space for G MOVQ SP, g(CX) @@ -185,6 +183,9 @@ TEXT runtime·externalthreadhandler(SB),NOSPLIT,$0 MOVQ SP, 0(SP) MOVQ $g_end, 8(SP) CALL runtime·memclr(SB) // smashes AX,BX,CX + LEAQ g_end(SP), BX + MOVQ BX, g_m(SP) + LEAQ -8192(SP), CX MOVQ CX, g_stackguard(SP) MOVQ DX, g_stackbase(SP) @@ -297,7 +298,7 @@ TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0 // Set up tls. LEAQ m_tls(CX), SI MOVQ SI, 0x28(GS) - MOVQ CX, m(SI) + MOVQ CX, g_m(DX) MOVQ DX, g(SI) // Someday the convention will be D is always cleared. @@ -328,7 +329,8 @@ TEXT runtime·usleep1(SB),NOSPLIT,$0 CALL AX RET - MOVQ m(R15), R13 + MOVQ g(R15), R13 + MOVQ g_m(R13), R13 // leave pc/sp for cpu profiler MOVQ (SP), R12 diff --git a/src/pkg/runtime/traceback_arm.c b/src/pkg/runtime/traceback_arm.c index d15244c2a9..3595002d89 100644 --- a/src/pkg/runtime/traceback_arm.c +++ b/src/pkg/runtime/traceback_arm.c @@ -236,7 +236,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, runtime·printf("\t%S:%d", file, line); if(frame.pc > f->entry) runtime·printf(" +%p", (uintptr)(frame.pc - f->entry)); - if(m->throwing > 0 && gp == m->curg || gotraceback >= 2) + if(g->m->throwing > 0 && gp == g->m->curg || gotraceback >= 2) runtime·printf(" fp=%p sp=%p", frame.fp, frame.sp); runtime·printf("\n"); nprint++; diff --git a/src/pkg/runtime/traceback_x86.c b/src/pkg/runtime/traceback_x86.c index 851504f529..f21469ba59 100644 --- a/src/pkg/runtime/traceback_x86.c +++ b/src/pkg/runtime/traceback_x86.c @@ -277,7 +277,7 @@ runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, runtime·printf("\t%S:%d", file, line); if(frame.pc > f->entry) runtime·printf(" +%p", (uintptr)(frame.pc - f->entry)); - if(m->throwing > 0 && gp == m->curg || gotraceback >= 2) + if(g->m->throwing > 0 && gp == g->m->curg || gotraceback >= 2) runtime·printf(" fp=%p sp=%p", frame.fp, frame.sp); runtime·printf("\n"); nprint++; diff --git a/src/pkg/runtime/vlop_arm.s b/src/pkg/runtime/vlop_arm.s index 80f516ec4f..c33640695c 100644 --- a/src/pkg/runtime/vlop_arm.s +++ b/src/pkg/runtime/vlop_arm.s @@ -72,30 +72,25 @@ TEXT _sfloat(SB), NOSPLIT, $64-0 // 4 arg + 14*4 saved regs + cpsr // registers into G, but they do not need to be kept at the // usual places a goroutine reschedules (at function calls), // so it would be a waste of 132 bytes per G. - MOVW m_locks(m), R1 + MOVW g_m(g), R8 + MOVW m_locks(R8), R1 ADD $1, R1 - MOVW R1, m_locks(m) + MOVW R1, m_locks(R8) MOVW $1, R1 - MOVW R1, m_softfloat(m) + MOVW R1, m_softfloat(R8) BL runtime·_sfloat2(SB) - MOVW m_locks(m), R1 + MOVW g_m(g), R8 + MOVW m_locks(R8), R1 SUB $1, R1 - MOVW R1, m_locks(m) + MOVW R1, m_locks(R8) MOVW $0, R1 - MOVW R1, m_softfloat(m) + MOVW R1, m_softfloat(R8) MOVW R0, 0(R13) MOVW 64(R13), R1 WORD $0xe128f001 // msr cpsr_f, r1 MOVW $12(R13), R0 - // Restore R1-R8 and R11-R12, but ignore the saved R9 (m) and R10 (g). - // Both are maintained by the runtime and always have correct values, - // so there is no need to restore old values here. - // The g should not have changed, but m may have, if we were preempted - // and restarted on a different thread, in which case restoring the old - // value is incorrect and will cause serious confusion in the runtime. - MOVM.IA.W (R0), [R1-R8] - MOVW $52(R13), R0 - MOVM.IA.W (R0), [R11-R12] + // Restore R1-R12, R0. + MOVM.IA.W (R0), [R1-R12] MOVW 8(R13), R0 RET -- 2.48.1