1 // Copyright 2009 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 // Fixed-size object allocator. Returned memory is not zeroed.
7 // See malloc.go for overview.
13 // FixAlloc is a simple free-list allocator for fixed size objects.
14 // Malloc uses a FixAlloc wrapped around sysAlloc to manages its
15 // MCache and MSpan objects.
17 // Memory returned by fixalloc.alloc is zeroed by default, but the
18 // caller may take responsibility for zeroing allocations by setting
19 // the zero flag to false. This is only safe if the memory never
20 // contains heap pointers.
22 // The caller is responsible for locking around FixAlloc calls.
23 // Callers can keep state in the object but the first word is
24 // smashed by freeing and reallocating.
26 // Consider marking fixalloc'd types go:notinheap.
27 type fixalloc
struct {
29 first
func(arg
, p unsafe
.Pointer
) // called first time p is returned
32 chunk
uintptr // use uintptr instead of unsafe.Pointer to avoid write barriers
34 inuse
uintptr // in-use bytes now
36 zero
bool // zero allocations
39 // A generic linked list of blocks. (Typically the block is bigger than sizeof(MLink).)
40 // Since assignments to mlink.next will result in a write barrier being performed
41 // this cannot be used by some of the internal GC structures. For example when
42 // the sweeper is placing an unmarked object on the free list it does not want the
43 // write barrier to be called since that could result in the object being reachable.
50 // Initialize f to allocate objects of the given size,
51 // using the allocator to obtain chunks of memory.
52 func (f
*fixalloc
) init(size
uintptr, first
func(arg
, p unsafe
.Pointer
), arg unsafe
.Pointer
, stat
*uint64) {
64 func (f
*fixalloc
) alloc() unsafe
.Pointer
{
66 print("runtime: use of FixAlloc_Alloc before FixAlloc_Init\n")
67 throw("runtime: internal error")
71 v
:= unsafe
.Pointer(f
.list
)
75 memclrNoHeapPointers(v
, f
.size
)
79 if uintptr(f
.nchunk
) < f
.size
{
80 f
.chunk
= uintptr(persistentalloc(_FixAllocChunk
, 0, f
.stat
))
81 f
.nchunk
= _FixAllocChunk
84 v
:= unsafe
.Pointer(f
.chunk
)
88 f
.chunk
= f
.chunk
+ f
.size
89 f
.nchunk
-= uint32(f
.size
)
94 func (f
*fixalloc
) free(p unsafe
.Pointer
) {