aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2014-04-02 16:49:27 -0400
committerRuss Cox <rsc@golang.org>2014-04-02 16:49:27 -0400
commit4676fae525a5c399274ac0fcb9503aee11d37c56 (patch)
tree7c9205be2f1b00ec7d42e04584234c594c912bf4 /src/pkg/runtime
parent9f9c9abb7e4bcc10398e2264a33cfe9ed805439f (diff)
downloadgo-4676fae525a5c399274ac0fcb9503aee11d37c56.tar.xz
cmd/gc, cmd/ld, runtime: compact liveness bitmaps
Reduce footprint of liveness bitmaps by about 5x. 1. Mark all liveness bitmap symbols as 4-byte aligned (they were aligned to a larger size by default). 2. The bitmap data is a bitmap count n followed by n bitmaps. Each bitmap begins with its own count m giving the number of bits. All the m's are the same for the n bitmaps. Emit this bitmap length once instead of n times. 3. Many bitmaps within a function have the same bit values, but each call site was given a distinct bitmap. Merge duplicate bitmaps so that no bitmap is written more than once. 4. Many functions end up with the same aggregate bitmap data. We used to name the bitmap data funcname.gcargs and funcname.gclocals. Instead, name it gclocals.<md5 of data> and mark it dupok so that the linker coalesces duplicate sets. This cut the bitmap data remaining after step 3 by 40%; I was not expecting it to be quite so dramatic. Applied to "go build -ldflags -w code.google.com/p/go.tools/cmd/godoc": bitmaps pclntab binary on disk before this CL 1326600 1985854 12738268 4-byte align 1154288 (0.87x) 1985854 (1.00x) 12566236 (0.99x) one bitmap len 782528 (0.54x) 1985854 (1.00x) 12193500 (0.96x) dedup bitmap 414748 (0.31x) 1948478 (0.98x) 11787996 (0.93x) dedup bitmap set 245580 (0.19x) 1948478 (0.98x) 11620060 (0.91x) While here, remove various dead blocks of code from plive.c. Fixes #6929. Fixes #7568. LGTM=khr R=khr CC=golang-codereviews https://golang.org/cl/83630044
Diffstat (limited to 'src/pkg/runtime')
-rw-r--r--src/pkg/runtime/heapdump.c22
-rw-r--r--src/pkg/runtime/malloc.h9
-rw-r--r--src/pkg/runtime/mgc0.c26
-rw-r--r--src/pkg/runtime/stack.c10
4 files changed, 28 insertions, 39 deletions
diff --git a/src/pkg/runtime/heapdump.c b/src/pkg/runtime/heapdump.c
index bc0fd49c0a..f9bc4e559f 100644
--- a/src/pkg/runtime/heapdump.c
+++ b/src/pkg/runtime/heapdump.c
@@ -244,7 +244,7 @@ struct ChildInfo {
// the layout of the outargs region.
uintptr argoff; // where the arguments start in the frame
uintptr arglen; // size of args region
- BitVector *args; // if not nil, pointer map of args region
+ BitVector args; // if args.n >= 0, pointer map of args region
byte *sp; // callee sp
uintptr depth; // depth in call stack (0 == most recent)
@@ -301,7 +301,7 @@ dumpframe(Stkframe *s, void *arg)
int32 pcdata;
StackMap *stackmap;
int8 *name;
- BitVector *bv;
+ BitVector bv;
child = (ChildInfo*)arg;
f = s->fn;
@@ -320,13 +320,13 @@ dumpframe(Stkframe *s, void *arg)
stackmap = runtime·funcdata(f, FUNCDATA_LocalsPointerMaps);
// Dump any types we will need to resolve Efaces.
- if(child->args != nil)
- dumpbvtypes(child->args, (byte*)s->sp + child->argoff);
+ if(child->args.n >= 0)
+ dumpbvtypes(&child->args, (byte*)s->sp + child->argoff);
if(stackmap != nil && stackmap->n > 0) {
bv = runtime·stackmapdata(stackmap, pcdata);
- dumpbvtypes(bv, s->varp - bv->n / BitsPerPointer * PtrSize);
+ dumpbvtypes(&bv, s->varp - bv.n / BitsPerPointer * PtrSize);
} else {
- bv = nil;
+ bv.n = -1;
}
// Dump main body of stack frame.
@@ -343,8 +343,8 @@ dumpframe(Stkframe *s, void *arg)
dumpcstr(name);
// Dump fields in the outargs section
- if(child->args != nil) {
- dumpbv(child->args, child->argoff);
+ if(child->args.n >= 0) {
+ dumpbv(&child->args, child->argoff);
} else {
// conservative - everything might be a pointer
for(off = child->argoff; off < child->argoff + child->arglen; off += PtrSize) {
@@ -370,7 +370,7 @@ dumpframe(Stkframe *s, void *arg)
} else if(stackmap->n > 0) {
// Locals bitmap information, scan just the pointers in
// locals.
- dumpbv(bv, s->varp - bv->n / BitsPerPointer * PtrSize - (byte*)s->sp);
+ dumpbv(&bv, s->varp - bv.n / BitsPerPointer * PtrSize - (byte*)s->sp);
}
dumpint(FieldKindEol);
@@ -383,7 +383,7 @@ dumpframe(Stkframe *s, void *arg)
if(stackmap != nil)
child->args = runtime·stackmapdata(stackmap, pcdata);
else
- child->args = nil;
+ child->args.n = -1;
return true;
}
@@ -421,7 +421,7 @@ dumpgoroutine(G *gp)
dumpint((uintptr)gp->panic);
// dump stack
- child.args = nil;
+ child.args.n = -1;
child.arglen = 0;
child.sp = nil;
child.depth = 0;
diff --git a/src/pkg/runtime/malloc.h b/src/pkg/runtime/malloc.h
index 4b9cbc9787..9d478f82c1 100644
--- a/src/pkg/runtime/malloc.h
+++ b/src/pkg/runtime/malloc.h
@@ -602,12 +602,13 @@ typedef struct BitVector BitVector;
struct BitVector
{
int32 n; // # of bits
- uint32 data[];
+ uint32 *data;
};
typedef struct StackMap StackMap;
struct StackMap
{
- int32 n;
+ int32 n; // number of bitmaps
+ int32 nbit; // number of bits in each bitmap
uint32 data[];
};
enum {
@@ -626,7 +627,7 @@ enum {
};
// Returns pointer map data for the given stackmap index
// (the index is encoded in PCDATA_StackMapIndex).
-BitVector* runtime·stackmapdata(StackMap *stackmap, int32 n);
+BitVector runtime·stackmapdata(StackMap *stackmap, int32 n);
// defined in mgc0.go
void runtime·gc_m_ptr(Eface*);
@@ -636,4 +637,4 @@ void runtime·memorydump(void);
int32 runtime·setgcpercent(int32);
// Value we use to mark dead pointers when GODEBUG=gcdead=1.
-#define PoisonPtr ((uintptr)0x6969696969696969LL)
+#define PoisonPtr ((uintptr)0xf9696969f9696969LL)
diff --git a/src/pkg/runtime/mgc0.c b/src/pkg/runtime/mgc0.c
index 26382f4142..d6eedfaa93 100644
--- a/src/pkg/runtime/mgc0.c
+++ b/src/pkg/runtime/mgc0.c
@@ -1403,24 +1403,12 @@ handoff(Workbuf *b)
extern byte pclntab[]; // base for f->ptrsoff
-BitVector*
+BitVector
runtime·stackmapdata(StackMap *stackmap, int32 n)
{
- BitVector *bv;
- uint32 *ptr;
- uint32 words;
- int32 i;
-
- if(n < 0 || n >= stackmap->n) {
+ if(n < 0 || n >= stackmap->n)
runtime·throw("stackmapdata: index out of range");
- }
- ptr = stackmap->data;
- for(i = 0; i < n; i++) {
- bv = (BitVector*)ptr;
- words = ((bv->n + 31) / 32) + 1;
- ptr += words;
- }
- return (BitVector*)ptr;
+ return (BitVector){stackmap->nbit, stackmap->data + n*((stackmap->nbit+31)/32)};
}
// Scans an interface data value when the interface type indicates
@@ -1533,7 +1521,7 @@ scanframe(Stkframe *frame, void *wbufp)
{
Func *f;
StackMap *stackmap;
- BitVector *bv;
+ BitVector bv;
uintptr size;
uintptr targetpc;
int32 pcdata;
@@ -1576,9 +1564,9 @@ scanframe(Stkframe *frame, void *wbufp)
runtime·throw("scanframe: bad symbol table");
}
bv = runtime·stackmapdata(stackmap, pcdata);
- size = (bv->n * PtrSize) / BitsPerPointer;
+ size = (bv.n * PtrSize) / BitsPerPointer;
precise = true;
- scanbitvector(f, true, frame->varp - size, bv, afterprologue, wbufp);
+ scanbitvector(f, true, frame->varp - size, &bv, afterprologue, wbufp);
}
}
@@ -1587,7 +1575,7 @@ scanframe(Stkframe *frame, void *wbufp)
stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps);
if(stackmap != nil) {
bv = runtime·stackmapdata(stackmap, pcdata);
- scanbitvector(f, precise, frame->argp, bv, true, wbufp);
+ scanbitvector(f, precise, frame->argp, &bv, true, wbufp);
} else
enqueue1(wbufp, (Obj){frame->argp, frame->arglen, 0});
return true;
diff --git a/src/pkg/runtime/stack.c b/src/pkg/runtime/stack.c
index f48b76c733..2c5e052365 100644
--- a/src/pkg/runtime/stack.c
+++ b/src/pkg/runtime/stack.c
@@ -436,7 +436,7 @@ adjustframe(Stkframe *frame, void *arg)
Func *f;
StackMap *stackmap;
int32 pcdata;
- BitVector *bv;
+ BitVector bv;
uintptr targetpc;
adjinfo = arg;
@@ -462,7 +462,7 @@ adjustframe(Stkframe *frame, void *arg)
bv = runtime·stackmapdata(stackmap, pcdata);
if(StackDebug >= 3)
runtime·printf(" locals\n");
- adjustpointers((byte**)frame->varp - bv->n / BitsPerPointer, bv, adjinfo, f);
+ adjustpointers((byte**)frame->varp - bv.n / BitsPerPointer, &bv, adjinfo, f);
}
// adjust inargs and outargs
if(frame->arglen != 0) {
@@ -472,7 +472,7 @@ adjustframe(Stkframe *frame, void *arg)
bv = runtime·stackmapdata(stackmap, pcdata);
if(StackDebug >= 3)
runtime·printf(" args\n");
- adjustpointers((byte**)frame->argp, bv, adjinfo, nil);
+ adjustpointers((byte**)frame->argp, &bv, adjinfo, nil);
}
return true;
}
@@ -491,7 +491,7 @@ adjustdefers(G *gp, AdjustInfo *adjinfo)
Func *f;
FuncVal *fn;
StackMap *stackmap;
- BitVector *bv;
+ BitVector bv;
for(dp = &gp->defer, d = *dp; d != nil; dp = &d->link, d = *dp) {
if(adjinfo->oldstk <= (byte*)d && (byte*)d < adjinfo->oldbase) {
@@ -526,7 +526,7 @@ adjustdefers(G *gp, AdjustInfo *adjinfo)
if(stackmap == nil)
runtime·throw("runtime: deferred function has no arg ptr map");
bv = runtime·stackmapdata(stackmap, 0);
- adjustpointers(d->args, bv, adjinfo, f);
+ adjustpointers(d->args, &bv, adjinfo, f);
}
d->argp += adjinfo->delta;
}