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>
// 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.
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)
package runtime
import (
+ "internal/abi"
"internal/goexperiment"
"runtime/internal/atomic"
"unsafe"
} 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() {