aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ld
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2012-11-13 13:06:29 -0500
committerRuss Cox <rsc@golang.org>2012-11-13 13:06:29 -0500
commit1120982590113361a985dffa8963283cebaa70c7 (patch)
tree9cf7710083d7b70f736a1a2b976b0fada6329e46 /src/cmd/ld
parent0eb42fa6e45b09e650a0abca24da7916a3e23384 (diff)
downloadgo-1120982590113361a985dffa8963283cebaa70c7.tar.xz
reflect: add ArrayOf, ChanOf, MapOf, SliceOf
In order to add these, we need to be able to find references to such types that already exist in the binary. To do that, introduce a new linker section holding a list of the types corresponding to arrays, chans, maps, and slices. To offset the storage cost of this list, and to simplify the code, remove the interface{} header from the representation of a runtime type. It was used in early versions of the code but was made obsolete by the kind field: a switch on kind is more efficient than a type switch. In the godoc binary, removing the interface{} header cuts two words from each of about 10,000 types. Adding back the list of pointers to array, chan, map, and slice types reintroduces one word for each of about 500 types. On a 64-bit machine, then, this CL *removes* a net 156 kB of read-only data from the binary. This CL does not include the needed support for precise garbage collection. I have created issue 4375 to track that. This CL also does not set the 'algorithm' - specifically the equality and copy functions - for a new array correctly, so I have unexported ArrayOf for now. That is also part of issue 4375. Fixes #2339. R=r, remyoudompheng, mirtchovski, iant CC=golang-dev https://golang.org/cl/6572043
Diffstat (limited to 'src/cmd/ld')
-rw-r--r--src/cmd/ld/data.c20
-rw-r--r--src/cmd/ld/decodesym.c6
-rw-r--r--src/cmd/ld/dwarf.c2
-rw-r--r--src/cmd/ld/go.c8
-rw-r--r--src/cmd/ld/lib.h1
-rw-r--r--src/cmd/ld/symtab.c6
6 files changed, 35 insertions, 8 deletions
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c
index 8fe1773047..51a46e8f47 100644
--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -1079,7 +1079,7 @@ dodata(void)
sect->vaddr = 0;
datsize = 0;
s = datap;
- for(; s != nil && s->type < SGCDATA; s = s->next) {
+ for(; s != nil && s->type < STYPELINK; s = s->next) {
if(s->align != 0)
datsize = rnd(datsize, s->align);
s->type = SRODATA;
@@ -1089,6 +1089,17 @@ dodata(void)
sect->len = datsize - sect->vaddr;
datsize = rnd(datsize, PtrSize);
+ /* type */
+ sect = addsection(&segtext, ".typelink", 04);
+ sect->vaddr = datsize;
+ for(; s != nil && s->type == STYPELINK; s = s->next) {
+ s->type = SRODATA;
+ s->value = datsize;
+ datsize += s->size;
+ }
+ sect->len = datsize - sect->vaddr;
+ datsize = rnd(datsize, PtrSize);
+
/* gcdata */
sect = addsection(&segtext, ".gcdata", 04);
sect->vaddr = datsize;
@@ -1194,7 +1205,7 @@ void
address(void)
{
Section *s, *text, *data, *rodata, *symtab, *pclntab, *noptr, *bss, *noptrbss;
- Section *gcdata, *gcbss;
+ Section *gcdata, *gcbss, *typelink;
Sym *sym, *sub;
uvlong va;
@@ -1241,7 +1252,8 @@ address(void)
text = segtext.sect;
rodata = text->next;
- gcdata = rodata->next;
+ typelink = rodata->next;
+ gcdata = typelink->next;
gcbss = gcdata->next;
symtab = gcbss->next;
pclntab = symtab->next;
@@ -1260,6 +1272,8 @@ address(void)
xdefine("etext", STEXT, text->vaddr + text->len);
xdefine("rodata", SRODATA, rodata->vaddr);
xdefine("erodata", SRODATA, rodata->vaddr + rodata->len);
+ xdefine("typelink", SRODATA, typelink->vaddr);
+ xdefine("etypelink", SRODATA, typelink->vaddr + typelink->len);
xdefine("gcdata", SGCDATA, gcdata->vaddr);
xdefine("egcdata", SGCDATA, gcdata->vaddr + gcdata->len);
xdefine("gcbss", SGCBSS, gcbss->vaddr);
diff --git a/src/cmd/ld/decodesym.c b/src/cmd/ld/decodesym.c
index 347835f8ca..ab3f4fbd55 100644
--- a/src/cmd/ld/decodesym.c
+++ b/src/cmd/ld/decodesym.c
@@ -71,21 +71,21 @@ decode_inuxi(uchar* p, int sz)
uint8
decodetype_kind(Sym *s)
{
- return s->p[3*PtrSize + 7] & ~KindNoPointers; // 0x13 / 0x1f
+ return s->p[1*PtrSize + 7] & ~KindNoPointers; // 0x13 / 0x1f
}
// Type.commonType.size
vlong
decodetype_size(Sym *s)
{
- return decode_inuxi(s->p + 2*PtrSize, PtrSize); // 0x8 / 0x10
+ return decode_inuxi(s->p, PtrSize); // 0x8 / 0x10
}
// Type.commonType.gc
Sym*
decodetype_gc(Sym *s)
{
- return decode_reloc_sym(s, 3*PtrSize + 8 + 1*PtrSize);
+ return decode_reloc_sym(s, 1*PtrSize + 8 + 1*PtrSize);
}
// Type.ArrayType.elem and Type.SliceType.Elem
diff --git a/src/cmd/ld/dwarf.c b/src/cmd/ld/dwarf.c
index 2cf450eda9..9c72f25db7 100644
--- a/src/cmd/ld/dwarf.c
+++ b/src/cmd/ld/dwarf.c
@@ -2082,7 +2082,7 @@ dwarfemitdebugsections(void)
newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, PtrSize, 0);
// Needed by the prettyprinter code for interface inspection.
- defgotype(lookup_or_diag("type.runtime.commonType"));
+ defgotype(lookup_or_diag("type.runtime.rtype"));
defgotype(lookup_or_diag("type.runtime.interfaceType"));
defgotype(lookup_or_diag("type.runtime.itab"));
diff --git a/src/cmd/ld/go.c b/src/cmd/ld/go.c
index 81ae71d736..be5b6d33e6 100644
--- a/src/cmd/ld/go.c
+++ b/src/cmd/ld/go.c
@@ -740,6 +740,12 @@ deadcode(void)
markflood();
+ // keep each beginning with 'typelink.' if the symbol it points at is being kept.
+ for(s = allsym; s != S; s = s->allsym) {
+ if(strncmp(s->name, "go.typelink.", 12) == 0)
+ s->reachable = s->nr==1 && s->r[0].sym->reachable;
+ }
+
// remove dead text but keep file information (z symbols).
last = nil;
z = nil;
@@ -771,7 +777,7 @@ deadcode(void)
s->reachable = 1;
s->hide = 1;
}
-
+
// record field tracking references
fmtstrinit(&fmt);
for(s = allsym; s != S; s = s->allsym) {
diff --git a/src/cmd/ld/lib.h b/src/cmd/ld/lib.h
index c2bac60102..cf334a4bf7 100644
--- a/src/cmd/ld/lib.h
+++ b/src/cmd/ld/lib.h
@@ -39,6 +39,7 @@ enum
SSTRING,
SGOSTRING,
SRODATA,
+ STYPELINK,
SGCDATA,
SGCBSS,
SSYMTAB,
diff --git a/src/cmd/ld/symtab.c b/src/cmd/ld/symtab.c
index 7513ff570d..a27b181edc 100644
--- a/src/cmd/ld/symtab.c
+++ b/src/cmd/ld/symtab.c
@@ -337,6 +337,8 @@ symtab(void)
// data.c:/^address will provide the actual values.
xdefine("text", STEXT, 0);
xdefine("etext", STEXT, 0);
+ xdefine("typelink", SRODATA, 0);
+ xdefine("etypelink", SRODATA, 0);
xdefine("rodata", SRODATA, 0);
xdefine("erodata", SRODATA, 0);
xdefine("gcdata", SGCDATA, 0);
@@ -382,6 +384,10 @@ symtab(void)
s->type = STYPE;
s->hide = 1;
}
+ if(strncmp(s->name, "go.typelink.", 12) == 0) {
+ s->type = STYPELINK;
+ s->hide = 1;
+ }
if(strncmp(s->name, "go.string.", 10) == 0) {
s->type = SGOSTRING;
s->hide = 1;