aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/6l
diff options
context:
space:
mode:
authorCarl Shapiro <cshapiro@google.com>2013-05-28 17:59:10 -0700
committerCarl Shapiro <cshapiro@google.com>2013-05-28 17:59:10 -0700
commit4e0a51c210ededa82809756ca1cc72b1fb1def8d (patch)
tree73e39d7d22cc17088ea10bcd2bc0ce165b45ef0d /src/cmd/6l
parent8bbb08533dab0dcf627db0b76ba65c3fb9b1d682 (diff)
downloadgo-4e0a51c210ededa82809756ca1cc72b1fb1def8d.tar.xz
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://golang.org/cl/9223046
Diffstat (limited to 'src/cmd/6l')
-rw-r--r--src/cmd/6l/6.out.h2
-rw-r--r--src/cmd/6l/l.h2
-rw-r--r--src/cmd/6l/obj.c33
-rw-r--r--src/cmd/6l/optab.c2
4 files changed, 39 insertions, 0 deletions
diff --git a/src/cmd/6l/6.out.h b/src/cmd/6l/6.out.h
index 237a802cde..e0aeafa94f 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 4d481c69d0..d40cc741b9 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 e98f91eeb7..b4e77388d5 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 b0d5ca788e..34c8a0c129 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