diff --git a/src/pkg/runtime/malloc.goc b/src/pkg/runtime/malloc.goc index b59693b5989..cf18e8c9e59 100644 --- a/src/pkg/runtime/malloc.goc +++ b/src/pkg/runtime/malloc.goc @@ -484,6 +484,53 @@ runtime·MHeap_SysAlloc(MHeap *h, uintptr n) return p; } +static struct +{ + Lock; + byte* pos; + byte* end; +} persistent; + +enum +{ + PersistentAllocChunk = 256<<10, + PersistentAllocMaxBlock = 64<<10, // VM reservation granularity is 64K on windows +}; + +// Wrapper around SysAlloc that can allocate small chunks. +// There is no associated free operation. +// Intended for things like function/type/debug-related persistent data. +// If align is 0, uses default align (currently 8). +void* +runtime·persistentalloc(uintptr size, uintptr align) +{ + byte *p; + + if(align) { + if(align&(align-1)) + runtime·throw("persistentalloc: align is now a power of 2"); + if(align > PageSize) + runtime·throw("persistentalloc: align is too large"); + } else + align = 8; + if(size >= PersistentAllocMaxBlock) + return runtime·SysAlloc(size); + runtime·lock(&persistent); + persistent.pos = (byte*)ROUND((uintptr)persistent.pos, align); + if(persistent.pos + size > persistent.end) { + persistent.pos = runtime·SysAlloc(PersistentAllocChunk); + if(persistent.pos == nil) { + runtime·unlock(&persistent); + runtime·throw("runtime: cannot allocate memory"); + } + persistent.end = persistent.pos + PersistentAllocChunk; + } + p = persistent.pos; + persistent.pos += size; + runtime·unlock(&persistent); + return p; +} + static Lock settype_lock; void diff --git a/src/pkg/runtime/malloc.h b/src/pkg/runtime/malloc.h index e732e3d15d6..99a19660716 100644 --- a/src/pkg/runtime/malloc.h +++ b/src/pkg/runtime/malloc.h @@ -445,6 +445,7 @@ void runtime·MHeap_MapBits(MHeap *h); void runtime·MHeap_Scavenger(void); void* runtime·mallocgc(uintptr size, uint32 flag, int32 dogc, int32 zeroed); +void* runtime·persistentalloc(uintptr size, uintptr align); int32 runtime·mlookup(void *v, byte **base, uintptr *size, MSpan **s); void runtime·gc(int32 force); void runtime·markallocated(void *v, uintptr n, bool noptr); diff --git a/src/pkg/runtime/symtab.c b/src/pkg/runtime/symtab.c index 5edcb49bda8..fdebe2cae37 100644 --- a/src/pkg/runtime/symtab.c +++ b/src/pkg/runtime/symtab.c @@ -69,11 +69,6 @@ struct Sym static uintptr mainoffset; -// A dynamically allocated string containing multiple substrings. -// Individual strings are slices of hugestring. -static String hugestring; -static int32 hugestring_len; - extern void main·main(void); static uintptr @@ -288,7 +283,6 @@ makepath(byte *buf, int32 nbuf, byte *path) return p - buf; } -// appends p to hugestring static String gostringn(byte *p, int32 l) { @@ -296,13 +290,8 @@ gostringn(byte *p, int32 l) 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; + s.str = runtime·persistentalloc(l, 1); runtime·memmove(s.str, p, l); return s; } @@ -333,8 +322,6 @@ dosrcline(Sym *sym) switch(sym->symtype) { case 't': case 'T': - if(hugestring.str == nil) - break; if(runtime·strcmp(sym->name, (byte*)"etext") == 0) break; f = &func[nfunc++]; @@ -559,11 +546,12 @@ buildfuncs(void) walksymtab(dofunc); // Initialize tables. - // 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); + // Memory obtained from runtime·persistentalloc() is not scanned by GC, + // this is fine because all pointers either point into sections of the executable + // or also obtained from persistentmalloc(). + func = runtime·persistentalloc((nfunc+1)*sizeof func[0], 0); func[nfunc].entry = (uint64)etext; - fname = runtime·mallocgc(nfname*sizeof fname[0], FlagNoPointers, 0, 1); + fname = runtime·persistentalloc(nfname*sizeof fname[0], 0); nfunc = 0; lastvalue = 0; walksymtab(dofunc); @@ -573,15 +561,9 @@ buildfuncs(void) // record src file and line info for each func files = runtime·malloc(maxfiles * sizeof(files[0])); - 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 + walksymtab(dosrcline); files = nil; - if(hugestring.len != hugestring_len) - runtime·throw("buildfunc: problem in initialization procedure"); - m->nomemprof--; }