github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/trace2region.go (about) 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. 4 5 //go:build goexperiment.exectracer2 6 7 // Simple not-in-heap bump-pointer traceRegion allocator. 8 9 package runtime 10 11 import ( 12 "internal/goarch" 13 "runtime/internal/sys" 14 "unsafe" 15 ) 16 17 // traceRegionAlloc is a non-thread-safe region allocator. 18 // It holds a linked list of traceRegionAllocBlock. 19 type traceRegionAlloc struct { 20 head *traceRegionAllocBlock 21 off uintptr 22 } 23 24 // traceRegionAllocBlock is a block in traceRegionAlloc. 25 // 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 { 30 _ sys.NotInHeap 31 next *traceRegionAllocBlock 32 data [64<<10 - goarch.PtrSize]byte 33 } 34 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") 41 } 42 block := (*traceRegionAllocBlock)(sysAlloc(unsafe.Sizeof(traceRegionAllocBlock{}), &memstats.other_sys)) 43 if block == nil { 44 throw("traceRegion: out of memory") 45 } 46 block.next = a.head 47 a.head = block 48 a.off = 0 49 } 50 p := &a.head.data[a.off] 51 a.off += n 52 return (*notInHeap)(unsafe.Pointer(p)) 53 } 54 55 // drop frees all previously allocated memory and resets the allocator. 56 func (a *traceRegionAlloc) drop() { 57 for a.head != nil { 58 block := a.head 59 a.head = block.next 60 sysFree(unsafe.Pointer(block), unsafe.Sizeof(traceRegionAllocBlock{}), &memstats.other_sys) 61 } 62 }