return
}
if typ.ptrdata != 0 {
- bulkBarrierPreWrite(uintptr(dst), uintptr(src), typ.size)
+ bulkBarrierPreWrite(uintptr(dst), uintptr(src), typ.ptrdata)
}
// There's a race here: if some other goroutine can write to
// src, it may change some pointer in src after we've
if writeBarrier.needed && typ.ptrdata != 0 && size >= sys.PtrSize {
// Pointer-align start address for bulk barrier.
adst, asrc, asize := dst, src, size
+ ptrdata := typ.ptrdata
+ if ptrdata > off {
+ ptrdata -= off
+ } else {
+ ptrdata = 0
+ }
if frag := -off & (sys.PtrSize - 1); frag != 0 {
adst = add(dst, frag)
asrc = add(src, frag)
asize -= frag
+ if ptrdata > frag {
+ ptrdata -= frag
+ } else {
+ ptrdata = 0
+ }
+ }
+ pwsize := asize &^ (sys.PtrSize - 1)
+ if pwsize > ptrdata {
+ pwsize = ptrdata
}
- bulkBarrierPreWrite(uintptr(adst), uintptr(asrc), asize&^(sys.PtrSize-1))
+ bulkBarrierPreWrite(uintptr(adst), uintptr(asrc), pwsize)
}
memmove(dst, src, size)
// before calling typedslicecopy.
size := uintptr(n) * typ.size
if writeBarrier.needed {
- bulkBarrierPreWrite(uintptr(dstp), uintptr(srcp), size)
+ pwsize := size - typ.size + typ.ptrdata
+ bulkBarrierPreWrite(uintptr(dstp), uintptr(srcp), pwsize)
}
// See typedmemmove for a discussion of the race between the
// barrier and memmove.
//go:nosplit
func typedmemclr(typ *_type, ptr unsafe.Pointer) {
if typ.ptrdata != 0 {
- bulkBarrierPreWrite(uintptr(ptr), 0, typ.size)
+ bulkBarrierPreWrite(uintptr(ptr), 0, typ.ptrdata)
}
memclrNoHeapPointers(ptr, typ.size)
}
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(old.array), lenmem)
+ bulkBarrierPreWriteSrcOnly(uintptr(p), uintptr(old.array), lenmem-et.size+et.ptrdata)
}
}
memmove(p, old.array, lenmem)