Skip to content

Commit 6fc1242

Browse files
cherrymuibradfitz
authored andcommitted
[release-branch.go1.12] cmd/compile: make KeepAlive work on stack object
Currently, runtime.KeepAlive applied on a stack object doesn't actually keeps the stack object alive, and the heap object referenced from it could be collected. This is because the address of the stack object is rematerializeable, and we just ignored KeepAlive on rematerializeable values. This CL fixes it. Updates #30476. Fixes #30478. Change-Id: Ic1f75ee54ed94ea79bd46a8ddcd9e81d01556d1d Reviewed-on: https://go-review.googlesource.com/c/164537 Run-TryBot: Cherry Zhang <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Keith Randall <[email protected]> (cherry picked from commit 40df9cc) Reviewed-on: https://go-review.googlesource.com/c/go/+/164627
1 parent f9d0594 commit 6fc1242

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

src/cmd/compile/internal/ssa/regalloc.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,13 @@ func (s *regAllocState) regalloc(f *Func) {
12201220
// This forces later liveness analysis to make the
12211221
// value live at this point.
12221222
v.SetArg(0, s.makeSpill(a, b))
1223+
} else if _, ok := a.Aux.(GCNode); ok && vi.rematerializeable {
1224+
// Rematerializeable value with a gc.Node. This is the address of
1225+
// a stack object (e.g. an LEAQ). Keep the object live.
1226+
// Change it to VarLive, which is what plive expects for locals.
1227+
v.Op = OpVarLive
1228+
v.SetArgs1(v.Args[1])
1229+
v.Aux = a.Aux
12231230
} else {
12241231
// In-register and rematerializeable values are already live.
12251232
// These are typically rematerializeable constants like nil,

test/fixedbugs/issue30476.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// run
2+
3+
// Copyright 2019 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
// Issue 30476: KeepAlive didn't keep stack object alive.
8+
9+
package main
10+
11+
import "runtime"
12+
13+
func main() {
14+
x := new([10]int)
15+
runtime.SetFinalizer(x, func(*[10]int) { panic("FAIL: finalizer runs") })
16+
p := &T{x, 0}
17+
use(p)
18+
runtime.GC()
19+
runtime.GC()
20+
runtime.GC()
21+
runtime.KeepAlive(p)
22+
}
23+
24+
type T struct {
25+
x *[10]int
26+
y int
27+
}
28+
29+
//go:noinline
30+
func use(*T) {}

0 commit comments

Comments
 (0)