ssa: add builtin append
This commit is contained in:
Binary file not shown.
40
internal/runtime/slice.go
Normal file
40
internal/runtime/slice.go
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package runtime
|
||||
|
||||
// nextslicecap computes the next appropriate slice length.
|
||||
func nextslicecap(newLen, oldCap int) int {
|
||||
newcap := oldCap
|
||||
doublecap := newcap + newcap
|
||||
if newLen > doublecap {
|
||||
return newLen
|
||||
}
|
||||
|
||||
const threshold = 256
|
||||
if oldCap < threshold {
|
||||
return doublecap
|
||||
}
|
||||
for {
|
||||
// Transition from growing 2x for small slices
|
||||
// to growing 1.25x for large slices. This formula
|
||||
// gives a smooth-ish transition between the two.
|
||||
newcap += (newcap + 3*threshold) >> 2
|
||||
|
||||
// We need to check `newcap >= newLen` and whether `newcap` overflowed.
|
||||
// newLen is guaranteed to be larger than zero, hence
|
||||
// when newcap overflows then `uint(newcap) > uint(newLen)`.
|
||||
// This allows to check for both with the same comparison.
|
||||
if uint(newcap) >= uint(newLen) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Set newcap to the requested cap when
|
||||
// the newcap calculation overflowed.
|
||||
if newcap <= 0 {
|
||||
return newLen
|
||||
}
|
||||
return newcap
|
||||
}
|
||||
@@ -70,4 +70,25 @@ func SliceData(s Slice) unsafe.Pointer {
|
||||
return s.data
|
||||
}
|
||||
|
||||
// SliceAppend append elem data and returns a slice.
|
||||
func SliceAppend(src Slice, data unsafe.Pointer, num, etSize int) Slice {
|
||||
if etSize == 0 {
|
||||
return src
|
||||
}
|
||||
oldLen := src.len
|
||||
newLen := src.len + num
|
||||
if newLen > src.cap {
|
||||
newCap := nextslicecap(newLen, src.cap)
|
||||
p := AllocZ(uintptr(newCap * etSize))
|
||||
if oldLen != 0 {
|
||||
c.Memcpy(p, src.data, uintptr(oldLen*etSize))
|
||||
}
|
||||
src.data = p
|
||||
src.cap = newCap
|
||||
}
|
||||
src.len = newLen
|
||||
c.Memcpy(c.Advance(src.data, oldLen*etSize), data, uintptr(num*etSize))
|
||||
return src
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user