diff options
Diffstat (limited to '')
-rw-r--r-- | src/runtime/trace2region.go | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/runtime/trace2region.go b/src/runtime/trace2region.go new file mode 100644 index 0000000..b514d12 --- /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) + } +} |