diff options
| author | Michael Anthony Knyszek <mknyszek@google.com> | 2024-04-09 03:41:06 +0000 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2024-04-09 04:07:57 +0000 |
| commit | 9f3f4c64dbfd37ef9f7113708a706a8099d72fd9 (patch) | |
| tree | 05048ee9895b3a6866c86f128ef3a6b84a54d493 /src/runtime/export_test.go | |
| parent | 9f13665088012298146c573bc2a7255b1caf2750 (diff) | |
| download | go-9f3f4c64dbfd37ef9f7113708a706a8099d72fd9.tar.xz | |
runtime: remove the allocheaders GOEXPERIMENT
This change removes the allocheaders, deleting all the old code and
merging mbitmap_allocheaders.go back into mbitmap.go.
This change also deletes the SetType benchmarks which were already
broken in the new GOEXPERIMENT (it's harder to set up than before). We
weren't really watching these benchmarks at all, and they don't provide
additional test coverage.
Change-Id: I135497201c3259087c5cd3722ed3fbe24791d25d
Reviewed-on: https://go-review.googlesource.com/c/go/+/567200
Reviewed-by: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/runtime/export_test.go')
| -rw-r--r-- | src/runtime/export_test.go | 133 |
1 files changed, 0 insertions, 133 deletions
diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go index 1ec45b8cc0..26325b3712 100644 --- a/src/runtime/export_test.go +++ b/src/runtime/export_test.go @@ -9,7 +9,6 @@ package runtime import ( "internal/abi" "internal/goarch" - "internal/goexperiment" "internal/goos" "internal/runtime/atomic" "runtime/internal/sys" @@ -239,138 +238,6 @@ var Write = write func Envs() []string { return envs } func SetEnvs(e []string) { envs = e } -// For benchmarking. - -// blockWrapper is a wrapper type that ensures a T is placed within a -// large object. This is necessary for safely benchmarking things -// that manipulate the heap bitmap, like heapBitsSetType. -// -// More specifically, allocating threads assume they're the sole writers -// to their span's heap bits, which allows those writes to be non-atomic. -// The heap bitmap is written byte-wise, so if one tried to call heapBitsSetType -// on an existing object in a small object span, we might corrupt that -// span's bitmap with a concurrent byte write to the heap bitmap. Large -// object spans contain exactly one object, so we can be sure no other P -// is going to be allocating from it concurrently, hence this wrapper type -// which ensures we have a T in a large object span. -type blockWrapper[T any] struct { - value T - _ [_MaxSmallSize]byte // Ensure we're a large object. -} - -func BenchSetType[T any](n int, resetTimer func()) { - x := new(blockWrapper[T]) - - // Escape x to ensure it is allocated on the heap, as we are - // working on the heap bits here. - Escape(x) - - // Grab the type. - var i any = *new(T) - e := *efaceOf(&i) - t := e._type - - // Benchmark setting the type bits for just the internal T of the block. - benchSetType(n, resetTimer, 1, unsafe.Pointer(&x.value), t) -} - -const maxArrayBlockWrapperLen = 32 - -// arrayBlockWrapper is like blockWrapper, but the interior value is intended -// to be used as a backing store for a slice. -type arrayBlockWrapper[T any] struct { - value [maxArrayBlockWrapperLen]T - _ [_MaxSmallSize]byte // Ensure we're a large object. -} - -// arrayLargeBlockWrapper is like arrayBlockWrapper, but the interior array -// accommodates many more elements. -type arrayLargeBlockWrapper[T any] struct { - value [1024]T - _ [_MaxSmallSize]byte // Ensure we're a large object. -} - -func BenchSetTypeSlice[T any](n int, resetTimer func(), len int) { - // We have two separate cases here because we want to avoid - // tests on big types but relatively small slices to avoid generating - // an allocation that's really big. This will likely force a GC which will - // skew the test results. - var y unsafe.Pointer - if len <= maxArrayBlockWrapperLen { - x := new(arrayBlockWrapper[T]) - // Escape x to ensure it is allocated on the heap, as we are - // working on the heap bits here. - Escape(x) - y = unsafe.Pointer(&x.value[0]) - } else { - x := new(arrayLargeBlockWrapper[T]) - Escape(x) - y = unsafe.Pointer(&x.value[0]) - } - - // Grab the type. - var i any = *new(T) - e := *efaceOf(&i) - t := e._type - - // Benchmark setting the type for a slice created from the array - // of T within the arrayBlock. - benchSetType(n, resetTimer, len, y, t) -} - -// benchSetType is the implementation of the BenchSetType* functions. -// x must be len consecutive Ts allocated within a large object span (to -// avoid a race on the heap bitmap). -// -// Note: this function cannot be generic. It would get its type from one of -// its callers (BenchSetType or BenchSetTypeSlice) whose type parameters are -// set by a call in the runtime_test package. That means this function and its -// callers will get instantiated in the package that provides the type argument, -// i.e. runtime_test. However, we call a function on the system stack. In race -// mode the runtime package is usually left uninstrumented because e.g. g0 has -// no valid racectx, but if we're instantiated in the runtime_test package, -// we might accidentally cause runtime code to be incorrectly instrumented. -func benchSetType(n int, resetTimer func(), len int, x unsafe.Pointer, t *_type) { - // This benchmark doesn't work with the allocheaders experiment. It sets up - // an elaborate scenario to be able to benchmark the function safely, but doing - // this work for the allocheaders' version of the function would be complex. - // Just fail instead and rely on the test code making sure we never get here. - if goexperiment.AllocHeaders { - panic("called benchSetType with allocheaders experiment enabled") - } - - // Compute the input sizes. - size := t.Size() * uintptr(len) - - // Validate this function's invariant. - s := spanOfHeap(uintptr(x)) - if s == nil { - panic("no heap span for input") - } - if s.spanclass.sizeclass() != 0 { - panic("span is not a large object span") - } - - // Round up the size to the size class to make the benchmark a little more - // realistic. However, validate it, to make sure this is safe. - allocSize := roundupsize(size, !t.Pointers()) - if s.npages*pageSize < allocSize { - panic("backing span not large enough for benchmark") - } - - // Benchmark heapBitsSetType by calling it in a loop. This is safe because - // x is in a large object span. - resetTimer() - systemstack(func() { - for i := 0; i < n; i++ { - heapBitsSetType(uintptr(x), allocSize, size, t) - } - }) - - // Make sure x doesn't get freed, since we're taking a uintptr. - KeepAlive(x) -} - const PtrSize = goarch.PtrSize var ForceGCPeriod = &forcegcperiod |
