patch reflect: Append/Index; Int fix
This commit is contained in:
@@ -286,6 +286,7 @@ func reflect_typedslicecopy(elemType *_type, dst, src slice) int {
|
||||
}
|
||||
return typedslicecopy(elemType, dst.array, dst.len, src.array, src.len)
|
||||
}
|
||||
*/
|
||||
|
||||
// typedmemclr clears the typed memory at ptr with type typ. The
|
||||
// memory at ptr must already be initialized (and hence in type-safe
|
||||
@@ -296,20 +297,11 @@ func reflect_typedslicecopy(elemType *_type, dst, src slice) int {
|
||||
// call memclrHasPointers.
|
||||
//
|
||||
// TODO: A "go:nosplitrec" annotation would be perfect for this.
|
||||
//
|
||||
//go:nosplit
|
||||
func typedmemclr(typ *_type, ptr unsafe.Pointer) {
|
||||
if writeBarrier.needed && typ.PtrBytes != 0 {
|
||||
bulkBarrierPreWrite(uintptr(ptr), 0, typ.PtrBytes)
|
||||
}
|
||||
memclrNoHeapPointers(ptr, typ.Size_)
|
||||
}
|
||||
|
||||
//go:linkname reflect_typedmemclr reflect.typedmemclr
|
||||
func reflect_typedmemclr(typ *_type, ptr unsafe.Pointer) {
|
||||
typedmemclr(typ, ptr)
|
||||
func Typedmemclr(typ *Type, ptr unsafe.Pointer) {
|
||||
c.Memset(ptr, 0, typ.Size_)
|
||||
}
|
||||
|
||||
/*
|
||||
//go:linkname reflect_typedmemclrpartial reflect.typedmemclrpartial
|
||||
func reflect_typedmemclrpartial(typ *_type, ptr unsafe.Pointer, off, size uintptr) {
|
||||
if writeBarrier.needed && typ.PtrBytes != 0 {
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
// 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
|
||||
}
|
||||
@@ -51,7 +51,15 @@ func SliceAppend(src Slice, data unsafe.Pointer, num, etSize int) Slice {
|
||||
return src
|
||||
}
|
||||
oldLen := src.len
|
||||
newLen := src.len + num
|
||||
src = GrowSlice(src, num, etSize)
|
||||
c.Memcpy(c.Advance(src.data, oldLen*etSize), data, uintptr(num*etSize))
|
||||
return src
|
||||
}
|
||||
|
||||
// GrowSlice grows slice and returns the grown slice.
|
||||
func GrowSlice(src Slice, num, etSize int) Slice {
|
||||
oldLen := src.len
|
||||
newLen := oldLen + num
|
||||
if newLen > src.cap {
|
||||
newCap := nextslicecap(newLen, src.cap)
|
||||
p := AllocZ(uintptr(newCap * etSize))
|
||||
@@ -62,10 +70,44 @@ func SliceAppend(src Slice, data unsafe.Pointer, num, etSize int) Slice {
|
||||
src.cap = newCap
|
||||
}
|
||||
src.len = newLen
|
||||
c.Memcpy(c.Advance(src.data, oldLen*etSize), data, uintptr(num*etSize))
|
||||
return src
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// SliceCopy copy data to slice and returns a slice.
|
||||
func SliceCopy(dst Slice, data unsafe.Pointer, num int, etSize int) int {
|
||||
n := dst.len
|
||||
|
||||
Reference in New Issue
Block a user