runtime·MHeap_SysAlloc ( MHeap *h , uintptr n ) { byte *p; #line 353 "malloc.goc" if ( n <= h->arena_end - h->arena_used ) { #line 355 "malloc.goc" p = h->arena_used; runtime·SysMap ( p , n ) ; h->arena_used += n; runtime·MHeap_MapBits ( h ) ; return p; } #line 363 "malloc.goc" if ( sizeof ( void* ) == 8 ) return nil; #line 369 "malloc.goc" p = runtime·SysAlloc ( n ) ; if ( p == nil ) return nil; #line 373 "malloc.goc" if ( p < h->arena_start || p+n - h->arena_start >= MaxArena32 ) { runtime·printf ( "runtime: memory allocated by OS not in usable range\n" ) ; runtime·SysFree ( p , n ) ; return nil; } #line 379 "malloc.goc" if ( p+n > h->arena_used ) { h->arena_used = p+n; if ( h->arena_used > h->arena_end ) h->arena_end = h->arena_used; runtime·MHeap_MapBits ( h ) ; } #line 386 "malloc.goc" return p; }
runtime·MHeap_SysAlloc ( MHeap *h , uintptr n ) { byte *p; #line 2418 "C:\Go\src\pkg\runtime\malloc.goc" if ( n > h->arena_end - h->arena_used ) { #line 2421 "C:\Go\src\pkg\runtime\malloc.goc" byte *new_end; uintptr needed; #line 2424 "C:\Go\src\pkg\runtime\malloc.goc" needed = ( uintptr ) h->arena_used + n - ( uintptr ) h->arena_end; #line 2426 "C:\Go\src\pkg\runtime\malloc.goc" needed = ( needed + ( 256<<20 ) - 1 ) & ~ ( ( 256<<20 ) -1 ) ; new_end = h->arena_end + needed; if ( new_end <= h->arena_start + MaxArena32 ) { p = runtime·SysReserve ( h->arena_end , new_end - h->arena_end ) ; if ( p == h->arena_end ) h->arena_end = new_end; } } if ( n <= h->arena_end - h->arena_used ) { #line 2436 "C:\Go\src\pkg\runtime\malloc.goc" p = h->arena_used; runtime·SysMap ( p , n ) ; h->arena_used += n; runtime·MHeap_MapBits ( h ) ; return p; } #line 2444 "C:\Go\src\pkg\runtime\malloc.goc" if ( sizeof ( void* ) == 8 && ( uintptr ) h->bitmap >= 0xffffffffU ) return nil; #line 2450 "C:\Go\src\pkg\runtime\malloc.goc" p = runtime·SysAlloc ( n ) ; if ( p == nil ) return nil; #line 2454 "C:\Go\src\pkg\runtime\malloc.goc" if ( p < h->arena_start || p+n - h->arena_start >= MaxArena32 ) { runtime·printf ( "runtime: memory allocated by OS (%p) not in usable range [%p,%p)\n" , p , h->arena_start , h->arena_start+MaxArena32 ) ; runtime·SysFree ( p , n ) ; return nil; } #line 2461 "C:\Go\src\pkg\runtime\malloc.goc" if ( p+n > h->arena_used ) { h->arena_used = p+n; if ( h->arena_used > h->arena_end ) h->arena_end = h->arena_used; runtime·MHeap_MapBits ( h ) ; } #line 2468 "C:\Go\src\pkg\runtime\malloc.goc" return p; }
void runtime·MHeap_MapSpans(MHeap *h) { uintptr n; // Map spans array, PageSize at a time. n = (uintptr)h->arena_used; n -= (uintptr)h->arena_start; n = n / PageSize * sizeof(h->spans[0]); n = ROUND(n, PhysPageSize); if(h->spans_mapped >= n) return; runtime·SysMap((byte*)h->spans + h->spans_mapped, n - h->spans_mapped, h->arena_reserved, &mstats.other_sys); h->spans_mapped = n; }
void runtime·MHeap_MapSpans(MHeap *h) { uintptr n; // Map spans array, PageSize at a time. n = (uintptr)h->arena_used; if(sizeof(void*) == 8) n -= (uintptr)h->arena_start; n = n / PageSize * sizeof(h->spans[0]); n = ROUND(n, PageSize); if(h->spans_mapped >= n) return; runtime·SysMap((byte*)h->spans + h->spans_mapped, n - h->spans_mapped); h->spans_mapped = n; }
runtime·MHeap_SysAlloc(MHeap *h, uintptr n) { byte *p, *p_end; uintptr p_size; bool reserved; if(n > h->arena_end - h->arena_used) { // We are in 32-bit mode, maybe we didn't use all possible address space yet. // Reserve some more space. byte *new_end; p_size = ROUND(n + PageSize, 256<<20); new_end = h->arena_end + p_size; if(new_end <= h->arena_start + MaxArena32) { // TODO: It would be bad if part of the arena // is reserved and part is not. p = runtime·SysReserve(h->arena_end, p_size, &reserved); if(p == h->arena_end) { h->arena_end = new_end; h->arena_reserved = reserved; } else if(p+p_size <= h->arena_start + MaxArena32) { // Keep everything page-aligned. // Our pages are bigger than hardware pages. h->arena_end = p+p_size; h->arena_used = p + (-(uintptr)p&(PageSize-1)); h->arena_reserved = reserved; } else { uint64 stat; stat = 0; runtime·SysFree(p, p_size, &stat); } } } if(n <= h->arena_end - h->arena_used) { // Keep taking from our reservation. p = h->arena_used; runtime·SysMap(p, n, h->arena_reserved, &mstats.heap_sys); h->arena_used += n; runtime·MHeap_MapBits(h); runtime·MHeap_MapSpans(h); if(raceenabled) runtime·racemapshadow(p, n); if(((uintptr)p & (PageSize-1)) != 0) runtime·throw("misrounded allocation in MHeap_SysAlloc"); return p; } // If using 64-bit, our reservation is all we have. if(h->arena_end - h->arena_start >= MaxArena32) return nil; // On 32-bit, once the reservation is gone we can // try to get memory at a location chosen by the OS // and hope that it is in the range we allocated bitmap for. p_size = ROUND(n, PageSize) + PageSize; p = runtime·sysAlloc(p_size, &mstats.heap_sys); if(p == nil) return nil; if(p < h->arena_start || p+p_size - h->arena_start >= MaxArena32) { runtime·printf("runtime: memory allocated by OS (%p) not in usable range [%p,%p)\n", p, h->arena_start, h->arena_start+MaxArena32); runtime·SysFree(p, p_size, &mstats.heap_sys); return nil; } p_end = p + p_size; p += -(uintptr)p & (PageSize-1); if(p+n > h->arena_used) { h->arena_used = p+n; if(p_end > h->arena_end) h->arena_end = p_end; runtime·MHeap_MapBits(h); runtime·MHeap_MapSpans(h); if(raceenabled) runtime·racemapshadow(p, n); } if(((uintptr)p & (PageSize-1)) != 0) runtime·throw("misrounded allocation in MHeap_SysAlloc"); return p; }