Commit 6d114905 authored by Austin Clements's avatar Austin Clements

[dev.garbage] runtime: fix allocfreetrace

We broke tracing of freed objects in GODEBUG=allocfreetrace=1 mode
when we removed the sweep over the mark bitmap. Fix it by
re-introducing the sweep over the bitmap specifically if we're in
allocfreetrace mode. This doesn't have to be even remotely efficient,
since the overhead of allocfreetrace is huge anyway, so we can keep
the code for this down to just a few lines.

Change-Id: I9e176b3b04c73608a0ea3068d5d0cd30760ebd40
Reviewed-on: https://go-review.googlesource.com/22592
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarRick Hudson <rlh@golang.org>
parent 38f67468
......@@ -743,23 +743,6 @@ func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer {
gcmarknewobject(uintptr(x), size, scanSize)
}
// The object x is about to be reused but tracefree and msanfree
// need to be informed.
// TODO:(rlh) It is quite possible that this object is being allocated
// out of a fresh span and that there is no preceding call to
// tracealloc with this object. If this is an issue then initialization
// of the fresh span needs to leave some crumbs around that can be used to
// avoid these calls. Furthermore these crumbs a likely the same as
// those needed to determine if the object needs to be zeroed.
// In the case of msanfree it does not make sense to call msanfree
// followed by msanmalloc. msanfree indicates that the bytes are not
// initialized but msanmalloc is about to indicate that they are.
// It makes no difference whether msanmalloc has been called on these
// bytes or not.
if debug.allocfreetrace != 0 {
tracefree(unsafe.Pointer(x), size)
}
if raceenabled {
racemalloc(x, size)
}
......
......@@ -251,6 +251,21 @@ func (s *mspan) sweep(preserve bool) bool {
}
}
if debug.allocfreetrace != 0 {
// Find all newly freed objects. This doesn't have to
// efficient; allocfreetrace has massive overhead.
mbits := s.markBitsForBase()
abits := s.allocBitsForIndex(0)
for i := uintptr(0); i < s.nelems; i++ {
if !mbits.isMarked() && (abits.index < s.freeindex || abits.isMarked()) {
x := s.base() + i*s.elemsize
tracefree(unsafe.Pointer(x), size)
}
mbits.advance()
abits.advance()
}
}
// Count the number of free objects in this span.
nfree = s.countFree()
if cl == 0 && nfree != 0 {
......
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