aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/export_test.go
diff options
context:
space:
mode:
authorMichael Anthony Knyszek <mknyszek@google.com>2020-09-16 16:22:28 +0000
committerMichael Knyszek <mknyszek@google.com>2020-09-16 17:07:38 +0000
commit2ae2a94857cb17a98a86a8332d6f76863982bf59 (patch)
treed9cc778fe5ef08e0b20391d52fce199e4d674b80 /src/runtime/export_test.go
parent37aa65357007411d121fbdbaa5a340aba21ab40a (diff)
downloadgo-2ae2a94857cb17a98a86a8332d6f76863982bf59.tar.gz
go-2ae2a94857cb17a98a86a8332d6f76863982bf59.zip
runtime: fix leak and locking in BenchmarkMSpanCountAlloc
CL 249917 made the mspan in MSpanCountAlloc no longer stack-allocated (for good reason), but then allocated an mspan on each call and did not free it, resulting in a leak. That allocation was also not protected by the heap lock, which could lead to data corruption of mheap fields and the spanalloc. To fix this, export some functions to allocate/free dummy mspans from spanalloc (with proper locking) and allocate just one up-front for the benchmark, freeing it at the end. Then, update MSpanCountAlloc to accept a dummy mspan. Note that we need to allocate the dummy mspan up-front otherwise we measure things like heap locking and fixalloc performance instead of what we actually want to measure: how fast we can do a popcount on the mark bits. Fixes #41391. Change-Id: If6629a6ec1ece639c7fb78532045837a8c872c04 Reviewed-on: https://go-review.googlesource.com/c/go/+/255297 Run-TryBot: Michael Knyszek <mknyszek@google.com> Reviewed-by: Keith Randall <khr@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Trust: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/runtime/export_test.go')
-rw-r--r--src/runtime/export_test.go28
1 files changed, 25 insertions, 3 deletions
diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go
index 929bb35db6..e3d6441c18 100644
--- a/src/runtime/export_test.go
+++ b/src/runtime/export_test.go
@@ -983,9 +983,31 @@ func MapHashCheck(m interface{}, k interface{}) (uintptr, uintptr) {
return x, y
}
-func MSpanCountAlloc(bits []byte) int {
- s := (*mspan)(mheap_.spanalloc.alloc())
+// mspan wrapper for testing.
+//go:notinheap
+type MSpan mspan
+
+// Allocate an mspan for testing.
+func AllocMSpan() *MSpan {
+ var s *mspan
+ systemstack(func() {
+ s = (*mspan)(mheap_.spanalloc.alloc())
+ })
+ return (*MSpan)(s)
+}
+
+// Free an allocated mspan.
+func FreeMSpan(s *MSpan) {
+ systemstack(func() {
+ mheap_.spanalloc.free(unsafe.Pointer(s))
+ })
+}
+
+func MSpanCountAlloc(ms *MSpan, bits []byte) int {
+ s := (*mspan)(ms)
s.nelems = uintptr(len(bits) * 8)
s.gcmarkBits = (*gcBits)(unsafe.Pointer(&bits[0]))
- return s.countAlloc()
+ result := s.countAlloc()
+ s.gcmarkBits = nil
+ return result
}