return
}
- // Account how much sweeping needs to be done before the next
- // GC cycle and set up proportional sweep statistics.
- var pagesToSweep uintptr
- for _, s := range work.spans {
- if s.state == mSpanInUse {
- pagesToSweep += s.npages
- }
- }
+ // Concurrent sweep needs to sweep all of the in-use pages by
+ // the time the allocated heap reaches the GC trigger. Compute
+ // the ratio of in-use pages to sweep per byte allocated.
heapDistance := int64(memstats.next_gc) - int64(memstats.heap_live)
// Add a little margin so rounding errors and concurrent
// sweep are less likely to leave pages unswept when GC starts.
heapDistance = _PageSize
}
lock(&mheap_.lock)
- mheap_.sweepPagesPerByte = float64(pagesToSweep) / float64(heapDistance)
+ mheap_.sweepPagesPerByte = float64(mheap_.pagesInUse) / float64(heapDistance)
mheap_.pagesSwept = 0
mheap_.spanBytesAlloc = 0
unlock(&mheap_.lock)
spans_mapped uintptr
// Proportional sweep
+ pagesInUse uint64 // pages of spans in stats _MSpanInUse; R/W with mheap.lock
spanBytesAlloc uint64 // bytes of spans allocated this cycle; updated atomically
pagesSwept uint64 // pages swept this cycle; updated atomically
sweepPagesPerByte float64 // proportional sweep ratio; written with lock, read without
+ // TODO(austin): pagesInUse should be a uintptr, but the 386
+ // compiler can't 8-byte align fields.
// Malloc stats.
largefree uint64 // bytes freed for large objects (>maxsmallsize)
}
// update stats, sweep lists
+ h.pagesInUse += uint64(npage)
if large {
memstats.heap_objects++
memstats.heap_live += uint64(npage << _PageShift)
// Try to add at least npage pages of memory to the heap,
// returning whether it worked.
+//
+// h must be locked.
func mHeap_Grow(h *mheap, npage uintptr) bool {
// Ask for a big chunk, to reduce the number of mappings
// the operating system needs to track; also amortizes
}
atomicstore(&s.sweepgen, h.sweepgen)
s.state = _MSpanInUse
+ h.pagesInUse += uint64(npage)
mHeap_FreeSpanLocked(h, s, false, true, 0)
return true
}
print("MHeap_FreeSpanLocked - span ", s, " ptr ", hex(s.start<<_PageShift), " ref ", s.ref, " sweepgen ", s.sweepgen, "/", h.sweepgen, "\n")
throw("MHeap_FreeSpanLocked - invalid free")
}
+ h.pagesInUse -= uint64(s.npages)
default:
throw("MHeap_FreeSpanLocked - invalid span state")
}