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 runtime
import (
)
// 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
// runtime/internal/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 += .size
if .zero {
memclrNoHeapPointers(, .size)
}
return
}
if uintptr(.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 += .size
return
}
func ( *fixalloc) ( unsafe.Pointer) {
.inuse -= .size
:= (*mlink)()
.next = .list
.list =
}
The pages are generated with Golds v0.7.0-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. |