internal/gclayout: make gclayout values constants

The previous versions calculated at init() prevented `interp` from running
in many cases, increasing compile times due to the increased need to revert
the partially interpreted results and also increasing binary runtime because
fewer optimizations had happened during interp.
This commit is contained in:
Damian Gryski
2025-07-08 15:20:49 -07:00
committed by Ron Evans
parent 3bb092d4d4
commit 8c5886060f
5 changed files with 25 additions and 34 deletions
+15 -24
View File
@@ -5,29 +5,20 @@ import "unsafe"
// Internal constants for gc layout
// See runtime/gc_precise.go
var (
NoPtrs unsafe.Pointer
Pointer unsafe.Pointer
String unsafe.Pointer
Slice unsafe.Pointer
type Layout uintptr
const (
// 16-bit int => bits = 4
// 32-bit int => bits = 5
// 64-bit int => bits = 6
sizeBits = 4 + unsafe.Sizeof(uintptr(0))/4
sizeShift = sizeBits + 1
NoPtrs = Layout(uintptr(0b0<<sizeShift) | uintptr(0b1<<1) | uintptr(1))
Pointer = Layout(uintptr(0b1<<sizeShift) | uintptr(0b1<<1) | uintptr(1))
String = Layout(uintptr(0b01<<sizeShift) | uintptr(0b10<<1) | uintptr(1))
Slice = Layout(uintptr(0b001<<sizeShift) | uintptr(0b11<<1) | uintptr(1))
)
func init() {
var sizeBits uintptr
switch unsafe.Sizeof(uintptr(0)) {
case 8:
sizeBits = 6
case 4:
sizeBits = 5
case 2:
sizeBits = 4
}
var sizeShift = sizeBits + 1
NoPtrs = unsafe.Pointer(uintptr(0b0<<sizeShift) | uintptr(0b1<<1) | uintptr(1))
Pointer = unsafe.Pointer(uintptr(0b1<<sizeShift) | uintptr(0b1<<1) | uintptr(1))
String = unsafe.Pointer(uintptr(0b01<<sizeShift) | uintptr(0b10<<1) | uintptr(1))
Slice = unsafe.Pointer(uintptr(0b001<<sizeShift) | uintptr(0b11<<1) | uintptr(1))
}
func (l Layout) AsPtr() unsafe.Pointer { return unsafe.Pointer(l) }
+4 -4
View File
@@ -708,16 +708,16 @@ func (r *RawType) gcLayout() unsafe.Pointer {
kind := r.Kind()
if kind < String {
return gclayout.NoPtrs
return gclayout.NoPtrs.AsPtr()
}
switch kind {
case Pointer, UnsafePointer, Chan, Map:
return gclayout.Pointer
return gclayout.Pointer.AsPtr()
case String:
return gclayout.String
return gclayout.String.AsPtr()
case Slice:
return gclayout.Slice
return gclayout.Slice.AsPtr()
}
// Unknown (for now); let the conservative pointer scanning handle it
+1 -1
View File
@@ -89,7 +89,7 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
gcLock.Lock()
needsResumeWorld = false
var ptr unsafe.Pointer
if layout == gclayout.NoPtrs {
if layout == gclayout.NoPtrs.AsPtr() {
// This object is entirely pointer free, for example make([]int, ...).
// Make sure the GC knows this so it doesn't scan the object
// unnecessarily to improve performance.
+1 -1
View File
@@ -51,7 +51,7 @@ func sliceGrow(oldBuf unsafe.Pointer, oldLen, oldCap, newCap, elemSize uintptr)
var layout unsafe.Pointer
// less type info here; can only go off element size
if elemSize < unsafe.Sizeof(uintptr(0)) {
layout = gclayout.NoPtrs
layout = gclayout.NoPtrs.AsPtr()
}
buf := alloc(newCap*elemSize, layout)
+4 -4
View File
@@ -60,7 +60,7 @@ func stringConcat(x, y _string) _string {
return x
} else {
length := x.length + y.length
buf := alloc(length, gclayout.NoPtrs)
buf := alloc(length, gclayout.NoPtrs.AsPtr())
memcpy(buf, unsafe.Pointer(x.ptr), x.length)
memcpy(unsafe.Add(buf, x.length), unsafe.Pointer(y.ptr), y.length)
return _string{ptr: (*byte)(buf), length: length}
@@ -73,7 +73,7 @@ func stringFromBytes(x struct {
len uintptr
cap uintptr
}) _string {
buf := alloc(x.len, gclayout.NoPtrs)
buf := alloc(x.len, gclayout.NoPtrs.AsPtr())
memcpy(buf, unsafe.Pointer(x.ptr), x.len)
return _string{ptr: (*byte)(buf), length: x.len}
}
@@ -84,7 +84,7 @@ func stringToBytes(x _string) (slice struct {
len uintptr
cap uintptr
}) {
buf := alloc(x.length, gclayout.NoPtrs)
buf := alloc(x.length, gclayout.NoPtrs.AsPtr())
memcpy(buf, unsafe.Pointer(x.ptr), x.length)
slice.ptr = (*byte)(buf)
slice.len = x.length
@@ -101,7 +101,7 @@ func stringFromRunes(runeSlice []rune) (s _string) {
}
// Allocate memory for the string.
s.ptr = (*byte)(alloc(s.length, gclayout.NoPtrs))
s.ptr = (*byte)(alloc(s.length, gclayout.NoPtrs.AsPtr()))
// Encode runes to UTF-8 and store the resulting bytes in the string.
index := uintptr(0)