summaryrefslogtreecommitdiff
path: root/abi/escape.go
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2025-03-19 04:40:49 -0500
committerJeff Carr <[email protected]>2025-03-19 04:40:49 -0500
commit17119d9298e132aa309f1cc95e439f29f61214b0 (patch)
tree578abd95ba2cfe0cdcec3f6e51d609ccb9e2f36b /abi/escape.go
day1v0.0.1
Diffstat (limited to 'abi/escape.go')
-rw-r--r--abi/escape.go33
1 files changed, 33 insertions, 0 deletions
diff --git a/abi/escape.go b/abi/escape.go
new file mode 100644
index 0000000..8cdae14
--- /dev/null
+++ b/abi/escape.go
@@ -0,0 +1,33 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package abi
+
+import "unsafe"
+
+// NoEscape hides the pointer p from escape analysis, preventing it
+// from escaping to the heap. It compiles down to nothing.
+//
+// WARNING: This is very subtle to use correctly. The caller must
+// ensure that it's truly safe for p to not escape to the heap by
+// maintaining runtime pointer invariants (for example, that globals
+// and the heap may not generally point into a stack).
+//
+//go:nosplit
+//go:nocheckptr
+func NoEscape(p unsafe.Pointer) unsafe.Pointer {
+ x := uintptr(p)
+ return unsafe.Pointer(x ^ 0)
+}
+
+var alwaysFalse bool
+var escapeSink any
+
+// Escape forces any pointers in x to escape to the heap.
+func Escape[T any](x T) T {
+ if alwaysFalse {
+ escapeSink = x
+ }
+ return x
+}