void runtime·largeAlloc_m(void) { uintptr npages, size; MSpan *s; void *v; int32 flag; //runtime·printf("largeAlloc size=%D\n", g->m->scalararg[0]); // Allocate directly from heap. size = g->m->scalararg[0]; flag = (int32)g->m->scalararg[1]; if(size + PageSize < size) runtime·throw("out of memory"); npages = size >> PageShift; if((size & PageMask) != 0) npages++; s = runtime·MHeap_Alloc(&runtime·mheap, npages, 0, 1, !(flag & FlagNoZero)); if(s == nil) runtime·throw("out of memory"); s->limit = (byte*)(s->start<<PageShift) + size; v = (void*)(s->start << PageShift); // setup for mark sweep runtime·markspan(v, 0, 0, true); g->m->ptrarg[0] = s; }
// Fetch a new span from the heap and // carve into objects for the free list. static bool MCentral_Grow(MCentral *c) { uintptr size, npages, i, n; MLink **tailp, *v; byte *p; MSpan *s; runtime·unlock(&c->lock); npages = runtime·class_to_allocnpages[c->sizeclass]; size = runtime·class_to_size[c->sizeclass]; n = (npages << PageShift) / size; s = runtime·MHeap_Alloc(&runtime·mheap, npages, c->sizeclass, 0, 1); if(s == nil) { // TODO(rsc): Log out of memory runtime·lock(&c->lock); return false; } // Carve span into sequence of blocks. tailp = &s->freelist; p = (byte*)(s->start << PageShift); s->limit = p + size*n; for(i=0; i<n; i++) { v = (MLink*)p; *tailp = v; tailp = &v->next; p += size; } *tailp = nil; runtime·markspan((byte*)(s->start<<PageShift), size, n, size*n < (s->npages<<PageShift)); runtime·lock(&c->lock); runtime·MSpanList_Insert(&c->nonempty, s); return true; }
// Fetch a new span from the heap and // carve into objects for the free list. static bool MCentral_Grow(MCentral *c) { int32 i, n, npages; uintptr size; MLink **tailp, *v; byte *p; MSpan *s; runtime·unlock(c); runtime·MGetSizeClassInfo(c->sizeclass, &size, &npages, &n); s = runtime·MHeap_Alloc(&runtime·mheap, npages, c->sizeclass, 0, 1); if(s == nil) { // TODO(rsc): Log out of memory runtime·lock(c); return false; } // Carve span into sequence of blocks. tailp = &s->freelist; p = (byte*)(s->start << PageShift); s->limit = p + size*n; for(i=0; i<n; i++) { v = (MLink*)p; *tailp = v; tailp = &v->next; p += size; } *tailp = nil; runtime·markspan((byte*)(s->start<<PageShift), size, n, size*n < (s->npages<<PageShift)); runtime·lock(c); c->nfree += n; runtime·MSpanList_Insert(&c->nonempty, s); return true; }
runtime·mallocgc ( uintptr size , uint32 flag , int32 dogc , int32 zeroed ) { int32 sizeclass , rate; MCache *c; uintptr npages; MSpan *s; void *v; #line 2080 "C:\Go\src\pkg\runtime\malloc.goc" if ( runtime·gcwaiting && g != m->g0 && m->locks == 0 ) runtime·gosched ( ) ; if ( m->mallocing ) runtime·throw ( "malloc/free - deadlock" ) ; m->mallocing = 1; if ( size == 0 ) size = 1; #line 2088 "C:\Go\src\pkg\runtime\malloc.goc" c = m->mcache; c->local_nmalloc++; if ( size <= MaxSmallSize ) { #line 2092 "C:\Go\src\pkg\runtime\malloc.goc" sizeclass = runtime·SizeToClass ( size ) ; size = runtime·class_to_size[sizeclass]; v = runtime·MCache_Alloc ( c , sizeclass , size , zeroed ) ; if ( v == nil ) runtime·throw ( "out of memory" ) ; c->local_alloc += size; c->local_total_alloc += size; c->local_by_size[sizeclass].nmalloc++; } else { #line 2104 "C:\Go\src\pkg\runtime\malloc.goc" npages = size >> PageShift; if ( ( size & PageMask ) != 0 ) npages++; s = runtime·MHeap_Alloc ( &runtime·mheap , npages , 0 , 1 ) ; if ( s == nil ) runtime·throw ( "out of memory" ) ; size = npages<<PageShift; c->local_alloc += size; c->local_total_alloc += size; v = ( void* ) ( s->start << PageShift ) ; #line 2116 "C:\Go\src\pkg\runtime\malloc.goc" runtime·markspan ( v , 0 , 0 , true ) ; } if ( ! ( flag & FlagNoGC ) ) runtime·markallocated ( v , size , ( flag&FlagNoPointers ) != 0 ) ; #line 2121 "C:\Go\src\pkg\runtime\malloc.goc" m->mallocing = 0; #line 2123 "C:\Go\src\pkg\runtime\malloc.goc" if ( ! ( flag & FlagNoProfiling ) && ( rate = runtime·MemProfileRate ) > 0 ) { if ( size >= rate ) goto profile; if ( m->mcache->next_sample > size ) m->mcache->next_sample -= size; else { #line 2131 "C:\Go\src\pkg\runtime\malloc.goc" if ( rate > 0x3fffffff ) rate = 0x3fffffff; m->mcache->next_sample = runtime·fastrand1 ( ) % ( 2*rate ) ; profile: runtime·setblockspecial ( v , true ) ; runtime·MProf_Malloc ( v , size ) ; } } #line 2140 "C:\Go\src\pkg\runtime\malloc.goc" if ( dogc && mstats.heap_alloc >= mstats.next_gc ) runtime·gc ( 0 ) ; return v; }