]> Cypherpunks.ru repositories - gostls13.git/blob - src/runtime/trace2region.go
runtime: add execution tracer v2 behind GOEXPERIMENT=exectracer2
[gostls13.git] / src / runtime / trace2region.go
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 }