For Austin's framepointer experiment.
Change-Id: I81b6f414943b3578924f853300b9193684f79bf4
Reviewed-on: https://go-review.googlesource.com/2994
Reviewed-by: Austin Clements <austin@google.com>
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);
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*
"$GOROOT/pkg/obj/${GOHOSTOS}_$GOHOSTARCH/lib9.a",
}},
{"runtime", []string{
- "zaexperiment.h",
"zversion.go",
}},
}
{"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},
)
}
- // 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")))
}
"\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)
}
EXTERN Link* ctxt;
EXTERN int nointerface;
-EXTERN int fieldtrack_enabled;
-EXTERN int precisestack_enabled;
EXTERN int writearchive;
EXTERN Biobuf bstdout;
#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
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
if(nacl)
flag_largemodel = 1;
- setexp();
-
fmtstrinit(&pragcgobuf);
quotefmtinstall();
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]);
}
}
// 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);
}
}
}
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.
#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)
char *p;
char buf[1024];
+ linksetexp();
nuxiinit(arch);
ctxt = emallocz(sizeof *ctxt);
return
}
-var goexperiment string = "GOEXPERIMENT" // TODO: defined in zaexperiment.h
-
func haveexperiment(name string) bool {
x := goexperiment
for x != "" {