2017-04-18 12:53:25 -07:00
|
|
|
// Copyright 2015 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"
|
|
|
|
|
"log"
|
|
|
|
|
"os"
|
|
|
|
|
"strings"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func envOr(key, value string) string {
|
|
|
|
|
if x := os.Getenv(key); x != "" {
|
|
|
|
|
return x
|
|
|
|
|
}
|
|
|
|
|
return value
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var (
|
cmd/link: set runtime.GOROOT default during link
Suppose you build the Go toolchain in directory A,
move the whole thing to directory B, and then use
it from B to build a new program hello.exe, and then
run hello.exe, and hello.exe crashes with a stack
trace into the standard library.
Long ago, you'd have seen hello.exe print file names
in the A directory tree, even though the files had moved
to the B directory tree. About two years ago we changed
the compiler to write down these files with the name
"$GOROOT" (that literal string) instead of A, so that the
final link from B could replace "$GOROOT" with B,
so that hello.exe's crash would show the correct source
file paths in the stack trace. (golang.org/cl/18200)
Now suppose that you do the same thing but hello.exe
doesn't crash: it prints fmt.Println(runtime.GOROOT()).
And you run hello.exe after clearing $GOROOT from the
environment.
Long ago, you'd have seen hello.exe print A instead of B.
Before this CL, you'd still see hello.exe print A instead of B.
This case is the one instance where a moved toolchain
still divulges its origin. Not anymore. After this CL, hello.exe
will print B, because the linker sets runtime/internal/sys.DefaultGoroot
with the effective GOROOT from link time.
This makes the default result of runtime.GOROOT once again
match the file names recorded in the binary, after two years
of divergence.
With that cleared up, we can reintroduce GOROOT into the
link action ID and also reenable TestExecutableGOROOT/RelocatedExe.
When $GOROOT_FINAL is set during link, it is used
in preference to $GOROOT, as always, but it was easier
to explain the behavior above without introducing that
complication.
Fixes #22155.
Fixes #20284.
Fixes #22475.
Change-Id: Ifdaeb77fd4678fdb337cf59ee25b2cd873ec1016
Reviewed-on: https://go-review.googlesource.com/86835
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-01-08 11:59:29 -05:00
|
|
|
defaultGOROOT string // set by linker
|
|
|
|
|
|
2021-03-15 15:43:45 -04:00
|
|
|
GOROOT = envOr("GOROOT", defaultGOROOT)
|
|
|
|
|
GOARCH = envOr("GOARCH", defaultGOARCH)
|
|
|
|
|
GOOS = envOr("GOOS", defaultGOOS)
|
|
|
|
|
GO386 = envOr("GO386", defaultGO386)
|
|
|
|
|
GOARM = goarm()
|
|
|
|
|
GOMIPS = gomips()
|
|
|
|
|
GOMIPS64 = gomips64()
|
|
|
|
|
GOPPC64 = goppc64()
|
|
|
|
|
GOWASM = gowasm()
|
|
|
|
|
GO_LDSO = defaultGO_LDSO
|
|
|
|
|
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
|
2017-04-18 12:53:25 -07:00
|
|
|
)
|
|
|
|
|
|
2019-04-16 02:49:09 +00:00
|
|
|
const (
|
|
|
|
|
ElfRelocOffset = 256
|
2020-10-30 18:36:41 -04:00
|
|
|
MachoRelocOffset = 2048 // reserve enough space for ELF relocations
|
2019-04-16 02:49:09 +00:00
|
|
|
)
|
|
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
func goarm() int {
|
2020-11-24 17:48:38 +01:00
|
|
|
def := defaultGOARM
|
2020-11-25 19:12:13 +01:00
|
|
|
if GOOS == "android" && GOARCH == "arm" {
|
|
|
|
|
// Android arm devices always support GOARM=7.
|
2020-11-24 17:48:38 +01:00
|
|
|
def = "7"
|
|
|
|
|
}
|
|
|
|
|
switch v := envOr("GOARM", def); v {
|
2017-04-18 12:53:25 -07:00
|
|
|
case "5":
|
|
|
|
|
return 5
|
|
|
|
|
case "6":
|
|
|
|
|
return 6
|
|
|
|
|
case "7":
|
|
|
|
|
return 7
|
|
|
|
|
}
|
|
|
|
|
// Fail here, rather than validate at multiple call sites.
|
|
|
|
|
log.Fatalf("Invalid GOARM value. Must be 5, 6, or 7.")
|
|
|
|
|
panic("unreachable")
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-22 18:23:31 +02:00
|
|
|
func gomips() string {
|
|
|
|
|
switch v := envOr("GOMIPS", defaultGOMIPS); v {
|
|
|
|
|
case "hardfloat", "softfloat":
|
|
|
|
|
return v
|
|
|
|
|
}
|
|
|
|
|
log.Fatalf("Invalid GOMIPS value. Must be hardfloat or softfloat.")
|
|
|
|
|
panic("unreachable")
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-26 15:37:27 +02:00
|
|
|
func gomips64() string {
|
|
|
|
|
switch v := envOr("GOMIPS64", defaultGOMIPS64); v {
|
|
|
|
|
case "hardfloat", "softfloat":
|
|
|
|
|
return v
|
|
|
|
|
}
|
|
|
|
|
log.Fatalf("Invalid GOMIPS64 value. Must be hardfloat or softfloat.")
|
|
|
|
|
panic("unreachable")
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-11 17:16:28 -02:00
|
|
|
func goppc64() int {
|
|
|
|
|
switch v := envOr("GOPPC64", defaultGOPPC64); v {
|
|
|
|
|
case "power8":
|
|
|
|
|
return 8
|
|
|
|
|
case "power9":
|
|
|
|
|
return 9
|
|
|
|
|
}
|
|
|
|
|
log.Fatalf("Invalid GOPPC64 value. Must be power8 or power9.")
|
|
|
|
|
panic("unreachable")
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-23 14:18:19 +01:00
|
|
|
type gowasmFeatures struct {
|
2019-03-23 15:25:42 +01:00
|
|
|
SignExt bool
|
2019-03-24 12:14:27 +01:00
|
|
|
SatConv bool
|
2019-03-23 14:18:19 +01:00
|
|
|
}
|
|
|
|
|
|
2019-04-08 11:23:42 -04:00
|
|
|
func (f gowasmFeatures) String() string {
|
2019-03-23 14:18:19 +01:00
|
|
|
var flags []string
|
2019-03-24 12:14:27 +01:00
|
|
|
if f.SatConv {
|
|
|
|
|
flags = append(flags, "satconv")
|
|
|
|
|
}
|
2019-03-23 15:25:42 +01:00
|
|
|
if f.SignExt {
|
|
|
|
|
flags = append(flags, "signext")
|
|
|
|
|
}
|
2019-03-23 14:18:19 +01:00
|
|
|
return strings.Join(flags, ",")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func gowasm() (f gowasmFeatures) {
|
|
|
|
|
for _, opt := range strings.Split(envOr("GOWASM", ""), ",") {
|
|
|
|
|
switch opt {
|
2019-03-24 12:14:27 +01:00
|
|
|
case "satconv":
|
|
|
|
|
f.SatConv = true
|
2019-03-23 15:25:42 +01:00
|
|
|
case "signext":
|
|
|
|
|
f.SignExt = true
|
2019-03-23 14:18:19 +01:00
|
|
|
case "":
|
|
|
|
|
// ignore
|
|
|
|
|
default:
|
|
|
|
|
log.Fatalf("Invalid GOWASM value. No such feature: " + opt)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
func Getgoextlinkenabled() string {
|
|
|
|
|
return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func init() {
|
2021-03-15 15:43:45 -04:00
|
|
|
// Capture "default" experiments.
|
|
|
|
|
defaultExpstring = Expstring()
|
|
|
|
|
|
|
|
|
|
goexperiment := envOr("GOEXPERIMENT", defaultGOEXPERIMENT)
|
|
|
|
|
|
cmd/dist: build bootstrap without GOEXPERIMENT
Currently, dist attempts to build the bootstrap with the GOEXPERIMENT
set in the environment. However, the logic is incomplete and notably
requires a hack to enable the appropriate build tags for
GOEXPERIMENT=regabi. Without this hack, the build becomes skewed
between a compiler that uses regabi and a runtime that doesn't when
building toolchain2.
We could try to improve the GOEXPERIMENT processing in cmd/dist, but
it will always chase cmd/internal/objabi and it's quite difficult to
share the logic with objabi because of the constraints on building
cmd/dist.
Instead, we switch to building go_bootstrap without any GOEXPERIMENT
and only start using GOEXPERIMENT once we have a working, modern
cmd/go (which has all the GOEXPERIMENT logic in it). We also build
toolchain1 without any GOEXPERIMENT set, in case the bootstrap
toolchain is recent enough to understand build-time GOEXPERIMENT
settings.
As part of this, we make GOEXPERIMENT=none mean "no experiments". This
is necessary since, now that we support setting GOEXPERIMENT at build
time, we need an explicit way to say "ignore all baked-in experiments".
For #40724.
Change-Id: I115399579b766a7a8b2f352f7e5efea5305666cd
Reviewed-on: https://go-review.googlesource.com/c/go/+/302050
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>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
2021-03-15 15:53:21 -04:00
|
|
|
// GOEXPERIMENT=none overrides all experiments enabled at dist time.
|
|
|
|
|
if goexperiment != "none" {
|
|
|
|
|
for _, f := range strings.Split(goexperiment, ",") {
|
|
|
|
|
if f != "" {
|
|
|
|
|
addexp(f)
|
|
|
|
|
}
|
2017-04-18 12:53:25 -07:00
|
|
|
}
|
|
|
|
|
}
|
2020-09-01 11:16:33 -04:00
|
|
|
|
|
|
|
|
// regabi is only supported on amd64.
|
|
|
|
|
if GOARCH != "amd64" {
|
all: explode GOEXPERIMENT=regabi into 5 sub-experiments
This separates GOEXPERIMENT=regabi into five sub-experiments:
regabiwrappers, regabig, regabireflect, regabidefer, and regabiargs.
Setting GOEXPERIMENT=regabi now implies the working subset of these
(currently, regabiwrappers, regabig, and regabireflect).
This simplifies testing, helps derisk the register ABI project,
and will also help with performance comparisons.
This replaces the -abiwrap flag to the compiler and linker with
the regabiwrappers experiment.
As part of this, regabiargs now enables registers for all calls
in the compiler. Previously, this was statically disabled in
regabiEnabledForAllCompilation, but now that we can control it
independently, this isn't necessary.
For #40724.
Change-Id: I5171e60cda6789031f2ef034cc2e7c5d62459122
Reviewed-on: https://go-review.googlesource.com/c/go/+/302070
Trust: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: David Chase <drchase@google.com>
2021-03-15 16:48:54 -04:00
|
|
|
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
|
2021-02-24 12:55:52 -05:00
|
|
|
Experiment.RegabiDefer = true
|
all: explode GOEXPERIMENT=regabi into 5 sub-experiments
This separates GOEXPERIMENT=regabi into five sub-experiments:
regabiwrappers, regabig, regabireflect, regabidefer, and regabiargs.
Setting GOEXPERIMENT=regabi now implies the working subset of these
(currently, regabiwrappers, regabig, and regabireflect).
This simplifies testing, helps derisk the register ABI project,
and will also help with performance comparisons.
This replaces the -abiwrap flag to the compiler and linker with
the regabiwrappers experiment.
As part of this, regabiargs now enables registers for all calls
in the compiler. Previously, this was statically disabled in
regabiEnabledForAllCompilation, but now that we can control it
independently, this isn't necessary.
For #40724.
Change-Id: I5171e60cda6789031f2ef034cc2e7c5d62459122
Reviewed-on: https://go-review.googlesource.com/c/go/+/302070
Trust: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: David Chase <drchase@google.com>
2021-03-15 16:48:54 -04:00
|
|
|
// Not ready yet:
|
|
|
|
|
//Experiment.RegabiArgs = true
|
|
|
|
|
}
|
|
|
|
|
// Check regabi dependencies.
|
|
|
|
|
if Experiment.RegabiG && !Experiment.RegabiWrappers {
|
|
|
|
|
panic("GOEXPERIMENT regabig requires regabiwrappers")
|
|
|
|
|
}
|
2021-03-29 17:38:20 -04:00
|
|
|
if Experiment.RegabiArgs && !(Experiment.RegabiWrappers && Experiment.RegabiG && Experiment.RegabiReflect && Experiment.RegabiDefer) {
|
|
|
|
|
panic("GOEXPERIMENT regabiargs requires regabiwrappers,regabig,regabireflect,regabidefer")
|
2020-09-01 11:16:33 -04:00
|
|
|
}
|
2021-03-15 15:43:45 -04:00
|
|
|
|
|
|
|
|
// Set GOEXPERIMENT to the parsed and canonicalized set of experiments.
|
|
|
|
|
GOEXPERIMENT = expList()
|
2017-04-18 12:53:25 -07:00
|
|
|
}
|
|
|
|
|
|
2021-03-16 17:06:25 -04:00
|
|
|
// 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.
|
|
|
|
|
//
|
2020-08-21 11:09:45 -07:00
|
|
|
// Note: must agree with runtime.framepointer_enabled.
|
2021-03-16 17:06:25 -04:00
|
|
|
var FramePointerEnabled = GOARCH == "amd64" || GOARCH == "arm64"
|
2017-04-18 12:53:25 -07:00
|
|
|
|
|
|
|
|
func addexp(s string) {
|
2021-03-17 12:22:58 -04:00
|
|
|
// We could do general integer parsing here, but there's no need yet.
|
2021-03-15 16:23:21 -04:00
|
|
|
v, vb := 1, true
|
2017-04-18 12:53:25 -07:00
|
|
|
name := s
|
|
|
|
|
if len(name) > 2 && name[:2] == "no" {
|
2021-03-15 16:23:21 -04:00
|
|
|
v, vb = 0, false
|
2017-04-18 12:53:25 -07:00
|
|
|
name = name[2:]
|
|
|
|
|
}
|
|
|
|
|
for i := 0; i < len(exper); i++ {
|
|
|
|
|
if exper[i].name == name {
|
2021-03-15 16:23:21 -04:00
|
|
|
switch val := exper[i].val.(type) {
|
|
|
|
|
case *int:
|
|
|
|
|
*val = v
|
|
|
|
|
case *bool:
|
|
|
|
|
*val = vb
|
|
|
|
|
default:
|
|
|
|
|
panic("bad GOEXPERIMENT type for " + s)
|
2017-04-18 12:53:25 -07:00
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fmt.Printf("unknown experiment %s\n", s)
|
|
|
|
|
os.Exit(2)
|
|
|
|
|
}
|
|
|
|
|
|
all: explode GOEXPERIMENT=regabi into 5 sub-experiments
This separates GOEXPERIMENT=regabi into five sub-experiments:
regabiwrappers, regabig, regabireflect, regabidefer, and regabiargs.
Setting GOEXPERIMENT=regabi now implies the working subset of these
(currently, regabiwrappers, regabig, and regabireflect).
This simplifies testing, helps derisk the register ABI project,
and will also help with performance comparisons.
This replaces the -abiwrap flag to the compiler and linker with
the regabiwrappers experiment.
As part of this, regabiargs now enables registers for all calls
in the compiler. Previously, this was statically disabled in
regabiEnabledForAllCompilation, but now that we can control it
independently, this isn't necessary.
For #40724.
Change-Id: I5171e60cda6789031f2ef034cc2e7c5d62459122
Reviewed-on: https://go-review.googlesource.com/c/go/+/302070
Trust: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: David Chase <drchase@google.com>
2021-03-15 16:48:54 -04:00
|
|
|
// Experiment contains flags for GOEXPERIMENTs.
|
2021-03-16 17:06:25 -04:00
|
|
|
var Experiment = ExpFlags{}
|
all: explode GOEXPERIMENT=regabi into 5 sub-experiments
This separates GOEXPERIMENT=regabi into five sub-experiments:
regabiwrappers, regabig, regabireflect, regabidefer, and regabiargs.
Setting GOEXPERIMENT=regabi now implies the working subset of these
(currently, regabiwrappers, regabig, and regabireflect).
This simplifies testing, helps derisk the register ABI project,
and will also help with performance comparisons.
This replaces the -abiwrap flag to the compiler and linker with
the regabiwrappers experiment.
As part of this, regabiargs now enables registers for all calls
in the compiler. Previously, this was statically disabled in
regabiEnabledForAllCompilation, but now that we can control it
independently, this isn't necessary.
For #40724.
Change-Id: I5171e60cda6789031f2ef034cc2e7c5d62459122
Reviewed-on: https://go-review.googlesource.com/c/go/+/302070
Trust: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: David Chase <drchase@google.com>
2021-03-15 16:48:54 -04:00
|
|
|
|
|
|
|
|
type ExpFlags struct {
|
2021-03-16 17:06:25 -04:00
|
|
|
FieldTrack bool
|
|
|
|
|
PreemptibleLoops bool
|
|
|
|
|
StaticLockRanking bool
|
|
|
|
|
|
all: explode GOEXPERIMENT=regabi into 5 sub-experiments
This separates GOEXPERIMENT=regabi into five sub-experiments:
regabiwrappers, regabig, regabireflect, regabidefer, and regabiargs.
Setting GOEXPERIMENT=regabi now implies the working subset of these
(currently, regabiwrappers, regabig, and regabireflect).
This simplifies testing, helps derisk the register ABI project,
and will also help with performance comparisons.
This replaces the -abiwrap flag to the compiler and linker with
the regabiwrappers experiment.
As part of this, regabiargs now enables registers for all calls
in the compiler. Previously, this was statically disabled in
regabiEnabledForAllCompilation, but now that we can control it
independently, this isn't necessary.
For #40724.
Change-Id: I5171e60cda6789031f2ef034cc2e7c5d62459122
Reviewed-on: https://go-review.googlesource.com/c/go/+/302070
Trust: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: David Chase <drchase@google.com>
2021-03-15 16:48:54 -04:00
|
|
|
// 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.
|
|
|
|
|
//
|
2021-03-29 17:38:20 -04:00
|
|
|
// 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).
|
all: explode GOEXPERIMENT=regabi into 5 sub-experiments
This separates GOEXPERIMENT=regabi into five sub-experiments:
regabiwrappers, regabig, regabireflect, regabidefer, and regabiargs.
Setting GOEXPERIMENT=regabi now implies the working subset of these
(currently, regabiwrappers, regabig, and regabireflect).
This simplifies testing, helps derisk the register ABI project,
and will also help with performance comparisons.
This replaces the -abiwrap flag to the compiler and linker with
the regabiwrappers experiment.
As part of this, regabiargs now enables registers for all calls
in the compiler. Previously, this was statically disabled in
regabiEnabledForAllCompilation, but now that we can control it
independently, this isn't necessary.
For #40724.
Change-Id: I5171e60cda6789031f2ef034cc2e7c5d62459122
Reviewed-on: https://go-review.googlesource.com/c/go/+/302070
Trust: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: David Chase <drchase@google.com>
2021-03-15 16:48:54 -04:00
|
|
|
RegabiArgs bool
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
// Toolchain experiments.
|
|
|
|
|
// These are controlled by the GOEXPERIMENT environment
|
|
|
|
|
// variable recorded when the toolchain is built.
|
|
|
|
|
var exper = []struct {
|
|
|
|
|
name string
|
2021-03-15 16:23:21 -04:00
|
|
|
val interface{} // Must be *int or *bool
|
2017-04-18 12:53:25 -07:00
|
|
|
}{
|
2021-03-16 17:06:25 -04:00
|
|
|
{"fieldtrack", &Experiment.FieldTrack},
|
|
|
|
|
{"preemptibleloops", &Experiment.PreemptibleLoops},
|
|
|
|
|
{"staticlockranking", &Experiment.StaticLockRanking},
|
all: explode GOEXPERIMENT=regabi into 5 sub-experiments
This separates GOEXPERIMENT=regabi into five sub-experiments:
regabiwrappers, regabig, regabireflect, regabidefer, and regabiargs.
Setting GOEXPERIMENT=regabi now implies the working subset of these
(currently, regabiwrappers, regabig, and regabireflect).
This simplifies testing, helps derisk the register ABI project,
and will also help with performance comparisons.
This replaces the -abiwrap flag to the compiler and linker with
the regabiwrappers experiment.
As part of this, regabiargs now enables registers for all calls
in the compiler. Previously, this was statically disabled in
regabiEnabledForAllCompilation, but now that we can control it
independently, this isn't necessary.
For #40724.
Change-Id: I5171e60cda6789031f2ef034cc2e7c5d62459122
Reviewed-on: https://go-review.googlesource.com/c/go/+/302070
Trust: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: David Chase <drchase@google.com>
2021-03-15 16:48:54 -04:00
|
|
|
{"regabi", &Experiment.regabi},
|
|
|
|
|
{"regabiwrappers", &Experiment.RegabiWrappers},
|
|
|
|
|
{"regabig", &Experiment.RegabiG},
|
|
|
|
|
{"regabireflect", &Experiment.RegabiReflect},
|
|
|
|
|
{"regabidefer", &Experiment.RegabiDefer},
|
|
|
|
|
{"regabiargs", &Experiment.RegabiArgs},
|
2017-04-18 12:53:25 -07:00
|
|
|
}
|
|
|
|
|
|
2021-03-15 15:43:45 -04:00
|
|
|
var defaultExpstring string
|
2017-07-17 10:45:27 -04:00
|
|
|
|
2021-03-15 15:43:45 -04:00
|
|
|
// expList returns the list of enabled GOEXPERIMENTS as a
|
|
|
|
|
// commas-separated list.
|
|
|
|
|
func expList() string {
|
|
|
|
|
buf := ""
|
2017-04-18 12:53:25 -07:00
|
|
|
for i := range exper {
|
2021-03-15 16:23:21 -04:00
|
|
|
switch val := exper[i].val.(type) {
|
|
|
|
|
case *int:
|
|
|
|
|
if *val != 0 {
|
|
|
|
|
buf += "," + exper[i].name
|
|
|
|
|
}
|
|
|
|
|
case *bool:
|
|
|
|
|
if *val {
|
|
|
|
|
buf += "," + exper[i].name
|
|
|
|
|
}
|
2017-04-18 12:53:25 -07:00
|
|
|
}
|
|
|
|
|
}
|
2021-03-15 15:43:45 -04:00
|
|
|
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"
|
2017-04-18 12:53:25 -07:00
|
|
|
}
|
2021-03-15 15:43:45 -04:00
|
|
|
return "X:" + list
|
2017-04-18 12:53:25 -07:00
|
|
|
}
|