...

Source file src/runtime/mfixalloc.go

Documentation: runtime

		 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.
		 4  
		 5  // Fixed-size object allocator. Returned memory is not zeroed.
		 6  //
		 7  // See malloc.go for overview.
		 8  
		 9  package runtime
		10  
		11  import "unsafe"
		12  
		13  // FixAlloc is a simple free-list allocator for fixed size objects.
		14  // Malloc uses a FixAlloc wrapped around sysAlloc to manage its
		15  // mcache and mspan objects.
		16  //
		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.
		21  //
		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.
		25  //
		26  // Consider marking fixalloc'd types go:notinheap.
		27  type fixalloc struct {
		28  	size	 uintptr
		29  	first	func(arg, p unsafe.Pointer) // called first time p is returned
		30  	arg		unsafe.Pointer
		31  	list	 *mlink
		32  	chunk	uintptr // use uintptr instead of unsafe.Pointer to avoid write barriers
		33  	nchunk uint32
		34  	inuse	uintptr // in-use bytes now
		35  	stat	 *sysMemStat
		36  	zero	 bool // zero allocations
		37  }
		38  
		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.
		44  //
		45  //go:notinheap
		46  type mlink struct {
		47  	next *mlink
		48  }
		49  
		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 *sysMemStat) {
		53  	f.size = size
		54  	f.first = first
		55  	f.arg = arg
		56  	f.list = nil
		57  	f.chunk = 0
		58  	f.nchunk = 0
		59  	f.inuse = 0
		60  	f.stat = stat
		61  	f.zero = true
		62  }
		63  
		64  func (f *fixalloc) alloc() unsafe.Pointer {
		65  	if f.size == 0 {
		66  		print("runtime: use of FixAlloc_Alloc before FixAlloc_Init\n")
		67  		throw("runtime: internal error")
		68  	}
		69  
		70  	if f.list != nil {
		71  		v := unsafe.Pointer(f.list)
		72  		f.list = f.list.next
		73  		f.inuse += f.size
		74  		if f.zero {
		75  			memclrNoHeapPointers(v, f.size)
		76  		}
		77  		return v
		78  	}
		79  	if uintptr(f.nchunk) < f.size {
		80  		f.chunk = uintptr(persistentalloc(_FixAllocChunk, 0, f.stat))
		81  		f.nchunk = _FixAllocChunk
		82  	}
		83  
		84  	v := unsafe.Pointer(f.chunk)
		85  	if f.first != nil {
		86  		f.first(f.arg, v)
		87  	}
		88  	f.chunk = f.chunk + f.size
		89  	f.nchunk -= uint32(f.size)
		90  	f.inuse += f.size
		91  	return v
		92  }
		93  
		94  func (f *fixalloc) free(p unsafe.Pointer) {
		95  	f.inuse -= f.size
		96  	v := (*mlink)(p)
		97  	v.next = f.list
		98  	f.list = v
		99  }
	 100  

View as plain text