// 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 "runtime.h"
#include "arch_GOARCH.h"
#include "stack.h"
#include "malloc.h"
#include "defs_GOOS_GOARCH.h"
#include "type.h"

MHeap runtime·mheap;
extern MStats mstats;	// defined in extern.go

extern volatile int32 runtime·MemProfileRate;

// 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.
void*
runtime·mallocgc(uintptr size, uint32 flag, int32 dogc, int32 zeroed)
{
	int32 sizeclass, rate;
	MCache *c;
	uintptr npages;
	MSpan *s;
	void *v;

	if(runtime·gcwaiting && g != m->g0 && m->locks == 0)
		runtime·gosched();
	if(m->mallocing)
		runtime·throw("malloc/free - deadlock");
	m->mallocing = 1;
	if(size == 0)
		size = 1;

	c = m->mcache;
	c->local_nmalloc++;
	if(size <= MaxSmallSize) {
		// Allocate from mcache free lists.
		sizeclass = runtime·SizeToClass(size);
		size = runtime·class_to_size[sizeclass];
		v = runtime·MCache_Alloc(c, sizeclass, size, zeroed);
		if(v == nil)
			runtime·throw("out of memory");
		c->local_alloc += size;
		c->local_total_alloc += size;
		c->local_by_size[sizeclass].nmalloc++;
	} else {
		// TODO(rsc): Report tracebacks for very large allocations.

		// Allocate directly from heap.
		npages = size >> PageShift;
		if((size & PageMask) != 0)
			npages++;
		s = runtime·MHeap_Alloc(&runtime·mheap, npages, 0, 1);
		if(s == nil)
			runtime·throw("out of memory");
		size = npages<<PageShift;
		c->local_alloc += size;
		c->local_total_alloc += size;
		v = (void*)(s->start << PageShift);

		// setup for mark sweep
		runtime·markspan(v, 0, 0, true);
	}
	if(!(flag & FlagNoGC))
		runtime·markallocated(v, size, (flag&FlagNoPointers) != 0);

	m->mallocing = 0;

	if(!(flag & FlagNoProfiling) && (rate = runtime·MemProfileRate) > 0) {
		if(size >= rate)
			goto profile;
		if(m->mcache->next_sample > size)
			m->mcache->next_sample -= size;
		else {
			// pick next profile time
			// If you change this, also change allocmcache.
			if(rate > 0x3fffffff)	// make 2*rate not overflow
				rate = 0x3fffffff;
			m->mcache->next_sample = runtime·fastrand1() % (2*rate);
		profile:
			runtime·setblockspecial(v, true);
			runtime·MProf_Malloc(v, size);
		}
	}

	if(dogc && mstats.heap_alloc >= mstats.next_gc)
		runtime·gc(0);
	return v;
}

void*
runtime·malloc(uintptr size)
{
	return runtime·mallocgc(size, 0, 0, 1);
}

// Free the object whose base pointer is v.
void
runtime·free(void *v)
{
	int32 sizeclass;
	MSpan *s;
	MCache *c;
	uint32 prof;
	uintptr size;

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

	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");
	}
	prof = runtime·blockspecial(v);

	// Find size class for v.
	sizeclass = s->sizeclass;
	c = m->mcache;
	if(sizeclass == 0) {
		// Large object.
		size = s->npages<<PageShift;
		*(uintptr*)(s->start<<PageShift) = 1;	// mark as "needs to be zeroed"
		// 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, size);
		runtime·unmarkspan(v, 1<<PageShift);
		runtime·MHeap_Free(&runtime·mheap, s, 1);
	} else {
		// Small object.
		size = runtime·class_to_size[sizeclass];
		if(size > sizeof(uintptr))
			((uintptr*)v)[1] = 1;	// mark as "needs to be zeroed"
		// Must mark v freed before calling MCache_Free:
		// it might coalesce v and other blocks into a bigger span
		// and change the bitmap further.
		runtime·markfreed(v, size);
		c->local_by_size[sizeclass].nfree++;
		runtime·MCache_Free(c, v, sizeclass, size);
	}
	c->local_alloc -= size;
	if(prof)
		runtime·MProf_Free(v, size);
	m->mallocing = 0;
}

int32
runtime·mlookup(void *v, byte **base, uintptr *size, MSpan **sp)
{
	uintptr n, i;
	byte *p;
	MSpan *s;

	m->mcache->local_nlookup++;
	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;
	}

	if((byte*)v >= (byte*)s->limit) {
		// pointers past the last block do not count as pointers.
		return 0;
	}

	n = runtime·class_to_size[s->sizeclass];
	if(base) {
		i = ((byte*)v - p)/n;
		*base = p + i*n;
	}
	if(size)
		*size = n;

	return 1;
}

