aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/panic.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-06-26 11:54:39 -0400
committerRuss Cox <rsc@golang.org>2014-06-26 11:54:39 -0400
commit89f185fe8a036b0fabce30b20c480cf1c832bdd7 (patch)
treecd8c84fca5164747bebd852da7edfed132ce4e70 /src/pkg/runtime/panic.c
parent2565b5c06086488b2b23d48929803c8c3cec4400 (diff)
downloadgo-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.c51
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");
}