diff options
Diffstat (limited to 'libgo/runtime/malloc.goc')
-rw-r--r-- | libgo/runtime/malloc.goc | 71 |
1 files changed, 40 insertions, 31 deletions
diff --git a/libgo/runtime/malloc.goc b/libgo/runtime/malloc.goc index b46995ae0b6..2ea69ee795b 100644 --- a/libgo/runtime/malloc.goc +++ b/libgo/runtime/malloc.goc @@ -26,21 +26,6 @@ extern MStats mstats; // defined in extern.go extern volatile int32 runtime_MemProfileRate __asm__ ("libgo_runtime.runtime.MemProfileRate"); -// Same algorithm from chan.c, but a different -// instance of the static uint32 x. -// Not protected by a lock - let the threads use -// the same random number if they like. -static uint32 -fastrand1(void) -{ - static uint32 x = 0x49f6428aUL; - - x += x; - if(x & 0x80000000L) - x ^= 0x88888eefUL; - return x; -} - // Allocate an object of at least size bytes. // Small objects are allocated from the per-thread cache's free lists. // Large objects (> 32 kB) are allocated straight from the heap. @@ -58,18 +43,18 @@ runtime_mallocgc(uintptr size, uint32 flag, int32 dogc, int32 zeroed) if(size == 0) size = 1; - mstats.nmalloc++; + c = m->mcache; + c->local_nmalloc++; if(size <= MaxSmallSize) { // Allocate from mcache free lists. sizeclass = runtime_SizeToClass(size); size = runtime_class_to_size[sizeclass]; - c = m->mcache; v = runtime_MCache_Alloc(c, sizeclass, size, zeroed); if(v == nil) runtime_throw("out of memory"); - mstats.alloc += size; - mstats.total_alloc += size; - mstats.by_size[sizeclass].nmalloc++; + c->local_alloc += size; + c->local_total_alloc += size; + c->local_by_size[sizeclass].nmalloc++; } else { // TODO(rsc): Report tracebacks for very large allocations. @@ -81,8 +66,8 @@ runtime_mallocgc(uintptr size, uint32 flag, int32 dogc, int32 zeroed) if(s == nil) runtime_throw("out of memory"); size = npages<<PageShift; - mstats.alloc += size; - mstats.total_alloc += size; + c->local_alloc += size; + c->local_total_alloc += size; v = (void*)(s->start << PageShift); // setup for mark sweep @@ -113,7 +98,7 @@ runtime_mallocgc(uintptr size, uint32 flag, int32 dogc, int32 zeroed) // pick next profile time if(rate > 0x3fffffff) // make 2*rate not overflow rate = 0x3fffffff; - m->mcache->next_sample = fastrand1() % (2*rate); + m->mcache->next_sample = runtime_fastrand1() % (2*rate); profile: runtime_setblockspecial(v); runtime_MProf_Malloc(v, size); @@ -158,6 +143,7 @@ __go_free(void *v) // Find size class for v. sizeclass = s->sizeclass; + c = m->mcache; if(sizeclass == 0) { // Large object. size = s->npages<<PageShift; @@ -169,18 +155,17 @@ __go_free(void *v) runtime_MHeap_Free(&runtime_mheap, s, 1); } else { // Small object. - c = m->mcache; size = runtime_class_to_size[sizeclass]; - if(size > (int32)sizeof(uintptr)) + if(size > sizeof(uintptr)) ((uintptr*)v)[1] = 1; // mark as "needs to be zeroed" // Must mark v freed before calling MCache_Free: // it might coalesce v and other blocks into a bigger span // and change the bitmap further. runtime_markfreed(v, size); - mstats.by_size[sizeclass].nfree++; + c->local_by_size[sizeclass].nfree++; runtime_MCache_Free(c, v, sizeclass, size); } - mstats.alloc -= size; + c->local_alloc -= size; if(prof) runtime_MProf_Free(v, size); @@ -197,7 +182,7 @@ runtime_mlookup(void *v, byte **base, uintptr *size, MSpan **sp) byte *p; MSpan *s; - mstats.nlookup++; + m->mcache->local_nlookup++; s = runtime_MHeap_LookupMaybe(&runtime_mheap, v); if(sp) *sp = s; @@ -226,9 +211,10 @@ runtime_mlookup(void *v, byte **base, uintptr *size, MSpan **sp) } n = runtime_class_to_size[s->sizeclass]; - i = ((byte*)v - p)/n; - if(base) + if(base) { + i = ((byte*)v - p)/n; *base = p + i*n; + } if(size) *size = n; @@ -260,7 +246,30 @@ runtime_allocmcache(void) return c; } -extern int32 runtime_sizeof_C_MStats +void +runtime_purgecachedstats(M* m) +{ + MCache *c; + + // Protected by either heap or GC lock. + c = m->mcache; + mstats.heap_alloc += c->local_cachealloc; + c->local_cachealloc = 0; + mstats.heap_objects += c->local_objects; + c->local_objects = 0; + mstats.nmalloc += c->local_nmalloc; + c->local_nmalloc = 0; + mstats.nfree += c->local_nfree; + c->local_nfree = 0; + mstats.nlookup += c->local_nlookup; + c->local_nlookup = 0; + mstats.alloc += c->local_alloc; + c->local_alloc= 0; + mstats.total_alloc += c->local_total_alloc; + c->local_total_alloc= 0; +} + +extern uintptr runtime_sizeof_C_MStats __asm__ ("libgo_runtime.runtime.Sizeof_C_MStats"); #define MaxArena32 (2U<<30) |