aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/runtime/slice.go
diff options
context:
space:
mode:
authorGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-22 17:43:43 -0300
committerGiuliano Belinassi <giuliano.belinassi@usp.br>2020-08-22 17:43:43 -0300
commita926878ddbd5a98b272c22171ce58663fc04c3e0 (patch)
tree86af256e5d9a9c06263c00adc90e5fe348008c43 /libgo/go/runtime/slice.go
parent542730f087133690b47e036dfd43eb0db8a650ce (diff)
parent07cbaed8ba7d1b6e4ab3a9f44175502a4e1ecdb1 (diff)
downloadgcc-devel/autopar_devel.zip
gcc-devel/autopar_devel.tar.gz
gcc-devel/autopar_devel.tar.bz2
Merge branch 'autopar_rebase2' into autopar_develdevel/autopar_devel
Quickly commit changes in the rebase branch.
Diffstat (limited to 'libgo/go/runtime/slice.go')
-rw-r--r--libgo/go/runtime/slice.go87
1 files changed, 68 insertions, 19 deletions
diff --git a/libgo/go/runtime/slice.go b/libgo/go/runtime/slice.go
index b61c2b1..97b2659 100644
--- a/libgo/go/runtime/slice.go
+++ b/libgo/go/runtime/slice.go
@@ -41,6 +41,55 @@ func panicmakeslicecap() {
panic(errorString("makeslice: cap out of range"))
}
+// makeslicecopy allocates a slice of "tolen" elements of type "et",
+// then copies "fromlen" elements of type "et" into that new allocation from "from".
+func makeslicecopy(et *_type, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer {
+ var tomem, copymem uintptr
+ if uintptr(tolen) > uintptr(fromlen) {
+ var overflow bool
+ tomem, overflow = math.MulUintptr(et.size, uintptr(tolen))
+ if overflow || tomem > maxAlloc || tolen < 0 {
+ panicmakeslicelen()
+ }
+ copymem = et.size * uintptr(fromlen)
+ } else {
+ // fromlen is a known good length providing and equal or greater than tolen,
+ // thereby making tolen a good slice length too as from and to slices have the
+ // same element width.
+ tomem = et.size * uintptr(tolen)
+ copymem = tomem
+ }
+
+ var to unsafe.Pointer
+ if et.ptrdata == 0 {
+ to = mallocgc(tomem, nil, false)
+ if copymem < tomem {
+ memclrNoHeapPointers(add(to, copymem), tomem-copymem)
+ }
+ } else {
+ // Note: can't use rawmem (which avoids zeroing of memory), because then GC can scan uninitialized memory.
+ to = mallocgc(tomem, et, true)
+ if copymem > 0 && writeBarrier.enabled {
+ // Only shade the pointers in old.array since we know the destination slice to
+ // only contains nil pointers because it has been cleared during alloc.
+ bulkBarrierPreWriteSrcOnly(uintptr(to), uintptr(from), copymem)
+ }
+ }
+
+ if raceenabled {
+ callerpc := getcallerpc()
+ pc := funcPC(makeslicecopy)
+ racereadrangepc(from, copymem, callerpc, pc)
+ }
+ if msanenabled {
+ msanread(from, copymem)
+ }
+
+ memmove(to, from, copymem)
+
+ return to
+}
+
func makeslice(et *_type, len, cap int) unsafe.Pointer {
mem, overflow := math.MulUintptr(et.size, uintptr(cap))
if overflow || mem > maxAlloc || len < 0 || len > cap {
@@ -187,7 +236,7 @@ func growslice(et *_type, oldarray unsafe.Pointer, oldlen, oldcap, cap int) slic
if lenmem > 0 && writeBarrier.enabled {
// Only shade the pointers in old.array since we know the destination slice p
// only contains nil pointers because it has been cleared during alloc.
- bulkBarrierPreWriteSrcOnly(uintptr(p), uintptr(oldarray), lenmem)
+ bulkBarrierPreWriteSrcOnly(uintptr(p), uintptr(oldarray), lenmem-et.size+et.ptrdata)
}
}
memmove(p, oldarray, lenmem)
@@ -199,14 +248,14 @@ func isPowerOfTwo(x uintptr) bool {
return x&(x-1) == 0
}
-func slicecopy(to, fm slice, width uintptr) int {
- if fm.len == 0 || to.len == 0 {
+func slicecopy(toPtr unsafe.Pointer, toLen int, fmPtr unsafe.Pointer, fmLen int, width uintptr) int {
+ if fmLen == 0 || toLen == 0 {
return 0
}
- n := fm.len
- if to.len < n {
- n = to.len
+ n := fmLen
+ if toLen < n {
+ n = toLen
}
if width == 0 {
@@ -216,43 +265,43 @@ func slicecopy(to, fm slice, width uintptr) int {
if raceenabled {
callerpc := getcallerpc()
pc := funcPC(slicecopy)
- racewriterangepc(to.array, uintptr(n*int(width)), callerpc, pc)
- racereadrangepc(fm.array, uintptr(n*int(width)), callerpc, pc)
+ racereadrangepc(fmPtr, uintptr(n*int(width)), callerpc, pc)
+ racewriterangepc(toPtr, uintptr(n*int(width)), callerpc, pc)
}
if msanenabled {
- msanwrite(to.array, uintptr(n*int(width)))
- msanread(fm.array, uintptr(n*int(width)))
+ msanread(fmPtr, uintptr(n*int(width)))
+ msanwrite(toPtr, uintptr(n*int(width)))
}
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)(to.array) = *(*byte)(fm.array) // known to be a byte pointer
+ *(*byte)(toPtr) = *(*byte)(fmPtr) // known to be a byte pointer
} else {
- memmove(to.array, fm.array, size)
+ memmove(toPtr, fmPtr, size)
}
return n
}
-func slicestringcopy(to []byte, fm string) int {
- if len(fm) == 0 || len(to) == 0 {
+func slicestringcopy(toPtr *byte, toLen int, fm string) int {
+ if len(fm) == 0 || toLen == 0 {
return 0
}
n := len(fm)
- if len(to) < n {
- n = len(to)
+ if toLen < n {
+ n = toLen
}
if raceenabled {
callerpc := getcallerpc()
pc := funcPC(slicestringcopy)
- racewriterangepc(unsafe.Pointer(&to[0]), uintptr(n), callerpc, pc)
+ racewriterangepc(unsafe.Pointer(toPtr), uintptr(n), callerpc, pc)
}
if msanenabled {
- msanwrite(unsafe.Pointer(&to[0]), uintptr(n))
+ msanwrite(unsafe.Pointer(toPtr), uintptr(n))
}
- memmove(unsafe.Pointer(&to[0]), stringStructOf(&fm).str, uintptr(n))
+ memmove(unsafe.Pointer(toPtr), stringStructOf(&fm).str, uintptr(n))
return n
}