// 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 "runtime.h"
#include "arch.h"
#include "malloc.h"
#include "go-type.h"

// Map gccgo field names to gc field names.
// Type aka __go_type_descriptor
#define kind __code
#define string __reflection

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

int32	runtime_checking;

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;
	MStats *pmstats;

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

	g = runtime_g();
	m = g->m;

	incallback = false;
	if(m->mcache == nil && m->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(0);
		m = runtime_m();
		incallback = true;
		flag |= FlagNoInvokeGC;
	}

	if((g->preempt || runtime_gcwaiting()) && g != m->g0 && m->locks == 0 && !(flag & FlagNoInvokeGC) && m->preemptoff.len == 0) {
		g->preempt = false;
		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 - (byte*)c->tiny);
				if(size1 <= tinysize) {
					// The object fits into existing tiny block.
					v = (MLink*)tiny;
					c->tiny = (byte*)c->tiny + size1;
					c->tinysize -= size1;
					m->mallocing = 0;
					m->locks--;
					if(incallback)
						runtime_entersyscall(0);
					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--;

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

	if(incallback)
		runtime_entersyscall(0);

	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 = (uintptr)((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_fastrand() % (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);
}

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);
		runtime_purgecachedstats(m->mcache);
		runtime_unlock(&runtime_mheap);
	}

	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 += (intptr)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;
	}
}

// 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;
	uintptr *pend;
	uintptr end;
	uintptr limit;
	uint64 i;
	bool reserved;

	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.

		end = 0;
		pend = &__go_end;
		if(pend != nil)
			end = *pend;
		p = (byte*)ROUND(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();
}

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;
	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);
	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);
			runtime_throw("runtime: cannot allocate memory");
		}
		persistent.end = persistent.pos + PersistentAllocChunk;
	}
	p = persistent.pos;
	persistent.pos += size;
	runtime_unlock(&persistent);
	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*
runtime_docnew(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 runtime_docnew(typ, 1, TypeInfo_SingleObject);
}

void*
runtime_cnewarray(const Type *typ, intgo n)
{
	return runtime_docnew(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((Type*)obj._type == nil) {
		runtime_printf("runtime.SetFinalizer: first argument is nil interface\n");
		goto throw;
	}
	if((((Type*)obj._type)->kind&kindMask) != GO_PTR) {
		runtime_printf("runtime.SetFinalizer: first argument is %S, not pointer\n", *((Type*)obj._type)->__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.data < runtime_mheap.arena_start || runtime_mheap.arena_used <= (byte*)obj.data)
		return;
	if(!runtime_mlookup(obj.data, &base, &size, nil) || obj.data != 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.data);
			goto throw;
		}
	}
	if((Type*)finalizer._type != nil) {
		runtime_createfing();
		if((((Type*)finalizer._type)->kind&kindMask) != GO_FUNC)
			goto badfunc;
		ft = (const FuncType*)finalizer._type;
		if(ft->__dotdotdot || ft->__in.__count != 1)
			goto badfunc;
		fint = *(Type**)ft->__in.__values;
		if(__go_type_descriptors_equal(fint, (Type*)obj._type)) {
			// ok - same type
		} else if((fint->kind&kindMask) == GO_PTR && (fint->__uncommon == nil || fint->__uncommon->__name == nil || ((Type*)obj._type)->__uncommon == nil || ((Type*)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 && getitab(fint, (Type*)obj._type, true) != nil) {
			// ok - satisfies non-empty interface
		} else
			goto badfunc;

		ot = (const PtrType*)obj._type;
		if(!runtime_addfinalizer(obj.data, *(FuncVal**)finalizer.data, 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.data);
	}
	return;

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

func KeepAlive(x Eface) {
	USED(x);
}
