aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/runtime/mfixalloc.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/runtime/mfixalloc.go')
-rw-r--r--libgo/go/runtime/mfixalloc.go15
1 files changed, 12 insertions, 3 deletions
diff --git a/libgo/go/runtime/mfixalloc.go b/libgo/go/runtime/mfixalloc.go
index 293c16b..b701a09b 100644
--- a/libgo/go/runtime/mfixalloc.go
+++ b/libgo/go/runtime/mfixalloc.go
@@ -30,7 +30,8 @@ type fixalloc struct {
arg unsafe.Pointer
list *mlink
chunk uintptr // use uintptr instead of unsafe.Pointer to avoid write barriers
- nchunk uint32
+ 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
@@ -50,12 +51,20 @@ type mlink struct {
// Initialize f to allocate objects of the given size,
// using the allocator to obtain chunks of memory.
func (f *fixalloc) init(size uintptr, first func(arg, p unsafe.Pointer), arg unsafe.Pointer, stat *sysMemStat) {
+ if size > _FixAllocChunk {
+ throw("runtime: fixalloc size too large")
+ }
+ if min := unsafe.Sizeof(mlink{}); size < min {
+ size = min
+ }
+
f.size = size
f.first = first
f.arg = arg
f.list = nil
f.chunk = 0
f.nchunk = 0
+ f.nalloc = uint32(_FixAllocChunk / size * size) // Round _FixAllocChunk down to an exact multiple of size to eliminate tail waste
f.inuse = 0
f.stat = stat
f.zero = true
@@ -77,8 +86,8 @@ func (f *fixalloc) alloc() unsafe.Pointer {
return v
}
if uintptr(f.nchunk) < f.size {
- f.chunk = uintptr(persistentalloc(_FixAllocChunk, 0, f.stat))
- f.nchunk = _FixAllocChunk
+ f.chunk = uintptr(persistentalloc(uintptr(f.nalloc), 0, f.stat))
+ f.nchunk = f.nalloc
}
v := unsafe.Pointer(f.chunk)