Commit 5556bfa9 authored by Russ Cox's avatar Russ Cox

runtime: cache gotraceback setting

On Plan 9 gotraceback calls getenv calls malloc, and we gotraceback
on every call to gentraceback, which happens during garbage collection.
Honestly I don't even know how this works on Plan 9.
I suspect it does not, and that we are getting by because
no one has tried to run with $GOTRACEBACK set at all.

This will speed up all the other systems by epsilon, since they
won't call getenv and atoi repeatedly.

LGTM=bradfitz
R=golang-codereviews, bradfitz, 0intro
CC=golang-codereviews
https://golang.org/cl/85430046
parent b3a33a65
...@@ -155,6 +155,10 @@ runtime·schedinit(void) ...@@ -155,6 +155,10 @@ runtime·schedinit(void)
// in a fault during a garbage collection, it will not // in a fault during a garbage collection, it will not
// need to allocated memory. // need to allocated memory.
runtime·newErrorCString(0, &i); runtime·newErrorCString(0, &i);
// Initialize the cached gotraceback value, since
// gotraceback calls getenv, which mallocs on Plan 9.
runtime·gotraceback(nil);
runtime·goargs(); runtime·goargs();
runtime·goenvs(); runtime·goenvs();
......
...@@ -20,22 +20,35 @@ enum { ...@@ -20,22 +20,35 @@ enum {
int32 int32
runtime·gotraceback(bool *crash) runtime·gotraceback(bool *crash)
{ {
// Keep a cached value to make gotraceback fast,
// since we call it on every call to gentraceback.
// The cached value is a uint32 in which the low bit
// is the "crash" setting and the top 31 bits are the
// gotraceback value.
static uint32 cache = ~(uint32)0;
byte *p; byte *p;
uint32 x;
if(crash != nil) if(crash != nil)
*crash = false; *crash = false;
p = runtime·getenv("GOTRACEBACK"); if(m->traceback != 0)
if(p == nil || p[0] == '\0') { return m->traceback;
if(m->traceback != 0) x = runtime·atomicload(&cache);
return m->traceback; if(x == ~(uint32)0) {
return 1; // default is on p = runtime·getenv("GOTRACEBACK");
} if(p == nil)
if(runtime·strcmp(p, (byte*)"crash") == 0) { p = (byte*)"";
if(crash != nil) if(p[0] == '\0')
*crash = true; x = 1<<1;
return 2; // extra information else if(runtime·strcmp(p, (byte*)"crash") == 0)
x = (2<<1) | 1;
else
x = runtime·atoi(p)<<1;
runtime·atomicstore(&cache, x);
} }
return runtime·atoi(p); if(crash != nil)
*crash = x&1;
return x>>1;
} }
int32 int32
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment