aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/mfinal.go
diff options
context:
space:
mode:
authorMichael Anthony Knyszek <mknyszek@google.com>2023-11-16 17:42:25 +0000
committerGopher Robot <gobot@golang.org>2023-11-17 22:55:27 +0000
commit0ef169abb1db6bd4e184ee87204dd883fb20cf1c (patch)
tree06b109bb21074b3ae28d6963cf4ccc06ddfb156c /src/runtime/mfinal.go
parent0b90c7d4453bb21ec3ad4d6c5a3eebf398a89e77 (diff)
downloadgo-0ef169abb1db6bd4e184ee87204dd883fb20cf1c.tar.xz
runtime: put allocation headers back at the start the object
A persistent performance regression was discovered on perf.golang.org/dashboard and this was narrowed down to the switch to footers. Using allocation headers instead resolves the issue. The benchmark results for allocation footers weren't realistic, because they were performed on a machine with enough L3 cache that it completely hid the additional cache miss introduced by allocation footers. This means that in some corner cases the Go runtime may no longer allocate 16-byte aligned memory. Note however that this property was *mostly* incidental and never guaranteed in any documentation. Allocation headers were tested widely within Google and no issues were found, so we're fairly confident that this will not affect very many users. Nonetheless, by Hyrum's Law some code might depend on it. A follow-up change will add a GODEBUG flag that ensures 16 byte alignment at the potential cost of some additional memory use. Users experiencing both a performance regression and an alignment issue can also disable the GOEXPERIMENT at build time. This reverts commit 1e250a219900651dad27f29eab0877eee4afd5b9. Change-Id: Ia7d62a9c60d1773c8b6d33322ee33a80ef814943 Reviewed-on: https://go-review.googlesource.com/c/go/+/543255 Auto-Submit: Michael Knyszek <mknyszek@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/runtime/mfinal.go')
-rw-r--r--src/runtime/mfinal.go8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/runtime/mfinal.go b/src/runtime/mfinal.go
index 18cd93e77e..be501e6fca 100644
--- a/src/runtime/mfinal.go
+++ b/src/runtime/mfinal.go
@@ -9,6 +9,7 @@ package runtime
import (
"internal/abi"
"internal/goarch"
+ "internal/goexperiment"
"runtime/internal/atomic"
"runtime/internal/sys"
"unsafe"
@@ -410,7 +411,7 @@ func SetFinalizer(obj any, finalizer any) {
}
// find the containing object
- base, _, _ := findObject(uintptr(e.data), 0, 0)
+ base, span, _ := findObject(uintptr(e.data), 0, 0)
if base == 0 {
if isGoPointerWithoutSpan(e.data) {
@@ -419,6 +420,11 @@ func SetFinalizer(obj any, finalizer any) {
throw("runtime.SetFinalizer: pointer not in allocated block")
}
+ // Move base forward if we've got an allocation header.
+ if goexperiment.AllocHeaders && !span.spanclass.noscan() && !heapBitsInSpan(span.elemsize) && span.spanclass.sizeclass() != 0 {
+ base += mallocHeaderSize
+ }
+
if uintptr(e.data) != base {
// As an implementation detail we allow to set finalizers for an inner byte
// of an object if it could come from tiny alloc (see mallocgc for details).