-
Notifications
You must be signed in to change notification settings - Fork 13
/
arena.go
47 lines (41 loc) · 1.5 KB
/
arena.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// SPDX-License-Identifier: Apache-2.0
package nuke
import (
"unsafe"
)
// Arena is an interface that describes a memory allocation arena.
type Arena interface {
// Alloc allocates memory of the given size and returns a pointer to it.
// The alignment parameter specifies the alignment of the allocated memory.
Alloc(size, alignment uintptr) unsafe.Pointer
// Reset resets the arena's state, optionally releasing the memory.
// After invoking this method any pointer previously returned by Alloc becomes immediately invalid.
Reset(release bool)
}
// New allocates memory for a value of type T using the provided Arena.
// If the arena is non-nil, it returns a *T pointer with memory allocated from the arena.
// If passed arena is nil, it allocates memory using Go's built-in new function.
func New[T any](a Arena) *T {
if a != nil {
var x T
if ptr := a.Alloc(unsafe.Sizeof(x), unsafe.Alignof(x)); ptr != nil {
return (*T)(ptr)
}
}
return new(T)
}
// MakeSlice creates a slice of type T with a given length and capacity,
// using the provided Arena for memory allocation.
// If the arena is non-nil, it returns a slice with memory allocated from the arena.
// Otherwise, it returns a slice using Go's built-in make function.
func MakeSlice[T any](a Arena, len, cap int) []T {
if a != nil {
var x T
bufSize := int(unsafe.Sizeof(x)) * cap
if ptr := (*T)(a.Alloc(uintptr(bufSize), unsafe.Alignof(x))); ptr != nil {
s := unsafe.Slice(ptr, cap)
return s[:len]
}
}
return make([]T, len, cap)
}