mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: keep pointer input arguments live throughout function
Introduce a KeepAlive op which makes sure that its argument is kept live until the KeepAlive. Use KeepAlive to mark pointer input arguments as live after each function call and at each return. We do this change only for pointer arguments. Those are the critical ones to handle because they might have finalizers. Doing compound arguments (slices, structs, ...) is more complicated because we would need to track field liveness individually (we do that for auto variables now, but inputs requires extra trickery). Turn off the automatic marking of args as live. That way, when args are explicitly nulled, plive will know that the original argument is dead. The KeepAlive op will be the eventual implementation of runtime.KeepAlive. Fixes #15277 Change-Id: I5f223e65d99c9f8342c03fbb1512c4d363e903e5 Reviewed-on: https://go-review.googlesource.com/22365 Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
d52022676d
commit
3572c6418b
10 changed files with 145 additions and 34 deletions
|
|
@ -68,11 +68,37 @@ type Node struct {
|
|||
Used bool
|
||||
Isddd bool // is the argument variadic
|
||||
Implicit bool
|
||||
Addrtaken bool // address taken, even if not moved to heap
|
||||
Assigned bool // is the variable ever assigned to
|
||||
Likely int8 // likeliness of if statement
|
||||
Hasbreak bool // has break statement
|
||||
hasVal int8 // +1 for Val, -1 for Opt, 0 for not yet set
|
||||
Addrtaken bool // address taken, even if not moved to heap
|
||||
Assigned bool // is the variable ever assigned to
|
||||
Likely int8 // likeliness of if statement
|
||||
hasVal int8 // +1 for Val, -1 for Opt, 0 for not yet set
|
||||
flags uint8 // TODO: store more bool fields in this flag field
|
||||
}
|
||||
|
||||
const (
|
||||
hasBreak = 1 << iota
|
||||
notLiveAtEnd
|
||||
)
|
||||
|
||||
func (n *Node) HasBreak() bool {
|
||||
return n.flags&hasBreak != 0
|
||||
}
|
||||
func (n *Node) SetHasBreak(b bool) {
|
||||
if b {
|
||||
n.flags |= hasBreak
|
||||
} else {
|
||||
n.flags &^= hasBreak
|
||||
}
|
||||
}
|
||||
func (n *Node) NotLiveAtEnd() bool {
|
||||
return n.flags¬LiveAtEnd != 0
|
||||
}
|
||||
func (n *Node) SetNotLiveAtEnd(b bool) {
|
||||
if b {
|
||||
n.flags |= notLiveAtEnd
|
||||
} else {
|
||||
n.flags &^= notLiveAtEnd
|
||||
}
|
||||
}
|
||||
|
||||
// Val returns the Val for the node.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue