aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/runtime/mbarrier.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/runtime/mbarrier.go')
-rw-r--r--libgo/go/runtime/mbarrier.go58
1 files changed, 20 insertions, 38 deletions
diff --git a/libgo/go/runtime/mbarrier.go b/libgo/go/runtime/mbarrier.go
index d54016f0..3b8f714 100644
--- a/libgo/go/runtime/mbarrier.go
+++ b/libgo/go/runtime/mbarrier.go
@@ -189,6 +189,8 @@ func gcmarkwb_m(slot *uintptr, ptr uintptr) {
func writebarrierptr_prewrite1(dst *uintptr, src uintptr) {
mp := acquirem()
if mp.inwb || mp.dying > 0 {
+ // We explicitly allow write barriers in startpanic_m,
+ // since we're going down anyway. Ignore them here.
releasem(mp)
return
}
@@ -244,6 +246,10 @@ func writebarrierptr_prewrite(dst *uintptr, src uintptr) {
// typedmemmove copies a value of type t to dst from src.
// Must be nosplit, see #16026.
+//
+// TODO: Perfect for go:nosplitrec since we can't have a safe point
+// anywhere in the bulk barrier or memmove.
+//
//go:nosplit
func typedmemmove(typ *_type, dst, src unsafe.Pointer) {
if typ.kind&kindNoPointers == 0 {
@@ -265,8 +271,8 @@ func typedmemmove(typ *_type, dst, src unsafe.Pointer) {
//go:linkname reflect_typedmemmove reflect.typedmemmove
func reflect_typedmemmove(typ *_type, dst, src unsafe.Pointer) {
if raceenabled {
- raceWriteObjectPC(typ, dst, getcallerpc(unsafe.Pointer(&typ)), funcPC(reflect_typedmemmove))
- raceReadObjectPC(typ, src, getcallerpc(unsafe.Pointer(&typ)), funcPC(reflect_typedmemmove))
+ raceWriteObjectPC(typ, dst, getcallerpc(), funcPC(reflect_typedmemmove))
+ raceReadObjectPC(typ, src, getcallerpc(), funcPC(reflect_typedmemmove))
}
if msanenabled {
msanwrite(dst, typ.size)
@@ -310,8 +316,12 @@ func typedslicecopy(typ *_type, dst, src slice) int {
dstp := dst.array
srcp := src.array
+ // The compiler emits calls to typedslicecopy before
+ // instrumentation runs, so unlike the other copying and
+ // assignment operations, it's not instrumented in the calling
+ // code and needs its own instrumentation.
if raceenabled {
- callerpc := getcallerpc(unsafe.Pointer(&typ))
+ callerpc := getcallerpc()
pc := funcPC(slicecopy)
racewriterangepc(dstp, uintptr(n)*typ.size, callerpc, pc)
racereadrangepc(srcp, uintptr(n)*typ.size, callerpc, pc)
@@ -329,41 +339,13 @@ func typedslicecopy(typ *_type, dst, src slice) int {
// compiler only emits calls to typedslicecopy for types with pointers,
// and growslice and reflect_typedslicecopy check for pointers
// before calling typedslicecopy.
- if !writeBarrier.needed {
- memmove(dstp, srcp, uintptr(n)*typ.size)
- return n
+ size := uintptr(n) * typ.size
+ if writeBarrier.needed {
+ bulkBarrierPreWrite(uintptr(dstp), uintptr(srcp), size)
}
-
- systemstack(func() {
- if uintptr(srcp) < uintptr(dstp) && uintptr(srcp)+uintptr(n)*typ.size > uintptr(dstp) {
- // Overlap with src before dst.
- // Copy backward, being careful not to move dstp/srcp
- // out of the array they point into.
- dstp = add(dstp, uintptr(n-1)*typ.size)
- srcp = add(srcp, uintptr(n-1)*typ.size)
- i := 0
- for {
- typedmemmove(typ, dstp, srcp)
- if i++; i >= n {
- break
- }
- dstp = add(dstp, -typ.size)
- srcp = add(srcp, -typ.size)
- }
- } else {
- // Copy forward, being careful not to move dstp/srcp
- // out of the array they point into.
- i := 0
- for {
- typedmemmove(typ, dstp, srcp)
- if i++; i >= n {
- break
- }
- dstp = add(dstp, typ.size)
- srcp = add(srcp, typ.size)
- }
- }
- })
+ // See typedmemmove for a discussion of the race between the
+ // barrier and memmove.
+ memmove(dstp, srcp, size)
return n
}
@@ -380,7 +362,7 @@ func reflect_typedslicecopy(elemType *_type, dst, src slice) int {
size := uintptr(n) * elemType.size
if raceenabled {
- callerpc := getcallerpc(unsafe.Pointer(&elemType))
+ callerpc := getcallerpc()
pc := funcPC(reflect_typedslicecopy)
racewriterangepc(dst.array, size, callerpc, pc)
racereadrangepc(src.array, size, callerpc, pc)