MCache*
runtime·allocmcache(void)
{
	int32 rate;
	MCache *c;

	runtime·lock(&runtime·mheap);
	c = runtime·FixAlloc_Alloc(&runtime·mheap.cachealloc);
	mstats.mcache_inuse = runtime·mheap.cachealloc.inuse;
	mstats.mcache_sys = runtime·mheap.cachealloc.sys;
	runtime·unlock(&runtime·mheap);

	// Set first allocation sample size.
	rate = runtime·MemProfileRate;
	if(rate > 0x3fffffff)	// make 2*rate not overflow
		rate = 0x3fffffff;
	if(rate != 0)
		c->next_sample = runtime·fastrand1() % (2*rate);

	return c;
}

void
runtime·purgecachedstats(M* m)
{
	MCache *c;

	// Protected by either heap or GC lock.
	c = m->mcache;
	mstats.heap_alloc += c->local_cachealloc;
	c->local_cachealloc = 0;
	mstats.heap_objects += c->local_objects;
	c->local_objects = 0;
	mstats.nmalloc += c->local_nmalloc;
	c->local_nmalloc = 0;
	mstats.nfree += c->local_nfree;
	c->local_nfree = 0;
	mstats.nlookup += c->local_nlookup;
	c->local_nlookup = 0;
	mstats.alloc += c->local_alloc;
	c->local_alloc= 0;
	mstats.total_alloc += c->local_total_alloc;
	c->local_total_alloc= 0;
}

uintptr runtime·sizeof_C_MStats = sizeof(MStats);

#define MaxArena32 (2U<<30)

void
runtime·mallocinit(void)
{
	byte *p;
	uintptr arena_size, bitmap_size;
	extern byte end[];
	byte *want;

	p = nil;
	arena_size = 0;
	bitmap_size = 0;
	
	// for 64-bit build
	USED(p);
	USED(arena_size);
	USED(bitmap_size);

	runtime·InitSizes();

	// 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) {
		// On a 64-bit machine, allocate from a single contiguous reservation.
		// 16 GB should be big enough for now.
		//
		// The code will work with the reservation at any address, but ask
		// SysReserve to use 0x000000f800000000 if possible.
		// Allocating a 16 GB region takes away 36 bits, and the amd64
		// doesn't let us choose the top 17 bits, so that leaves the 11 bits
		// in the middle of 0x00f8 for us to choose.  Choosing 0x00f8 means
		// that the valid memory addresses will begin 0x00f8, 0x00f9, 0x00fa, 0x00fb.
		// None of the bytes f8 f9 fa fb can appear in valid UTF-8, and
		// they are otherwise as far from ff (likely a common byte) as possible.
		// Choosing 0x00 for the leading 6 bits was more arbitrary, but it
		// is not a common ASCII code point either.  Using 0x11f8 instead
		// caused out of memory errors on OS X during thread allocations.
		// 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 17 GB (because the bitmap ends up being 1 GB)
		// but it hardly matters: fc is not valid UTF-8 either, and we have to
		// allocate 15 GB before we get that far.
		//
		// If this fails we fall back to the 32 bit memory mechanism
		arena_size = 16LL<<30;
		bitmap_size = arena_size / (sizeof(void*)*8/4);
		p = runtime·SysReserve((void*)(0x00f8ULL<<32), bitmap_size + arena_size);
	}
	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;
		
		// 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.
		want = (byte*)(((uintptr)end + (1<<18) + (1<<20) - 1)&~((1<<20)-1));
		p = runtime·SysReserve(want, bitmap_size + arena_size);
		if(p == nil)
			runtime·throw("runtime: cannot reserve arena virtual address space");
	}
	if((uintptr)p & (((uintptr)1<<PageShift)-1))
		runtime·throw("runtime: SysReserve returned unaligned address");

	runtime·mheap.bitmap = p;
	runtime·mheap.arena_start = p + bitmap_size;
	runtime·mheap.arena_used = runtime·mheap.arena_start;
	runtime·mheap.arena_end = runtime·mheap.arena_start + arena_size;

	// Initialize the rest of the allocator.	
	runtime·MHeap_Init(&runtime·mheap, runtime·SysAlloc);
	m->mcache = runtime·allocmcache();

	// See if it works.
	runtime·free(runtime·malloc(1));
}

