mirror of
https://github.com/golang/go
synced 2024-11-19 14:04:46 -07:00
runtime: only clear pointer-containing memory during map delete
When deleting entries from a map, only clear the key and value if they contain pointers. And use memclrHasPointers to do so. While we're here, specialize key clearing in mapdelete_faststr, and fix another missed usage of add in mapdelete. Benchmarking impeded by #21546. Change-Id: I3f6f924f738d6b899b722d6438e9e63f52359b84 Reviewed-on: https://go-review.googlesource.com/57630 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
29e6bdc69c
commit
0c7fd56951
@ -681,16 +681,20 @@ func mapdelete(t *maptype, h *hmap, key unsafe.Pointer) {
|
||||
if !alg.equal(key, k2) {
|
||||
continue
|
||||
}
|
||||
// Only clear key if there are pointers in it.
|
||||
if t.indirectkey {
|
||||
*(*unsafe.Pointer)(k) = nil
|
||||
} else {
|
||||
typedmemclr(t.key, k)
|
||||
} else if t.key.kind&kindNoPointers == 0 {
|
||||
memclrHasPointers(k, t.key.size)
|
||||
}
|
||||
v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*uintptr(t.keysize) + i*uintptr(t.valuesize))
|
||||
if t.indirectvalue {
|
||||
*(*unsafe.Pointer)(v) = nil
|
||||
} else {
|
||||
typedmemclr(t.elem, v)
|
||||
// Only clear value if there are pointers in it.
|
||||
if t.indirectvalue || t.elem.kind&kindNoPointers == 0 {
|
||||
v := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.valuesize))
|
||||
if t.indirectvalue {
|
||||
*(*unsafe.Pointer)(v) = nil
|
||||
} else {
|
||||
memclrHasPointers(v, t.elem.size)
|
||||
}
|
||||
}
|
||||
b.tophash[i] = empty
|
||||
h.count--
|
||||
|
@ -652,9 +652,15 @@ func mapdelete_fast32(t *maptype, h *hmap, key uint32) {
|
||||
if key != *(*uint32)(k) || b.tophash[i] == empty {
|
||||
continue
|
||||
}
|
||||
typedmemclr(t.key, unsafe.Pointer(k))
|
||||
v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*4 + i*uintptr(t.valuesize))
|
||||
typedmemclr(t.elem, v)
|
||||
// Only clear key if there are pointers in it.
|
||||
if t.key.kind&kindNoPointers == 0 {
|
||||
memclrHasPointers(k, t.key.size)
|
||||
}
|
||||
// Only clear value if there are pointers in it.
|
||||
if t.elem.kind&kindNoPointers == 0 {
|
||||
v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*4 + i*uintptr(t.valuesize))
|
||||
memclrHasPointers(v, t.elem.size)
|
||||
}
|
||||
b.tophash[i] = empty
|
||||
h.count--
|
||||
goto done
|
||||
@ -699,9 +705,15 @@ func mapdelete_fast64(t *maptype, h *hmap, key uint64) {
|
||||
if key != *(*uint64)(k) || b.tophash[i] == empty {
|
||||
continue
|
||||
}
|
||||
typedmemclr(t.key, unsafe.Pointer(k))
|
||||
v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*8 + i*uintptr(t.valuesize))
|
||||
typedmemclr(t.elem, v)
|
||||
// Only clear key if there are pointers in it.
|
||||
if t.key.kind&kindNoPointers == 0 {
|
||||
memclrHasPointers(k, t.key.size)
|
||||
}
|
||||
// Only clear value if there are pointers in it.
|
||||
if t.elem.kind&kindNoPointers == 0 {
|
||||
v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*8 + i*uintptr(t.valuesize))
|
||||
memclrHasPointers(v, t.elem.size)
|
||||
}
|
||||
b.tophash[i] = empty
|
||||
h.count--
|
||||
goto done
|
||||
@ -752,9 +764,12 @@ func mapdelete_faststr(t *maptype, h *hmap, ky string) {
|
||||
if k.str != key.str && !memequal(k.str, key.str, uintptr(key.len)) {
|
||||
continue
|
||||
}
|
||||
typedmemclr(t.key, unsafe.Pointer(k))
|
||||
v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*2*sys.PtrSize + i*uintptr(t.valuesize))
|
||||
typedmemclr(t.elem, v)
|
||||
*(*string)(kptr) = ""
|
||||
// Only clear value if there are pointers in it.
|
||||
if t.elem.kind&kindNoPointers == 0 {
|
||||
v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*2*sys.PtrSize + i*uintptr(t.valuesize))
|
||||
memclrHasPointers(v, t.elem.size)
|
||||
}
|
||||
b.tophash[i] = empty
|
||||
h.count--
|
||||
goto done
|
||||
|
Loading…
Reference in New Issue
Block a user