diff options
author | Cherry Zhang <cherryyz@google.com> | 2020-10-28 09:12:20 -0400 |
---|---|---|
committer | Cherry Zhang <cherryyz@google.com> | 2020-10-28 09:12:20 -0400 |
commit | a16e30d162c1c7408db7821e7b9513cefa09c6ca (patch) | |
tree | af752ba9ba44c547df39bb0af9bff79f610ba9d5 /src/cmd/compile/internal/gc/esc.go | |
parent | 91e4d2d57bc341dd82c98247117114c851380aef (diff) | |
parent | cf6cfba4d5358404dd890f6025e573a4b2156543 (diff) | |
download | go-git-dev.link.tar.gz |
[dev.link] all: merge branch 'master' into dev.linkdev.link
Clean merge.
Change-Id: Ia7b2808bc649790198d34c226a61d9e569084dc5
Diffstat (limited to 'src/cmd/compile/internal/gc/esc.go')
-rw-r--r-- | src/cmd/compile/internal/gc/esc.go | 47 |
1 files changed, 29 insertions, 18 deletions
diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go index 375331d1f5..6f328ab5ea 100644 --- a/src/cmd/compile/internal/gc/esc.go +++ b/src/cmd/compile/internal/gc/esc.go @@ -169,36 +169,47 @@ func mayAffectMemory(n *Node) bool { } } -func mustHeapAlloc(n *Node) bool { +// heapAllocReason returns the reason the given Node must be heap +// allocated, or the empty string if it doesn't. +func heapAllocReason(n *Node) string { if n.Type == nil { - return false + return "" } // Parameters are always passed via the stack. if n.Op == ONAME && (n.Class() == PPARAM || n.Class() == PPARAMOUT) { - return false + return "" } if n.Type.Width > maxStackVarSize { - return true + return "too large for stack" } if (n.Op == ONEW || n.Op == OPTRLIT) && n.Type.Elem().Width >= maxImplicitStackVarSize { - return true + return "too large for stack" } if n.Op == OCLOSURE && closureType(n).Size() >= maxImplicitStackVarSize { - return true + return "too large for stack" } if n.Op == OCALLPART && partialCallType(n).Size() >= maxImplicitStackVarSize { - return true + return "too large for stack" } - if n.Op == OMAKESLICE && !isSmallMakeSlice(n) { - return true + if n.Op == OMAKESLICE { + r := n.Right + if r == nil { + r = n.Left + } + if !smallintconst(r) { + return "non-constant size" + } + if t := n.Type; t.Elem().Width != 0 && r.Int64Val() >= maxImplicitStackVarSize/t.Elem().Width { + return "too large for stack" + } } - return false + return "" } // addrescapes tags node n as having had its address taken @@ -271,7 +282,7 @@ func addrescapes(n *Node) { // moveToHeap records the parameter or local variable n as moved to the heap. func moveToHeap(n *Node) { - if Debug['r'] != 0 { + if Debug.r != 0 { Dump("MOVE", n) } if compiling_runtime { @@ -348,7 +359,7 @@ func moveToHeap(n *Node) { n.Xoffset = 0 n.Name.Param.Heapaddr = heapaddr n.Esc = EscHeap - if Debug['m'] != 0 { + if Debug.m != 0 { Warnl(n.Pos, "moved to heap: %v", n) } } @@ -378,7 +389,7 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string { // but we are reusing the ability to annotate an individual function // argument and pass those annotations along to importing code. if f.Type.IsUintptr() { - if Debug['m'] != 0 { + if Debug.m != 0 { Warnl(f.Pos, "assuming %v is unsafe uintptr", name()) } return unsafeUintptrTag @@ -393,11 +404,11 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string { // External functions are assumed unsafe, unless // //go:noescape is given before the declaration. if fn.Func.Pragma&Noescape != 0 { - if Debug['m'] != 0 && f.Sym != nil { + if Debug.m != 0 && f.Sym != nil { Warnl(f.Pos, "%v does not escape", name()) } } else { - if Debug['m'] != 0 && f.Sym != nil { + if Debug.m != 0 && f.Sym != nil { Warnl(f.Pos, "leaking param: %v", name()) } esc.AddHeap(0) @@ -408,14 +419,14 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string { if fn.Func.Pragma&UintptrEscapes != 0 { if f.Type.IsUintptr() { - if Debug['m'] != 0 { + if Debug.m != 0 { Warnl(f.Pos, "marking %v as escaping uintptr", name()) } return uintptrEscapesTag } if f.IsDDD() && f.Type.Elem().IsUintptr() { // final argument is ...uintptr. - if Debug['m'] != 0 { + if Debug.m != 0 { Warnl(f.Pos, "marking %v as escaping ...uintptr", name()) } return uintptrEscapesTag @@ -437,7 +448,7 @@ func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string { esc := loc.paramEsc esc.Optimize() - if Debug['m'] != 0 && !loc.escapes { + if Debug.m != 0 && !loc.escapes { if esc.Empty() { Warnl(f.Pos, "%v does not escape", name()) } |