mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
internal/goexperiment,cmd: consolidate GOEXPERIMENTs into a new package
Currently there's knowledge about the list of GOEXPERIMENTs in a few different places. This CL introduces a new package and consolidates the list into one place: the internal/goexperiment.Flags struct type. This package gives us a central place to document the experiments as well as the GOEXPERIMENT environment variable itself. It will also give us a place to put built-time constants derived from the enabled experiments. Now the objabi package constructs experiment names by reflecting over this struct type rather than having a separate list of these names (this is similar to how the compiler handles command-line flags and debug options). We also expose a better-typed API to the toolchain for propagating enabled experiments. Change-Id: I06e026712b59fe2bd7cd11a869aedb48ffe5a4b7 Reviewed-on: https://go-review.googlesource.com/c/go/+/307817 Trust: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
0c4a08cb74
commit
6304b401e4
7 changed files with 215 additions and 203 deletions
|
|
@ -46,31 +46,18 @@ func NewInput(name string) *Input {
|
||||||
func predefine(defines flags.MultiFlag) map[string]*Macro {
|
func predefine(defines flags.MultiFlag) map[string]*Macro {
|
||||||
macros := make(map[string]*Macro)
|
macros := make(map[string]*Macro)
|
||||||
|
|
||||||
// Set macros for various GOEXPERIMENTs so we can easily
|
// Set macros for GOEXPERIMENTs so we can easily switch
|
||||||
// switch runtime assembly code based on them.
|
// runtime assembly code based on them.
|
||||||
if *flags.CompilingRuntime {
|
if *flags.CompilingRuntime {
|
||||||
set := func(name string) {
|
for _, exp := range objabi.EnabledExperiments() {
|
||||||
|
// Define macro.
|
||||||
|
name := "GOEXPERIMENT_" + exp
|
||||||
macros[name] = &Macro{
|
macros[name] = &Macro{
|
||||||
name: name,
|
name: name,
|
||||||
args: nil,
|
args: nil,
|
||||||
tokens: Tokenize("1"),
|
tokens: Tokenize("1"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if objabi.Experiment.RegabiWrappers {
|
|
||||||
set("GOEXPERIMENT_regabiwrappers")
|
|
||||||
}
|
|
||||||
if objabi.Experiment.RegabiG {
|
|
||||||
set("GOEXPERIMENT_regabig")
|
|
||||||
}
|
|
||||||
if objabi.Experiment.RegabiReflect {
|
|
||||||
set("GOEXPERIMENT_regabireflect")
|
|
||||||
}
|
|
||||||
if objabi.Experiment.RegabiDefer {
|
|
||||||
set("GOEXPERIMENT_regabidefer")
|
|
||||||
}
|
|
||||||
if objabi.Experiment.RegabiArgs {
|
|
||||||
set("GOEXPERIMENT_regabiargs")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range defines {
|
for _, name := range defines {
|
||||||
|
|
|
||||||
1
src/cmd/dist/buildtool.go
vendored
1
src/cmd/dist/buildtool.go
vendored
|
|
@ -58,6 +58,7 @@ var bootstrapDirs = []string{
|
||||||
"debug/macho",
|
"debug/macho",
|
||||||
"debug/pe",
|
"debug/pe",
|
||||||
"go/constant",
|
"go/constant",
|
||||||
|
"internal/goexperiment",
|
||||||
"internal/goversion",
|
"internal/goversion",
|
||||||
"internal/race",
|
"internal/race",
|
||||||
"internal/unsafeheader",
|
"internal/unsafeheader",
|
||||||
|
|
|
||||||
|
|
@ -277,8 +277,8 @@ func (b *Builder) buildActionID(a *Action) cache.ActionID {
|
||||||
key, val := cfg.GetArchEnv()
|
key, val := cfg.GetArchEnv()
|
||||||
fmt.Fprintf(h, "%s=%s\n", key, val)
|
fmt.Fprintf(h, "%s=%s\n", key, val)
|
||||||
|
|
||||||
if objabi.GOEXPERIMENT != "" {
|
if goexperiment := objabi.GOEXPERIMENT(); goexperiment != "" {
|
||||||
fmt.Fprintf(h, "GOEXPERIMENT=%q\n", objabi.GOEXPERIMENT)
|
fmt.Fprintf(h, "GOEXPERIMENT=%q\n", goexperiment)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(rsc): Convince compiler team not to add more magic environment variables,
|
// TODO(rsc): Convince compiler team not to add more magic environment variables,
|
||||||
|
|
@ -1251,8 +1251,8 @@ func (b *Builder) printLinkerConfig(h io.Writer, p *load.Package) {
|
||||||
key, val := cfg.GetArchEnv()
|
key, val := cfg.GetArchEnv()
|
||||||
fmt.Fprintf(h, "%s=%s\n", key, val)
|
fmt.Fprintf(h, "%s=%s\n", key, val)
|
||||||
|
|
||||||
if objabi.GOEXPERIMENT != "" {
|
if goexperiment := objabi.GOEXPERIMENT(); goexperiment != "" {
|
||||||
fmt.Fprintf(h, "GOEXPERIMENT=%q\n", objabi.GOEXPERIMENT)
|
fmt.Fprintf(h, "GOEXPERIMENT=%q\n", goexperiment)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The linker writes source file paths that say GOROOT_FINAL, but
|
// The linker writes source file paths that say GOROOT_FINAL, but
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func BuildInit() {
|
func BuildInit() {
|
||||||
|
|
@ -53,7 +52,7 @@ func BuildInit() {
|
||||||
// used for compiling alternative files for the experiment. This allows
|
// used for compiling alternative files for the experiment. This allows
|
||||||
// changes for the experiment, like extra struct fields in the runtime,
|
// changes for the experiment, like extra struct fields in the runtime,
|
||||||
// without affecting the base non-experiment code at all.
|
// without affecting the base non-experiment code at all.
|
||||||
for _, expt := range strings.Split(objabi.GOEXPERIMENT, ",") {
|
for _, expt := range objabi.EnabledExperiments() {
|
||||||
cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, "goexperiment."+expt)
|
cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, "goexperiment."+expt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
132
src/cmd/internal/objabi/exp.go
Normal file
132
src/cmd/internal/objabi/exp.go
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
// Copyright 2021 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package objabi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"internal/goexperiment"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Experiment contains the toolchain experiments enabled for the
|
||||||
|
// current build.
|
||||||
|
//
|
||||||
|
// (This is not necessarily the set of experiments the compiler itself
|
||||||
|
// was built with.)
|
||||||
|
var Experiment goexperiment.Flags
|
||||||
|
|
||||||
|
var defaultExpstring string // Set by package init
|
||||||
|
|
||||||
|
// FramePointerEnabled enables the use of platform conventions for
|
||||||
|
// saving frame pointers.
|
||||||
|
//
|
||||||
|
// This used to be an experiment, but now it's always enabled on
|
||||||
|
// platforms that support it.
|
||||||
|
//
|
||||||
|
// Note: must agree with runtime.framepointer_enabled.
|
||||||
|
var FramePointerEnabled = GOARCH == "amd64" || GOARCH == "arm64"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// Capture "default" experiments.
|
||||||
|
defaultExpstring = Expstring()
|
||||||
|
|
||||||
|
goexperiment := envOr("GOEXPERIMENT", defaultGOEXPERIMENT)
|
||||||
|
|
||||||
|
// GOEXPERIMENT=none overrides all experiments enabled at dist time.
|
||||||
|
if goexperiment != "none" {
|
||||||
|
// Create a map of known experiment names.
|
||||||
|
names := make(map[string]reflect.Value)
|
||||||
|
rv := reflect.ValueOf(&Experiment).Elem()
|
||||||
|
rt := rv.Type()
|
||||||
|
for i := 0; i < rt.NumField(); i++ {
|
||||||
|
field := rv.Field(i)
|
||||||
|
names[strings.ToLower(rt.Field(i).Name)] = field
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse names.
|
||||||
|
for _, f := range strings.Split(goexperiment, ",") {
|
||||||
|
if f == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val := true
|
||||||
|
if strings.HasPrefix(f, "no") {
|
||||||
|
f, val = f[2:], false
|
||||||
|
}
|
||||||
|
field, ok := names[f]
|
||||||
|
if !ok {
|
||||||
|
fmt.Printf("unknown experiment %s\n", f)
|
||||||
|
os.Exit(2)
|
||||||
|
}
|
||||||
|
field.SetBool(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// regabi is only supported on amd64.
|
||||||
|
if GOARCH != "amd64" {
|
||||||
|
Experiment.Regabi = false
|
||||||
|
Experiment.RegabiWrappers = false
|
||||||
|
Experiment.RegabiG = false
|
||||||
|
Experiment.RegabiReflect = false
|
||||||
|
Experiment.RegabiDefer = false
|
||||||
|
Experiment.RegabiArgs = false
|
||||||
|
}
|
||||||
|
// Setting regabi sets working sub-experiments.
|
||||||
|
if Experiment.Regabi {
|
||||||
|
Experiment.RegabiWrappers = true
|
||||||
|
Experiment.RegabiG = true
|
||||||
|
Experiment.RegabiReflect = true
|
||||||
|
Experiment.RegabiDefer = true
|
||||||
|
// Not ready yet:
|
||||||
|
//Experiment.RegabiArgs = true
|
||||||
|
}
|
||||||
|
// Check regabi dependencies.
|
||||||
|
if Experiment.RegabiG && !Experiment.RegabiWrappers {
|
||||||
|
panic("GOEXPERIMENT regabig requires regabiwrappers")
|
||||||
|
}
|
||||||
|
if Experiment.RegabiArgs && !(Experiment.RegabiWrappers && Experiment.RegabiG && Experiment.RegabiReflect && Experiment.RegabiDefer) {
|
||||||
|
panic("GOEXPERIMENT regabiargs requires regabiwrappers,regabig,regabireflect,regabidefer")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// expList returns the list of enabled GOEXPERIMENTs names.
|
||||||
|
func expList(flags *goexperiment.Flags) []string {
|
||||||
|
var list []string
|
||||||
|
rv := reflect.ValueOf(&Experiment).Elem()
|
||||||
|
rt := rv.Type()
|
||||||
|
for i := 0; i < rt.NumField(); i++ {
|
||||||
|
val := rv.Field(i).Bool()
|
||||||
|
if val {
|
||||||
|
field := rt.Field(i)
|
||||||
|
list = append(list, strings.ToLower(field.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expstring returns the GOEXPERIMENT string that should appear in Go
|
||||||
|
// version signatures. This always starts with "X:".
|
||||||
|
func Expstring() string {
|
||||||
|
list := expList(&Experiment)
|
||||||
|
if len(list) == 0 {
|
||||||
|
return "X:none"
|
||||||
|
}
|
||||||
|
return "X:" + strings.Join(list, ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GOEXPERIMENT returns a comma-separated list of enabled experiments.
|
||||||
|
// This is derived from the GOEXPERIMENT environment variable if set,
|
||||||
|
// or the value of GOEXPERIMENT when make.bash was run if not.
|
||||||
|
func GOEXPERIMENT() string {
|
||||||
|
return strings.Join(expList(&Experiment), ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnabledExperiments returns a list of enabled experiments, as
|
||||||
|
// lower-cased experiment names.
|
||||||
|
func EnabledExperiments() []string {
|
||||||
|
return expList(&Experiment)
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
package objabi
|
package objabi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -32,12 +31,6 @@ var (
|
||||||
GOWASM = gowasm()
|
GOWASM = gowasm()
|
||||||
GO_LDSO = defaultGO_LDSO
|
GO_LDSO = defaultGO_LDSO
|
||||||
Version = version
|
Version = version
|
||||||
|
|
||||||
// GOEXPERIMENT is a comma-separated list of enabled
|
|
||||||
// experiments. This is derived from the GOEXPERIMENT
|
|
||||||
// environment variable if set, or the value of GOEXPERIMENT
|
|
||||||
// when make.bash was run if not.
|
|
||||||
GOEXPERIMENT string // Set by package init
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -128,175 +121,3 @@ func gowasm() (f gowasmFeatures) {
|
||||||
func Getgoextlinkenabled() string {
|
func Getgoextlinkenabled() string {
|
||||||
return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED)
|
return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
// Capture "default" experiments.
|
|
||||||
defaultExpstring = Expstring()
|
|
||||||
|
|
||||||
goexperiment := envOr("GOEXPERIMENT", defaultGOEXPERIMENT)
|
|
||||||
|
|
||||||
// GOEXPERIMENT=none overrides all experiments enabled at dist time.
|
|
||||||
if goexperiment != "none" {
|
|
||||||
for _, f := range strings.Split(goexperiment, ",") {
|
|
||||||
if f != "" {
|
|
||||||
addexp(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// regabi is only supported on amd64.
|
|
||||||
if GOARCH != "amd64" {
|
|
||||||
Experiment.regabi = false
|
|
||||||
Experiment.RegabiWrappers = false
|
|
||||||
Experiment.RegabiG = false
|
|
||||||
Experiment.RegabiReflect = false
|
|
||||||
Experiment.RegabiDefer = false
|
|
||||||
Experiment.RegabiArgs = false
|
|
||||||
}
|
|
||||||
// Setting regabi sets working sub-experiments.
|
|
||||||
if Experiment.regabi {
|
|
||||||
Experiment.RegabiWrappers = true
|
|
||||||
Experiment.RegabiG = true
|
|
||||||
Experiment.RegabiReflect = true
|
|
||||||
Experiment.RegabiDefer = true
|
|
||||||
// Not ready yet:
|
|
||||||
//Experiment.RegabiArgs = true
|
|
||||||
}
|
|
||||||
// Check regabi dependencies.
|
|
||||||
if Experiment.RegabiG && !Experiment.RegabiWrappers {
|
|
||||||
panic("GOEXPERIMENT regabig requires regabiwrappers")
|
|
||||||
}
|
|
||||||
if Experiment.RegabiArgs && !(Experiment.RegabiWrappers && Experiment.RegabiG && Experiment.RegabiReflect && Experiment.RegabiDefer) {
|
|
||||||
panic("GOEXPERIMENT regabiargs requires regabiwrappers,regabig,regabireflect,regabidefer")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set GOEXPERIMENT to the parsed and canonicalized set of experiments.
|
|
||||||
GOEXPERIMENT = expList()
|
|
||||||
}
|
|
||||||
|
|
||||||
// FramePointerEnabled enables the use of platform conventions for
|
|
||||||
// saving frame pointers.
|
|
||||||
//
|
|
||||||
// This used to be an experiment, but now it's always enabled on
|
|
||||||
// platforms that support it.
|
|
||||||
//
|
|
||||||
// Note: must agree with runtime.framepointer_enabled.
|
|
||||||
var FramePointerEnabled = GOARCH == "amd64" || GOARCH == "arm64"
|
|
||||||
|
|
||||||
func addexp(s string) {
|
|
||||||
// We could do general integer parsing here, but there's no need yet.
|
|
||||||
v, vb := 1, true
|
|
||||||
name := s
|
|
||||||
if len(name) > 2 && name[:2] == "no" {
|
|
||||||
v, vb = 0, false
|
|
||||||
name = name[2:]
|
|
||||||
}
|
|
||||||
for i := 0; i < len(exper); i++ {
|
|
||||||
if exper[i].name == name {
|
|
||||||
switch val := exper[i].val.(type) {
|
|
||||||
case *int:
|
|
||||||
*val = v
|
|
||||||
case *bool:
|
|
||||||
*val = vb
|
|
||||||
default:
|
|
||||||
panic("bad GOEXPERIMENT type for " + s)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("unknown experiment %s\n", s)
|
|
||||||
os.Exit(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Experiment contains flags for GOEXPERIMENTs.
|
|
||||||
var Experiment = ExpFlags{}
|
|
||||||
|
|
||||||
type ExpFlags struct {
|
|
||||||
FieldTrack bool
|
|
||||||
PreemptibleLoops bool
|
|
||||||
StaticLockRanking bool
|
|
||||||
|
|
||||||
// regabi is split into several sub-experiments that can be
|
|
||||||
// enabled individually. GOEXPERIMENT=regabi implies the
|
|
||||||
// subset that are currently "working". Not all combinations work.
|
|
||||||
regabi bool
|
|
||||||
// RegabiWrappers enables ABI wrappers for calling between
|
|
||||||
// ABI0 and ABIInternal functions. Without this, the ABIs are
|
|
||||||
// assumed to be identical so cross-ABI calls are direct.
|
|
||||||
RegabiWrappers bool
|
|
||||||
// RegabiG enables dedicated G and zero registers in
|
|
||||||
// ABIInternal.
|
|
||||||
//
|
|
||||||
// Requires wrappers because it makes the ABIs incompatible.
|
|
||||||
RegabiG bool
|
|
||||||
// RegabiReflect enables the register-passing paths in
|
|
||||||
// reflection calls. This is also gated by intArgRegs in
|
|
||||||
// reflect and runtime (which are disabled by default) so it
|
|
||||||
// can be used in targeted tests.
|
|
||||||
RegabiReflect bool
|
|
||||||
// RegabiDefer enables desugaring defer and go calls
|
|
||||||
// into argument-less closures.
|
|
||||||
RegabiDefer bool
|
|
||||||
// RegabiArgs enables register arguments/results in all
|
|
||||||
// compiled Go functions.
|
|
||||||
//
|
|
||||||
// Requires wrappers (to do ABI translation), g (because
|
|
||||||
// runtime assembly that's been ported to ABIInternal uses the
|
|
||||||
// G register), reflect (so reflection calls use registers),
|
|
||||||
// and defer (because the runtime doesn't support passing
|
|
||||||
// register arguments to defer/go).
|
|
||||||
RegabiArgs bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toolchain experiments.
|
|
||||||
// These are controlled by the GOEXPERIMENT environment
|
|
||||||
// variable recorded when the toolchain is built.
|
|
||||||
var exper = []struct {
|
|
||||||
name string
|
|
||||||
val interface{} // Must be *int or *bool
|
|
||||||
}{
|
|
||||||
{"fieldtrack", &Experiment.FieldTrack},
|
|
||||||
{"preemptibleloops", &Experiment.PreemptibleLoops},
|
|
||||||
{"staticlockranking", &Experiment.StaticLockRanking},
|
|
||||||
{"regabi", &Experiment.regabi},
|
|
||||||
{"regabiwrappers", &Experiment.RegabiWrappers},
|
|
||||||
{"regabig", &Experiment.RegabiG},
|
|
||||||
{"regabireflect", &Experiment.RegabiReflect},
|
|
||||||
{"regabidefer", &Experiment.RegabiDefer},
|
|
||||||
{"regabiargs", &Experiment.RegabiArgs},
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultExpstring string
|
|
||||||
|
|
||||||
// expList returns the list of enabled GOEXPERIMENTS as a
|
|
||||||
// commas-separated list.
|
|
||||||
func expList() string {
|
|
||||||
buf := ""
|
|
||||||
for i := range exper {
|
|
||||||
switch val := exper[i].val.(type) {
|
|
||||||
case *int:
|
|
||||||
if *val != 0 {
|
|
||||||
buf += "," + exper[i].name
|
|
||||||
}
|
|
||||||
case *bool:
|
|
||||||
if *val {
|
|
||||||
buf += "," + exper[i].name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(buf) == 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return buf[1:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expstring returns the GOEXPERIMENT string that should appear in Go
|
|
||||||
// version signatures. This always starts with "X:".
|
|
||||||
func Expstring() string {
|
|
||||||
list := expList()
|
|
||||||
if list == "" {
|
|
||||||
return "X:none"
|
|
||||||
}
|
|
||||||
return "X:" + list
|
|
||||||
}
|
|
||||||
|
|
|
||||||
72
src/internal/goexperiment/flags.go
Normal file
72
src/internal/goexperiment/flags.go
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
// Copyright 2021 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package goexperiment implements support for toolchain experiments.
|
||||||
|
//
|
||||||
|
// Toolchain experiments are controlled by the GOEXPERIMENT
|
||||||
|
// environment variable. GOEXPERIMENT is a comma-separated list of
|
||||||
|
// experiment names. GOEXPERIMENT can be set at make.bash time, which
|
||||||
|
// sets the default experiments for binaries built with the tool
|
||||||
|
// chain; or it can be set at build time. GOEXPERIMENT can also be set
|
||||||
|
// to "none", which disables any experiments that were enabled at
|
||||||
|
// make.bash time.
|
||||||
|
//
|
||||||
|
// Experiments are exposed to the build in the following ways:
|
||||||
|
//
|
||||||
|
// - Build tag goexperiment.x is set if experiment x (lower case) is
|
||||||
|
// enabled.
|
||||||
|
//
|
||||||
|
// - In runtime assembly, the macro GOEXPERIMENT_x is defined if
|
||||||
|
// experiment x (lower case) is enabled.
|
||||||
|
//
|
||||||
|
// - TODO(austin): More to come.
|
||||||
|
//
|
||||||
|
// In the toolchain, the set of experiments enabled for the current
|
||||||
|
// build should be accessed via objabi.Experiment.
|
||||||
|
//
|
||||||
|
// For the set of experiments supported by the current toolchain, see
|
||||||
|
// go doc internal/experiment.Flags.
|
||||||
|
package goexperiment
|
||||||
|
|
||||||
|
// Flags is the set of experiments that can be enabled or disabled in
|
||||||
|
// the current toolchain.
|
||||||
|
//
|
||||||
|
// When specified in the GOEXPERIMENT environment variable or as build
|
||||||
|
// tags, experiments use the strings.ToLower of their field name.
|
||||||
|
type Flags struct {
|
||||||
|
FieldTrack bool
|
||||||
|
PreemptibleLoops bool
|
||||||
|
StaticLockRanking bool
|
||||||
|
|
||||||
|
// Regabi is split into several sub-experiments that can be
|
||||||
|
// enabled individually. GOEXPERIMENT=regabi implies the
|
||||||
|
// subset that are currently "working". Not all combinations work.
|
||||||
|
Regabi bool
|
||||||
|
// RegabiWrappers enables ABI wrappers for calling between
|
||||||
|
// ABI0 and ABIInternal functions. Without this, the ABIs are
|
||||||
|
// assumed to be identical so cross-ABI calls are direct.
|
||||||
|
RegabiWrappers bool
|
||||||
|
// RegabiG enables dedicated G and zero registers in
|
||||||
|
// ABIInternal.
|
||||||
|
//
|
||||||
|
// Requires wrappers because it makes the ABIs incompatible.
|
||||||
|
RegabiG bool
|
||||||
|
// RegabiReflect enables the register-passing paths in
|
||||||
|
// reflection calls. This is also gated by intArgRegs in
|
||||||
|
// reflect and runtime (which are disabled by default) so it
|
||||||
|
// can be used in targeted tests.
|
||||||
|
RegabiReflect bool
|
||||||
|
// RegabiDefer enables desugaring defer and go calls
|
||||||
|
// into argument-less closures.
|
||||||
|
RegabiDefer bool
|
||||||
|
// RegabiArgs enables register arguments/results in all
|
||||||
|
// compiled Go functions.
|
||||||
|
//
|
||||||
|
// Requires wrappers (to do ABI translation), g (because
|
||||||
|
// runtime assembly that's been ported to ABIInternal uses the
|
||||||
|
// G register), reflect (so reflection calls use registers),
|
||||||
|
// and defer (because the runtime doesn't support passing
|
||||||
|
// register arguments to defer/go).
|
||||||
|
RegabiArgs bool
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue