// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// See malloc.h for overview.
//
// TODO(rsc): double-check stats.

package runtime
#include <stddef.h>
#include <errno.h>
#include <stdlib.h>
#include "go-alloc.h"
#include "runtime.h"
#include "arch.h"
#include "malloc.h"
#include "interface.h"
#include "go-type.h"
#include "race.h"

// Map gccgo field names to gc field names.
// Eface aka __go_empty_interface.
#define type __type_descriptor
// Type aka __go_type_descriptor
#define kind __code
#define string __reflection
#define KindPtr GO_PTR
#define KindNoPointers GO_NO_POINTERS

// GCCGO SPECIFIC CHANGE
//
// There is a long comment in runtime_mallocinit about where to put the heap
// on a 64-bit system.  It makes assumptions that are not valid on linux/arm64
// -- it assumes user space can choose the lower 47 bits of a pointer, but on
// linux/arm64 we can only choose the lower 39 bits.  This means the heap is
// roughly a quarter of the available address space and we cannot choose a bit
// pattern that all pointers will have -- luckily the GC is mostly precise
// these days so this doesn't matter all that much.  The kernel (as of 3.13)
// will allocate address space starting either down from 0x7fffffffff or up
// from 0x2000000000, so we put the heap roughly in the middle of these two
// addresses to minimize the chance that a non-heap allocation will get in the
// way of the heap.
//
// This all means that there isn't much point in trying 256 different
// locations for the heap on such systems.
#ifdef __aarch64__
#define HeapBase(i) ((void*)(uintptr)(0x40ULL<<32))
#define HeapBaseOptions 1
#else
#define HeapBase(i) ((void*)(uintptr)(i<<40|0x00c0ULL<<32))
#define HeapBaseOptions 0x80
#endif
// END GCCGO SPECIFIC CHANGE

// Mark mheap as 'no pointers', it does not contain interesting pointers but occupies ~45K.
MHeap runtime_mheap;
MStats mstats;

int32	runtime_checking;

extern MStats mstats;	// defined in zruntime_def_$GOOS_$GOARCH.go

extern volatile intgo runtime_MemProfileRate
  __asm__ (GOSYM_PREFIX "runtime.MemProfileRate");

static MSpan* largealloc(uint32, uintptr*);
static void profilealloc(void *v, uintptr size);
static void settype(MSpan *s, void *v, uintptr typ);

// 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.
// If the block will be freed with runtime_free(), typ must be 0.
void*
runtime_mallocgc(uintptr size, uintptr typ, uint32 flag)
{
	M *m;
	G *g;
	int32 sizeclass;
	uintptr tinysize, size1;
	intgo rate;
	MCache *c;
	MSpan *s;
	MLink *v, *next;
	byte *tiny;
	bool incallback;
	void *closure;

	if(size == 0) {
		// All 0-length allocations use this pointer.
		// The language does not require the allocations to
		// have distinct values.
		return &runtime_zerobase;
	}

	m = runtime_m();
	g = runtime_g();

	// We should not be called in between __go_set_closure and the
	// actual function call, but cope with it if we are.
	closure = g->closure;

	incallback = false;
	if(m->mcache == nil && g->ncgo > 0) {
		// For gccgo this case can occur when a cgo or SWIG function
		// has an interface return type and the function
		// returns a non-pointer, so memory allocation occurs
		// after syscall.Cgocall but before syscall.CgocallDone.
		// We treat it as a callback.
		runtime_exitsyscall();
		m = runtime_m();
		incallback = true;
		flag |= FlagNoInvokeGC;
	}

	if(runtime_gcwaiting() && g != m->g0 && m->locks == 0 && !(flag & FlagNoInvokeGC)) {
		runtime_gosched();
		m = runtime_m();
	}
	if(m->mallocing)
		runtime_throw("malloc/free - deadlock");
	// Disable preemption during settype.
	// We can not use m->mallocing for this, because settype calls mallocgc.
	m->locks++;
	m->mallocing = 1;

	if(DebugTypeAtBlockEnd)
		size += sizeof(uintptr);

	c = m->mcache;
	if(!runtime_debug.efence && size <= MaxSmallSize) {
		if((flag&(FlagNoScan|FlagNoGC)) == FlagNoScan && size < TinySize) {
			// Tiny allocator.
			//
			// Tiny allocator combines several tiny allocation requests
			// into a single memory block. The resulting memory block
			// is freed when all subobjects are unreachable. The subobjects
			// must be FlagNoScan (don't have pointers), this ensures that
			// the amount of potentially wasted memory is bounded.
			//
			// Size of the memory block used for combining (TinySize) is tunable.
			// Current setting is 16 bytes, which relates to 2x worst case memory
			// wastage (when all but one subobjects are unreachable).
			// 8 bytes would result in no wastage at all, but provides less
			// opportunities for combining.
			// 32 bytes provides more opportunities for combining,
			// but can lead to 4x worst case wastage.
			// The best case winning is 8x regardless of block size.
			//
			// Objects obtained from tiny allocator must not be freed explicitly.
			// So when an object will be freed explicitly, we ensure that
			// its size >= TinySize.
			//
			// SetFinalizer has a special case for objects potentially coming
			// from tiny allocator, it such case it allows to set finalizers
			// for an inner byte of a memory block.
			//
			// The main targets of tiny allocator are small strings and
			// standalone escaping variables. On a json benchmark
			// the allocator reduces number of allocations by ~12% and
			// reduces heap size by ~20%.

			tinysize = c->tinysize;
			if(size <= tinysize) {
				tiny = c->tiny;
				// Align tiny pointer for required (conservative) alignment.
				if((size&7) == 0)
					tiny = (byte*)ROUND((uintptr)tiny, 8);
				else if((size&3) == 0)
					tiny = (byte*)ROUND((uintptr)tiny, 4);
				else if((size&1) == 0)
					tiny = (byte*)ROUND((uintptr)tiny, 2);
				size1 = size + (tiny - c->tiny);
				if(size1 <= tinysize) {
					// The object fits into existing tiny block.
					v = (MLink*)tiny;
					c->tiny += size1;
					c->tinysize -= size1;
					m->mallocing = 0;
					m->locks--;
					if(incallback)
						runtime_entersyscall();
					g->closure = closure;
					return v;
				}
			}
			// Allocate a new TinySize block.
			s = c->alloc[TinySizeClass];
			if(s->freelist == nil)
				s = runtime_MCache_Refill(c, TinySizeClass);
			v = s->freelist;
			next = v->next;
			s->freelist = next;
			s->ref++;
			if(next != nil)  // prefetching nil leads to a DTLB miss
				PREFETCH(next);
			((uint64*)v)[0] = 0;
			((uint64*)v)[1] = 0;
			// See if we need to replace the existing tiny block with the new one
			// based on amount of remaining free space.
			if(TinySize-size > tinysize) {
				c->tiny = (byte*)v + size;
				c->tinysize = TinySize - size;
			}
			size = TinySize;
			goto done;
		}
		// Allocate from mcache free lists.
		// Inlined version of SizeToClass().
		if(size <= 1024-8)
			sizeclass = runtime_size_to_class8[(size+7)>>3];
		else
			sizeclass = runtime_size_to_class128[(size-1024+127) >> 7];
		size = runtime_class_to_size[sizeclass];
		s = c->alloc[sizeclass];
		if(s->freelist == nil)
			s = runtime_MCache_Refill(c, sizeclass);
		v = s->freelist;
		next = v->next;
		s->freelist = next;
		s->ref++;
		if(next != nil)  // prefetching nil leads to a DTLB miss
			PREFETCH(next);
		if(!(flag & FlagNoZero)) {
			v->next = nil;
			// block is zeroed iff second word is zero ...
			if(size > 2*sizeof(uintptr) && ((uintptr*)v)[1] != 0)
				runtime_memclr((byte*)v, size);
		}
	done:
		c->local_cachealloc += size;
	} else {
		// Allocate directly from heap.
		s = largealloc(flag, &size);
		v = (void*)(s->start << PageShift);
	}

	if(flag & FlagNoGC)
		runtime_marknogc(v);
	else if(!(flag & FlagNoScan))
		runtime_markscan(v);

	if(DebugTypeAtBlockEnd)
		*(uintptr*)((uintptr)v+size-sizeof(uintptr)) = typ;

	m->mallocing = 0;
	// TODO: save type even if FlagNoScan?  Potentially expensive but might help
	// heap profiling/tracing.
	if(UseSpanType && !(flag & FlagNoScan) && typ != 0)
		settype(s, v, typ);

	if(raceenabled)
		runtime_racemalloc(v, size);

	if(runtime_debug.allocfreetrace)
		runtime_tracealloc(v, size, typ);

	if(!(flag & FlagNoProfiling) && (rate = runtime_MemProfileRate) > 0) {
		if(size < (uintptr)rate && size < (uintptr)(uint32)c->next_sample)
			c->next_sample -= size;
		else
			profilealloc(v, size);
	}

	m->locks--;

	if(!(flag & FlagNoInvokeGC) && mstats.heap_alloc >= mstats.next_gc)
		runtime_gc(0);

	if(incallback)
		runtime_entersyscall();

	g->closure = closure;

	return v;
}

static MSpan*
largealloc(uint32 flag, uintptr *sizep)
{
	uintptr npages, size;
	MSpan *s;
	void *v;

	// Allocate directly from heap.
	size = *sizep;
	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;
	*sizep = npages<<PageShift;
	v = (void*)(s->start << PageShift);
	// setup for mark sweep
	runtime_markspan(v, 0, 0, true);
	return s;
}

static void
profilealloc(void *v, uintptr size)
{
	uintptr rate;
	int32 next;
	MCache *c;

	c = runtime_m()->mcache;
	rate = runtime_MemProfileRate;
	if(size < rate) {
		// pick next profile time
		// If you change this, also change allocmcache.
		if(rate > 0x3fffffff)	// make 2*rate not overflow
			rate = 0x3fffffff;
		next = runtime_fastrand1() % (2*rate);
		// Subtract the "remainder" of the current allocation.
		// Otherwise objects that are close in size to sampling rate
		// will be under-sampled, because we consistently discard this remainder.
		next -= (size - c->next_sample);
		if(next < 0)
			next = 0;
		c->next_sample = next;
	}
	runtime_MProf_Malloc(v, size);
}

void*
__go_alloc(uintptr size)
{
	return runtime_mallocgc(size, 0, FlagNoInvokeGC);
}

// Free the object whose base pointer is v.
void
__go_free(void *v)
{
	M *m;
	int32 sizeclass;
	MSpan *s;
	MCache *c;
	uintptr size;

	if(v == nil)
		return;
	
	// If you change this also change mgc0.c:/^sweep,
	// which has a copy of the guts of free.

	m = runtime_m();
	if(m->mallocing)
		runtime_throw("malloc/free - deadlock");
	m->mallocing = 1;

	if(!runtime_mlookup(v, nil, nil, &s)) {
		runtime_printf("free %p: not an allocated block\n", v);
		runtime_throw("free runtime_mlookup");
	}
	size = s->elemsize;
	sizeclass = s->sizeclass;
	// Objects that are smaller than TinySize can be allocated using tiny alloc,
	// if then such object is combined with an object with finalizer, we will crash.
	if(size < TinySize)
		runtime_throw("freeing too small block");

	if(runtime_debug.allocfreetrace)
		runtime_tracefree(v, size);

	// Ensure that the span is swept.
	// If we free into an unswept span, we will corrupt GC bitmaps.
	runtime_MSpan_EnsureSwept(s);

	if(s->specials != nil)
		runtime_freeallspecials(s, v, size);

	c = m->mcache;
	if(sizeclass == 0) {
		// Large object.
		s->needzero = 1;
		// Must mark v freed before calling unmarkspan and MHeap_Free:
		// they might coalesce v into other spans and change the bitmap further.
		runtime_markfreed(v);
		runtime_unmarkspan(v, 1<<PageShift);
		// NOTE(rsc,dvyukov): The original implementation of efence
		// in CL 22060046 used SysFree instead of SysFault, so that
		// the operating system would eventually give the memory
		// back to us again, so that an efence program could run
		// longer without running out of memory. Unfortunately,
		// calling SysFree here without any kind of adjustment of the
		// heap data structures means that when the memory does
		// come back to us, we have the wrong metadata for it, either in
		// the MSpan structures or in the garbage collection bitmap.
		// Using SysFault here means that the program will run out of
		// memory fairly quickly in efence mode, but at least it won't
		// have mysterious crashes due to confused memory reuse.
		// It should be possible to switch back to SysFree if we also 
		// implement and then call some kind of MHeap_DeleteSpan.
		if(runtime_debug.efence)
			runtime_SysFault((void*)(s->start<<PageShift), size);
		else
			runtime_MHeap_Free(&runtime_mheap, s, 1);
		c->local_nlargefree++;
		c->local_largefree += size;
	} else {
		// Small object.
		if(size > 2*sizeof(uintptr))
			((uintptr*)v)[1] = (uintptr)0xfeedfeedfeedfeedll;	// mark as "needs to be zeroed"
		else if(size > sizeof(uintptr))
			((uintptr*)v)[1] = 0;
		// Must mark v freed before calling MCache_Free:
		// it might coalesce v and other blocks into a bigger span
		// and change the bitmap further.
		c->local_nsmallfree[sizeclass]++;
		c->local_cachealloc -= size;
		if(c->alloc[sizeclass] == s) {
			// We own the span, so we can just add v to the freelist
			runtime_markfreed(v);
			((MLink*)v)->next = s->freelist;
			s->freelist = v;
			s->ref--;
		} else {
			// Someone else owns this span.  Add to free queue.
			runtime_MCache_Free(c, v, sizeclass, size);
		}
	}
	m->mallocing = 0;
}

int32
runtime_mlookup(void *v, byte **base, uintptr *size, MSpan **sp)
{
	M *m;
	uintptr n, i;
	byte *p;
	MSpan *s;

	m = runtime_m();

	m->mcache->local_nlookup++;
	if (sizeof(void*) == 4 && m->mcache->local_nlookup >= (1<<30)) {
		// purge cache stats to prevent overflow
		runtime_lock(&runtime_mheap.lock);
		runtime_purgecachedstats(m->mcache);
		runtime_unlock(&runtime_mheap.lock);
	}

	s = runtime_MHeap_LookupMaybe(&runtime_mheap, v);
	if(sp)
		*sp = s;
	if(s == nil) {
		runtime_checkfreed(v, 1);
		if(base)
			*base = nil;
		if(size)
			*size = 0;
		return 0;
	}

	p = (byte*)((uintptr)s->start<<PageShift);
	if(s->sizeclass == 0) {
		// Large object.
		if(base)
			*base = p;
		if(size)
			*size = s->npages<<PageShift;
		return 1;
	}

	n = s->elemsize;
	if(base) {
		i = ((byte*)v - p)/n;
		*base = p + i*n;
	}
	if(size)
		*size = n;

	return 1;
}

void
runtime_purgecachedstats(MCache *c)
{
	MHeap *h;
	int32 i;

	// Protected by either heap or GC lock.
	h = &runtime_mheap;
	mstats.heap_alloc += c->local_cachealloc;
	c->local_cachealloc = 0;
	mstats.nlookup += c->local_nlookup;
	c->local_nlookup = 0;
	h->largefree += c->local_largefree;
	c->local_largefree = 0;
	h->nlargefree += c->local_nlargefree;
	c->local_nlargefree = 0;
	for(i=0; i<(int32)nelem(c->local_nsmallfree); i++) {
		h->nsmallfree[i] += c->local_nsmallfree[i];
		c->local_nsmallfree[i] = 0;
	}
}

extern uintptr runtime_sizeof_C_MStats
  __asm__ (GOSYM_PREFIX "runtime.Sizeof_C_MStats");

// Size of the trailing by_size array differs between Go and C,
// NumSizeClasses was changed, but we can not change Go struct because of backward compatibility.
// sizeof_C_MStats is what C thinks about size of Go struct.

// Initialized in mallocinit because it's defined in go/runtime/mem.go.

#define MaxArena32 (2U<<30)

void
runtime_mallocinit(void)
{
	byte *p, *p1;
	uintptr arena_size, bitmap_size, spans_size, p_size;
	extern byte _end[];
	uintptr limit;
	uint64 i;
	bool reserved;

	runtime_sizeof_C_MStats = sizeof(MStats) - (NumSizeClasses - 61) * sizeof(mstats.by_size[0]);

	p = nil;
	p_size = 0;
	arena_size = 0;
	bitmap_size = 0;
	spans_size = 0;
	reserved = false;

	// for 64-bit build
	USED(p);
	USED(p_size);
	USED(arena_size);
	USED(bitmap_size);
	USED(spans_size);

	runtime_InitSizes();

	if(runtime_class_to_size[TinySizeClass] != TinySize)
		runtime_throw("bad TinySizeClass");

	// limit = runtime_memlimit();
	// See https://code.google.com/p/go/issues/detail?id=5049
	// TODO(rsc): Fix after 1.1.
	limit = 0;

	// Set up the allocation arena, a contiguous area of memory where
	// allocated data will be found.  The arena begins with a bitmap large
	// enough to hold 4 bits per allocated word.
	if(sizeof(void*) == 8 && (limit == 0 || limit > (1<<30))) {
		// On a 64-bit machine, allocate from a single contiguous reservation.
		// 128 GB (MaxMem) should be big enough for now.
		//
		// The code will work with the reservation at any address, but ask
		// SysReserve to use 0x0000XXc000000000 if possible (XX=00...7f).
		// Allocating a 128 GB region takes away 37 bits, and the amd64
		// doesn't let us choose the top 17 bits, so that leaves the 11 bits
		// in the middle of 0x00c0 for us to choose.  Choosing 0x00c0 means
		// that the valid memory addresses will begin 0x00c0, 0x00c1, ..., 0x00df.
		// In little-endian, that's c0 00, c1 00, ..., df 00. None of those are valid
		// UTF-8 sequences, and they are otherwise as far away from 
		// ff (likely a common byte) as possible.  If that fails, we try other 0xXXc0
		// addresses.  An earlier attempt to use 0x11f8 caused out of memory errors
		// on OS X during thread allocations.  0x00c0 causes conflicts with
		// AddressSanitizer which reserves all memory up to 0x0100.
		// These choices are both for debuggability and to reduce the
		// odds of the conservative garbage collector not collecting memory
		// because some non-pointer block of memory had a bit pattern
		// that matched a memory address.
		//
		// Actually we reserve 136 GB (because the bitmap ends up being 8 GB)
		// but it hardly matters: e0 00 is not valid UTF-8 either.
		//
		// If this fails we fall back to the 32 bit memory mechanism
		arena_size = MaxMem;
		bitmap_size = arena_size / (sizeof(void*)*8/4);
		spans_size = arena_size / PageSize * sizeof(runtime_mheap.spans[0]);
		spans_size = ROUND(spans_size, PageSize);
		for(i = 0; i < HeapBaseOptions; i++) {
			p = HeapBase(i);
			p_size = bitmap_size + spans_size + arena_size + PageSize;
			p = runtime_SysReserve(p, p_size, &reserved);
			if(p != nil)
				break;
		}
	}
	if (p == nil) {
		// On a 32-bit machine, we can't typically get away
		// with a giant virtual address space reservation.
		// Instead we map the memory information bitmap
		// immediately after the data segment, large enough
		// to handle another 2GB of mappings (256 MB),
		// along with a reservation for another 512 MB of memory.
		// When that gets used up, we'll start asking the kernel
		// for any memory anywhere and hope it's in the 2GB
		// following the bitmap (presumably the executable begins
		// near the bottom of memory, so we'll have to use up
		// most of memory before the kernel resorts to giving out
		// memory before the beginning of the text segment).
		//
		// Alternatively we could reserve 512 MB bitmap, enough
		// for 4GB of mappings, and then accept any memory the
		// kernel threw at us, but normally that's a waste of 512 MB
		// of address space, which is probably too much in a 32-bit world.
		bitmap_size = MaxArena32 / (sizeof(void*)*8/4);
		arena_size = 512<<20;
		spans_size = MaxArena32 / PageSize * sizeof(runtime_mheap.spans[0]);
		if(limit > 0 && arena_size+bitmap_size+spans_size > limit) {
			bitmap_size = (limit / 9) & ~((1<<PageShift) - 1);
			arena_size = bitmap_size * 8;
			spans_size = arena_size / PageSize * sizeof(runtime_mheap.spans[0]);
		}
		spans_size = ROUND(spans_size, PageSize);

		// SysReserve treats the address we ask for, end, as a hint,
		// not as an absolute requirement.  If we ask for the end
		// of the data segment but the operating system requires
		// a little more space before we can start allocating, it will
		// give out a slightly higher pointer.  Except QEMU, which
		// is buggy, as usual: it won't adjust the pointer upward.
		// So adjust it upward a little bit ourselves: 1/4 MB to get
		// away from the running binary image and then round up
		// to a MB boundary.
		p = (byte*)ROUND((uintptr)_end + (1<<18), 1<<20);
		p_size = bitmap_size + spans_size + arena_size + PageSize;
		p = runtime_SysReserve(p, p_size, &reserved);
		if(p == nil)
			runtime_throw("runtime: cannot reserve arena virtual address space");
	}

	// PageSize can be larger than OS definition of page size,
	// so SysReserve can give us a PageSize-unaligned pointer.
	// To overcome this we ask for PageSize more and round up the pointer.
	p1 = (byte*)ROUND((uintptr)p, PageSize);

	runtime_mheap.spans = (MSpan**)p1;
	runtime_mheap.bitmap = p1 + spans_size;
	runtime_mheap.arena_start = p1 + spans_size + bitmap_size;
	runtime_mheap.arena_used = runtime_mheap.arena_start;
	runtime_mheap.arena_end = p + p_size;
	runtime_mheap.arena_reserved = reserved;

	if(((uintptr)runtime_mheap.arena_start & (PageSize-1)) != 0)
		runtime_throw("misrounded allocation in mallocinit");

	// Initialize the rest of the allocator.	
	runtime_MHeap_Init(&runtime_mheap);
	runtime_m()->mcache = runtime_allocmcache();

	// See if it works.
	runtime_free(runtime_malloc(TinySize));
}

void*
runtime_MHeap_SysAlloc(MHeap *h, uintptr n)
{
	byte *p, *p_end;
	uintptr p_size;
	bool reserved;


	if(n > (uintptr)(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 <= (uintptr)(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((uintptr)(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 || (uintptr)(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;
}

static struct
{
	Lock	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, uint64 *stat)
{
	byte *p;

	if(align != 0) {
		if(align&(align-1))
			runtime_throw("persistentalloc: align is not a power of 2");
		if(align > PageSize)
			runtime_throw("persistentalloc: align is too large");
	} else
		align = 8;
	if(size >= PersistentAllocMaxBlock)
		return runtime_SysAlloc(size, stat);
	runtime_lock(&persistent.lock);
	persistent.pos = (byte*)ROUND((uintptr)persistent.pos, align);
	if(persistent.pos + size > persistent.end) {
		persistent.pos = runtime_SysAlloc(PersistentAllocChunk, &mstats.other_sys);
		if(persistent.pos == nil) {
			runtime_unlock(&persistent.lock);
			runtime_throw("runtime: cannot allocate memory");
		}
		persistent.end = persistent.pos + PersistentAllocChunk;
	}
	p = persistent.pos;
	persistent.pos += size;
	runtime_unlock(&persistent.lock);
	if(stat != &mstats.other_sys) {
		// reaccount the allocation against provided stat
		runtime_xadd64(stat, size);
		runtime_xadd64(&mstats.other_sys, -(uint64)size);
	}
	return p;
}

static void
settype(MSpan *s, void *v, uintptr typ)
{
	uintptr size, ofs, j, t;
	uintptr ntypes, nbytes2, nbytes3;
	uintptr *data2;
	byte *data3;

	if(s->sizeclass == 0) {
		s->types.compression = MTypes_Single;
		s->types.data = typ;
		return;
	}
	size = s->elemsize;
	ofs = ((uintptr)v - (s->start<<PageShift)) / size;

	switch(s->types.compression) {
	case MTypes_Empty:
		ntypes = (s->npages << PageShift) / size;
		nbytes3 = 8*sizeof(uintptr) + 1*ntypes;
		data3 = runtime_mallocgc(nbytes3, 0, FlagNoProfiling|FlagNoScan|FlagNoInvokeGC);
		s->types.compression = MTypes_Bytes;
		s->types.data = (uintptr)data3;
		((uintptr*)data3)[1] = typ;
		data3[8*sizeof(uintptr) + ofs] = 1;
		break;
		
	case MTypes_Words:
		((uintptr*)s->types.data)[ofs] = typ;
		break;
		
	case MTypes_Bytes:
		data3 = (byte*)s->types.data;
		for(j=1; j<8; j++) {
			if(((uintptr*)data3)[j] == typ) {
				break;
			}
			if(((uintptr*)data3)[j] == 0) {
				((uintptr*)data3)[j] = typ;
				break;
			}
		}
		if(j < 8) {
			data3[8*sizeof(uintptr) + ofs] = j;
		} else {
			ntypes = (s->npages << PageShift) / size;
			nbytes2 = ntypes * sizeof(uintptr);
			data2 = runtime_mallocgc(nbytes2, 0, FlagNoProfiling|FlagNoScan|FlagNoInvokeGC);
			s->types.compression = MTypes_Words;
			s->types.data = (uintptr)data2;
			
			// Move the contents of data3 to data2. Then deallocate data3.
			for(j=0; j<ntypes; j++) {
				t = data3[8*sizeof(uintptr) + j];
				t = ((uintptr*)data3)[t];
				data2[j] = t;
			}
			data2[ofs] = typ;
		}
		break;
	}
}

uintptr
runtime_gettype(void *v)
{
	MSpan *s;
	uintptr t, ofs;
	byte *data;

	s = runtime_MHeap_LookupMaybe(&runtime_mheap, v);
	if(s != nil) {
		t = 0;
		switch(s->types.compression) {
		case MTypes_Empty:
			break;
		case MTypes_Single:
			t = s->types.data;
			break;
		case MTypes_Words:
			ofs = (uintptr)v - (s->start<<PageShift);
			t = ((uintptr*)s->types.data)[ofs/s->elemsize];
			break;
		case MTypes_Bytes:
			ofs = (uintptr)v - (s->start<<PageShift);
			data = (byte*)s->types.data;
			t = data[8*sizeof(uintptr) + ofs/s->elemsize];
			t = ((uintptr*)data)[t];
			break;
		default:
			runtime_throw("runtime_gettype: invalid compression kind");
		}
		if(0) {
			runtime_printf("%p -> %d,%X\n", v, (int32)s->types.compression, (int64)t);
		}
		return t;
	}
	return 0;
}

// Runtime stubs.

void*
runtime_mal(uintptr n)
{
	return runtime_mallocgc(n, 0, 0);
}

func new(typ *Type) (ret *uint8) {
	ret = runtime_mallocgc(typ->__size, (uintptr)typ | TypeInfo_SingleObject, typ->kind&KindNoPointers ? FlagNoScan : 0);
}

static void*
cnew(const Type *typ, intgo n, int32 objtyp)
{
	if((objtyp&(PtrSize-1)) != objtyp)
		runtime_throw("runtime: invalid objtyp");
	if(n < 0 || (typ->__size > 0 && (uintptr)n > (MaxMem/typ->__size)))
		runtime_panicstring("runtime: allocation size out of range");
	return runtime_mallocgc(typ->__size*n, (uintptr)typ | objtyp, typ->kind&KindNoPointers ? FlagNoScan : 0);
}

// same as runtime_new, but callable from C
void*
runtime_cnew(const Type *typ)
{
	return cnew(typ, 1, TypeInfo_SingleObject);
}

void*
runtime_cnewarray(const Type *typ, intgo n)
{
	return cnew(typ, n, TypeInfo_Array);
}

func GC() {
	runtime_gc(2);  // force GC and do eager sweep
}

func SetFinalizer(obj Eface, finalizer Eface) {
	byte *base;
	uintptr size;
	const FuncType *ft;
	const Type *fint;
	const PtrType *ot;

	if(obj.__type_descriptor == nil) {
		runtime_printf("runtime.SetFinalizer: first argument is nil interface\n");
		goto throw;
	}
	if(obj.__type_descriptor->__code != GO_PTR) {
		runtime_printf("runtime.SetFinalizer: first argument is %S, not pointer\n", *obj.__type_descriptor->__reflection);
		goto throw;
	}
	ot = (const PtrType*)obj.type;
	// As an implementation detail we do not run finalizers for zero-sized objects,
	// because we use &runtime_zerobase for all such allocations.
	if(ot->__element_type != nil && ot->__element_type->__size == 0)
		return;
	// The following check is required for cases when a user passes a pointer to composite literal,
	// but compiler makes it a pointer to global. For example:
	//	var Foo = &Object{}
	//	func main() {
	//		runtime.SetFinalizer(Foo, nil)
	//	}
	// See issue 7656.
	if((byte*)obj.__object < runtime_mheap.arena_start || runtime_mheap.arena_used <= (byte*)obj.__object)
		return;
	if(!runtime_mlookup(obj.__object, &base, &size, nil) || obj.__object != base) {
		// As an implementation detail we allow to set finalizers for an inner byte
		// of an object if it could come from tiny alloc (see mallocgc for details).
		if(ot->__element_type == nil || (ot->__element_type->__code&KindNoPointers) == 0 || ot->__element_type->__size >= TinySize) {
			runtime_printf("runtime.SetFinalizer: pointer not at beginning of allocated block (%p)\n", obj.__object);
			goto throw;
		}
	}
	if(finalizer.__type_descriptor != nil) {
		runtime_createfing();
		if(finalizer.__type_descriptor->__code != GO_FUNC)
			goto badfunc;
		ft = (const FuncType*)finalizer.__type_descriptor;
		if(ft->__dotdotdot || ft->__in.__count != 1)
			goto badfunc;
		fint = *(Type**)ft->__in.__values;
		if(__go_type_descriptors_equal(fint, obj.__type_descriptor)) {
			// ok - same type
		} else if(fint->__code == GO_PTR && (fint->__uncommon == nil || fint->__uncommon->__name == nil || obj.type->__uncommon == nil || obj.type->__uncommon->__name == nil) && __go_type_descriptors_equal(((const PtrType*)fint)->__element_type, ((const PtrType*)obj.type)->__element_type)) {
			// ok - not same type, but both pointers,
			// one or the other is unnamed, and same element type, so assignable.
		} else if(fint->kind == GO_INTERFACE && ((const InterfaceType*)fint)->__methods.__count == 0) {
			// ok - satisfies empty interface
		} else if(fint->kind == GO_INTERFACE && __go_convert_interface_2(fint, obj.__type_descriptor, 1) != nil) {
			// ok - satisfies non-empty interface
		} else
			goto badfunc;

		ot = (const PtrType*)obj.__type_descriptor;
		if(!runtime_addfinalizer(obj.__object, *(FuncVal**)finalizer.__object, ft, ot)) {
			runtime_printf("runtime.SetFinalizer: finalizer already set\n");
			goto throw;
		}
	} else {
		// NOTE: asking to remove a finalizer when there currently isn't one set is OK.
		runtime_removefinalizer(obj.__object);
	}
	return;

badfunc:
	runtime_printf("runtime.SetFinalizer: cannot pass %S to finalizer %S\n", *obj.__type_descriptor->__reflection, *finalizer.__type_descriptor->__reflection);
throw:
	runtime_throw("runtime.SetFinalizer");
}
