1
0
mirror of https://github.com/golang/go synced 2024-11-19 21:04:43 -07:00

runtime: hide symbol table from garbage collector

R=rsc
CC=golang-dev
https://golang.org/cl/6243059
This commit is contained in:
Jan Ziak 2012-05-30 13:04:48 -04:00 committed by Russ Cox
parent c633f85f65
commit 46d7d5fcf5

View File

@ -16,6 +16,7 @@
#include "defs_GOOS_GOARCH.h" #include "defs_GOOS_GOARCH.h"
#include "os_GOOS.h" #include "os_GOOS.h"
#include "arch_GOARCH.h" #include "arch_GOARCH.h"
#include "malloc.h"
extern byte pclntab[], epclntab[], symtab[], esymtab[]; extern byte pclntab[], epclntab[], symtab[], esymtab[];
@ -28,6 +29,11 @@ struct Sym
// byte *gotype; // byte *gotype;
}; };
// A dynamically allocated string containing multiple substrings.
// Individual strings are slices of hugestring.
static String hugestring;
static int32 hugestring_len;
// Walk over symtab, calling fn(&s) for each symbol. // Walk over symtab, calling fn(&s) for each symbol.
static void static void
walksymtab(void (*fn)(Sym*)) walksymtab(void (*fn)(Sym*))
@ -135,14 +141,15 @@ dofunc(Sym *sym)
// put together the path name for a z entry. // put together the path name for a z entry.
// the f entries have been accumulated into fname already. // the f entries have been accumulated into fname already.
static void // returns the length of the path name.
static int32
makepath(byte *buf, int32 nbuf, byte *path) makepath(byte *buf, int32 nbuf, byte *path)
{ {
int32 n, len; int32 n, len;
byte *p, *ep, *q; byte *p, *ep, *q;
if(nbuf <= 0) if(nbuf <= 0)
return; return 0;
p = buf; p = buf;
ep = buf + nbuf; ep = buf + nbuf;
@ -163,6 +170,26 @@ makepath(byte *buf, int32 nbuf, byte *path)
runtime·memmove(p, q, len+1); runtime·memmove(p, q, len+1);
p += len; p += len;
} }
return p - buf;
}
// appends p to hugestring
static String
gostringn(byte *p, int32 l)
{
String s;
if(l == 0)
return runtime·emptystring;
if(hugestring.str == nil) {
hugestring_len += l;
return runtime·emptystring;
}
s.str = hugestring.str + hugestring.len;
s.len = l;
hugestring.len += s.len;
runtime·memmove(s.str, p, l);
return s;
} }
// walk symtab accumulating path names for use by pc/ln table. // walk symtab accumulating path names for use by pc/ln table.
@ -181,11 +208,13 @@ dosrcline(Sym *sym)
static int32 incstart; static int32 incstart;
static int32 nfunc, nfile, nhist; static int32 nfunc, nfile, nhist;
Func *f; Func *f;
int32 i; int32 i, l;
switch(sym->symtype) { switch(sym->symtype) {
case 't': case 't':
case 'T': case 'T':
if(hugestring.str == nil)
break;
if(runtime·strcmp(sym->name, (byte*)"etext") == 0) if(runtime·strcmp(sym->name, (byte*)"etext") == 0)
break; break;
f = &func[nfunc++]; f = &func[nfunc++];
@ -200,23 +229,23 @@ dosrcline(Sym *sym)
case 'z': case 'z':
if(sym->value == 1) { if(sym->value == 1) {
// entry for main source file for a new object. // entry for main source file for a new object.
makepath(srcbuf, sizeof srcbuf, sym->name+1); l = makepath(srcbuf, sizeof srcbuf, sym->name+1);
nhist = 0; nhist = 0;
nfile = 0; nfile = 0;
if(nfile == nelem(files)) if(nfile == nelem(files))
return; return;
files[nfile].srcstring = runtime·gostring(srcbuf); files[nfile].srcstring = gostringn(srcbuf, l);
files[nfile].aline = 0; files[nfile].aline = 0;
files[nfile++].delta = 0; files[nfile++].delta = 0;
} else { } else {
// push or pop of included file. // push or pop of included file.
makepath(srcbuf, sizeof srcbuf, sym->name+1); l = makepath(srcbuf, sizeof srcbuf, sym->name+1);
if(srcbuf[0] != '\0') { if(srcbuf[0] != '\0') {
if(nhist++ == 0) if(nhist++ == 0)
incstart = sym->value; incstart = sym->value;
if(nhist == 0 && nfile < nelem(files)) { if(nhist == 0 && nfile < nelem(files)) {
// new top-level file // new top-level file
files[nfile].srcstring = runtime·gostring(srcbuf); files[nfile].srcstring = gostringn(srcbuf, l);
files[nfile].aline = sym->value; files[nfile].aline = sym->value;
// this is "line 0" // this is "line 0"
files[nfile++].delta = sym->value - 1; files[nfile++].delta = sym->value - 1;
@ -408,10 +437,12 @@ buildfuncs(void)
nfname = 0; nfname = 0;
walksymtab(dofunc); walksymtab(dofunc);
// initialize tables // Initialize tables.
func = runtime·mal((nfunc+1)*sizeof func[0]); // Can use FlagNoPointers - all pointers either point into sections of the executable
// or point into hugestring.
func = runtime·mallocgc((nfunc+1)*sizeof func[0], FlagNoPointers, 0, 1);
func[nfunc].entry = (uint64)etext; func[nfunc].entry = (uint64)etext;
fname = runtime·mal(nfname*sizeof fname[0]); fname = runtime·mallocgc(nfname*sizeof fname[0], FlagNoPointers, 0, 1);
nfunc = 0; nfunc = 0;
walksymtab(dofunc); walksymtab(dofunc);
@ -419,7 +450,13 @@ buildfuncs(void)
splitpcln(); splitpcln();
// record src file and line info for each func // record src file and line info for each func
walksymtab(dosrcline); walksymtab(dosrcline); // pass 1: determine hugestring_len
hugestring.str = runtime·mallocgc(hugestring_len, FlagNoPointers, 0, 0);
hugestring.len = 0;
walksymtab(dosrcline); // pass 2: fill and use hugestring
if(hugestring.len != hugestring_len)
runtime·throw("buildfunc: problem in initialization procedure");
m->nomemprof--; m->nomemprof--;
} }