mirror of
https://github.com/golang/go
synced 2024-11-11 21:10:21 -07:00
build: implement GOEXPERIMENT again in runtime, and add to liblink
For Austin's framepointer experiment. Change-Id: I81b6f414943b3578924f853300b9193684f79bf4 Reviewed-on: https://go-review.googlesource.com/2994 Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
parent
8bf6e09f4c
commit
dba9eb3369
@ -586,6 +586,11 @@ void* emallocz(long n);
|
||||
void* erealloc(void *p, long n);
|
||||
char* estrdup(char *p);
|
||||
char* expandpkg(char *t0, char *pkg);
|
||||
void linksetexp(void);
|
||||
char* expstring(void);
|
||||
|
||||
extern int fieldtrack_enabled;
|
||||
extern int framepointer_enabled;
|
||||
|
||||
// ld.c
|
||||
void addhist(Link *ctxt, int32 line, int type);
|
||||
@ -656,6 +661,9 @@ extern LinkArch linkarm;
|
||||
extern LinkArch linkppc64;
|
||||
extern LinkArch linkppc64le;
|
||||
|
||||
extern int linkbasepointer;
|
||||
extern void linksetexp(void);
|
||||
|
||||
#pragma varargck type "A" int
|
||||
#pragma varargck type "E" uint
|
||||
#pragma varargck type "D" Addr*
|
||||
|
6
src/cmd/dist/build.go
vendored
6
src/cmd/dist/build.go
vendored
@ -576,7 +576,6 @@ var deptab = []struct {
|
||||
"$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/lib9.a",
|
||||
}},
|
||||
{"runtime", []string{
|
||||
"zaexperiment.h",
|
||||
"zversion.go",
|
||||
}},
|
||||
}
|
||||
@ -601,7 +600,6 @@ var gentab = []struct {
|
||||
{"anames9.c", mkanames},
|
||||
{"zdefaultcc.go", mkzdefaultcc},
|
||||
{"zversion.go", mkzversion},
|
||||
{"zaexperiment.h", mkzexperiment},
|
||||
|
||||
// not generated anymore, but delete the file if we see it
|
||||
{"enam.c", nil},
|
||||
@ -937,8 +935,8 @@ func install(dir string) {
|
||||
)
|
||||
}
|
||||
|
||||
// gc/lex.c records the GOEXPERIMENT setting used during the build.
|
||||
if name == "lex.c" {
|
||||
// liblink/go.c records the GOEXPERIMENT setting used during the build.
|
||||
if name == "go.c" {
|
||||
compile = append(compile,
|
||||
"-D", fmt.Sprintf("GOEXPERIMENT=%q", os.Getenv("GOEXPERIMENT")))
|
||||
}
|
||||
|
17
src/cmd/dist/buildruntime.go
vendored
17
src/cmd/dist/buildruntime.go
vendored
@ -27,21 +27,8 @@ func mkzversion(dir, file string) {
|
||||
"\n"+
|
||||
"const defaultGoroot = `%s`\n"+
|
||||
"const theVersion = `%s`\n"+
|
||||
"\n"+
|
||||
"var buildVersion = theVersion\n", goroot_final, goversion)
|
||||
|
||||
writefile(out, file, 0)
|
||||
}
|
||||
|
||||
// mkzexperiment writes zaexperiment.h (sic):
|
||||
//
|
||||
// #define GOEXPERIMENT "experiment string"
|
||||
//
|
||||
func mkzexperiment(dir, file string) {
|
||||
out := fmt.Sprintf(
|
||||
"// auto generated by go tool dist\n"+
|
||||
"\n"+
|
||||
"#define GOEXPERIMENT \"%s\"\n", os.Getenv("GOEXPERIMENT"))
|
||||
"const goexperiment = `%s`\n"+
|
||||
"var buildVersion = theVersion\n", goroot_final, goversion, os.Getenv("GOEXPERIMENT"))
|
||||
|
||||
writefile(out, file, 0)
|
||||
}
|
||||
|
@ -994,8 +994,6 @@ EXTERN int debuglive;
|
||||
EXTERN Link* ctxt;
|
||||
|
||||
EXTERN int nointerface;
|
||||
EXTERN int fieldtrack_enabled;
|
||||
EXTERN int precisestack_enabled;
|
||||
EXTERN int writearchive;
|
||||
|
||||
EXTERN Biobuf bstdout;
|
||||
|
@ -33,19 +33,6 @@ static char *goos, *goarch, *goroot;
|
||||
|
||||
#define BOM 0xFEFF
|
||||
|
||||
// Compiler experiments.
|
||||
// These are controlled by the GOEXPERIMENT environment
|
||||
// variable recorded when the compiler is built.
|
||||
static struct {
|
||||
char *name;
|
||||
int *val;
|
||||
} exper[] = {
|
||||
// {"rune32", &rune32},
|
||||
{"fieldtrack", &fieldtrack_enabled},
|
||||
{"precisestack", &precisestack_enabled},
|
||||
{nil, nil},
|
||||
};
|
||||
|
||||
// Debug arguments.
|
||||
// These can be specified with the -d flag, as in "-d nil"
|
||||
// to set the debug_checknil variable. In general the list passed
|
||||
@ -55,55 +42,8 @@ static struct {
|
||||
int *val;
|
||||
} debugtab[] = {
|
||||
{"nil", &debug_checknil},
|
||||
{nil, nil},
|
||||
};
|
||||
|
||||
static void
|
||||
addexp(char *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; exper[i].name != nil; i++) {
|
||||
if(strcmp(exper[i].name, s) == 0) {
|
||||
*exper[i].val = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
print("unknown experiment %s\n", s);
|
||||
exits("unknown experiment");
|
||||
}
|
||||
|
||||
static void
|
||||
setexp(void)
|
||||
{
|
||||
char *f[20];
|
||||
int i, nf;
|
||||
|
||||
precisestack_enabled = 1; // on by default
|
||||
|
||||
// cmd/dist #defines GOEXPERIMENT for us.
|
||||
nf = getfields(GOEXPERIMENT, f, nelem(f), 1, ",");
|
||||
for(i=0; i<nf; i++)
|
||||
addexp(f[i]);
|
||||
}
|
||||
|
||||
char*
|
||||
expstring(void)
|
||||
{
|
||||
int i;
|
||||
static char buf[512];
|
||||
|
||||
strcpy(buf, "X");
|
||||
for(i=0; exper[i].name != nil; i++)
|
||||
if(*exper[i].val)
|
||||
seprint(buf+strlen(buf), buf+sizeof buf, ",%s", exper[i].name);
|
||||
if(strlen(buf) == 1)
|
||||
strcpy(buf, "X,none");
|
||||
buf[1] = ':';
|
||||
return buf;
|
||||
}
|
||||
|
||||
// Our own isdigit, isspace, isalpha, isalnum that take care
|
||||
// of EOF and other out of range arguments.
|
||||
static int
|
||||
@ -272,8 +212,6 @@ main(int argc, char *argv[])
|
||||
if(nacl)
|
||||
flag_largemodel = 1;
|
||||
|
||||
setexp();
|
||||
|
||||
fmtstrinit(&pragcgobuf);
|
||||
quotefmtinstall();
|
||||
|
||||
@ -344,13 +282,14 @@ main(int argc, char *argv[])
|
||||
|
||||
nf = getfields(debugstr, f, nelem(f), 1, ",");
|
||||
for(i=0; i<nf; i++) {
|
||||
for(j=0; debugtab[j].name != nil; j++) {
|
||||
for(j=0; j<nelem(debugtab); j++) {
|
||||
if(strcmp(debugtab[j].name, f[i]) == 0) {
|
||||
*debugtab[j].val = 1;
|
||||
if(debugtab[j].val != nil)
|
||||
*debugtab[j].val = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(debugtab[j].name == nil)
|
||||
if(j >= nelem(debugtab))
|
||||
sysfatal("unknown debug information -d '%s'\n", f[i]);
|
||||
}
|
||||
}
|
||||
|
@ -1487,25 +1487,21 @@ livenessepilogue(Liveness *lv)
|
||||
// Annotate ambiguously live variables so that they can
|
||||
// be zeroed at function entry.
|
||||
// livein and liveout are dead here and used as temporaries.
|
||||
// For now, only enabled when using GOEXPERIMENT=precisestack
|
||||
// during make.bash / all.bash.
|
||||
if(precisestack_enabled) {
|
||||
bvresetall(livein);
|
||||
bvandnot(liveout, any, all);
|
||||
if(!bvisempty(liveout)) {
|
||||
for(pos = 0; pos < liveout->n; pos++) {
|
||||
if(!bvget(liveout, pos))
|
||||
continue;
|
||||
bvset(all, pos); // silence future warnings in this block
|
||||
n = *(Node**)arrayget(lv->vars, pos);
|
||||
if(!n->needzero) {
|
||||
n->needzero = 1;
|
||||
if(debuglive >= 1)
|
||||
warnl(p->lineno, "%N: %lN is ambiguously live", curfn->nname, n);
|
||||
// Record in 'ambiguous' bitmap.
|
||||
xoffset = n->xoffset + stkptrsize;
|
||||
twobitwalktype1(n->type, &xoffset, ambig);
|
||||
}
|
||||
bvresetall(livein);
|
||||
bvandnot(liveout, any, all);
|
||||
if(!bvisempty(liveout)) {
|
||||
for(pos = 0; pos < liveout->n; pos++) {
|
||||
if(!bvget(liveout, pos))
|
||||
continue;
|
||||
bvset(all, pos); // silence future warnings in this block
|
||||
n = *(Node**)arrayget(lv->vars, pos);
|
||||
if(!n->needzero) {
|
||||
n->needzero = 1;
|
||||
if(debuglive >= 1)
|
||||
warnl(p->lineno, "%N: %lN is ambiguously live", curfn->nname, n);
|
||||
// Record in 'ambiguous' bitmap.
|
||||
xoffset = n->xoffset + stkptrsize;
|
||||
twobitwalktype1(n->type, &xoffset, ambig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2521,9 +2521,9 @@ paramstoheap(Type **argin, int out)
|
||||
v = t->nname;
|
||||
if(v && v->sym && v->sym->name[0] == '~' && v->sym->name[1] == 'r') // unnamed result
|
||||
v = N;
|
||||
// In precisestack mode, the garbage collector assumes results
|
||||
// For precise stacks, the garbage collector assumes results
|
||||
// are always live, so zero them always.
|
||||
if(out && (precisestack_enabled || (v == N && hasdefer))) {
|
||||
if(out) {
|
||||
// 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.
|
||||
|
@ -9,6 +9,66 @@
|
||||
#include <bio.h>
|
||||
#include <link.h>
|
||||
|
||||
int framepointer_enabled;
|
||||
int fieldtrack_enabled;
|
||||
|
||||
// Toolchain experiments.
|
||||
// These are controlled by the GOEXPERIMENT environment
|
||||
// variable recorded when the toolchain is built.
|
||||
// This list is also known to cmd/gc.
|
||||
static struct {
|
||||
char *name;
|
||||
int *val;
|
||||
} exper[] = {
|
||||
{"fieldtrack", &fieldtrack_enabled},
|
||||
{"basepointer", &framepointer_enabled},
|
||||
};
|
||||
|
||||
static void
|
||||
addexp(char *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i < nelem(exper); i++ ) {
|
||||
if(strcmp(exper[i].name, s) == 0) {
|
||||
if(exper[i].val != nil)
|
||||
*exper[i].val = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
print("unknown experiment %s\n", s);
|
||||
exits("unknown experiment");
|
||||
}
|
||||
|
||||
void
|
||||
linksetexp(void)
|
||||
{
|
||||
char *f[20];
|
||||
int i, nf;
|
||||
|
||||
// cmd/dist #defines GOEXPERIMENT for us.
|
||||
nf = getfields(GOEXPERIMENT, f, nelem(f), 1, ",");
|
||||
for(i=0; i<nf; i++)
|
||||
addexp(f[i]);
|
||||
}
|
||||
|
||||
char*
|
||||
expstring(void)
|
||||
{
|
||||
int i;
|
||||
static char buf[512];
|
||||
|
||||
strcpy(buf, "X");
|
||||
for(i=0; i<nelem(exper); i++)
|
||||
if(*exper[i].val)
|
||||
seprint(buf+strlen(buf), buf+sizeof buf, ",%s", exper[i].name);
|
||||
if(strlen(buf) == 1)
|
||||
strcpy(buf, "X,none");
|
||||
buf[1] = ':';
|
||||
return buf;
|
||||
}
|
||||
|
||||
// replace all "". with pkg.
|
||||
char*
|
||||
expandpkg(char *t0, char *pkg)
|
||||
|
@ -90,6 +90,7 @@ linknew(LinkArch *arch)
|
||||
char *p;
|
||||
char buf[1024];
|
||||
|
||||
linksetexp();
|
||||
nuxiinit(arch);
|
||||
|
||||
ctxt = emallocz(sizeof *ctxt);
|
||||
|
@ -3163,8 +3163,6 @@ func setMaxThreads(in int) (out int) {
|
||||
return
|
||||
}
|
||||
|
||||
var goexperiment string = "GOEXPERIMENT" // TODO: defined in zaexperiment.h
|
||||
|
||||
func haveexperiment(name string) bool {
|
||||
x := goexperiment
|
||||
for x != "" {
|
||||
|
Loading…
Reference in New Issue
Block a user