diff options
author | David Chase <drchase@google.com> | 2021-02-19 18:00:48 -0500 |
---|---|---|
committer | David Chase <drchase@google.com> | 2021-03-04 16:21:10 +0000 |
commit | 3778f8e07d06cabfccd1508295ad67270af078cd (patch) | |
tree | 81b1273462ea0c5751571072c47fb3303985b4fc /src/cmd/compile/internal/liveness | |
parent | a2d92b5143ad6ed1b55b71032c5c1f468ba76fd4 (diff) | |
download | go-3778f8e07d06cabfccd1508295ad67270af078cd.tar.gz go-3778f8e07d06cabfccd1508295ad67270af078cd.zip |
cmd/compile: fix pointer maps for morestack
Verified with test and with single step watching changes to register
values across morestack calls, after reload.
Also added stack-growth test with pointer parameters of varying lifetime.
For #40724.
Change-Id: Idb5fe27786ac5c6665a734d41e68d3d39de2f4da
Reviewed-on: https://go-review.googlesource.com/c/go/+/294429
Trust: David Chase <drchase@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/liveness')
-rw-r--r-- | src/cmd/compile/internal/liveness/plive.go | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/liveness/plive.go b/src/cmd/compile/internal/liveness/plive.go index 53ae797fce..48a26cf66a 100644 --- a/src/cmd/compile/internal/liveness/plive.go +++ b/src/cmd/compile/internal/liveness/plive.go @@ -297,6 +297,22 @@ func affectedVar(v *ssa.Value) (*ir.Name, ssa.SymEffect) { n, _ := ssa.AutoVar(v) return n, ssa.SymWrite + case ssa.OpArgIntReg: + // This forces the spill slot for the register to be live at function entry. + // one of the following holds for a function F with pointer-valued register arg X: + // 0. No GC (so an uninitialized spill slot is okay) + // 1. GC at entry of F. GC is precise, but the spills around morestack initialize X's spill slot + // 2. Stack growth at entry of F. Same as GC. + // 3. GC occurs within F itself. This has to be from preemption, and thus GC is conservative. + // a. X is in a register -- then X is seen, and the spill slot is also scanned conservatively. + // b. X is spilled -- the spill slot is initialized, and scanned conservatively + // c. X is not live -- the spill slot is scanned conservatively, and it may contain X from an earlier spill. + // 4. GC within G, transitively called from F + // a. X is live at call site, therefore is spilled, to its spill slot (which is live because of subsequent LoadReg). + // b. X is not live at call site -- but neither is its spill slot. + n, _ := ssa.AutoVar(v) + return n, ssa.SymRead + case ssa.OpVarLive: return v.Aux.(*ir.Name), ssa.SymRead case ssa.OpVarDef, ssa.OpVarKill: |