Source File
mfixalloc.go
Belonging Package
runtime
// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.// Fixed-size object allocator. Returned memory is not zeroed.//// See malloc.go for overview.package runtimeimport// FixAlloc is a simple free-list allocator for fixed size objects.// Malloc uses a FixAlloc wrapped around sysAlloc to manage its// mcache and mspan objects.//// Memory returned by fixalloc.alloc is zeroed by default, but the// caller may take responsibility for zeroing allocations by setting// the zero flag to false. This is only safe if the memory never// contains heap pointers.//// The caller is responsible for locking around FixAlloc calls.// Callers can keep state in the object but the first word is// smashed by freeing and reallocating.//// Consider marking fixalloc'd types go:notinheap.type fixalloc struct {size uintptrfirst func(arg, p unsafe.Pointer) // called first time p is returnedarg unsafe.Pointerlist *mlinkchunk uintptr // use uintptr instead of unsafe.Pointer to avoid write barriersnchunk uint32inuse uintptr // in-use bytes nowstat *sysMemStatzero bool // zero allocations}// A generic linked list of blocks. (Typically the block is bigger than sizeof(MLink).)// Since assignments to mlink.next will result in a write barrier being performed// this cannot be used by some of the internal GC structures. For example when// the sweeper is placing an unmarked object on the free list it does not want the// write barrier to be called since that could result in the object being reachable.////go:notinheaptype mlink struct {next *mlink}// Initialize f to allocate objects of the given size,// using the allocator to obtain chunks of memory.func ( *fixalloc) ( uintptr, func(, unsafe.Pointer), unsafe.Pointer, *sysMemStat) {.size =.first =.arg =.list = nil.chunk = 0.nchunk = 0.inuse = 0.stat =.zero = true}func ( *fixalloc) () unsafe.Pointer {if .size == 0 {print("runtime: use of FixAlloc_Alloc before FixAlloc_Init\n")throw("runtime: internal error")}if .list != nil {:= unsafe.Pointer(.list).list = .list.next.inuse += .sizeif .zero {memclrNoHeapPointers(, .size)}return}if uintptr(.nchunk) < .size {.chunk = uintptr(persistentalloc(_FixAllocChunk, 0, .stat)).nchunk = _FixAllocChunk}:= unsafe.Pointer(.chunk)if .first != nil {.first(.arg, )}.chunk = .chunk + .size.nchunk -= uint32(.size).inuse += .sizereturn}func ( *fixalloc) ( unsafe.Pointer) {.inuse -= .size:= (*mlink)().next = .list.list =}