aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/trace2region.go
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2024-03-20 12:54:39 -0700
committerColin Cross <ccross@android.com>2024-03-20 14:11:54 -0700
commitfbe2133b4d3417adc93daa3819fccf52d2bb66ea (patch)
tree489499c233d3e979128afcc077ea1c6c01725ddf /src/runtime/trace2region.go
parent68a2d6d0813d288a1149f79a7223284fa2f5559f (diff)
parentdb6097f8cbaceaed02051850d2411c88b763a0c3 (diff)
downloadgo-fbe2133b4d3417adc93daa3819fccf52d2bb66ea.tar.gz
Merge tag 'upstream-go1.22.1'HEADmastermain
Bug: 330574836 Test: builds Change-Id: Icaf805d49ad96dd3f2960c5f92b4eeb7c131291c
Diffstat (limited to 'src/runtime/trace2region.go')
-rw-r--r--src/runtime/trace2region.go62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/runtime/trace2region.go b/src/runtime/trace2region.go
new file mode 100644
index 0000000000..b514d127b5
--- /dev/null
+++ b/src/runtime/trace2region.go
@@ -0,0 +1,62 @@
+// Copyright 2023 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.
+
+//go:build goexperiment.exectracer2
+
+// Simple not-in-heap bump-pointer traceRegion allocator.
+
+package runtime
+
+import (
+ "internal/goarch"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+// traceRegionAlloc is a non-thread-safe region allocator.
+// It holds a linked list of traceRegionAllocBlock.
+type traceRegionAlloc struct {
+ head *traceRegionAllocBlock
+ off uintptr
+}
+
+// traceRegionAllocBlock is a block in traceRegionAlloc.
+//
+// traceRegionAllocBlock is allocated from non-GC'd memory, so it must not
+// contain heap pointers. Writes to pointers to traceRegionAllocBlocks do
+// not need write barriers.
+type traceRegionAllocBlock struct {
+ _ sys.NotInHeap
+ next *traceRegionAllocBlock
+ data [64<<10 - goarch.PtrSize]byte
+}
+
+// alloc allocates n-byte block.
+func (a *traceRegionAlloc) alloc(n uintptr) *notInHeap {
+ n = alignUp(n, goarch.PtrSize)
+ if a.head == nil || a.off+n > uintptr(len(a.head.data)) {
+ if n > uintptr(len(a.head.data)) {
+ throw("traceRegion: alloc too large")
+ }
+ block := (*traceRegionAllocBlock)(sysAlloc(unsafe.Sizeof(traceRegionAllocBlock{}), &memstats.other_sys))
+ if block == nil {
+ throw("traceRegion: out of memory")
+ }
+ block.next = a.head
+ a.head = block
+ a.off = 0
+ }
+ p := &a.head.data[a.off]
+ a.off += n
+ return (*notInHeap)(unsafe.Pointer(p))
+}
+
+// drop frees all previously allocated memory and resets the allocator.
+func (a *traceRegionAlloc) drop() {
+ for a.head != nil {
+ block := a.head
+ a.head = block.next
+ sysFree(unsafe.Pointer(block), unsafe.Sizeof(traceRegionAllocBlock{}), &memstats.other_sys)
+ }
+}