void*
runtime·MHeap_SysAlloc(MHeap *h, uintptr n)
{
	byte *p;

	if(n <= h->arena_end - h->arena_used) {
		// Keep taking from our reservation.
		p = h->arena_used;
		runtime·SysMap(p, n);
		h->arena_used += n;
		runtime·MHeap_MapBits(h);
		return p;
	}
	
	// If using 64-bit, our reservation is all we have.
	if(sizeof(void*) == 8 && (uintptr)h->bitmap >= 0xffffffffU)
		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 = runtime·SysAlloc(n);
	if(p == nil)
		return nil;

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

	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);
	}
	
	return p;
}

// Runtime stubs.

void*
runtime·mal(uintptr n)
{
	return runtime·mallocgc(n, 0, 1, 1);
}

func new(typ *Type) (ret *uint8) {
	uint32 flag = typ->kind&KindNoPointers ? FlagNoPointers : 0;
	ret = runtime·mallocgc(typ->size, flag, 1, 1);
	FLUSH(&ret);
}

void*
runtime·stackalloc(uint32 n)
{
	// Stackalloc must be called on scheduler stack, so that we
	// never try to grow the stack during the code that stackalloc runs.
	// Doing so would cause a deadlock (issue 1547).
	if(g != m->g0)
		runtime·throw("stackalloc not on scheduler stack");

	// Stack allocator uses malloc/free most of the time,
	// but if we're in the middle of malloc and need stack,
	// we have to do something else to avoid deadlock.
	// In that case, we fall back on a fixed-size free-list
	// allocator, assuming that inside malloc all the stack
	// frames are small, so that all the stack allocations
	// will be a single size, the minimum (right now, 5k).
	if(m->mallocing || m->gcing || n == FixedStack) {
		if(n != FixedStack) {
			runtime·printf("stackalloc: in malloc, size=%d want %d", FixedStack, n);
			runtime·throw("stackalloc");
		}
		return runtime·FixAlloc_Alloc(m->stackalloc);
	}
	return runtime·mallocgc(n, FlagNoProfiling|FlagNoGC, 0, 0);
}

void
runtime·stackfree(void *v, uintptr n)
{
	if(m->mallocing || m->gcing || n == FixedStack) {
		runtime·FixAlloc_Free(m->stackalloc, v);
		return;
	}
	runtime·free(v);
}

func Alloc(n uintptr) (p *byte) {
	p = runtime·malloc(n);
}

func Free(p *byte) {
	runtime·free(p);
}

func Lookup(p *byte) (base *byte, size uintptr) {
	runtime·mlookup(p, &base, &size, nil);
}

func GC() {
	runtime·gc(1);
}

func SetFinalizer(obj Eface, finalizer Eface) {
	byte *base;
	uintptr size;
	FuncType *ft;
	int32 i, nret;
	Type *t;

	if(obj.type == nil) {
		runtime·printf("runtime.SetFinalizer: first argument is nil interface\n");
		goto throw;
	}
	if(obj.type->kind != KindPtr) {
		runtime·printf("runtime.SetFinalizer: first argument is %S, not pointer\n", *obj.type->string);
		goto throw;
	}
	if(!runtime·mlookup(obj.data, &base, &size, nil) || obj.data != base) {
		runtime·printf("runtime.SetFinalizer: pointer not at beginning of allocated block\n");
		goto throw;
	}
	nret = 0;
	if(finalizer.type != nil) {
		if(finalizer.type->kind != KindFunc)
			goto badfunc;
		ft = (FuncType*)finalizer.type;
		if(ft->dotdotdot || ft->in.len != 1 || *(Type**)ft->in.array != obj.type)
			goto badfunc;

		// compute size needed for return parameters
		for(i=0; i<ft->out.len; i++) {
			t = ((Type**)ft->out.array)[i];
			nret = (nret + t->align - 1) & ~(t->align - 1);
			nret += t->size;
		}
		nret = (nret + sizeof(void*)-1) & ~(sizeof(void*)-1);
	}
	
	if(!runtime·addfinalizer(obj.data, finalizer.data, nret)) {
		runtime·printf("runtime.SetFinalizer: finalizer already set\n");
		goto throw;
	}
	return;

badfunc:
	runtime·printf("runtime.SetFinalizer: second argument is %S, not func(%S)\n", *finalizer.type->string, *obj.type->string);
throw:
	runtime·throw("runtime.SetFinalizer");
}
