Commit 4e3f8e91 authored by Russ Cox's avatar Russ Cox

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
parent f7410873
...@@ -253,6 +253,10 @@ ggloblnod(Node *nam, int32 width) ...@@ -253,6 +253,10 @@ ggloblnod(Node *nam, int32 width)
p->to.sym = S; p->to.sym = S;
p->to.type = D_CONST; p->to.type = D_CONST;
p->to.offset = width; p->to.offset = width;
if(nam->readonly)
p->from.scale = RODATA;
if(nam->type != T && !haspointers(nam->type))
p->from.scale |= NOPTR;
} }
void void
......
...@@ -35,7 +35,8 @@ ...@@ -35,7 +35,8 @@
#define NOPROF (1<<0) #define NOPROF (1<<0)
#define DUPOK (1<<1) #define DUPOK (1<<1)
#define NOSPLIT (1<<2) #define NOSPLIT (1<<2)
#define ALLTHUMBS (1<<3) #define RODATA (1<<3)
#define NOPTR (1<<4)
#define REGRET 0 #define REGRET 0
/* -1 disables use of REGARG */ /* -1 disables use of REGARG */
......
...@@ -540,7 +540,7 @@ loop: ...@@ -540,7 +540,7 @@ loop:
s->type = SBSS; s->type = SBSS;
s->value = 0; s->value = 0;
} }
if(s->type != SBSS && !s->dupok) { if(s->type != SBSS && s->type != SNOPTRDATA && !s->dupok) {
diag("redefinition: %s\n%P", s->name, p); diag("redefinition: %s\n%P", s->name, p);
s->type = SBSS; s->type = SBSS;
s->value = 0; s->value = 0;
...@@ -549,6 +549,10 @@ loop: ...@@ -549,6 +549,10 @@ loop:
s->size = p->to.offset; s->size = p->to.offset;
if(p->reg & DUPOK) if(p->reg & DUPOK)
s->dupok = 1; s->dupok = 1;
if(p->from.scale & RODATA)
s->type = SRODATA;
else if(p->from.scale & NOPTR)
s->type = SNOPTRDATA;
break; break;
case ADATA: case ADATA:
......
...@@ -231,6 +231,8 @@ ggloblnod(Node *nam, int32 width) ...@@ -231,6 +231,8 @@ ggloblnod(Node *nam, int32 width)
p->to.offset = width; p->to.offset = width;
if(nam->readonly) if(nam->readonly)
p->from.scale = RODATA; p->from.scale = RODATA;
if(nam->type != T && !haspointers(nam->type))
p->from.scale |= NOPTR;
} }
void void
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#define DUPOK (1<<1) #define DUPOK (1<<1)
#define NOSPLIT (1<<2) #define NOSPLIT (1<<2)
#define RODATA (1<<3) #define RODATA (1<<3)
#define NOPTR (1<<4)
/* /*
* amd64 * amd64
......
...@@ -555,7 +555,7 @@ loop: ...@@ -555,7 +555,7 @@ loop:
s->type = SBSS; s->type = SBSS;
s->size = 0; s->size = 0;
} }
if(s->type != SBSS && !s->dupok) { if(s->type != SBSS && s->type != SNOPTRDATA && !s->dupok) {
diag("%s: redefinition: %s in %s", diag("%s: redefinition: %s in %s",
pn, s->name, TNAME); pn, s->name, TNAME);
s->type = SBSS; s->type = SBSS;
...@@ -567,6 +567,8 @@ loop: ...@@ -567,6 +567,8 @@ loop:
s->dupok = 1; s->dupok = 1;
if(p->from.scale & RODATA) if(p->from.scale & RODATA)
s->type = SRODATA; s->type = SRODATA;
else if(p->from.scale & NOPTR)
s->type = SNOPTRDATA;
goto loop; goto loop;
case ADATA: case ADATA:
......
...@@ -232,6 +232,8 @@ ggloblnod(Node *nam, int32 width) ...@@ -232,6 +232,8 @@ ggloblnod(Node *nam, int32 width)
p->to.offset = width; p->to.offset = width;
if(nam->readonly) if(nam->readonly)
p->from.scale = RODATA; p->from.scale = RODATA;
if(nam->type != T && !haspointers(nam->type))
p->from.scale |= NOPTR;
} }
void void
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#define DUPOK (1<<1) #define DUPOK (1<<1)
#define NOSPLIT (1<<2) #define NOSPLIT (1<<2)
#define RODATA (1<<3) #define RODATA (1<<3)
#define NOPTR (1<<4)
enum as enum as
{ {
......
...@@ -563,7 +563,7 @@ loop: ...@@ -563,7 +563,7 @@ loop:
s->type = SBSS; s->type = SBSS;
s->size = 0; s->size = 0;
} }
if(s->type != SBSS && !s->dupok) { if(s->type != SBSS && s->type != SNOPTRDATA && !s->dupok) {
diag("%s: redefinition: %s in %s", diag("%s: redefinition: %s in %s",
pn, s->name, TNAME); pn, s->name, TNAME);
s->type = SBSS; s->type = SBSS;
...@@ -575,6 +575,8 @@ loop: ...@@ -575,6 +575,8 @@ loop:
s->dupok = 1; s->dupok = 1;
if(p->from.scale & RODATA) if(p->from.scale & RODATA)
s->type = SRODATA; s->type = SRODATA;
else if(p->from.scale & NOPTR)
s->type = SNOPTRDATA;
goto loop; goto loop;
case ADATA: case ADATA:
......
...@@ -615,7 +615,7 @@ addstring(Sym *s, char *str) ...@@ -615,7 +615,7 @@ addstring(Sym *s, char *str)
int32 r; int32 r;
if(s->type == 0) if(s->type == 0)
s->type = SDATA; s->type = SNOPTRDATA;
s->reachable = 1; s->reachable = 1;
r = s->size; r = s->size;
n = strlen(str)+1; n = strlen(str)+1;
...@@ -782,7 +782,7 @@ void ...@@ -782,7 +782,7 @@ void
dodata(void) dodata(void)
{ {
int32 t, datsize; int32 t, datsize;
Section *sect; Section *sect, *noptr;
Sym *s, *last, **l; Sym *s, *last, **l;
if(debug['v']) if(debug['v'])
...@@ -887,7 +887,7 @@ dodata(void) ...@@ -887,7 +887,7 @@ dodata(void)
/* writable ELF sections */ /* writable ELF sections */
datsize = 0; 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); sect = addsection(&segdata, s->name, 06);
if(s->align != 0) if(s->align != 0)
datsize = rnd(datsize, s->align); datsize = rnd(datsize, s->align);
...@@ -897,17 +897,26 @@ dodata(void) ...@@ -897,17 +897,26 @@ dodata(void)
datsize += rnd(s->size, PtrSize); datsize += rnd(s->size, PtrSize);
sect->len = datsize - sect->vaddr; sect->len = datsize - sect->vaddr;
} }
/* data */ /* pointer-free data, then data */
sect = addsection(&segdata, ".data", 06); sect = addsection(&segdata, ".noptrdata", 06);
sect->vaddr = datsize; 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; s->type = SDATA;
t = s->size; t = s->size;
if(t == 0 && s->name[0] != '.') {
diag("%s: no size", s->name);
t = 1;
}
if(t >= PtrSize) if(t >= PtrSize)
t = rnd(t, PtrSize); t = rnd(t, PtrSize);
else if(t > 2) else if(t > 2)
...@@ -925,7 +934,6 @@ dodata(void) ...@@ -925,7 +934,6 @@ dodata(void)
s->value = datsize; s->value = datsize;
datsize += t; datsize += t;
} }
sect->len = datsize - sect->vaddr;
/* bss */ /* bss */
sect = addsection(&segdata, ".bss", 06); sect = addsection(&segdata, ".bss", 06);
...@@ -996,7 +1004,7 @@ textaddress(void) ...@@ -996,7 +1004,7 @@ textaddress(void)
void void
address(void) address(void)
{ {
Section *s, *text, *data, *rodata, *symtab, *pclntab; Section *s, *text, *data, *rodata, *symtab, *pclntab, *noptr;
Sym *sym, *sub; Sym *sym, *sub;
uvlong va; uvlong va;
...@@ -1022,6 +1030,7 @@ address(void) ...@@ -1022,6 +1030,7 @@ address(void)
if(HEADTYPE == Hplan9x32) if(HEADTYPE == Hplan9x32)
segdata.fileoff = segtext.fileoff + segtext.filelen; segdata.fileoff = segtext.fileoff + segtext.filelen;
data = nil; data = nil;
noptr = nil;
for(s=segdata.sect; s != nil; s=s->next) { for(s=segdata.sect; s != nil; s=s->next) {
s->vaddr = va; s->vaddr = va;
va += s->len; va += s->len;
...@@ -1029,6 +1038,8 @@ address(void) ...@@ -1029,6 +1038,8 @@ address(void)
segdata.len = va - segdata.vaddr; segdata.len = va - segdata.vaddr;
if(strcmp(s->name, ".data") == 0) if(strcmp(s->name, ".data") == 0)
data = s; data = s;
if(strcmp(s->name, ".noptrdata") == 0)
noptr = s;
} }
segdata.filelen -= data->next->len; // deduct .bss segdata.filelen -= data->next->len; // deduct .bss
...@@ -1039,7 +1050,7 @@ address(void) ...@@ -1039,7 +1050,7 @@ address(void)
for(sym = datap; sym != nil; sym = sym->next) { for(sym = datap; sym != nil; sym = sym->next) {
cursym = sym; cursym = sym;
if(sym->type < SDATA) if(sym->type < SNOPTRDATA)
sym->value += rodata->vaddr; sym->value += rodata->vaddr;
else else
sym->value += segdata.sect->vaddr; sym->value += segdata.sect->vaddr;
...@@ -1055,6 +1066,8 @@ address(void) ...@@ -1055,6 +1066,8 @@ address(void)
xdefine("esymtab", SRODATA, symtab->vaddr + symtab->len); xdefine("esymtab", SRODATA, symtab->vaddr + symtab->len);
xdefine("pclntab", SRODATA, pclntab->vaddr); xdefine("pclntab", SRODATA, pclntab->vaddr);
xdefine("epclntab", SRODATA, pclntab->vaddr + pclntab->len); 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("data", SBSS, data->vaddr);
xdefine("edata", SBSS, data->vaddr + data->len); xdefine("edata", SBSS, data->vaddr + data->len);
xdefine("end", SBSS, segdata.vaddr + segdata.len); xdefine("end", SBSS, segdata.vaddr + segdata.len);
......
...@@ -43,6 +43,7 @@ enum ...@@ -43,6 +43,7 @@ enum
SPCLNTAB, SPCLNTAB,
SELFROSECT, SELFROSECT,
SELFSECT, SELFSECT,
SNOPTRDATA,
SDATA, SDATA,
SMACHO, /* Mach-O __nl_symbol_ptr */ SMACHO, /* Mach-O __nl_symbol_ptr */
SMACHOGOT, SMACHOGOT,
......
...@@ -330,6 +330,8 @@ symtab(void) ...@@ -330,6 +330,8 @@ symtab(void)
xdefine("etext", STEXT, 0); xdefine("etext", STEXT, 0);
xdefine("rodata", SRODATA, 0); xdefine("rodata", SRODATA, 0);
xdefine("erodata", SRODATA, 0); xdefine("erodata", SRODATA, 0);
xdefine("noptrdata", SBSS, 0);
xdefine("enoptrdata", SBSS, 0);
xdefine("data", SBSS, 0); xdefine("data", SBSS, 0);
xdefine("edata", SBSS, 0); xdefine("edata", SBSS, 0);
xdefine("end", SBSS, 0); xdefine("end", SBSS, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment