aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/heapdump.c
diff options
context:
space:
mode:
authorDmitriy Vyukov <dvyukov@google.com>2014-08-13 20:42:55 +0400
committerDmitriy Vyukov <dvyukov@google.com>2014-08-13 20:42:55 +0400
commit187d0f672029e0fa0106024dd2f554b247aa7aff (patch)
treeaafd4668d393057cf86b9890ccf4fe7df4ed68bd /src/pkg/runtime/heapdump.c
parentaa549ce449a0edccea03b7f4912ee3f9fa9b9b38 (diff)
downloadgo-187d0f672029e0fa0106024dd2f554b247aa7aff.tar.xz
runtime: keep objects in free lists marked as allocated.
Restore https://golang.org/cl/41040043 after GC rewrite. Original description: On the plus side, we don't need to change the bits on malloc and free. On the downside, we need to mark objects in the free lists during GC. But the free lists are small at GC time, so it should be a net win. benchmark old ns/op new ns/op delta BenchmarkMalloc8 21.9 20.4 -6.85% BenchmarkMalloc16 31.1 29.6 -4.82% LGTM=khr R=khr CC=golang-codereviews, rlh, rsc https://golang.org/cl/122280043
Diffstat (limited to 'src/pkg/runtime/heapdump.c')
-rw-r--r--src/pkg/runtime/heapdump.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/src/pkg/runtime/heapdump.c b/src/pkg/runtime/heapdump.c
index b002feb1c2..e5032783a8 100644
--- a/src/pkg/runtime/heapdump.c
+++ b/src/pkg/runtime/heapdump.c
@@ -525,11 +525,17 @@ dumproots(void)
runtime·iterate_finq(finq_callback);
}
+// Bit vector of free marks.
+// Needs to be as big as the largest number of objects per span.
+#pragma dataflag NOPTR
+static byte free[PageSize/8];
+
static void
dumpobjs(void)
{
- uintptr i, j, size, n, off, shift, *bitp, bits;
+ uintptr i, j, size, n;
MSpan *s;
+ MLink *l;
byte *p;
for(i = 0; i < runtime·mheap.nspan; i++) {
@@ -539,13 +545,15 @@ dumpobjs(void)
p = (byte*)(s->start << PageShift);
size = s->elemsize;
n = (s->npages << PageShift) / size;
+ if(n > nelem(free))
+ runtime·throw("free array doesn't have enough entries");
+ for(l = s->freelist; l != nil; l = l->next)
+ free[((byte*)l - p) / size] = true;
for(j = 0; j < n; j++, p += size) {
- off = (uintptr*)p - (uintptr*)runtime·mheap.arena_start;
- bitp = (uintptr*)runtime·mheap.arena_start - off/wordsPerBitmapWord - 1;
- shift = (off % wordsPerBitmapWord) * gcBits;
- bits = (*bitp >> shift) & bitMask;
- if(bits != bitAllocated)
- continue;
+ if(free[j]) {
+ free[j] = false;
+ continue;
+ }
dumpobj(p, size, makeheapobjbv(p, size));
}
}