[dev.typeparams] cmd/compile, runtime: always enable defer/go wrapping

Hardwire regabidefers to true. Remove it from GOEXPERIMENTs.

Fallback paths are not cleaned up in this CL. That will be done
in later CLs.

Change-Id: Iec1112a1e55d5f6ef70232a5ff6e702f649071c4
Reviewed-on: https://go-review.googlesource.com/c/go/+/325913
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
Cherry Mui 2021-06-04 13:53:18 -04:00
parent e58bddde70
commit a9de78ac88
10 changed files with 17 additions and 45 deletions

View file

@ -4696,7 +4696,7 @@ func (s *state) openDeferRecord(n *ir.CallExpr) {
var args []*ssa.Value var args []*ssa.Value
var argNodes []*ir.Name var argNodes []*ir.Name
if buildcfg.Experiment.RegabiDefer && (len(n.Args) != 0 || n.Op() == ir.OCALLINTER || n.X.Type().NumResults() != 0) { if len(n.Args) != 0 || n.Op() == ir.OCALLINTER || n.X.Type().NumResults() != 0 {
s.Fatalf("defer call with arguments or results: %v", n) s.Fatalf("defer call with arguments or results: %v", n)
} }
@ -4951,7 +4951,7 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
} }
} }
if buildcfg.Experiment.RegabiDefer && k != callNormal && (len(n.Args) != 0 || n.Op() == ir.OCALLINTER || n.X.Type().NumResults() != 0) { if k != callNormal && (len(n.Args) != 0 || n.Op() == ir.OCALLINTER || n.X.Type().NumResults() != 0) {
s.Fatalf("go/defer call with arguments: %v", n) s.Fatalf("go/defer call with arguments: %v", n)
} }

View file

@ -7,7 +7,6 @@ package walk
import ( import (
"fmt" "fmt"
"go/constant" "go/constant"
"internal/buildcfg"
"cmd/compile/internal/base" "cmd/compile/internal/base"
"cmd/compile/internal/escape" "cmd/compile/internal/escape"
@ -790,9 +789,7 @@ func (o *orderState) stmt(n ir.Node) {
n.Call = walkRecover(n.Call.(*ir.CallExpr), &init) n.Call = walkRecover(n.Call.(*ir.CallExpr), &init)
o.stmtList(init) o.stmtList(init)
} }
if buildcfg.Experiment.RegabiDefer { o.wrapGoDefer(n)
o.wrapGoDefer(n)
}
o.out = append(o.out, n) o.out = append(o.out, n)
o.cleanTemp(t) o.cleanTemp(t)

View file

@ -30,7 +30,6 @@ var experimentBaseline = goexperiment.Flags{
RegabiWrappers: regabiSupported, RegabiWrappers: regabiSupported,
RegabiG: regabiSupported, RegabiG: regabiSupported,
RegabiReflect: regabiSupported, RegabiReflect: regabiSupported,
RegabiDefer: true,
RegabiArgs: regabiSupported, RegabiArgs: regabiSupported,
} }
@ -70,7 +69,6 @@ func parseExperiments() goexperiment.Flags {
flags.RegabiWrappers = v flags.RegabiWrappers = v
flags.RegabiG = v flags.RegabiG = v
flags.RegabiReflect = v flags.RegabiReflect = v
flags.RegabiDefer = v
flags.RegabiArgs = v flags.RegabiArgs = v
} }
@ -110,8 +108,8 @@ func parseExperiments() goexperiment.Flags {
if flags.RegabiG && !flags.RegabiWrappers { if flags.RegabiG && !flags.RegabiWrappers {
Error = fmt.Errorf("GOEXPERIMENT regabig requires regabiwrappers") Error = fmt.Errorf("GOEXPERIMENT regabig requires regabiwrappers")
} }
if flags.RegabiArgs && !(flags.RegabiWrappers && flags.RegabiG && flags.RegabiReflect && flags.RegabiDefer) { if flags.RegabiArgs && !(flags.RegabiWrappers && flags.RegabiG && flags.RegabiReflect) {
Error = fmt.Errorf("GOEXPERIMENT regabiargs requires regabiwrappers,regabig,regabireflect,regabidefer") Error = fmt.Errorf("GOEXPERIMENT regabiargs requires regabiwrappers,regabig,regabireflect")
} }
return flags return flags
} }

