aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ld
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2012-02-19 03:19:52 -0500
committerRuss Cox <rsc@golang.org>2012-02-19 03:19:52 -0500
commit4e3f8e915fadd17b7caffaae273eddd3528ac080 (patch)
treee5dd1e72fb0804a95996bb19af1a05ce435612bc /src/cmd/ld
parentf7410873ba731e4896c27f9ee866c18cb15668bf (diff)
downloadgo-4e3f8e915fadd17b7caffaae273eddd3528ac080.tar.xz
gc, ld: tag data as no-pointers and allocate in separate section
The garbage collector can avoid scanning this section, with reduces collection time as well as the number of false positives. Helps a little bit with issue 909, but certainly does not solve it. R=ken2 CC=golang-dev https://golang.org/cl/5671099
Diffstat (limited to 'src/cmd/ld')
-rw-r--r--src/cmd/ld/data.c41
-rw-r--r--src/cmd/ld/lib.h1
-rw-r--r--src/cmd/ld/symtab.c2
3 files changed, 30 insertions, 14 deletions
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c
index b5f1b99312..e5e1db6d6e 100644
--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -615,7 +615,7 @@ addstring(Sym *s, char *str)
int32 r;
if(s->type == 0)
- s->type = SDATA;
+ s->type = SNOPTRDATA;
s->reachable = 1;
r = s->size;
n = strlen(str)+1;
@@ -782,7 +782,7 @@ void
dodata(void)
{
int32 t, datsize;
- Section *sect;
+ Section *sect, *noptr;
Sym *s, *last, **l;
if(debug['v'])
@@ -887,7 +887,7 @@ dodata(void)
/* writable ELF sections */
datsize = 0;
- for(; s != nil && s->type < SDATA; s = s->next) {
+ for(; s != nil && s->type < SNOPTRDATA; s = s->next) {
sect = addsection(&segdata, s->name, 06);
if(s->align != 0)
datsize = rnd(datsize, s->align);
@@ -897,17 +897,26 @@ dodata(void)
datsize += rnd(s->size, PtrSize);
sect->len = datsize - sect->vaddr;
}
-
- /* data */
- sect = addsection(&segdata, ".data", 06);
+
+ /* pointer-free data, then data */
+ sect = addsection(&segdata, ".noptrdata", 06);
sect->vaddr = datsize;
- for(; s != nil && s->type < SBSS; s = s->next) {
+ noptr = sect;
+ for(; ; s = s->next) {
+ if((s == nil || s->type >= SDATA) && sect == noptr) {
+ // finish noptrdata, start data
+ datsize = rnd(datsize, 8);
+ sect->len = datsize - sect->vaddr;
+ sect = addsection(&segdata, ".data", 06);
+ sect->vaddr = datsize;
+ }
+ if(s == nil || s->type >= SBSS) {
+ // finish data
+ sect->len = datsize - sect->vaddr;
+ break;
+ }
s->type = SDATA;
t = s->size;
- if(t == 0 && s->name[0] != '.') {
- diag("%s: no size", s->name);
- t = 1;
- }
if(t >= PtrSize)
t = rnd(t, PtrSize);
else if(t > 2)
@@ -925,7 +934,6 @@ dodata(void)
s->value = datsize;
datsize += t;
}
- sect->len = datsize - sect->vaddr;
/* bss */
sect = addsection(&segdata, ".bss", 06);
@@ -996,7 +1004,7 @@ textaddress(void)
void
address(void)
{
- Section *s, *text, *data, *rodata, *symtab, *pclntab;
+ Section *s, *text, *data, *rodata, *symtab, *pclntab, *noptr;
Sym *sym, *sub;
uvlong va;
@@ -1022,6 +1030,7 @@ address(void)
if(HEADTYPE == Hplan9x32)
segdata.fileoff = segtext.fileoff + segtext.filelen;
data = nil;
+ noptr = nil;
for(s=segdata.sect; s != nil; s=s->next) {
s->vaddr = va;
va += s->len;
@@ -1029,6 +1038,8 @@ address(void)
segdata.len = va - segdata.vaddr;
if(strcmp(s->name, ".data") == 0)
data = s;
+ if(strcmp(s->name, ".noptrdata") == 0)
+ noptr = s;
}
segdata.filelen -= data->next->len; // deduct .bss
@@ -1039,7 +1050,7 @@ address(void)
for(sym = datap; sym != nil; sym = sym->next) {
cursym = sym;
- if(sym->type < SDATA)
+ if(sym->type < SNOPTRDATA)
sym->value += rodata->vaddr;
else
sym->value += segdata.sect->vaddr;
@@ -1055,6 +1066,8 @@ address(void)
xdefine("esymtab", SRODATA, symtab->vaddr + symtab->len);
xdefine("pclntab", SRODATA, pclntab->vaddr);
xdefine("epclntab", SRODATA, pclntab->vaddr + pclntab->len);
+ xdefine("noptrdata", SBSS, noptr->vaddr);
+ xdefine("enoptrdata", SBSS, noptr->vaddr + noptr->len);
xdefine("data", SBSS, data->vaddr);
xdefine("edata", SBSS, data->vaddr + data->len);
xdefine("end", SBSS, segdata.vaddr + segdata.len);
diff --git a/src/cmd/ld/lib.h b/src/cmd/ld/lib.h
index 188ff9f928..a66a571c21 100644
--- a/src/cmd/ld/lib.h
+++ b/src/cmd/ld/lib.h
@@ -43,6 +43,7 @@ enum
SPCLNTAB,
SELFROSECT,
SELFSECT,
+ SNOPTRDATA,
SDATA,
SMACHO, /* Mach-O __nl_symbol_ptr */
SMACHOGOT,
diff --git a/src/cmd/ld/symtab.c b/src/cmd/ld/symtab.c
index 00413af009..d89359958e 100644
--- a/src/cmd/ld/symtab.c
+++ b/src/cmd/ld/symtab.c
@@ -330,6 +330,8 @@ symtab(void)
xdefine("etext", STEXT, 0);
xdefine("rodata", SRODATA, 0);
xdefine("erodata", SRODATA, 0);
+ xdefine("noptrdata", SBSS, 0);
+ xdefine("enoptrdata", SBSS, 0);
xdefine("data", SBSS, 0);
xdefine("edata", SBSS, 0);
xdefine("end", SBSS, 0);