aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/malloc.go
diff options
context:
space:
mode:
authorDmitriy Vyukov <dvyukov@google.com>2014-08-19 17:38:00 +0400
committerDmitriy Vyukov <dvyukov@google.com>2014-08-19 17:38:00 +0400
commitff3fa1b32dba4448bed45282b1038a4f8e9c23dc (patch)
treed5c7458bf20b8918dde0750efb67b6d9aaa33026 /src/pkg/runtime/malloc.go
parentfb44fb6cb7fdadced51db03403b9f5d93fefa5a5 (diff)
downloadgo-ff3fa1b32dba4448bed45282b1038a4f8e9c23dc.tar.xz
runtime: make the GC bitmap a byte array
Half the code in the garbage collector accesses the bitmap as an array of bytes instead of as an array of uintptrs. This is tricky to do correctly in a portable fashion, it breaks on big-endian systems. Make the bitmap a byte array. Simplifies markallocated, scanblock and span sweep along the way, as we don't need to recalculate bitmap position for each word. LGTM=khr R=golang-codereviews, khr CC=golang-codereviews, rlh, rsc https://golang.org/cl/125250043
Diffstat (limited to 'src/pkg/runtime/malloc.go')
-rw-r--r--src/pkg/runtime/malloc.go22
1 files changed, 7 insertions, 15 deletions
diff --git a/src/pkg/runtime/malloc.go b/src/pkg/runtime/malloc.go
index 152b3b6b68..8ee460755f 100644
--- a/src/pkg/runtime/malloc.go
+++ b/src/pkg/runtime/malloc.go
@@ -22,8 +22,8 @@ const (
pageSize = 1 << pageShift
pageMask = pageSize - 1
- wordsPerBitmapWord = ptrSize * 8 / 4
gcBits = 4
+ wordsPerBitmapByte = 8 / gcBits
bitsPerPointer = 2
bitsMask = 1<<bitsPerPointer - 1
pointersPerByte = 8 / bitsPerPointer
@@ -211,8 +211,8 @@ func gomallocgc(size uintptr, typ *_type, flags int) unsafe.Pointer {
{
arena_start := uintptr(unsafe.Pointer(mheap_.arena_start))
off := (uintptr(x) - arena_start) / ptrSize
- xbits := (*uintptr)(unsafe.Pointer(arena_start - off/wordsPerBitmapWord*ptrSize - ptrSize))
- shift := (off % wordsPerBitmapWord) * gcBits
+ xbits := (*uint8)(unsafe.Pointer(arena_start - off/wordsPerBitmapByte - 1))
+ shift := (off % wordsPerBitmapByte) * gcBits
if debugMalloc && ((*xbits>>shift)&(bitMask|bitPtrMask)) != bitBoundary {
println("runtime: bits =", (*xbits>>shift)&(bitMask|bitPtrMask))
gothrow("bad bits in markallocated")
@@ -260,8 +260,7 @@ func gomallocgc(size uintptr, typ *_type, flags int) unsafe.Pointer {
ptrmask = (*uint8)(unsafe.Pointer(&typ.gc[0])) // embed mask
}
if size == 2*ptrSize {
- xbitsb := (*uint8)(add(unsafe.Pointer(xbits), shift/8))
- *xbitsb = *ptrmask | bitBoundary
+ *xbits = *ptrmask | bitBoundary
goto marked
}
te = uintptr(typ.size) / ptrSize
@@ -283,19 +282,12 @@ func gomallocgc(size uintptr, typ *_type, flags int) unsafe.Pointer {
v &^= uint8(bitPtrMask << 4)
}
- off := (uintptr(x) + i - arena_start) / ptrSize
- xbits := (*uintptr)(unsafe.Pointer(arena_start - off/wordsPerBitmapWord*ptrSize - ptrSize))
- shift := (off % wordsPerBitmapWord) * gcBits
- xbitsb := (*uint8)(add(unsafe.Pointer(xbits), shift/8))
- *xbitsb = v
+ *xbits = v
+ xbits = (*byte)(add(unsafe.Pointer(xbits), ^uintptr(0)))
}
if size0%(2*ptrSize) == 0 && size0 < size {
// Mark the word after last object's word as bitsDead.
- off := (uintptr(x) + size0 - arena_start) / ptrSize
- xbits := (*uintptr)(unsafe.Pointer(arena_start - off/wordsPerBitmapWord*ptrSize - ptrSize))
- shift := (off % wordsPerBitmapWord) * gcBits
- xbitsb := (*uint8)(add(unsafe.Pointer(xbits), shift/8))
- *xbitsb = bitsDead << 2
+ *xbits = bitsDead << 2
}
}
marked: