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
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);
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
return p - buf;
}
-// appends p to hugestring
static String
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;
}
switch(sym->symtype) {
case 't':
case 'T':
- if(hugestring.str == nil)
- break;
if(runtime·strcmp(sym->name, (byte*)"etext") == 0)
break;
f = &func[nfunc++];
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);
// 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--;
}