diff options
author | David Chase <drchase@google.com> | 2021-03-10 20:54:11 -0500 |
---|---|---|
committer | David Chase <drchase@google.com> | 2021-03-16 19:22:44 +0000 |
commit | 0ec2c4abbad7d678ebc4afc4c69af7d952fc3404 (patch) | |
tree | 82ab8d9323deb085f5a4d7bd2b44856dfbcc9bf6 /src/cmd/compile/internal/abi/abiutils.go | |
parent | 832a01aad409dc0e41eabb53bfdb64d1a41b2c83 (diff) | |
download | go-0ec2c4abbad7d678ebc4afc4c69af7d952fc3404.tar.gz go-0ec2c4abbad7d678ebc4afc4c69af7d952fc3404.zip |
cmd/compile: (fixed) spill output parameters passed in registers as autos
Repair of CL 300749.
ALSO:
found evidence that stack maps for bodyless methods are wrong.
gofmt in test/abi
removed never-executed code in types/size.go
Updates #44816.
Updates #40724.
Change-Id: Ifeb5fee60f60e7c7b58ee0457f58a3265d6cf3f6
Reviewed-on: https://go-review.googlesource.com/c/go/+/302071
Trust: David Chase <drchase@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/cmd/compile/internal/abi/abiutils.go')
-rw-r--r-- | src/cmd/compile/internal/abi/abiutils.go | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/src/cmd/compile/internal/abi/abiutils.go b/src/cmd/compile/internal/abi/abiutils.go index ecde34313a..7573c13158 100644 --- a/src/cmd/compile/internal/abi/abiutils.go +++ b/src/cmd/compile/internal/abi/abiutils.go @@ -69,6 +69,14 @@ func (a *ABIParamResultInfo) SpillAreaSize() int64 { return a.spillAreaSize } +// ArgWidth returns the amount of stack needed for all the inputs +// and outputs of a function or method, including ABI-defined parameter +// slots and ABI-defined spill slots for register-resident parameters. +// The name is inherited from (*Type).ArgWidth(), which it replaces. +func (a *ABIParamResultInfo) ArgWidth() int64 { + return a.spillAreaSize + a.offsetToSpillArea - a.config.LocalsOffset() +} + // RegIndex stores the index into the set of machine registers used by // the ABI on a specific architecture for parameter passing. RegIndex // values 0 through N-1 (where N is the number of integer registers @@ -414,20 +422,25 @@ func (config *ABIConfig) ABIAnalyzeFuncType(ft *types.Func) *ABIParamResultInfo // ABIAnalyze returns the same result as ABIAnalyzeFuncType, but also // updates the offsets of all the receiver, input, and output fields. -func (config *ABIConfig) ABIAnalyze(t *types.Type) *ABIParamResultInfo { +// If setNname is true, it also sets the FrameOffset of the Nname for +// the field(s); this is for use when compiling a function and figuring out +// spill locations. Doing this for callers can cause races for register +// outputs because their frame location transitions from BOGUS_FUNARG_OFFSET +// to zero to an as-if-AUTO offset that has no use for callers. +func (config *ABIConfig) ABIAnalyze(t *types.Type, setNname bool) *ABIParamResultInfo { ft := t.FuncType() result := config.ABIAnalyzeFuncType(ft) // Fill in the frame offsets for receiver, inputs, results k := 0 if t.NumRecvs() != 0 { - config.updateOffset(result, ft.Receiver.FieldSlice()[0], result.inparams[0], false) + config.updateOffset(result, ft.Receiver.FieldSlice()[0], result.inparams[0], false, setNname) k++ } for i, f := range ft.Params.FieldSlice() { - config.updateOffset(result, f, result.inparams[k+i], false) + config.updateOffset(result, f, result.inparams[k+i], false, setNname) } for i, f := range ft.Results.FieldSlice() { - config.updateOffset(result, f, result.outparams[i], true) + config.updateOffset(result, f, result.outparams[i], true, setNname) } return result } @@ -442,7 +455,7 @@ func FieldOffsetOf(f *types.Field) int64 { return f.Offset } -func (config *ABIConfig) updateOffset(result *ABIParamResultInfo, f *types.Field, a ABIParamAssignment, isReturn bool) { +func (config *ABIConfig) updateOffset(result *ABIParamResultInfo, f *types.Field, a ABIParamAssignment, isReturn, setNname bool) { // Everything except return values in registers has either a frame home (if not in a register) or a frame spill location. if !isReturn || len(a.Registers) == 0 { // The type frame offset DOES NOT show effects of minimum frame size. @@ -455,11 +468,19 @@ func (config *ABIConfig) updateOffset(result *ABIParamResultInfo, f *types.Field // Set the Offset the first time. After that, we may recompute it, but it should never change. f.Offset = off if f.Nname != nil { + // always set it in this case. f.Nname.(*ir.Name).SetFrameOffset(off) + f.Nname.(*ir.Name).SetIsOutputParamInRegisters(false) } } else if fOffset != off { panic(fmt.Errorf("Offset changed from %d to %d", fOffset, off)) } + } else { + if setNname && f.Nname != nil { + fname := f.Nname.(*ir.Name) + fname.SetIsOutputParamInRegisters(true) + fname.SetFrameOffset(0) + } } } |