diff options
| author | Russ Cox <rsc@golang.org> | 2012-11-13 13:06:29 -0500 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2012-11-13 13:06:29 -0500 |
| commit | 1120982590113361a985dffa8963283cebaa70c7 (patch) | |
| tree | 9cf7710083d7b70f736a1a2b976b0fada6329e46 /src/cmd/ld | |
| parent | 0eb42fa6e45b09e650a0abca24da7916a3e23384 (diff) | |
| download | go-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.c | 20 | ||||
| -rw-r--r-- | src/cmd/ld/decodesym.c | 6 | ||||
| -rw-r--r-- | src/cmd/ld/dwarf.c | 2 | ||||
| -rw-r--r-- | src/cmd/ld/go.c | 8 | ||||
| -rw-r--r-- | src/cmd/ld/lib.h | 1 | ||||
| -rw-r--r-- | src/cmd/ld/symtab.c | 6 |
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; |
