// 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"

// 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
#define kindMask GO_CODE_MASK

// 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 runtime_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;

	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();

	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();
					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(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
			runtime_profilealloc(v, size);
	}

	m->locks--;

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

	if(incallback)
		runtime_entersyscall();

	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
runtime_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(((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(((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->kind&kindMask) != 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->kind&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->kind&kindMask) != 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->kind&kindMask) == 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&kindMask) == GO_INTERFACE && ((const InterfaceType*)fint)->__methods.__count == 0) {
			// ok - satisfies empty interface
		} else if((fint->kind&kindMask) == 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");
}
