malloc.mx raw

   1  // Copyright 2025 The Go Authors. All rights reserved.
   2  // Use of this source code is governed by a BSD-style
   3  // license that can be found in the LICENSE file.
   4  
   5  package gc
   6  
   7  import "internal/goarch"
   8  
   9  const (
  10  	ptrBits = 8 * goarch.PtrSize
  11  
  12  	// A malloc header is functionally a single type pointer, but
  13  	// we need to use 8 here to ensure 8-byte alignment of allocations
  14  	// on 32-bit platforms. It's wasteful, but a lot of code relies on
  15  	// 8-byte alignment for 8-byte atomics.
  16  	MallocHeaderSize = 8
  17  
  18  	// The minimum object size that has a malloc header, exclusive.
  19  	//
  20  	// The size of this value controls overheads from the malloc header.
  21  	// The minimum size is bound by writeHeapBitsSmall, which assumes that the
  22  	// pointer bitmap for objects of a size smaller than this doesn't cross
  23  	// more than one pointer-word boundary. This sets an upper-bound on this
  24  	// value at the number of bits in a uintptr, multiplied by the pointer
  25  	// size in bytes.
  26  	//
  27  	// We choose a value here that has a natural cutover point in terms of memory
  28  	// overheads. This value just happens to be the maximum possible value this
  29  	// can be.
  30  	//
  31  	// A span with heap bits in it will have 128 bytes of heap bits on 64-bit
  32  	// platforms, and 256 bytes of heap bits on 32-bit platforms. The first size
  33  	// class where malloc headers match this overhead for 64-bit platforms is
  34  	// 512 bytes (8 KiB / 512 bytes * 8 bytes-per-header = 128 bytes of overhead).
  35  	// On 32-bit platforms, this same point is the 256 byte size class
  36  	// (8 KiB / 256 bytes * 8 bytes-per-header = 256 bytes of overhead).
  37  	//
  38  	// Guaranteed to be exactly at a size class boundary. The reason this value is
  39  	// an exclusive minimum is subtle. Suppose we're allocating a 504-byte object
  40  	// and its rounded up to 512 bytes for the size class. If minSizeForMallocHeader
  41  	// is 512 and an inclusive minimum, then a comparison against minSizeForMallocHeader
  42  	// by the two values would produce different results. In other words, the comparison
  43  	// would not be invariant to size-class rounding. Eschewing this property means a
  44  	// more complex check or possibly storing additional state to determine whether a
  45  	// span has malloc headers.
  46  	MinSizeForMallocHeader = goarch.PtrSize * ptrBits
  47  
  48  	// PageSize is the increment in which spans are managed.
  49  	PageSize = 1 << PageShift
  50  )
  51