diff options
author | Carl Shapiro <cshapiro@google.com> | 2013-05-28 17:59:10 -0700 |
---|---|---|
committer | Carl Shapiro <cshapiro@google.com> | 2013-05-28 17:59:10 -0700 |
commit | 4a6234a0f402c669e526d32a06e20cf97511783e (patch) | |
tree | a67fb26de7ceb14f49d55e06c9ce2ce9a86af6e7 /src/cmd/6l | |
parent | 9a560c16f07777f01c2931ab5de580fd506b28e7 (diff) | |
download | go-4a6234a0f402c669e526d32a06e20cf97511783e.tar.gz |
cmd/5l, cmd/6l, cmd/8l, cmd/gc, runtime: generate and use bitmaps of argument pointer locations
With this change the compiler emits a bitmap for each function
covering its stack frame arguments area. If an argument word
is known to contain a pointer, a bit is set. The garbage
collector reads this information when scanning the stack by
frames and uses it to ignores locations known to not contain a
pointer.
R=golang-dev, bradfitz, daniel.morsing, dvyukov, khr, khr, iant, cshapiro
CC=golang-dev
https://codereview.appspot.com/9223046
Diffstat (limited to 'src/cmd/6l')
-rw-r--r-- | src/cmd/6l/6.out.h | 2 | ||||
-rw-r--r-- | src/cmd/6l/l.h | 2 | ||||
-rw-r--r-- | src/cmd/6l/obj.c | 33 | ||||
-rw-r--r-- | src/cmd/6l/optab.c | 2 |
4 files changed, 39 insertions, 0 deletions
diff --git a/src/cmd/6l/6.out.h b/src/cmd/6l/6.out.h index 237a802cd..e0aeafa94 100644 --- a/src/cmd/6l/6.out.h +++ b/src/cmd/6l/6.out.h @@ -763,6 +763,8 @@ enum as AUSEFIELD, ALOCALS, ATYPE, + ANPTRS, + APTRS, ALAST }; diff --git a/src/cmd/6l/l.h b/src/cmd/6l/l.h index 4d481c69d..d40cc741b 100644 --- a/src/cmd/6l/l.h +++ b/src/cmd/6l/l.h @@ -161,6 +161,8 @@ struct Sym int32 elfsym; int32 locals; // size of stack frame locals area int32 args; // size of stack frame incoming arguments area + int32 nptrs; // number of bits in the pointer map + uint32* ptrs; // pointer map data Sym* hash; // in hash table Sym* allsym; // in all symbol list Sym* next; // in text or data list diff --git a/src/cmd/6l/obj.c b/src/cmd/6l/obj.c index e98f91eeb..b4e77388d 100644 --- a/src/cmd/6l/obj.c +++ b/src/cmd/6l/obj.c @@ -616,6 +616,38 @@ loop: pc++; goto loop; + case ANPTRS: + if(skip) + goto casdef; + if(cursym->nptrs != -1) { + diag("ldobj1: multiple pointer maps defined for %s", cursym->name); + errorexit(); + } + if(p->to.offset > cursym->args/PtrSize) { + diag("ldobj1: pointer map definition for %s exceeds its argument size", cursym->name); + errorexit(); + } + cursym->nptrs = p->to.offset; + if(cursym->nptrs != 0) + cursym->ptrs = mal((rnd(cursym->nptrs, 32) / 32) * sizeof(*cursym->ptrs)); + pc++; + goto loop; + + case APTRS: + if(skip) + goto casdef; + if(cursym->nptrs == -1 || cursym->ptrs == NULL) { + diag("ldobj1: pointer map data provided for %s without a definition", cursym->name); + errorexit(); + } + if(p->from.offset*32 >= rnd(cursym->nptrs, 32)) { + diag("ldobj1: excessive pointer map data provided for %s", cursym->name); + errorexit(); + } + cursym->ptrs[p->from.offset] = p->to.offset; + pc++; + goto loop; + case ATEXT: s = p->from.sym; if(s->text != nil) { @@ -660,6 +692,7 @@ loop: s->type = STEXT; s->value = pc; s->args = p->to.offset >> 32; + s->nptrs = -1; lastp = p; p->pc = pc++; goto loop; diff --git a/src/cmd/6l/optab.c b/src/cmd/6l/optab.c index b0d5ca788..34c8a0c12 100644 --- a/src/cmd/6l/optab.c +++ b/src/cmd/6l/optab.c @@ -1337,6 +1337,8 @@ Optab optab[] = { AUSEFIELD, ynop, Px, 0,0 }, { ALOCALS }, { ATYPE }, + { ANPTRS }, + { APTRS }, { AEND }, 0 |