Commit c907a754 authored by Martin Möhrmann's avatar Martin Möhrmann

cmd/compile: refactor appendslice to use newer gc code style

- add comments with builtin function signatures that are instantiated
- use Nodes type from the beginning instead of
  []*Node with a later conversion to Nodes
- use conv(x, y) helper function instead of nod(OCONV, x, y)
- factor out repeated calls to Type.Elem()

This makes the function style similar to newer functions like extendslice.

passes toolstash -cmp

Change-Id: Iedab191af9e0884fb6762c9c168430c1d2246979
Reviewed-on: https://go-review.googlesource.com/112598
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 379d2dea
......@@ -2950,92 +2950,93 @@ func appendslice(n *Node, init *Nodes) *Node {
l1 := n.List.First()
l2 := n.List.Second()
var l []*Node
var nodes Nodes
// var s []T
s := temp(l1.Type)
l = append(l, nod(OAS, s, l1)) // s = l1
nodes.Append(nod(OAS, s, l1)) // s = l1
elemtype := s.Type.Elem()
// n := len(s) + len(l2)
nn := temp(types.Types[TINT])
l = append(l, nod(OAS, nn, nod(OADD, nod(OLEN, s, nil), nod(OLEN, l2, nil))))
nodes.Append(nod(OAS, nn, nod(OADD, nod(OLEN, s, nil), nod(OLEN, l2, nil))))
// if uint(n) > uint(cap(s))
nif := nod(OIF, nil, nil)
nif.Left = nod(OGT, nod(OCONV, nn, nil), nod(OCONV, nod(OCAP, s, nil), nil))
nif.Left.Left.Type = types.Types[TUINT]
nif.Left.Right.Type = types.Types[TUINT]
nuint := conv(nn, types.Types[TUINT])
scapuint := conv(nod(OCAP, s, nil), types.Types[TUINT])
nif.Left = nod(OGT, nuint, scapuint)
// instantiate growslice(Type*, []any, int) []any
// instantiate growslice(typ *type, []any, int) []any
fn := syslook("growslice")
fn = substArgTypes(fn, s.Type.Elem(), s.Type.Elem())
fn = substArgTypes(fn, elemtype, elemtype)
// s = growslice(T, s, n)
nif.Nbody.Set1(nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(s.Type.Elem()), s, nn)))
l = append(l, nif)
nif.Nbody.Set1(nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(elemtype), s, nn)))
nodes.Append(nif)
// s = s[:n]
nt := nod(OSLICE, s, nil)
nt.SetSliceBounds(nil, nn, nil)
l = append(l, nod(OAS, s, nt))
nodes.Append(nod(OAS, s, nt))
if l1.Type.Elem().HasHeapPointer() {
var ncopy *Node
if elemtype.HasHeapPointer() {
// copy(s[len(l1):], l2)
nptr1 := nod(OSLICE, s, nil)
nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil)
nptr2 := l2
Curfn.Func.setWBPos(n.Pos)
// instantiate typedslicecopy(typ *type, dst any, src any) int
fn := syslook("typedslicecopy")
fn = substArgTypes(fn, l1.Type, l2.Type)
var ln Nodes
ln.Set(l)
nt := mkcall1(fn, types.Types[TINT], &ln, typename(l1.Type.Elem()), nptr1, nptr2)
l = append(ln.Slice(), nt)
ncopy = mkcall1(fn, types.Types[TINT], &nodes, typename(elemtype), nptr1, nptr2)
} else if instrumenting && !compiling_runtime {
// rely on runtime to instrument copy.
// copy(s[len(l1):], l2)
nptr1 := nod(OSLICE, s, nil)
nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil)
nptr2 := l2
var ln Nodes
ln.Set(l)
var nt *Node
if l2.Type.IsString() {
// instantiate func slicestringcopy(to any, fr any) int
fn := syslook("slicestringcopy")
fn = substArgTypes(fn, l1.Type, l2.Type)
nt = mkcall1(fn, types.Types[TINT], &ln, nptr1, nptr2)
ncopy = mkcall1(fn, types.Types[TINT], &nodes, nptr1, nptr2)
} else {
// instantiate func slicecopy(to any, fr any, wid uintptr) int
fn := syslook("slicecopy")
fn = substArgTypes(fn, l1.Type, l2.Type)
nt = mkcall1(fn, types.Types[TINT], &ln, nptr1, nptr2, nodintconst(s.Type.Elem().Width))
ncopy = mkcall1(fn, types.Types[TINT], &nodes, nptr1, nptr2, nodintconst(elemtype.Width))
}
l = append(ln.Slice(), nt)
} else {
// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
nptr1 := nod(OINDEX, s, nod(OLEN, l1, nil))
nptr1.SetBounded(true)
nptr1 = nod(OADDR, nptr1, nil)
nptr2 := nod(OSPTR, l2, nil)
fn := syslook("memmove")
fn = substArgTypes(fn, s.Type.Elem(), s.Type.Elem())
var ln Nodes
ln.Set(l)
nwid := cheapexpr(conv(nod(OLEN, l2, nil), types.Types[TUINTPTR]), &ln)
nwid := cheapexpr(conv(nod(OLEN, l2, nil), types.Types[TUINTPTR]), &nodes)
nwid = nod(OMUL, nwid, nodintconst(elemtype.Width))
nwid = nod(OMUL, nwid, nodintconst(s.Type.Elem().Width))
nt := mkcall1(fn, nil, &ln, nptr1, nptr2, nwid)
l = append(ln.Slice(), nt)
// instantiate func memmove(to *any, frm *any, length uintptr)
fn := syslook("memmove")
fn = substArgTypes(fn, elemtype, elemtype)
ncopy = mkcall1(fn, nil, &nodes, nptr1, nptr2, nwid)
}
ln := append(nodes.Slice(), ncopy)
typecheckslice(l, Etop)
walkstmtlist(l)
init.Append(l...)
typecheckslice(ln, Etop)
walkstmtlist(ln)
init.Append(ln...)
return s
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment