bool runtime·addfinalizer(void *p, void (*f)(void*), int32 nret) { Fintab *tab; byte *base; if(debug) { if(!runtime·mlookup(p, &base, nil, nil) || p != base) runtime·throw("addfinalizer on invalid pointer"); } tab = TAB(p); runtime·lock(tab); if(f == nil) { lookfintab(tab, p, true, nil); runtime·unlock(tab); return true; } if(lookfintab(tab, p, false, nil)) { runtime·unlock(tab); return false; } if(tab->nkey >= tab->max/2+tab->max/4) { // keep table at most 3/4 full: // allocate new table and rehash. resizefintab(tab); } addfintab(tab, p, f, nret); runtime·setblockspecial(p, true); runtime·unlock(tab); 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; }