mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: change Func.{Enter,Exit} from NodeList to slice
Introduces a new types Nodes that can be used to replace NodeList. Update #14473. Change-Id: Id77c5dcae0cbeb898ba12dd46bd400aad408871c Reviewed-on: https://go-review.googlesource.com/19969 Reviewed-by: David Crawshaw <crawshaw@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
6520da6ed5
commit
188e3d2515
9 changed files with 157 additions and 44 deletions
|
|
@ -2621,7 +2621,7 @@ func cgen_ret(n *Node) {
|
||||||
if hasdefer {
|
if hasdefer {
|
||||||
Ginscall(Deferreturn, 0)
|
Ginscall(Deferreturn, 0)
|
||||||
}
|
}
|
||||||
Genlist(Curfn.Func.Exit)
|
Genslice(Curfn.Func.Exit.Slice())
|
||||||
p := Thearch.Gins(obj.ARET, nil, nil)
|
p := Thearch.Gins(obj.ARET, nil, nil)
|
||||||
if n != nil && n.Op == ORETJMP {
|
if n != nil && n.Op == ORETJMP {
|
||||||
p.To.Type = obj.TYPE_MEM
|
p.To.Type = obj.TYPE_MEM
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,7 @@ func capturevars(xfunc *Node) {
|
||||||
lineno = xfunc.Lineno
|
lineno = xfunc.Lineno
|
||||||
|
|
||||||
func_ := xfunc.Func.Closure
|
func_ := xfunc.Func.Closure
|
||||||
func_.Func.Enter = nil
|
func_.Func.Enter.Set(nil)
|
||||||
for _, v := range func_.Func.Cvars() {
|
for _, v := range func_.Func.Cvars() {
|
||||||
if v.Type == nil {
|
if v.Type == nil {
|
||||||
// if v->type is nil, it means v looked like it was
|
// if v->type is nil, it means v looked like it was
|
||||||
|
|
@ -265,7 +265,7 @@ func capturevars(xfunc *Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
typecheck(&outer, Erv)
|
typecheck(&outer, Erv)
|
||||||
func_.Func.Enter = list(func_.Func.Enter, outer)
|
func_.Func.Enter.Append(outer)
|
||||||
}
|
}
|
||||||
|
|
||||||
lineno = int32(lno)
|
lineno = int32(lno)
|
||||||
|
|
@ -350,9 +350,7 @@ func transformclosure(xfunc *Node) {
|
||||||
xfunc.Type = f.Type // update type of ODCLFUNC
|
xfunc.Type = f.Type // update type of ODCLFUNC
|
||||||
} else {
|
} else {
|
||||||
// The closure is not called, so it is going to stay as closure.
|
// The closure is not called, so it is going to stay as closure.
|
||||||
nvar := 0
|
var body []*Node
|
||||||
|
|
||||||
var body *NodeList
|
|
||||||
offset := int64(Widthptr)
|
offset := int64(Widthptr)
|
||||||
var addr *Node
|
var addr *Node
|
||||||
var cv *Node
|
var cv *Node
|
||||||
|
|
@ -360,7 +358,6 @@ func transformclosure(xfunc *Node) {
|
||||||
if v.Op == OXXX {
|
if v.Op == OXXX {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
nvar++
|
|
||||||
|
|
||||||
// cv refers to the field inside of closure OSTRUCTLIT.
|
// cv refers to the field inside of closure OSTRUCTLIT.
|
||||||
cv = Nod(OCLOSUREVAR, nil, nil)
|
cv = Nod(OCLOSUREVAR, nil, nil)
|
||||||
|
|
@ -378,7 +375,7 @@ func transformclosure(xfunc *Node) {
|
||||||
v.Class = PAUTO
|
v.Class = PAUTO
|
||||||
v.Ullman = 1
|
v.Ullman = 1
|
||||||
xfunc.Func.Dcl = append(xfunc.Func.Dcl, v)
|
xfunc.Func.Dcl = append(xfunc.Func.Dcl, v)
|
||||||
body = list(body, Nod(OAS, v, cv))
|
body = append(body, Nod(OAS, v, cv))
|
||||||
} else {
|
} else {
|
||||||
// Declare variable holding addresses taken from closure
|
// Declare variable holding addresses taken from closure
|
||||||
// and initialize in entry prologue.
|
// and initialize in entry prologue.
|
||||||
|
|
@ -392,14 +389,16 @@ func transformclosure(xfunc *Node) {
|
||||||
if v.Name.Byval {
|
if v.Name.Byval {
|
||||||
cv = Nod(OADDR, cv, nil)
|
cv = Nod(OADDR, cv, nil)
|
||||||
}
|
}
|
||||||
body = list(body, Nod(OAS, addr, cv))
|
body = append(body, Nod(OAS, addr, cv))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typechecklist(body, Etop)
|
if len(body) > 0 {
|
||||||
walkstmtlist(body)
|
typecheckslice(body, Etop)
|
||||||
xfunc.Func.Enter = body
|
walkstmtslice(body)
|
||||||
xfunc.Func.Needctxt = nvar > 0
|
xfunc.Func.Enter.Set(body)
|
||||||
|
xfunc.Func.Needctxt = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lineno = int32(lno)
|
lineno = int32(lno)
|
||||||
|
|
@ -443,7 +442,7 @@ func walkclosure(func_ *Node, init **NodeList) *Node {
|
||||||
clos := Nod(OCOMPLIT, nil, Nod(OIND, typ, nil))
|
clos := Nod(OCOMPLIT, nil, Nod(OIND, typ, nil))
|
||||||
clos.Esc = func_.Esc
|
clos.Esc = func_.Esc
|
||||||
clos.Right.Implicit = true
|
clos.Right.Implicit = true
|
||||||
clos.List = concat(list1(Nod(OCFUNC, func_.Func.Closure.Func.Nname, nil)), func_.Func.Enter)
|
clos.List = concat(list1(Nod(OCFUNC, func_.Func.Closure.Func.Nname, nil)), func_.Func.Enter.NodeList())
|
||||||
|
|
||||||
// Force type conversion from *struct to the func type.
|
// Force type conversion from *struct to the func type.
|
||||||
clos = Nod(OCONVNOP, clos, nil)
|
clos = Nod(OCONVNOP, clos, nil)
|
||||||
|
|
|
||||||
|
|
@ -1729,10 +1729,42 @@ func Hconv(l *NodeList, flag int) string {
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Hconvslice(l []*Node, flag int) string {
|
||||||
|
if len(l) == 0 && fmtmode == FDbg {
|
||||||
|
return "<nil>"
|
||||||
|
}
|
||||||
|
|
||||||
|
sf := flag
|
||||||
|
sm, sb := setfmode(&flag)
|
||||||
|
sep := "; "
|
||||||
|
if fmtmode == FDbg {
|
||||||
|
sep = "\n"
|
||||||
|
} else if flag&obj.FmtComma != 0 {
|
||||||
|
sep = ", "
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
for i, n := range l {
|
||||||
|
buf.WriteString(Nconv(n, 0))
|
||||||
|
if i+1 < len(l) {
|
||||||
|
buf.WriteString(sep)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flag = sf
|
||||||
|
fmtbody = sb
|
||||||
|
fmtmode = sm
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
func dumplist(s string, l *NodeList) {
|
func dumplist(s string, l *NodeList) {
|
||||||
fmt.Printf("%s%v\n", s, Hconv(l, obj.FmtSign))
|
fmt.Printf("%s%v\n", s, Hconv(l, obj.FmtSign))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func dumpslice(s string, l []*Node) {
|
||||||
|
fmt.Printf("%s%v\n", s, Hconvslice(l, obj.FmtSign))
|
||||||
|
}
|
||||||
|
|
||||||
func Dump(s string, n *Node) {
|
func Dump(s string, n *Node) {
|
||||||
fmt.Printf("%s [%p]%v\n", s, n, Nconv(n, obj.FmtSign))
|
fmt.Printf("%s [%p]%v\n", s, n, Nconv(n, obj.FmtSign))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -219,6 +219,12 @@ func Genlist(l *NodeList) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Genslice(l []*Node) {
|
||||||
|
for _, n := range l {
|
||||||
|
gen(n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// generate code to start new proc running call n.
|
// generate code to start new proc running call n.
|
||||||
func cgen_proc(n *Node, proc int) {
|
func cgen_proc(n *Node, proc int) {
|
||||||
switch n.Left.Op {
|
switch n.Left.Op {
|
||||||
|
|
|
||||||
|
|
@ -471,7 +471,7 @@ func compile(fn *Node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Genlist(Curfn.Func.Enter)
|
Genslice(Curfn.Func.Enter.Slice())
|
||||||
Genlist(Curfn.Nbody)
|
Genlist(Curfn.Nbody)
|
||||||
gclean()
|
gclean()
|
||||||
checklabels()
|
checklabels()
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ func instrument(fn *Node) {
|
||||||
instrumentlist(fn.Nbody, nil)
|
instrumentlist(fn.Nbody, nil)
|
||||||
|
|
||||||
// nothing interesting for race detector in fn->enter
|
// nothing interesting for race detector in fn->enter
|
||||||
instrumentlist(fn.Func.Exit, nil)
|
instrumentslice(fn.Func.Exit.Slice(), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if flag_race != 0 {
|
if flag_race != 0 {
|
||||||
|
|
@ -71,18 +71,18 @@ func instrument(fn *Node) {
|
||||||
nodpc.Type = Types[TUINTPTR]
|
nodpc.Type = Types[TUINTPTR]
|
||||||
nodpc.Xoffset = int64(-Widthptr)
|
nodpc.Xoffset = int64(-Widthptr)
|
||||||
nd := mkcall("racefuncenter", nil, nil, nodpc)
|
nd := mkcall("racefuncenter", nil, nil, nodpc)
|
||||||
fn.Func.Enter = concat(list1(nd), fn.Func.Enter)
|
fn.Func.Enter.Set(append([]*Node{nd}, fn.Func.Enter.Slice()...))
|
||||||
nd = mkcall("racefuncexit", nil, nil)
|
nd = mkcall("racefuncexit", nil, nil)
|
||||||
fn.Func.Exit = list(fn.Func.Exit, nd)
|
fn.Func.Exit.Append(nd)
|
||||||
}
|
}
|
||||||
|
|
||||||
if Debug['W'] != 0 {
|
if Debug['W'] != 0 {
|
||||||
s := fmt.Sprintf("after instrument %v", fn.Func.Nname.Sym)
|
s := fmt.Sprintf("after instrument %v", fn.Func.Nname.Sym)
|
||||||
dumplist(s, fn.Nbody)
|
dumplist(s, fn.Nbody)
|
||||||
s = fmt.Sprintf("enter %v", fn.Func.Nname.Sym)
|
s = fmt.Sprintf("enter %v", fn.Func.Nname.Sym)
|
||||||
dumplist(s, fn.Func.Enter)
|
dumpslice(s, fn.Func.Enter.Slice())
|
||||||
s = fmt.Sprintf("exit %v", fn.Func.Nname.Sym)
|
s = fmt.Sprintf("exit %v", fn.Func.Nname.Sym)
|
||||||
dumplist(s, fn.Func.Exit)
|
dumpslice(s, fn.Func.Exit.Slice())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,6 +100,18 @@ func instrumentlist(l *NodeList, init **NodeList) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func instrumentslice(l []*Node, init **NodeList) {
|
||||||
|
for i := range l {
|
||||||
|
var instr *NodeList
|
||||||
|
instrumentnode(&l[i], &instr, 0, 0)
|
||||||
|
if init == nil {
|
||||||
|
l[i].Ninit = concat(l[i].Ninit, instr)
|
||||||
|
} else {
|
||||||
|
*init = concat(*init, instr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// walkexpr and walkstmt combined
|
// walkexpr and walkstmt combined
|
||||||
// walks the tree and adds calls to the
|
// walks the tree and adds calls to the
|
||||||
// instrumentation code to top-level (statement) nodes' init
|
// instrumentation code to top-level (statement) nodes' init
|
||||||
|
|
|
||||||
|
|
@ -149,8 +149,8 @@ type Param struct {
|
||||||
// Func holds Node fields used only with function-like nodes.
|
// Func holds Node fields used only with function-like nodes.
|
||||||
type Func struct {
|
type Func struct {
|
||||||
Shortname *Node
|
Shortname *Node
|
||||||
Enter *NodeList
|
Enter Nodes
|
||||||
Exit *NodeList
|
Exit Nodes
|
||||||
cvars *[]*Node // closure params
|
cvars *[]*Node // closure params
|
||||||
Dcl []*Node // autodcl for this func/closure
|
Dcl []*Node // autodcl for this func/closure
|
||||||
Inldcl *[]*Node // copy of dcl for use in inlining
|
Inldcl *[]*Node // copy of dcl for use in inlining
|
||||||
|
|
@ -506,3 +506,55 @@ func count(l *NodeList) int {
|
||||||
}
|
}
|
||||||
return int(n)
|
return int(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Nodes is a pointer to a slice of *Node.
|
||||||
|
// For fields that are not used in most nodes, this is used instead of
|
||||||
|
// a slice to save space.
|
||||||
|
type Nodes struct{ slice *[]*Node }
|
||||||
|
|
||||||
|
// Slice returns the entries in Nodes as a slice.
|
||||||
|
// Changes to the slice entries (as in s[i] = n) will be reflected in
|
||||||
|
// the Nodes.
|
||||||
|
func (n *Nodes) Slice() []*Node {
|
||||||
|
if n.slice == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return *n.slice
|
||||||
|
}
|
||||||
|
|
||||||
|
// NodeList returns the entries in Nodes as a NodeList.
|
||||||
|
// Changes to the NodeList entries (as in l.N = n) will *not* be
|
||||||
|
// reflect in the Nodes.
|
||||||
|
// This wastes memory and should be used as little as possible.
|
||||||
|
func (n *Nodes) NodeList() *NodeList {
|
||||||
|
if n.slice == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var ret *NodeList
|
||||||
|
for _, n := range *n.slice {
|
||||||
|
ret = list(ret, n)
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets Nodes to a slice.
|
||||||
|
// This takes ownership of the slice.
|
||||||
|
func (n *Nodes) Set(s []*Node) {
|
||||||
|
if len(s) == 0 {
|
||||||
|
n.slice = nil
|
||||||
|
} else {
|
||||||
|
n.slice = &s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append appends entries to Nodes.
|
||||||
|
// If a slice is passed in, this will take ownership of it.
|
||||||
|
func (n *Nodes) Append(a ...*Node) {
|
||||||
|
if n.slice == nil {
|
||||||
|
if len(a) > 0 {
|
||||||
|
n.slice = &a
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*n.slice = append(*n.slice, a...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,12 @@ func typechecklist(l *NodeList, top int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func typecheckslice(l []*Node, top int) {
|
||||||
|
for i := range l {
|
||||||
|
typecheck(&l[i], top)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var _typekind = []string{
|
var _typekind = []string{
|
||||||
TINT: "int",
|
TINT: "int",
|
||||||
TUINT: "uint",
|
TUINT: "uint",
|
||||||
|
|
|
||||||
|
|
@ -71,9 +71,9 @@ func walk(fn *Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
heapmoves()
|
heapmoves()
|
||||||
if Debug['W'] != 0 && Curfn.Func.Enter != nil {
|
if Debug['W'] != 0 && len(Curfn.Func.Enter.Slice()) > 0 {
|
||||||
s := fmt.Sprintf("enter %v", Curfn.Func.Nname.Sym)
|
s := fmt.Sprintf("enter %v", Curfn.Func.Nname.Sym)
|
||||||
dumplist(s, Curfn.Func.Enter)
|
dumpslice(s, Curfn.Func.Enter.Slice())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,6 +83,12 @@ func walkstmtlist(l *NodeList) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func walkstmtslice(l []*Node) {
|
||||||
|
for i := range l {
|
||||||
|
walkstmt(&l[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func samelist(a *NodeList, b *NodeList) bool {
|
func samelist(a *NodeList, b *NodeList) bool {
|
||||||
for ; a != nil && b != nil; a, b = a.Next, b.Next {
|
for ; a != nil && b != nil; a, b = a.Next, b.Next {
|
||||||
if a.N != b.N {
|
if a.N != b.N {
|
||||||
|
|
@ -320,7 +326,7 @@ func walkstmt(np **Node) {
|
||||||
ll := ascompatee(n.Op, rl, n.List, &n.Ninit)
|
ll := ascompatee(n.Op, rl, n.List, &n.Ninit)
|
||||||
n.List = reorder3(ll)
|
n.List = reorder3(ll)
|
||||||
for lr := n.List; lr != nil; lr = lr.Next {
|
for lr := n.List; lr != nil; lr = lr.Next {
|
||||||
lr.N = applywritebarrier(lr.N, &n.Ninit)
|
lr.N = applywritebarrier(lr.N)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -588,9 +594,9 @@ opswitch:
|
||||||
// transformclosure already did all preparation work.
|
// transformclosure already did all preparation work.
|
||||||
|
|
||||||
// Prepend captured variables to argument list.
|
// Prepend captured variables to argument list.
|
||||||
n.List = concat(n.Left.Func.Enter, n.List)
|
n.List = concat(n.Left.Func.Enter.NodeList(), n.List)
|
||||||
|
|
||||||
n.Left.Func.Enter = nil
|
n.Left.Func.Enter.Set(nil)
|
||||||
|
|
||||||
// Replace OCLOSURE with ONAME/PFUNC.
|
// Replace OCLOSURE with ONAME/PFUNC.
|
||||||
n.Left = n.Left.Func.Closure.Func.Nname
|
n.Left = n.Left.Func.Closure.Func.Nname
|
||||||
|
|
@ -724,7 +730,7 @@ opswitch:
|
||||||
r := convas(Nod(OAS, n.Left, n.Right), init)
|
r := convas(Nod(OAS, n.Left, n.Right), init)
|
||||||
r.Dodata = n.Dodata
|
r.Dodata = n.Dodata
|
||||||
n = r
|
n = r
|
||||||
n = applywritebarrier(n, init)
|
n = applywritebarrier(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
case OAS2:
|
case OAS2:
|
||||||
|
|
@ -735,7 +741,7 @@ opswitch:
|
||||||
ll := ascompatee(OAS, n.List, n.Rlist, init)
|
ll := ascompatee(OAS, n.List, n.Rlist, init)
|
||||||
ll = reorder3(ll)
|
ll = reorder3(ll)
|
||||||
for lr := ll; lr != nil; lr = lr.Next {
|
for lr := ll; lr != nil; lr = lr.Next {
|
||||||
lr.N = applywritebarrier(lr.N, init)
|
lr.N = applywritebarrier(lr.N)
|
||||||
}
|
}
|
||||||
n = liststmt(ll)
|
n = liststmt(ll)
|
||||||
|
|
||||||
|
|
@ -750,7 +756,7 @@ opswitch:
|
||||||
|
|
||||||
ll := ascompatet(n.Op, n.List, &r.Type, 0, init)
|
ll := ascompatet(n.Op, n.List, &r.Type, 0, init)
|
||||||
for lr := ll; lr != nil; lr = lr.Next {
|
for lr := ll; lr != nil; lr = lr.Next {
|
||||||
lr.N = applywritebarrier(lr.N, init)
|
lr.N = applywritebarrier(lr.N)
|
||||||
}
|
}
|
||||||
n = liststmt(concat(list1(r), ll))
|
n = liststmt(concat(list1(r), ll))
|
||||||
|
|
||||||
|
|
@ -2133,7 +2139,7 @@ func needwritebarrier(l *Node, r *Node) bool {
|
||||||
|
|
||||||
// TODO(rsc): Perhaps componentgen should run before this.
|
// TODO(rsc): Perhaps componentgen should run before this.
|
||||||
|
|
||||||
func applywritebarrier(n *Node, init **NodeList) *Node {
|
func applywritebarrier(n *Node) *Node {
|
||||||
if n.Left != nil && n.Right != nil && needwritebarrier(n.Left, n.Right) {
|
if n.Left != nil && n.Right != nil && needwritebarrier(n.Left, n.Right) {
|
||||||
if Debug_wb > 1 {
|
if Debug_wb > 1 {
|
||||||
Warnl(int(n.Lineno), "marking %v for barrier", Nconv(n.Left, 0))
|
Warnl(int(n.Lineno), "marking %v for barrier", Nconv(n.Left, 0))
|
||||||
|
|
@ -2542,12 +2548,12 @@ func vmatch1(l *Node, r *Node) bool {
|
||||||
// walk through argin parameters.
|
// walk through argin parameters.
|
||||||
// generate and return code to allocate
|
// generate and return code to allocate
|
||||||
// copies of escaped parameters to the heap.
|
// copies of escaped parameters to the heap.
|
||||||
func paramstoheap(argin **Type, out int) *NodeList {
|
func paramstoheap(argin **Type, out int) []*Node {
|
||||||
var savet Iter
|
var savet Iter
|
||||||
var v *Node
|
var v *Node
|
||||||
var as *Node
|
var as *Node
|
||||||
|
|
||||||
var nn *NodeList
|
var nn []*Node
|
||||||
for t := Structfirst(&savet, argin); t != nil; t = structnext(&savet) {
|
for t := Structfirst(&savet, argin); t != nil; t = structnext(&savet) {
|
||||||
v = t.Nname
|
v = t.Nname
|
||||||
if v != nil && v.Sym != nil && v.Sym.Name[0] == '~' && v.Sym.Name[1] == 'r' { // unnamed result
|
if v != nil && v.Sym != nil && v.Sym.Name[0] == '~' && v.Sym.Name[1] == 'r' { // unnamed result
|
||||||
|
|
@ -2560,7 +2566,7 @@ func paramstoheap(argin **Type, out int) *NodeList {
|
||||||
// Defer might stop a panic and show the
|
// Defer might stop a panic and show the
|
||||||
// return values as they exist at the time of panic.
|
// return values as they exist at the time of panic.
|
||||||
// Make sure to zero them on entry to the function.
|
// Make sure to zero them on entry to the function.
|
||||||
nn = list(nn, Nod(OAS, nodarg(t, 1), nil))
|
nn = append(nn, Nod(OAS, nodarg(t, 1), nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
if v == nil || v.Class&PHEAP == 0 {
|
if v == nil || v.Class&PHEAP == 0 {
|
||||||
|
|
@ -2574,13 +2580,13 @@ func paramstoheap(argin **Type, out int) *NodeList {
|
||||||
if prealloc[v] == nil {
|
if prealloc[v] == nil {
|
||||||
prealloc[v] = callnew(v.Type)
|
prealloc[v] = callnew(v.Type)
|
||||||
}
|
}
|
||||||
nn = list(nn, Nod(OAS, v.Name.Heapaddr, prealloc[v]))
|
nn = append(nn, Nod(OAS, v.Name.Heapaddr, prealloc[v]))
|
||||||
if v.Class&^PHEAP != PPARAMOUT {
|
if v.Class&^PHEAP != PPARAMOUT {
|
||||||
as = Nod(OAS, v, v.Name.Param.Stackparam)
|
as = Nod(OAS, v, v.Name.Param.Stackparam)
|
||||||
v.Name.Param.Stackparam.Typecheck = 1
|
v.Name.Param.Stackparam.Typecheck = 1
|
||||||
typecheck(&as, Etop)
|
typecheck(&as, Etop)
|
||||||
as = applywritebarrier(as, &nn)
|
as = applywritebarrier(as)
|
||||||
nn = list(nn, as)
|
nn = append(nn, as)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2588,17 +2594,17 @@ func paramstoheap(argin **Type, out int) *NodeList {
|
||||||
}
|
}
|
||||||
|
|
||||||
// walk through argout parameters copying back to stack
|
// walk through argout parameters copying back to stack
|
||||||
func returnsfromheap(argin **Type) *NodeList {
|
func returnsfromheap(argin **Type) []*Node {
|
||||||
var savet Iter
|
var savet Iter
|
||||||
var v *Node
|
var v *Node
|
||||||
|
|
||||||
var nn *NodeList
|
var nn []*Node
|
||||||
for t := Structfirst(&savet, argin); t != nil; t = structnext(&savet) {
|
for t := Structfirst(&savet, argin); t != nil; t = structnext(&savet) {
|
||||||
v = t.Nname
|
v = t.Nname
|
||||||
if v == nil || v.Class != PHEAP|PPARAMOUT {
|
if v == nil || v.Class != PHEAP|PPARAMOUT {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
nn = list(nn, Nod(OAS, v.Name.Param.Stackparam, v))
|
nn = append(nn, Nod(OAS, v.Name.Param.Stackparam, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nn
|
return nn
|
||||||
|
|
@ -2611,11 +2617,11 @@ func heapmoves() {
|
||||||
lno := lineno
|
lno := lineno
|
||||||
lineno = Curfn.Lineno
|
lineno = Curfn.Lineno
|
||||||
nn := paramstoheap(getthis(Curfn.Type), 0)
|
nn := paramstoheap(getthis(Curfn.Type), 0)
|
||||||
nn = concat(nn, paramstoheap(getinarg(Curfn.Type), 0))
|
nn = append(nn, paramstoheap(getinarg(Curfn.Type), 0)...)
|
||||||
nn = concat(nn, paramstoheap(Getoutarg(Curfn.Type), 1))
|
nn = append(nn, paramstoheap(Getoutarg(Curfn.Type), 1)...)
|
||||||
Curfn.Func.Enter = concat(Curfn.Func.Enter, nn)
|
Curfn.Func.Enter.Append(nn...)
|
||||||
lineno = Curfn.Func.Endlineno
|
lineno = Curfn.Func.Endlineno
|
||||||
Curfn.Func.Exit = returnsfromheap(Getoutarg(Curfn.Type))
|
Curfn.Func.Exit.Append(returnsfromheap(Getoutarg(Curfn.Type))...)
|
||||||
lineno = lno
|
lineno = lno
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue