github.com/aloncn/graphics-go@v0.0.1/src/runtime/mfixalloc.go (about) 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 manages its 15 // MCache and MSpan objects. 16 // 17 // Memory returned by FixAlloc_Alloc is not zeroed. 18 // The caller is responsible for locking around FixAlloc calls. 19 // Callers can keep state in the object but the first word is 20 // smashed by freeing and reallocating. 21 type fixalloc struct { 22 size uintptr 23 first func(arg, p unsafe.Pointer) // called first time p is returned 24 arg unsafe.Pointer 25 list *mlink 26 chunk unsafe.Pointer 27 nchunk uint32 28 inuse uintptr // in-use bytes now 29 stat *uint64 30 } 31 32 // A generic linked list of blocks. (Typically the block is bigger than sizeof(MLink).) 33 // Since assignments to mlink.next will result in a write barrier being preformed 34 // this can not be used by some of the internal GC structures. For example when 35 // the sweeper is placing an unmarked object on the free list it does not want the 36 // write barrier to be called since that could result in the object being reachable. 37 type mlink struct { 38 next *mlink 39 } 40 41 // Initialize f to allocate objects of the given size, 42 // using the allocator to obtain chunks of memory. 43 func (f *fixalloc) init(size uintptr, first func(arg, p unsafe.Pointer), arg unsafe.Pointer, stat *uint64) { 44 f.size = size 45 f.first = first 46 f.arg = arg 47 f.list = nil 48 f.chunk = nil 49 f.nchunk = 0 50 f.inuse = 0 51 f.stat = stat 52 } 53 54 func (f *fixalloc) alloc() unsafe.Pointer { 55 if f.size == 0 { 56 print("runtime: use of FixAlloc_Alloc before FixAlloc_Init\n") 57 throw("runtime: internal error") 58 } 59 60 if f.list != nil { 61 v := unsafe.Pointer(f.list) 62 f.list = f.list.next 63 f.inuse += f.size 64 return v 65 } 66 if uintptr(f.nchunk) < f.size { 67 f.chunk = persistentalloc(_FixAllocChunk, 0, f.stat) 68 f.nchunk = _FixAllocChunk 69 } 70 71 v := f.chunk 72 if f.first != nil { 73 f.first(f.arg, v) 74 } 75 f.chunk = add(f.chunk, f.size) 76 f.nchunk -= uint32(f.size) 77 f.inuse += f.size 78 return v 79 } 80 81 func (f *fixalloc) free(p unsafe.Pointer) { 82 f.inuse -= f.size 83 v := (*mlink)(p) 84 v.next = f.list 85 f.list = v 86 }