mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: unify reflect, string and slice copy runtime functions
Use a common runtime slicecopy function to copy strings or slices into slices. This deduplicates similar code previously used in reflect.slicecopy and runtime.stringslicecopy. Change-Id: I09572ff0647a9e12bb5c6989689ce1c43f16b7f1 Reviewed-on: https://go-review.googlesource.com/c/go/+/254658 Run-TryBot: Martin Möhrmann <moehrmann@google.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Martin Möhrmann <moehrmann@google.com> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
eaa97fbf20
commit
790fa1c546
6 changed files with 248 additions and 304 deletions
|
|
@ -243,12 +243,13 @@ func isPowerOfTwo(x uintptr) bool {
|
|||
return x&(x-1) == 0
|
||||
}
|
||||
|
||||
func slicecopy(toPtr unsafe.Pointer, toLen int, fmPtr unsafe.Pointer, fmLen int, width uintptr) int {
|
||||
if fmLen == 0 || toLen == 0 {
|
||||
// slicecopy is used to copy from a string or slice of pointerless elements into a slice.
|
||||
func slicecopy(toPtr unsafe.Pointer, toLen int, fromPtr unsafe.Pointer, fromLen int, width uintptr) int {
|
||||
if fromLen == 0 || toLen == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
n := fmLen
|
||||
n := fromLen
|
||||
if toLen < n {
|
||||
n = toLen
|
||||
}
|
||||
|
|
@ -257,46 +258,23 @@ func slicecopy(toPtr unsafe.Pointer, toLen int, fmPtr unsafe.Pointer, fmLen int,
|
|||
return n
|
||||
}
|
||||
|
||||
size := uintptr(n) * width
|
||||
if raceenabled {
|
||||
callerpc := getcallerpc()
|
||||
pc := funcPC(slicecopy)
|
||||
racereadrangepc(fmPtr, uintptr(n*int(width)), callerpc, pc)
|
||||
racewriterangepc(toPtr, uintptr(n*int(width)), callerpc, pc)
|
||||
racereadrangepc(fromPtr, size, callerpc, pc)
|
||||
racewriterangepc(toPtr, size, callerpc, pc)
|
||||
}
|
||||
if msanenabled {
|
||||
msanread(fmPtr, uintptr(n*int(width)))
|
||||
msanwrite(toPtr, uintptr(n*int(width)))
|
||||
msanread(fromPtr, size)
|
||||
msanwrite(toPtr, size)
|
||||
}
|
||||
|
||||
size := uintptr(n) * width
|
||||
if size == 1 { // common case worth about 2x to do here
|
||||
// TODO: is this still worth it with new memmove impl?
|
||||
*(*byte)(toPtr) = *(*byte)(fmPtr) // known to be a byte pointer
|
||||
*(*byte)(toPtr) = *(*byte)(fromPtr) // known to be a byte pointer
|
||||
} else {
|
||||
memmove(toPtr, fmPtr, size)
|
||||
memmove(toPtr, fromPtr, size)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func slicestringcopy(toPtr *byte, toLen int, fm string) int {
|
||||
if len(fm) == 0 || toLen == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
n := len(fm)
|
||||
if toLen < n {
|
||||
n = toLen
|
||||
}
|
||||
|
||||
if raceenabled {
|
||||
callerpc := getcallerpc()
|
||||
pc := funcPC(slicestringcopy)
|
||||
racewriterangepc(unsafe.Pointer(toPtr), uintptr(n), callerpc, pc)
|
||||
}
|
||||
if msanenabled {
|
||||
msanwrite(unsafe.Pointer(toPtr), uintptr(n))
|
||||
}
|
||||
|
||||
memmove(unsafe.Pointer(toPtr), stringStructOf(&fm).str, uintptr(n))
|
||||
return n
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue