diff options
| author | Russ Cox <rsc@golang.org> | 2014-06-26 11:54:39 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2014-06-26 11:54:39 -0400 |
| commit | 89f185fe8a036b0fabce30b20c480cf1c832bdd7 (patch) | |
| tree | cd8c84fca5164747bebd852da7edfed132ce4e70 /src/pkg/runtime/panic.c | |
| parent | 2565b5c06086488b2b23d48929803c8c3cec4400 (diff) | |
| download | go-89f185fe8a036b0fabce30b20c480cf1c832bdd7.tar.xz | |
all: remove 'extern register M *m' from runtime
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
Diffstat (limited to 'src/pkg/runtime/panic.c')
| -rw-r--r-- | src/pkg/runtime/panic.c | 51 |
1 files changed, 27 insertions, 24 deletions
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"); } |
