internal/gocore: fix pointer locations for small objects in green tea The tests are currently broken when GOEXPERIMENT=greenteagc because that shifted where the pointer/scalar bits are located for small objects a little bit. This change modifies gocore to look in the right place and detect if GOEXPERIMENT=greenteagc is enabled (and if we're using Green Tea in general, if/when it becomes the default). This was not caught by the builders because we don't have an x/debug builder that sets the GOEXPERIMENT. Change-Id: I746ce601ebc12738920616889200f23642f7280f Reviewed-on: https://go-review.googlesource.com/c/debug/+/699975 Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Nicolas Hillegeer <aktau@google.com> Commit-Queue: Nicolas Hillegeer <aktau@google.com>
diff --git a/internal/gocore/process.go b/internal/gocore/process.go index e01480e..03606b9 100644 --- a/internal/gocore/process.go +++ b/internal/gocore/process.go
@@ -362,6 +362,9 @@ spanManual := uint8(p.rtConsts.get("runtime.mSpanManual")) spanDead := uint8(p.rtConsts.get("runtime.mSpanDead")) + // Green Tea GC. + spanInlineMarkBitsTyp := p.rtTypeByName["runtime.spanInlineMarkBits"] + // Malloc header constants (go 1.22+) minSizeForMallocHeader := int64(p.rtConsts.get("runtime.minSizeForMallocHeader")) mallocHeaderSize := int64(p.rtConsts.get("runtime.mallocHeaderSize")) @@ -474,7 +477,16 @@ if elemSize <= minSizeForMallocHeader { // Heap bits in span. bitmapSize := spanSize / int64(heap.ptrSize) / 8 - bitmapAddr := min.Add(spanSize - bitmapSize) + markBitsSize := int64(0) + if spanInlineMarkBitsTyp != nil && elemSize >= 16 { + // Green Tea GC only: we store the mark bits inline + // in the span for small objects >= 16 bytes in size. + markBitsSize = spanInlineMarkBitsTyp.Size + } + objectsSize := spanSize - (bitmapSize + markBitsSize) + + // Span layout: [objects][heapbits][markbits] (mark bits with Green Tea GC only) + bitmapAddr := min.Add(objectsSize) for i := int64(0); i < bitmapSize; i++ { bits := p.proc.ReadUint8(bitmapAddr.Add(int64(i))) for j := int64(0); j < 8; j++ {