Commit 2f99e889 authored by Michael Anthony Knyszek's avatar Michael Anthony Knyszek Committed by Austin Clements

runtime: de-duplicate coalescing code

Currently the code surrounding coalescing is duplicated between merging
with the span before the span considered for coalescing and merging with
the span after. This change factors out the shared portions of these
codepaths into a local closure which acts as a helper.

Change-Id: I7919fbed3f9a833eafb324a21a4beaa81f2eaa91
Reviewed-on: https://go-review.googlesource.com/c/158077
Run-TryBot: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarAustin Clements <austin@google.com>
parent 79ac638e
...@@ -425,41 +425,41 @@ func (h *mheap) coalesce(s *mspan) { ...@@ -425,41 +425,41 @@ func (h *mheap) coalesce(s *mspan) {
needsScavenge := false needsScavenge := false
prescavenged := s.released() // number of bytes already scavenged. prescavenged := s.released() // number of bytes already scavenged.
// Coalesce with earlier, later spans. // merge is a helper which merges other into s, deletes references to other
if before := spanOf(s.base() - 1); before != nil && before.state == mSpanFree { // in heap metadata, and then discards it.
// Now adjust s. merge := func(other *mspan) {
s.startAddr = before.startAddr // Adjust s via base and npages.
s.npages += before.npages if other.startAddr < s.startAddr {
s.needzero |= before.needzero s.startAddr = other.startAddr
h.setSpan(before.base(), s) }
s.npages += other.npages
s.needzero |= other.needzero
// If before or s are scavenged, then we need to scavenge the final coalesced span. // If before or s are scavenged, then we need to scavenge the final coalesced span.
needsScavenge = needsScavenge || before.scavenged || s.scavenged needsScavenge = needsScavenge || other.scavenged || s.scavenged
prescavenged += before.released() prescavenged += other.released()
// The size is potentially changing so the treap needs to delete adjacent nodes and // The size is potentially changing so the treap needs to delete adjacent nodes and
// insert back as a combined node. // insert back as a combined node.
if before.scavenged { if other.scavenged {
h.scav.removeSpan(before) h.scav.removeSpan(other)
} else { } else {
h.free.removeSpan(before) h.free.removeSpan(other)
} }
before.state = mSpanDead other.state = mSpanDead
h.spanalloc.free(unsafe.Pointer(before)) h.spanalloc.free(unsafe.Pointer(other))
}
// Coalesce with earlier, later spans.
if before := spanOf(s.base() - 1); before != nil && before.state == mSpanFree {
merge(before)
h.setSpan(s.base(), s)
} }
// Now check to see if next (greater addresses) span is free and can be coalesced. // Now check to see if next (greater addresses) span is free and can be coalesced.
if after := spanOf(s.base() + s.npages*pageSize); after != nil && after.state == mSpanFree { if after := spanOf(s.base() + s.npages*pageSize); after != nil && after.state == mSpanFree {
s.npages += after.npages merge(after)
s.needzero |= after.needzero
h.setSpan(s.base()+s.npages*pageSize-1, s) h.setSpan(s.base()+s.npages*pageSize-1, s)
needsScavenge = needsScavenge || after.scavenged || s.scavenged
prescavenged += after.released()
if after.scavenged {
h.scav.removeSpan(after)
} else {
h.free.removeSpan(after)
}
after.state = mSpanDead
h.spanalloc.free(unsafe.Pointer(after))
} }
if needsScavenge { if needsScavenge {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment