compiler: add //go:noheap pragma

This commit is contained in:
Ayke van Laethem
2026-05-20 11:01:50 +02:00
committed by Ayke
parent 7b486e398a
commit 85d223c5e2
12 changed files with 135 additions and 10 deletions
+69
View File
@@ -0,0 +1,69 @@
package main
//go:noheap
func main() {
// This object is optimized away, and won't cause a linker failure.
var a int
add(&a)
// This object is not optimized away since its address is captured.
var b int
escape(&b)
// A simple defer won't cause a heap allocation.
defer func() {
println("once")
}()
// A defer in a loop does causes a heap allocation.
for range 3 {
defer func() {
println("many")
}()
}
// This slice should not be heap-allocated.
s1 := make([]int, 5)
sum(s1)
// But this slice is.
s2 := make([]int, 5)
escape(&s2[0])
// Allocated at compile time as a global, so won't escape at runtime.
escape(globalInt)
}
func add(n *int) {
*n++
}
func sum(slice []int) (result int) {
for n := range slice {
result += n
}
return result
}
var globalInt = globalNewInt()
var globalAssign *int
//go:noheap
func globalNewInt() *int {
return new(int)
}
func escape(n *int) {
// Do some stuff that will definitely force a heap allocation.
// (This might be optimized in the future, in which case we need to change
// the function again).
n2 := func(n *int) *int {
return n
}(n)
println(n2)
}
// ERROR: noheap.go:10: object allocated on the heap in //go:noheap function
// ERROR: noheap.go:20: object allocated on the heap in //go:noheap function
// ERROR: noheap.go:30: object allocated on the heap in //go:noheap function