View file

@ -1,9 +0,0 @@
// Code generated by mkconsts.go. DO NOT EDIT.
//go:build !goexperiment.regabidefer
// +build !goexperiment.regabidefer
package goexperiment
const RegabiDefer = false
const RegabiDeferInt = 0

View file

@ -1,9 +0,0 @@
// Code generated by mkconsts.go. DO NOT EDIT.
//go:build goexperiment.regabidefer
// +build goexperiment.regabidefer
package goexperiment
const RegabiDefer = true
const RegabiDeferInt = 1

View file

@ -78,9 +78,6 @@ type Flags struct {
// reflect and runtime (which are disabled by default) so it // reflect and runtime (which are disabled by default) so it
// can be used in targeted tests. // can be used in targeted tests.
RegabiReflect bool RegabiReflect bool
// RegabiDefer enables desugaring defer and go calls
// into argument-less closures.
RegabiDefer bool
// RegabiArgs enables register arguments/results in all // RegabiArgs enables register arguments/results in all
// compiled Go functions. // compiled Go functions.
// //

View file

@ -6,7 +6,6 @@ package runtime
import ( import (
"internal/abi" "internal/abi"
"internal/goexperiment"
"runtime/internal/atomic" "runtime/internal/atomic"
"runtime/internal/sys" "runtime/internal/sys"
"unsafe" "unsafe"
@ -236,7 +235,7 @@ func deferproc(siz int32, fn *funcval) { // arguments of fn follow fn
throw("defer on system stack") throw("defer on system stack")
} }
if goexperiment.RegabiDefer && siz != 0 { if true && siz != 0 {
// TODO: Make deferproc just take a func(). // TODO: Make deferproc just take a func().
throw("defer with non-empty frame") throw("defer with non-empty frame")
} }
@ -293,7 +292,7 @@ func deferprocStack(d *_defer) {
// go code on the system stack can't defer // go code on the system stack can't defer
throw("defer on system stack") throw("defer on system stack")
} }
if goexperiment.RegabiDefer && d.siz != 0 { if true && d.siz != 0 {
throw("defer with non-empty frame") throw("defer with non-empty frame")
} }
// siz and fn are already set. // siz and fn are already set.
@ -395,7 +394,7 @@ func deferArgs(d *_defer) unsafe.Pointer {
// that experiment, we should change the type of d.fn. // that experiment, we should change the type of d.fn.
//go:nosplit //go:nosplit
func deferFunc(d *_defer) func() { func deferFunc(d *_defer) func() {
if !goexperiment.RegabiDefer { if false {
throw("requires GOEXPERIMENT=regabidefer") throw("requires GOEXPERIMENT=regabidefer")
} }
var fn func() var fn func()
@ -655,7 +654,7 @@ func Goexit() {
addOneOpenDeferFrame(gp, 0, nil) addOneOpenDeferFrame(gp, 0, nil)
} }
} else { } else {
if goexperiment.RegabiDefer { if true {
// Save the pc/sp in deferCallSave(), so we can "recover" back to this // Save the pc/sp in deferCallSave(), so we can "recover" back to this
// loop if necessary. // loop if necessary.
deferCallSave(&p, deferFunc(d)) deferCallSave(&p, deferFunc(d))
@ -857,7 +856,7 @@ func runOpenDeferFrame(gp *g, d *_defer) bool {
argWidth, fd = readvarintUnsafe(fd) argWidth, fd = readvarintUnsafe(fd)
closureOffset, fd = readvarintUnsafe(fd) closureOffset, fd = readvarintUnsafe(fd)
nArgs, fd = readvarintUnsafe(fd) nArgs, fd = readvarintUnsafe(fd)
if goexperiment.RegabiDefer && argWidth != 0 { if true && argWidth != 0 {
throw("defer with non-empty frame") throw("defer with non-empty frame")
} }
if deferBits&(1<<i) == 0 { if deferBits&(1<<i) == 0 {
@ -885,7 +884,7 @@ func runOpenDeferFrame(gp *g, d *_defer) bool {
deferBits = deferBits &^ (1 << i) deferBits = deferBits &^ (1 << i)
*(*uint8)(unsafe.Pointer(d.varp - uintptr(deferBitsOffset))) = deferBits *(*uint8)(unsafe.Pointer(d.varp - uintptr(deferBitsOffset))) = deferBits
p := d._panic p := d._panic
if goexperiment.RegabiDefer { if true {
deferCallSave(p, deferFunc(d)) deferCallSave(p, deferFunc(d))
} else { } else {
reflectcallSave(p, unsafe.Pointer(closure), deferArgs, argWidth) reflectcallSave(p, unsafe.Pointer(closure), deferArgs, argWidth)
@ -913,7 +912,7 @@ func runOpenDeferFrame(gp *g, d *_defer) bool {
// This is marked as a wrapper by the compiler so it doesn't appear in // This is marked as a wrapper by the compiler so it doesn't appear in
// tracebacks. // tracebacks.
func reflectcallSave(p *_panic, fn, arg unsafe.Pointer, argsize uint32) { func reflectcallSave(p *_panic, fn, arg unsafe.Pointer, argsize uint32) {
if goexperiment.RegabiDefer { if true {
throw("not allowed with GOEXPERIMENT=regabidefer") throw("not allowed with GOEXPERIMENT=regabidefer")
} }
if p != nil { if p != nil {
@ -939,7 +938,7 @@ func reflectcallSave(p *_panic, fn, arg unsafe.Pointer, argsize uint32) {
// This is marked as a wrapper by the compiler so it doesn't appear in // This is marked as a wrapper by the compiler so it doesn't appear in
// tracebacks. // tracebacks.
func deferCallSave(p *_panic, fn func()) { func deferCallSave(p *_panic, fn func()) {
if !goexperiment.RegabiDefer { if false {
throw("only allowed with GOEXPERIMENT=regabidefer") throw("only allowed with GOEXPERIMENT=regabidefer")
} }
if p != nil { if p != nil {
@ -1042,7 +1041,7 @@ func gopanic(e interface{}) {
} else { } else {
p.argp = unsafe.Pointer(getargp()) p.argp = unsafe.Pointer(getargp())
if goexperiment.RegabiDefer { if true {
fn := deferFunc(d) fn := deferFunc(d)
fn() fn()
} else { } else {

View file

@ -7,7 +7,6 @@ package runtime
import ( import (
"internal/abi" "internal/abi"
"internal/cpu" "internal/cpu"
"internal/goexperiment"
"runtime/internal/atomic" "runtime/internal/atomic"
"runtime/internal/sys" "runtime/internal/sys"
"unsafe" "unsafe"
@ -4259,7 +4258,7 @@ func newproc(siz int32, fn *funcval) {
// //
//go:systemstack //go:systemstack
func newproc1(fn *funcval, argp unsafe.Pointer, narg int32, callergp *g, callerpc uintptr) *g { func newproc1(fn *funcval, argp unsafe.Pointer, narg int32, callergp *g, callerpc uintptr) *g {
if goexperiment.RegabiDefer && narg != 0 { if true && narg != 0 {
// TODO: When we commit to GOEXPERIMENT=regabidefer, // TODO: When we commit to GOEXPERIMENT=regabidefer,
// rewrite the comments for newproc and newproc1. // rewrite the comments for newproc and newproc1.
// newproc will no longer have a funny stack layout or // newproc will no longer have a funny stack layout or

View file

@ -1,5 +1,5 @@
// errorcheckwithauto -0 -l -live -wb=0 -d=ssa/insert_resched_checks/off // errorcheckwithauto -0 -l -live -wb=0 -d=ssa/insert_resched_checks/off
// +build !ppc64,!ppc64le,goexperiment.regabidefer,!goexperiment.regabiargs // +build !ppc64,!ppc64le,!goexperiment.regabiargs
// ppc64 needs a better tighten pass to make f18 pass // ppc64 needs a better tighten pass to make f18 pass
// rescheduling checks need to be turned off because there are some live variables across the inserted check call // rescheduling checks need to be turned off because there are some live variables across the inserted check call

View file

@ -1,5 +1,5 @@
// errorcheckwithauto -0 -l -live -wb=0 -d=ssa/insert_resched_checks/off // errorcheckwithauto -0 -l -live -wb=0 -d=ssa/insert_resched_checks/off
// +build amd64,goexperiment.regabidefer,goexperiment.regabiargs // +build amd64,goexperiment.regabiargs
// Copyright 2014 The Go Authors. All rights reserved. // Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style