1 // Copyright 2023 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 //go:build goexperiment.exectracer2
7 // Simple not-in-heap bump-pointer traceRegion allocator.
13 "runtime/internal/sys"
17 // traceRegionAlloc is a non-thread-safe region allocator.
18 // It holds a linked list of traceRegionAllocBlock.
19 type traceRegionAlloc struct {
20 head *traceRegionAllocBlock
24 // traceRegionAllocBlock is a block in traceRegionAlloc.
26 // traceRegionAllocBlock is allocated from non-GC'd memory, so it must not
27 // contain heap pointers. Writes to pointers to traceRegionAllocBlocks do
28 // not need write barriers.
29 type traceRegionAllocBlock struct {
31 next *traceRegionAllocBlock
32 data [64<<10 - goarch.PtrSize]byte
35 // alloc allocates n-byte block.
36 func (a *traceRegionAlloc) alloc(n uintptr) *notInHeap {
37 n = alignUp(n, goarch.PtrSize)
38 if a.head == nil || a.off+n > uintptr(len(a.head.data)) {
39 if n > uintptr(len(a.head.data)) {
40 throw("traceRegion: alloc too large")
42 block := (*traceRegionAllocBlock)(sysAlloc(unsafe.Sizeof(traceRegionAllocBlock{}), &memstats.other_sys))
44 throw("traceRegion: out of memory")
50 p := &a.head.data[a.off]
52 return (*notInHeap)(unsafe.Pointer(p))
55 // drop frees all previously allocated memory and resets the allocator.
56 func (a *traceRegionAlloc) drop() {
60 sysFree(unsafe.Pointer(block), unsafe.Sizeof(traceRegionAllocBlock{}), &memstats.other_sys)