1
0
mirror of https://github.com/golang/go synced 2024-11-26 19:41:19 -07:00

internal/buildcfg: make regabi an alias for regabi sub-experiments

Currently, specifying GOEXPERIMENT=regabi will turn on all regabi
sub-experiments, but GOEXPERIMENT=noregabi won't turn anything off.
Regabi also isn't a "real" experiment in the sense that nothing in the
code base should depend on it as an experiment flag (it should depend
on the appropriate sub-experiments).

Hence, drop Regabi from goexperiment.Flags and make "regabi" in
GOEXPERIMENT be a real alias for all of the sub-flags, so regabi will
turn on all of the sub-flags and noregabi will turn off all of the
sub-flags.

This way, once we enable the sub-experiments in the baseline
configuration, it will be easy to turn off with "noregabi".

For #40724.

Change-Id: I0fb95be42f756d412e729a396be607d629ae2bab
Reviewed-on: https://go-review.googlesource.com/c/go/+/310609
Trust: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Austin Clements 2021-04-15 16:18:30 -04:00
parent 94817890c2
commit 14dbd6e776
2 changed files with 21 additions and 17 deletions

View File

@ -45,12 +45,25 @@ func parseExperiments() goexperiment.Flags {
if env != "" { if env != "" {
// Create a map of known experiment names. // Create a map of known experiment names.
names := make(map[string]reflect.Value) names := make(map[string]func(bool))
rv := reflect.ValueOf(&flags).Elem() rv := reflect.ValueOf(&flags).Elem()
rt := rv.Type() rt := rv.Type()
for i := 0; i < rt.NumField(); i++ { for i := 0; i < rt.NumField(); i++ {
field := rv.Field(i) field := rv.Field(i)
names[strings.ToLower(rt.Field(i).Name)] = field names[strings.ToLower(rt.Field(i).Name)] = field.SetBool
}
// "regabi" is an alias for all working regabi
// subexperiments, and not an experiment itself. Doing
// this as an alias make both "regabi" and "noregabi"
// do the right thing.
names["regabi"] = func(v bool) {
flags.RegabiWrappers = v
flags.RegabiG = v
flags.RegabiReflect = v
flags.RegabiDefer = v
// Not ready yet:
//flags.RegabiArgs = v
} }
// Parse names. // Parse names.
@ -69,33 +82,23 @@ func parseExperiments() goexperiment.Flags {
if strings.HasPrefix(f, "no") { if strings.HasPrefix(f, "no") {
f, val = f[2:], false f, val = f[2:], false
} }
field, ok := names[f] set, ok := names[f]
if !ok { if !ok {
fmt.Printf("unknown experiment %s\n", f) fmt.Printf("unknown experiment %s\n", f)
os.Exit(2) os.Exit(2)
} }
field.SetBool(val) set(val)
} }
} }
// regabi is only supported on amd64. // regabi is only supported on amd64.
if GOARCH != "amd64" { if GOARCH != "amd64" {
flags.Regabi = false
flags.RegabiWrappers = false flags.RegabiWrappers = false
flags.RegabiG = false flags.RegabiG = false
flags.RegabiReflect = false flags.RegabiReflect = false
flags.RegabiDefer = false flags.RegabiDefer = false
flags.RegabiArgs = false flags.RegabiArgs = false
} }
// Setting regabi sets working sub-experiments.
if flags.Regabi {
flags.RegabiWrappers = true
flags.RegabiG = true
flags.RegabiReflect = true
flags.RegabiDefer = true
// Not ready yet:
//flags.RegabiArgs = true
}
// Check regabi dependencies. // Check regabi dependencies.
if flags.RegabiG && !flags.RegabiWrappers { if flags.RegabiG && !flags.RegabiWrappers {
panic("GOEXPERIMENT regabig requires regabiwrappers") panic("GOEXPERIMENT regabig requires regabiwrappers")

View File

@ -60,9 +60,10 @@ type Flags struct {
StaticLockRanking bool StaticLockRanking bool
// Regabi is split into several sub-experiments that can be // Regabi is split into several sub-experiments that can be
// enabled individually. GOEXPERIMENT=regabi implies the // enabled individually. Not all combinations work.
// subset that are currently "working". Not all combinations work. // The "regabi" GOEXPERIMENT is an alias for all "working"
Regabi bool // subexperiments.
// RegabiWrappers enables ABI wrappers for calling between // RegabiWrappers enables ABI wrappers for calling between
// ABI0 and ABIInternal functions. Without this, the ABIs are // ABI0 and ABIInternal functions. Without this, the ABIs are
// assumed to be identical so cross-ABI calls are direct. // assumed to be identical so cross-ABI calls are direct.