// 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 not in heap by embedding// internal/runtime/sys.NotInHeap.type fixalloc struct { size uintptr first func(arg, p unsafe.Pointer) // called first time p is returned arg unsafe.Pointer list *mlink chunk uintptr// use uintptr instead of unsafe.Pointer to avoid write barriers nchunk uint32// bytes remaining in current chunk nalloc uint32// size of new chunks in bytes inuse uintptr// in-use bytes now stat *sysMemStat zero 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.type mlink struct { _ sys.NotInHeap 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) {if > _FixAllocChunk {throw("runtime: fixalloc size too large") } = max(, unsafe.Sizeof(mlink{})) .size = .first = .arg = .list = nil .chunk = 0 .nchunk = 0 .nalloc = uint32(_FixAllocChunk / * ) // Round _FixAllocChunk down to an exact multiple of size to eliminate tail waste .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 }ifuintptr(.nchunk) < .size { .chunk = uintptr(persistentalloc(uintptr(.nalloc), 0, .stat)) .nchunk = .nalloc } := 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 = }
The pages are generated with Goldsv0.7.9-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.