Skip to content

Commit 397d211

Browse files
mknyszekgopherbot
authored andcommitted
runtime: merge inline mark bits with gcmarkBits 8 bytes at a time
Currently, with Green Tea GC, we need to copy (really bitwise-or) mark bits back into mspan.gcmarkBits, so that it can propagate to mspan.allocBits at sweep time. This function does actually seem to make sweeping small spans a good bit more expensive, though sweeping is still relatively cheap. There's some low-hanging fruit here though, in that the merge is performed one byte at a time, but this is pretty inefficient. We can almost as easily perform this merge one word at a time instead, which seems to make this operation about 33% faster. For #73581. Change-Id: I170d36e7a2193199c423dcd556cba048ebd698af Reviewed-on: https://go-review.googlesource.com/c/go/+/687935 Reviewed-by: Michael Pratt <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Cherry Mui <[email protected]> Auto-Submit: Michael Knyszek <[email protected]>
1 parent 7dceabd commit 397d211

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

src/runtime/mgcmark_greenteagc.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,13 @@ func (s *mspan) mergeInlineMarks(dst *gcBits) {
192192
}
193193
bytes := divRoundUp(uintptr(s.nelems), 8)
194194
imb := s.inlineMarkBits()
195-
_ = imb.marks[bytes-1]
196-
for i := uintptr(0); i < bytes; i++ {
197-
*dst.bytep(i) |= imb.marks[i]
195+
imbMarks := (*gc.ObjMask)(unsafe.Pointer(&imb.marks))
196+
for i := uintptr(0); i < bytes; i += goarch.PtrSize {
197+
marks := bswapIfBigEndian(imbMarks[i/goarch.PtrSize])
198+
if i/goarch.PtrSize == uintptr(len(imb.marks)+1)/goarch.PtrSize-1 {
199+
marks &^= 0xff << ((goarch.PtrSize - 1) * 8) // mask out class
200+
}
201+
*(*uintptr)(unsafe.Pointer(dst.bytep(i))) |= bswapIfBigEndian(marks)
198202
}
199203
if doubleCheckGreenTea && !s.spanclass.noscan() && imb.marks != imb.scans {
200204
throw("marks don't match scans for span with pointer")
@@ -652,7 +656,7 @@ func spanSetScans(spanBase uintptr, nelems uint16, imb *spanInlineMarkBits, toSc
652656
marks := imbMarks[i/goarch.PtrSize]
653657
scans = bswapIfBigEndian(scans)
654658
marks = bswapIfBigEndian(marks)
655-
if i/goarch.PtrSize == 64/goarch.PtrSize-1 {
659+
if i/goarch.PtrSize == uintptr(len(imb.marks)+1)/goarch.PtrSize-1 {
656660
scans &^= 0xff << ((goarch.PtrSize - 1) * 8) // mask out owned
657661
marks &^= 0xff << ((goarch.PtrSize - 1) * 8) // mask out class
658662
}

0 commit comments

Comments
 (0)