mirror of
https://github.com/golang/go
synced 2024-11-23 21:40:05 -07:00
[dev.garbage] runtime: bitmap allocation data structs
The bitmap allocation data structure prototypes. Before this is released these underlying data structures need to be more performant but the signatures of helper functions utilizing these structures will remain stable. Change-Id: I5ace12f2fb512a7038a52bbde2bfb7e98783bcbe Reviewed-on: https://go-review.googlesource.com/19221 Reviewed-by: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
6d6e16001b
commit
2ac8bdc52a
@ -97,6 +97,9 @@ const (
|
||||
pageShift = _PageShift
|
||||
pageSize = _PageSize
|
||||
pageMask = _PageMask
|
||||
// By construction, single page spans of the smallest object class
|
||||
// have the most objects per span.
|
||||
maxObjsPerSpan = pageSize / 8
|
||||
|
||||
mSpanInUse = _MSpanInUse
|
||||
|
||||
|
@ -117,9 +117,41 @@ type mspan struct {
|
||||
prev **mspan // previous span's next field, or list head's first field if none
|
||||
list *mSpanList // For debugging. TODO: Remove.
|
||||
|
||||
start pageID // starting page number
|
||||
npages uintptr // number of pages in span
|
||||
freelist gclinkptr // list of free objects
|
||||
start pageID // starting page number
|
||||
npages uintptr // number of pages in span
|
||||
freelist gclinkptr // list of free objects for _MSpanInUse
|
||||
stackfreelist gclinkptr // list of free stacks, avoids overloading freelist for _MSpanStack
|
||||
|
||||
// freeindex is the slot index between 0 and nelems at which to begin scanning
|
||||
// for the next free object in this span.
|
||||
// Each allocation scans allocBits starting at freeindex until it encounters a 0
|
||||
// indicating a free object. freeindex is then adjusted so that subsequent scans begin
|
||||
// just past the the newly discovered free object.
|
||||
//
|
||||
// If freeindex == nelem, this span has no free objects.
|
||||
//
|
||||
// allocBits is a bitmap of objects in this span.
|
||||
// If n >= freeindex and allocBits[n/8] & (1<<(n%8)) is 0
|
||||
// then object n is free;
|
||||
// otherwise, object n is allocated. Bits starting at nelem are
|
||||
// undefined and should never be referenced.
|
||||
//
|
||||
// Object n starts at address n*elemsize + (start << pageShift).
|
||||
freeindex uintptr
|
||||
allocBits *[maxObjsPerSpan / 8]uint8
|
||||
gcmarkBits *[maxObjsPerSpan / 8]uint8
|
||||
nelems uintptr // number of object in the span.
|
||||
// TODO(rlh) consider moving some of these fields into seperate arrays.
|
||||
// Put another way is an array of structs a better idea than a struct of arrays.
|
||||
|
||||
// allocBits and gcmarkBits currently point to either markbits1
|
||||
// or markbits2. At the end of a GC cycle allocBits and
|
||||
// gcmarkBits swap roles simply by swapping pointers.
|
||||
// This level of indirection also facilitates an implementation
|
||||
// where markbits1 and markbits2 are not inlined in mspan.
|
||||
markbits1 [maxObjsPerSpan / 8]uint8 // A bit for each obj.
|
||||
markbits2 [maxObjsPerSpan / 8]uint8 // A bit for each obj.
|
||||
|
||||
// sweep generation:
|
||||
// if sweepgen == h->sweepgen - 2, the span needs sweeping
|
||||
// if sweepgen == h->sweepgen - 1, the span is currently being swept
|
||||
|
@ -55,7 +55,7 @@ var size_to_class128 [(_MaxSmallSize-1024)/128 + 1]int8
|
||||
|
||||
func sizeToClass(size int32) int32 {
|
||||
if size > _MaxSmallSize {
|
||||
throw("SizeToClass - invalid size")
|
||||
throw("invalid size")
|
||||
}
|
||||
if size > 1024-8 {
|
||||
return int32(size_to_class128[(size-1024+127)>>7])
|
||||
@ -79,7 +79,7 @@ func initSizes() {
|
||||
}
|
||||
}
|
||||
if align&(align-1) != 0 {
|
||||
throw("InitSizes - bug")
|
||||
throw("incorrect alignment")
|
||||
}
|
||||
|
||||
// Make the allocnpages big enough that
|
||||
@ -106,10 +106,18 @@ func initSizes() {
|
||||
sizeclass++
|
||||
}
|
||||
if sizeclass != _NumSizeClasses {
|
||||
print("sizeclass=", sizeclass, " NumSizeClasses=", _NumSizeClasses, "\n")
|
||||
throw("InitSizes - bad NumSizeClasses")
|
||||
print("runtime: sizeclass=", sizeclass, " NumSizeClasses=", _NumSizeClasses, "\n")
|
||||
throw("bad NumSizeClasses")
|
||||
}
|
||||
// Check maxObjsPerSpan => number of objects invariant.
|
||||
for i, size := range class_to_size {
|
||||
if size != 0 && class_to_allocnpages[i]*pageSize/size > maxObjsPerSpan {
|
||||
throw("span contains too many objects")
|
||||
}
|
||||
if size == 0 && i != 0 {
|
||||
throw("size is 0 but class is not 0")
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the size_to_class tables.
|
||||
nextsize := 0
|
||||
for sizeclass = 1; sizeclass < _NumSizeClasses; sizeclass++ {
|
||||
@ -128,12 +136,12 @@ func initSizes() {
|
||||
for n := int32(0); n < _MaxSmallSize; n++ {
|
||||
sizeclass := sizeToClass(n)
|
||||
if sizeclass < 1 || sizeclass >= _NumSizeClasses || class_to_size[sizeclass] < n {
|
||||
print("size=", n, " sizeclass=", sizeclass, " runtime·class_to_size=", class_to_size[sizeclass], "\n")
|
||||
print("runtime: size=", n, " sizeclass=", sizeclass, " runtime·class_to_size=", class_to_size[sizeclass], "\n")
|
||||
print("incorrect SizeToClass\n")
|
||||
goto dump
|
||||
}
|
||||
if sizeclass > 1 && class_to_size[sizeclass-1] >= n {
|
||||
print("size=", n, " sizeclass=", sizeclass, " runtime·class_to_size=", class_to_size[sizeclass], "\n")
|
||||
print("runtime: size=", n, " sizeclass=", sizeclass, " runtime·class_to_size=", class_to_size[sizeclass], "\n")
|
||||
print("SizeToClass too big\n")
|
||||
goto dump
|
||||
}
|
||||
@ -155,18 +163,18 @@ func initSizes() {
|
||||
|
||||
dump:
|
||||
if true {
|
||||
print("NumSizeClasses=", _NumSizeClasses, "\n")
|
||||
print("runtime: NumSizeClasses=", _NumSizeClasses, "\n")
|
||||
print("runtime·class_to_size:")
|
||||
for sizeclass = 0; sizeclass < _NumSizeClasses; sizeclass++ {
|
||||
print(" ", class_to_size[sizeclass], "")
|
||||
}
|
||||
print("\n\n")
|
||||
print("size_to_class8:")
|
||||
print("runtime: size_to_class8:")
|
||||
for i := 0; i < len(size_to_class8); i++ {
|
||||
print(" ", i*8, "=>", size_to_class8[i], "(", class_to_size[size_to_class8[i]], ")\n")
|
||||
}
|
||||
print("\n")
|
||||
print("size_to_class128:")
|
||||
print("runtime: size_to_class128:")
|
||||
for i := 0; i < len(size_to_class128); i++ {
|
||||
print(" ", i*128, "=>", size_to_class128[i], "(", class_to_size[size_to_class128[i]], ")\n")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user