Source file src/internal/runtime/gc/scan/expand_reference.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 scan 6 7 import ( 8 "internal/goarch" 9 "internal/runtime/gc" 10 ) 11 12 // ExpandReference is a reference implementation of an expander function 13 // that translates object mark bits into a bitmap of one bit per word of 14 // marked object, assuming the object is of the provided size class. 15 func ExpandReference(sizeClass int, packed *gc.ObjMask, unpacked *gc.PtrMask) { 16 // Look up the size and derive the number of objects in a span. 17 // We're only concerned with small objects in single-page spans, 18 // and gc.PtrMask enforces this by being statically sized to 19 // accomodate only such spans. 20 size := uintptr(gc.SizeClassToSize[sizeClass]) 21 nObj := uintptr(gc.SizeClassToNPages[sizeClass]) * gc.PageSize / size 22 23 // f is the expansion factor. For example, if our objects are of size 48, 24 // then each mark bit will translate into 6 (48/8 = 6) set bits in the 25 // pointer bitmap. 26 f := size / goarch.PtrSize 27 for i := range nObj { 28 // Check if the object is marked. 29 if packed[i/goarch.PtrBits]&(uintptr(1)<<(i%goarch.PtrBits)) == 0 { 30 continue 31 } 32 // Propagate that mark into the destination into one bit per the 33 // expansion factor f, offset to the object's offset within the span. 34 for j := range f { 35 b := i*f + j // i*f is the start bit for the object, j indexes into each corresponding word after. 36 unpacked[b/goarch.PtrBits] |= uintptr(1) << (b % goarch.PtrBits) 37 } 38 } 39 } 40