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