// non-escaping temp to use, if any.
// orderexpr did not compute the type; fill it in now.
- if func_.Alloc != nil {
- func_.Alloc.Type = clos.Left.Left.Type
- func_.Alloc.Orig.Type = func_.Alloc.Type
- clos.Left.Right = func_.Alloc
- func_.Alloc = nil
+ if x := prealloc[func_]; x != nil {
+ x.Type = clos.Left.Left.Type
+ x.Orig.Type = x.Type
+ clos.Left.Right = x
+ delete(prealloc, func_)
}
walkexpr(&clos, init)
// non-escaping temp to use, if any.
// orderexpr did not compute the type; fill it in now.
- if n.Alloc != nil {
- n.Alloc.Type = clos.Left.Left.Type
- n.Alloc.Orig.Type = n.Alloc.Type
- clos.Left.Right = n.Alloc
- n.Alloc = nil
+ if x := prealloc[n]; x != nil {
+ x.Type = clos.Left.Left.Type
+ x.Orig.Type = x.Type
+ clos.Left.Right = x
+ delete(prealloc, n)
}
walkexpr(&clos, init)
if compiling_runtime != 0 {
Yyerror("%v escapes to heap, not allowed in runtime.", n)
}
- if n.Alloc == nil {
- n.Alloc = callnew(n.Type)
+ if prealloc[n] == nil {
+ prealloc[n] = callnew(n.Type)
}
- Cgen_as(n.Name.Heapaddr, n.Alloc)
+ Cgen_as(n.Name.Heapaddr, prealloc[n])
}
/*
n.Right = ordercopyexpr(r, r.Type, order, 0)
// n->alloc is the temp for the iterator.
- n.Alloc = ordertemp(Types[TUINT8], order, true)
+ prealloc[n] = ordertemp(Types[TUINT8], order, true)
}
for l := n.List; l != nil; l = l.Next {
}
}
+// prealloc[x] records the allocation to use for x.
+var prealloc = map[*Node]*Node{}
+
// Orderexpr orders a single expression, appending side
// effects to order->out as needed.
// If this is part of an assignment lhs = *np, lhs is given.
t := typ(TARRAY)
t.Bound = int64(count(n.List))
t.Type = Types[TSTRING]
- n.Alloc = ordertemp(t, order, false)
+ prealloc[n] = ordertemp(t, order, false)
}
// Mark string(byteSlice) arguments to reuse byteSlice backing
case OCLOSURE:
if n.Noescape && n.Func.Cvars != nil {
- n.Alloc = ordertemp(Types[TUINT8], order, false) // walk will fill in correct type
+ prealloc[n] = ordertemp(Types[TUINT8], order, false) // walk will fill in correct type
}
case OARRAYLIT, OCALLPART:
orderexprlist(n.List, order)
orderexprlist(n.Rlist, order)
if n.Noescape {
- n.Alloc = ordertemp(Types[TUINT8], order, false) // walk will fill in correct type
+ prealloc[n] = ordertemp(Types[TUINT8], order, false) // walk will fill in correct type
}
case ODDDARG:
// Allocate a temporary that will be cleaned up when this statement
// completes. We could be more aggressive and try to arrange for it
// to be cleaned up when the call completes.
- n.Alloc = ordertemp(n.Type.Type, order, false)
+ prealloc[n] = ordertemp(n.Type.Type, order, false)
}
case ODOTTYPE, ODOTTYPE2:
ha := a
th := hiter(t)
- hit := n.Alloc
+ hit := prealloc[n]
hit.Type = th
n.Left = nil
keyname := newname(th.Type.Sym) // depends on layout of iterator struct. See reflect.go:hiter
// set auto to point at new temp or heap (3 assign)
var a *Node
- if n.Alloc != nil {
+ if x := prealloc[n]; x != nil {
// temp allocated during order.c for dddarg
- n.Alloc.Type = t
+ x.Type = t
if vstat == nil {
- a = Nod(OAS, n.Alloc, nil)
+ a = Nod(OAS, x, nil)
typecheck(&a, Etop)
*init = list(*init, a) // zero new temp
}
- a = Nod(OADDR, n.Alloc, nil)
+ a = Nod(OADDR, x, nil)
} else if n.Esc == EscNone {
a = temp(t)
if vstat == nil {
Name *Name
Pack *Node // real package for import . names
Curfn *Node // function for local variables
- Alloc *Node // allocation call
Param *Param
// OPACK
n.Type = tslice
} else {
n = Nod(OCOMPLIT, nil, typenod(tslice))
- if ddd != nil {
- n.Alloc = ddd.Alloc // temporary to use
+ if ddd != nil && prealloc[ddd] != nil {
+ prealloc[n] = prealloc[ddd] // temporary to use
}
n.List = lr0
n.Esc = esc
if compiling_runtime != 0 {
Yyerror("%v escapes to heap, not allowed in runtime.", v)
}
- if v.Alloc == nil {
- v.Alloc = callnew(v.Type)
+ if prealloc[v] == nil {
+ prealloc[v] = callnew(v.Type)
}
- nn = list(nn, Nod(OAS, v.Name.Heapaddr, v.Alloc))
+ nn = list(nn, Nod(OAS, v.Name.Heapaddr, prealloc[v]))
if v.Class&^PHEAP != PPARAMOUT {
as = Nod(OAS, v, v.Param.Stackparam)
v.Param.Stackparam.Typecheck = 1
t.Type = Types[TSTRING]
t.Bound = -1
slice := Nod(OCOMPLIT, nil, typenod(t))
- slice.Alloc = n.Alloc
+ if prealloc[n] != nil {
+ prealloc[slice] = prealloc[n]
+ }
slice.List = args.Next // skip buf arg
args = list1(buf)
args = list(args, slice)