From 56fb8350c835d1ccf0e6cdb8f753c85e2e0748a8 Mon Sep 17 00:00:00 2001 From: Michael Anthony Knyszek Date: Wed, 18 Sep 2024 01:58:50 +0000 Subject: runtime: don't call span.heapBits in writeHeapBitsSmall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For whatever reason, span.heapBits is kind of slow. It accounts for about a quarter of the cost of writeHeapBitsSmall, which is absurd. We get a nice speed improvement for small allocations by eliminating this call. │ before │ after │ │ sec/op │ sec/op vs base │ MallocTypeInfo16-4 29.47n ± 1% 27.02n ± 1% -8.31% (p=0.002 n=6) Change-Id: I6270e26902e5a9254cf1503fac81c3c799c59d6a Reviewed-on: https://go-review.googlesource.com/c/go/+/614255 Reviewed-by: Keith Randall LUCI-TryBot-Result: Go LUCI Reviewed-by: Keith Randall Auto-Submit: Michael Knyszek --- src/runtime/malloc.go | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/runtime/malloc.go') diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go index 7076ced453..71dda120d4 100644 --- a/src/runtime/malloc.go +++ b/src/runtime/malloc.go @@ -427,8 +427,15 @@ func mallocinit() { // Check that the minimum size (exclusive) for a malloc header is also // a size class boundary. This is important to making sure checks align // across different parts of the runtime. + // + // While we're here, also check to make sure all these size classes' + // span sizes are one page. Some code relies on this. minSizeForMallocHeaderIsSizeClass := false + sizeClassesUpToMinSizeForMallocHeaderAreOnePage := true for i := 0; i < len(class_to_size); i++ { + if class_to_allocnpages[i] > 1 { + sizeClassesUpToMinSizeForMallocHeaderAreOnePage = false + } if minSizeForMallocHeader == uintptr(class_to_size[i]) { minSizeForMallocHeaderIsSizeClass = true break @@ -437,6 +444,9 @@ func mallocinit() { if !minSizeForMallocHeaderIsSizeClass { throw("min size of malloc header is not a size class boundary") } + if !sizeClassesUpToMinSizeForMallocHeaderAreOnePage { + throw("expected all size classes up to min size for malloc header to fit in one-page spans") + } // Check that the pointer bitmap for all small sizes without a malloc header // fits in a word. if minSizeForMallocHeader/goarch.PtrSize > 8*goarch.PtrSize { -- cgit v1.3-5-g9baa