]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: ensure we free unrolled GC bitmaps
authorKeith Randall <khr@golang.org>
Thu, 11 Jan 2024 20:52:16 +0000 (12:52 -0800)
committerGopher Robot <gobot@golang.org>
Thu, 11 Jan 2024 21:16:56 +0000 (21:16 +0000)
CL 555355 has a bug in it - the GC program flag was also used to decide
when to free the unrolled bitmap. After that CL, we just don't free any
unrolled bitmaps, leading to a memory leak.

Use a separate flag to track types that need to be freed when their
corresponding object is freed.

Change-Id: I841b65492561f5b5e1853875fbd8e8a872205a84
Reviewed-on: https://go-review.googlesource.com/c/go/+/555416
Auto-Submit: Keith Randall <khr@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/internal/abi/type.go
src/runtime/mbitmap_allocheaders.go
src/runtime/mgcsweep.go

index 86f055cb917696681b346ced25224f8ae7d1e189..659fb7bffd32e9df57e773c252effc57e4fe73b5 100644 (file)
@@ -111,6 +111,12 @@ const (
        // TFlagRegularMemory means that equal and hash functions can treat
        // this type as a single region of t.size bytes.
        TFlagRegularMemory TFlag = 1 << 3
+
+       // TFlagUnrolledBitmap marks special types that are unrolled-bitmap
+       // versions of types with GC programs.
+       // These types need to be deallocated when the underlying object
+       // is freed.
+       TFlagUnrolledBitmap TFlag = 1 << 4
 )
 
 // NameOff is the offset to a name from moduledata.types.  See resolveNameOff in runtime.
index bc574ad68943efe1fb9799dedae12ce6e75e40bf..1ec055352e788b2974fc48c35b0e7506644956f3 100644 (file)
@@ -886,6 +886,7 @@ func heapSetType(x, dataSize uintptr, typ *_type, header **_type, span *mspan) (
                        gctyp.Size_ = typ.Size_
                        gctyp.PtrBytes = typ.PtrBytes
                        gctyp.GCData = (*byte)(add(unsafe.Pointer(progSpan.base()), heapBitsOff))
+                       gctyp.TFlag = abi.TFlagUnrolledBitmap
 
                        // Expand the GC program into space reserved at the end of the new span.
                        runGCProg(addb(typ.GCData, 4), gctyp.GCData)
index 0fbb23d57399b5c2cb9038b43df130ee3a38b392..3dbe9bcec72fb16b62e980cc5043f1b32426eb8d 100644 (file)
@@ -25,6 +25,7 @@
 package runtime
 
 import (
+       "internal/abi"
        "internal/goexperiment"
        "runtime/internal/atomic"
        "unsafe"
@@ -789,7 +790,7 @@ func (sl *sweepLocked) sweep(preserve bool) bool {
                        } else {
                                mheap_.freeSpan(s)
                        }
-                       if goexperiment.AllocHeaders && s.largeType != nil && s.largeType.Kind_&kindGCProg != 0 {
+                       if goexperiment.AllocHeaders && s.largeType != nil && s.largeType.TFlag&abi.TFlagUnrolledBitmap != 0 {
                                // In the allocheaders experiment, the unrolled GCProg bitmap is allocated separately.
                                // Free the space for the unrolled bitmap.
                                systemstack(func() {