1
0
mirror of https://github.com/golang/go synced 2024-11-23 20:40:07 -07:00

build: disable precise collection of stack frames

The code for call site-specific pointer bitmaps was not ready in time,
but the zeroing required without it is too expensive to use by default.
We will have to wait for precise collection of stack frames until Go 1.3.

The precise collection can be re-enabled by

        GOEXPERIMENT=precisestack ./all.bash

but that will not be the default for a Go 1.2 build.

Fixes #6087.

R=golang-dev, jeremyjackins, dan.kortschak, r
CC=golang-dev
https://golang.org/cl/13677045
This commit is contained in:
Russ Cox 2013-09-16 20:26:10 -04:00
parent 2a5dcfafec
commit 30ecb4cd05
10 changed files with 80 additions and 14 deletions

1
src/cmd/dist/a.h vendored
View File

@ -101,6 +101,7 @@ void mkzgoarch(char*, char*);
void mkzgoos(char*, char*);
void mkzruntimedefs(char*, char*);
void mkzversion(char*, char*);
void mkzexperiment(char*, char*);
// buildgo.c
void mkzdefaultcc(char*, char*);

View File

@ -557,6 +557,7 @@ static struct {
"$GOROOT/pkg/obj/$GOOS_$GOARCH/lib9.a",
}},
{"pkg/runtime", {
"zaexperiment.h", // must sort above zasm
"zasm_$GOOS_$GOARCH.h",
"zsys_$GOOS_$GOARCH.s",
"zgoarch_$GOARCH.go",
@ -589,6 +590,7 @@ static struct {
{"zgoos_", mkzgoos},
{"zruntime_defs_", mkzruntimedefs},
{"zversion.go", mkzversion},
{"zaexperiment.h", mkzexperiment},
};
// install installs the library, package, or binary associated with dir,

View File

@ -38,6 +38,34 @@ mkzversion(char *dir, char *file)
bfree(&out);
}
// mkzexperiment writes zaexperiment.h (sic):
//
// #define GOEXPERIMENT "experiment string"
//
void
mkzexperiment(char *dir, char *file)
{
Buf b, out, exp;
USED(dir);
binit(&b);
binit(&out);
binit(&exp);
xgetenv(&exp, "GOEXPERIMENT");
bwritestr(&out, bprintf(&b,
"// auto generated by go tool dist\n"
"\n"
"#define GOEXPERIMENT \"%s\"\n", bstr(&exp)));
writefile(&out, file, 0);
bfree(&b);
bfree(&out);
bfree(&exp);
}
// mkzgoarch writes zgoarch_$GOARCH.go:
//
// package runtime
@ -193,12 +221,13 @@ mkzasm(char *dir, char *file)
{
int i, n;
char *aggr, *p;
Buf in, b, out;
Buf in, b, out, exp;
Vec argv, lines, fields;
binit(&in);
binit(&b);
binit(&out);
binit(&exp);
vinit(&argv);
vinit(&lines);
vinit(&fields);
@ -284,6 +313,9 @@ ok:
bwritestr(&out, bprintf(&b, "#define cb_max %d\n", MAXWINCB));
}
xgetenv(&exp, "GOEXPERIMENT");
bwritestr(&out, bprintf(&b, "#define GOEXPERIMENT \"%s\"\n", bstr(&exp)));
// Write both to file and to workdir/zasm_GOOS_GOARCH.h.
writefile(&out, file, 0);
writefile(&out, bprintf(&b, "%s/zasm_GOOS_GOARCH.h", workdir), 0);
@ -291,6 +323,7 @@ ok:
bfree(&in);
bfree(&b);
bfree(&out);
bfree(&exp);
vfree(&argv);
vfree(&lines);
vfree(&fields);

View File

@ -982,6 +982,7 @@ EXTERN int noescape;
EXTERN int nointerface;
EXTERN int fieldtrack_enabled;
EXTERN int precisestack_enabled;
/*
* y.tab.c

View File

@ -41,6 +41,7 @@ static struct {
} exper[] = {
// {"rune32", &rune32},
{"fieldtrack", &fieldtrack_enabled},
{"precisestack", &precisestack_enabled},
{nil, nil},
};

View File

@ -316,7 +316,7 @@ walktype(Type *type, Bvec *bv)
walktype1(type, &xoffset, bv);
}
// Compute a bit vector to describes the pointer containing locations
// Compute a bit vector to describe the pointer-containing locations
// in the in and out argument list and dump the bitvector length and
// data to the provided symbol.
static void
@ -344,9 +344,9 @@ dumpgcargs(Node *fn, Sym *sym)
ggloblsym(sym, off, 0, 1);
}
// Compute a bit vector to describes the pointer containing locations
// in local variables and dumps the bitvector length and data out to
// the provided symbol. Returns the vector for use and freeing by caller.
// Compute a bit vector to describe the pointer-containing locations
// in local variables and dump the bitvector length and data out to
// the provided symbol. Return the vector for use and freeing by caller.
static Bvec*
dumpgclocals(Node* fn, Sym *sym)
{
@ -438,11 +438,13 @@ allocauto(Prog* ptxt)
ll->n->used = 0;
markautoused(ptxt);
// TODO: Remove when liveness analysis sets needzero instead.
for(ll=curfn->dcl; ll != nil; ll=ll->next)
if (ll->n->class == PAUTO)
ll->n->needzero = 1; // ll->n->addrtaken;
if(precisestack_enabled) {
// TODO: Remove when liveness analysis sets needzero instead.
for(ll=curfn->dcl; ll != nil; ll=ll->next)
if(ll->n->class == PAUTO)
ll->n->needzero = 1; // ll->n->addrtaken;
}
listsort(&curfn->dcl, cmpstackvar);

View File

@ -2331,9 +2331,9 @@ paramstoheap(Type **argin, int out)
v = t->nname;
if(v && v->sym && v->sym->name[0] == '~')
v = N;
// The garbage collector assumes results are always live,
// so zero them always (1 ||).
if(out && (1 || (v == N && hasdefer))) {
// In precisestack mode, the garbage collector assumes results
// are always live, so zero them always.
if(out && (precisestack_enabled || (v == N && hasdefer))) {
// Defer might stop a panic and show the
// return values as they exist at the time of panic.
// Make sure to zero them on entry to the function.

View File

@ -1345,7 +1345,7 @@ scaninterfacedata(uintptr bits, byte *scanp, bool afterprologue)
Itab *tab;
Type *type;
if(afterprologue) {
if(runtime·precisestack && afterprologue) {
if(bits == BitsIface) {
tab = *(Itab**)scanp;
if(tab->type->size <= sizeof(void*) && (tab->type->kind & KindNoPointers))

View File

@ -4,6 +4,7 @@
#include "runtime.h"
#include "arch_GOARCH.h"
#include "zaexperiment.h"
#include "malloc.h"
#include "stack.h"
#include "race.h"
@ -112,6 +113,7 @@ static void injectglist(G*);
static bool preemptall(void);
static bool preemptone(P*);
static bool exitsyscallfast(void);
static bool haveexperiment(int8*);
// The bootstrap sequence is:
//
@ -128,6 +130,7 @@ runtime·schedinit(void)
byte *p;
runtime·sched.maxmcount = 10000;
runtime·precisestack = haveexperiment("precisestack");
m->nomemprof++;
runtime·mprofinit();
@ -2929,3 +2932,24 @@ runtimedebug·setMaxThreads(intgo in, intgo out)
runtime·unlock(&runtime·sched);
FLUSH(&out);
}
static int8 experiment[] = GOEXPERIMENT; // defined in zaexperiment.h
static bool
haveexperiment(int8 *name)
{
int32 i, j;
for(i=0; i<sizeof(experiment); i++) {
if((i == 0 || experiment[i-1] == ',') && experiment[i] == name[0]) {
for(j=0; name[j]; j++)
if(experiment[i+j] != name[j])
goto nomatch;
if(experiment[i+j] != '\0' && experiment[i+j] != ',')
goto nomatch;
return 1;
}
nomatch:;
}
return 0;
}

View File

@ -539,6 +539,8 @@ struct DebugVars
int32 scheddetail;
};
extern bool runtime·precisestack;
/*
* defined macros
* you need super-gopher-guru privilege