cmd/compile, runtime: stop returning t.zero on hashmap miss
Previously t.zero always pointed to runtime.zerovalue. Change the hashmap code
to always return a runtime pointer directly, and change that pointer to point
to a larger buffer if one is needed.
(It might be better to only copy from the pointer returned by the mapaccess
functions when the value type is small enough and have the compiler insert
explicit zeroing for larger value types, but I tried and failed to do this).
This removes all uses of the zero field of the type data; the field itself can
be removed in a separate change.
Fixes #11491
Change-Id: I5b81752ff4067d74a5a281c41e88f151bae0171e
Reviewed-on: https://go-review.googlesource.com/13784
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/src/runtime/hashmap_fast.go b/src/runtime/hashmap_fast.go
index 02c51a2..f9d7846 100644
--- a/src/runtime/hashmap_fast.go
+++ b/src/runtime/hashmap_fast.go
@@ -14,7 +14,7 @@
racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess1_fast32))
}
if h == nil || h.count == 0 {
- return unsafe.Pointer(t.elem.zero)
+ return atomicloadp(unsafe.Pointer(&zeroptr))
}
var b *bmap
if h.B == 0 {
@@ -45,7 +45,7 @@
}
b = b.overflow(t)
if b == nil {
- return unsafe.Pointer(t.elem.zero)
+ return atomicloadp(unsafe.Pointer(&zeroptr))
}
}
}
@@ -56,7 +56,7 @@
racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess2_fast32))
}
if h == nil || h.count == 0 {
- return unsafe.Pointer(t.elem.zero), false
+ return atomicloadp(unsafe.Pointer(&zeroptr)), false
}
var b *bmap
if h.B == 0 {
@@ -87,7 +87,7 @@
}
b = b.overflow(t)
if b == nil {
- return unsafe.Pointer(t.elem.zero), false
+ return atomicloadp(unsafe.Pointer(&zeroptr)), false
}
}
}
@@ -98,7 +98,7 @@
racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess1_fast64))
}
if h == nil || h.count == 0 {
- return unsafe.Pointer(t.elem.zero)
+ return atomicloadp(unsafe.Pointer(&zeroptr))
}
var b *bmap
if h.B == 0 {
@@ -129,7 +129,7 @@
}
b = b.overflow(t)
if b == nil {
- return unsafe.Pointer(t.elem.zero)
+ return atomicloadp(unsafe.Pointer(&zeroptr))
}
}
}
@@ -140,7 +140,7 @@
racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess2_fast64))
}
if h == nil || h.count == 0 {
- return unsafe.Pointer(t.elem.zero), false
+ return atomicloadp(unsafe.Pointer(&zeroptr)), false
}
var b *bmap
if h.B == 0 {
@@ -171,7 +171,7 @@
}
b = b.overflow(t)
if b == nil {
- return unsafe.Pointer(t.elem.zero), false
+ return atomicloadp(unsafe.Pointer(&zeroptr)), false
}
}
}
@@ -182,7 +182,7 @@
racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess1_faststr))
}
if h == nil || h.count == 0 {
- return unsafe.Pointer(t.elem.zero)
+ return atomicloadp(unsafe.Pointer(&zeroptr))
}
key := (*stringStruct)(unsafe.Pointer(&ky))
if h.B == 0 {
@@ -203,7 +203,7 @@
return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+i*uintptr(t.valuesize))
}
}
- return unsafe.Pointer(t.elem.zero)
+ return atomicloadp(unsafe.Pointer(&zeroptr))
}
// long key, try not to do more comparisons than necessary
keymaybe := uintptr(bucketCnt)
@@ -241,7 +241,7 @@
return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+keymaybe*uintptr(t.valuesize))
}
}
- return unsafe.Pointer(t.elem.zero)
+ return atomicloadp(unsafe.Pointer(&zeroptr))
}
dohash:
hash := t.key.alg.hash(noescape(unsafe.Pointer(&ky)), uintptr(h.hash0))
@@ -273,7 +273,7 @@
}
b = b.overflow(t)
if b == nil {
- return unsafe.Pointer(t.elem.zero)
+ return atomicloadp(unsafe.Pointer(&zeroptr))
}
}
}
@@ -284,7 +284,7 @@
racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess2_faststr))
}
if h == nil || h.count == 0 {
- return unsafe.Pointer(t.elem.zero), false
+ return atomicloadp(unsafe.Pointer(&zeroptr)), false
}
key := (*stringStruct)(unsafe.Pointer(&ky))
if h.B == 0 {
@@ -305,7 +305,7 @@
return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+i*uintptr(t.valuesize)), true
}
}
- return unsafe.Pointer(t.elem.zero), false
+ return atomicloadp(unsafe.Pointer(&zeroptr)), false
}
// long key, try not to do more comparisons than necessary
keymaybe := uintptr(bucketCnt)
@@ -341,7 +341,7 @@
return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+keymaybe*uintptr(t.valuesize)), true
}
}
- return unsafe.Pointer(t.elem.zero), false
+ return atomicloadp(unsafe.Pointer(&zeroptr)), false
}
dohash:
hash := t.key.alg.hash(noescape(unsafe.Pointer(&ky)), uintptr(h.hash0))
@@ -373,7 +373,7 @@
}
b = b.overflow(t)
if b == nil {
- return unsafe.Pointer(t.elem.zero), false
+ return atomicloadp(unsafe.Pointer(&zeroptr)), false
}
}
}