// Copyright 2013 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.

#include "runtime.h"
#include "arch_GOARCH.h"
#include "malloc.h"
#include "stack.h"
#include "funcdata.h"
#include "typekind.h"
#include "type.h"
#include "race.h"
#include "mgc0.h"
#include "textflag.h"

enum
{
	// StackDebug == 0: no logging
	//            == 1: logging of per-stack operations
	//            == 2: logging of per-frame operations
	//            == 3: logging of per-word updates
	//            == 4: logging of per-word reads
	StackDebug = 0,
	StackFromSystem = 0,	// allocate stacks from system memory instead of the heap
	StackFaultOnFree = 0,	// old stacks are mapped noaccess to detect use after free
	StackPoisonCopy = 0,	// fill stack that should not be accessed with garbage, to detect bad dereferences during copy

	StackCache = 1,
};

// Global pool of spans that have free stacks.
// Stacks are assigned an order according to size.
//     order = log_2(size/FixedStack)
// There is a free list for each order.
MSpan runtime·stackpool[NumStackOrders];
Mutex runtime·stackpoolmu;
// TODO: one lock per order?

static Stack stackfreequeue;

void
runtime·stackinit(void)
{
	int32 i;

	if((StackCacheSize & PageMask) != 0)
		runtime·throw("cache size must be a multiple of page size");

	for(i = 0; i < NumStackOrders; i++)
		runtime·MSpanList_Init(&runtime·stackpool[i]);
}

// Allocates a stack from the free pool.  Must be called with
// stackpoolmu held.
static MLink*
poolalloc(uint8 order)
{
	MSpan *list;
	MSpan *s;
	MLink *x;
	uintptr i;

	list = &runtime·stackpool[order];
	s = list->next;
	if(s == list) {
		// no free stacks.  Allocate another span worth.
		s = runtime·MHeap_AllocStack(&runtime·mheap, StackCacheSize >> PageShift);
		if(s == nil)
			runtime·throw("out of memory");
		if(s->ref != 0)
			runtime·throw("bad ref");
		if(s->freelist != nil)
			runtime·throw("bad freelist");
#ifdef GOOS_openbsd
		runtime·sysMarkStack((void *)(s->start << PageShift), s->npages << PageShift);
#endif
		for(i = 0; i < StackCacheSize; i += FixedStack << order) {
			x = (MLink*)((s->start << PageShift) + i);
			x->next = s->freelist;
			s->freelist = x;
		}
		runtime·MSpanList_Insert(list, s);
	}
	x = s->freelist;
	if(x == nil)
		runtime·throw("span has no free stacks");
	s->freelist = x->next;
	s->ref++;
	if(s->freelist == nil) {
		// all stacks in s are allocated.
		runtime·MSpanList_Remove(s);
	}
	return x;
}

// Adds stack x to the free pool.  Must be called with stackpoolmu held.
static void
poolfree(MLink *x, uint8 order)
{
	MSpan *s;

	s = runtime·MHeap_Lookup(&runtime·mheap, x);
	if(s->state != MSpanStack)
		runtime·throw("freeing stack not in a stack span");
	if(s->freelist == nil) {
		// s will now have a free stack
		runtime·MSpanList_Insert(&runtime·stackpool[order], s);
	}
	x->next = s->freelist;
	s->freelist = x;
	s->ref--;
	if(s->ref == 0) {
		// span is completely free - return to heap
		runtime·MSpanList_Remove(s);
		s->freelist = nil;
#ifdef GOOS_openbsd
		runtime·sysUnmarkStack((void *)(s->start << PageShift), s->npages << PageShift);
#endif
		runtime·MHeap_FreeStack(&runtime·mheap, s);
	}
}

// stackcacherefill/stackcacherelease implement a global pool of stack segments.
// The pool is required to prevent unlimited growth of per-thread caches.
static void
stackcacherefill(MCache *c, uint8 order)
{
	MLink *x, *list;
	uintptr size;

	if(StackDebug >= 1)
		runtime·printf("stackcacherefill order=%d\n", order);

	// Grab some stacks from the global cache.
	// Grab half of the allowed capacity (to prevent thrashing).
	list = nil;
	size = 0;
	runtime·lock(&runtime·stackpoolmu);
	while(size < StackCacheSize/2) {
		x = poolalloc(order);
		x->next = list;
		list = x;
		size += FixedStack << order;
	}
	runtime·unlock(&runtime·stackpoolmu);

	c->stackcache[order].list = list;
	c->stackcache[order].size = size;
}

static void
stackcacherelease(MCache *c, uint8 order)
{
	MLink *x, *y;
	uintptr size;

	if(StackDebug >= 1)
		runtime·printf("stackcacherelease order=%d\n", order);
	x = c->stackcache[order].list;
	size = c->stackcache[order].size;
	runtime·lock(&runtime·stackpoolmu);
	while(size > StackCacheSize/2) {
		y = x->next;
		poolfree(x, order);
		x = y;
		size -= FixedStack << order;
	}
	runtime·unlock(&runtime·stackpoolmu);
	c->stackcache[order].list = x;
	c->stackcache[order].size = size;
}

void
runtime·stackcache_clear(MCache *c)
{
	uint8 order;
	MLink *x, *y;

	if(StackDebug >= 1)
		runtime·printf("stackcache clear\n");
	runtime·lock(&runtime·stackpoolmu);
	for(order = 0; order < NumStackOrders; order++) {
		x = c->stackcache[order].list;
		while(x != nil) {
			y = x->next;
			poolfree(x, order);
			x = y;
		}
		c->stackcache[order].list = nil;
		c->stackcache[order].size = 0;
	}
	runtime·unlock(&runtime·stackpoolmu);
}

Stack
runtime·stackalloc(uint32 n)
{
	uint8 order;
	uint32 n2;
	void *v;
	MLink *x;
	MSpan *s;
	MCache *c;

	// 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 != g->m->g0)
		runtime·throw("stackalloc not on scheduler stack");
	if((n & (n-1)) != 0)
		runtime·throw("stack size not a power of 2");
	if(StackDebug >= 1)
		runtime·printf("stackalloc %d\n", n);

	if(runtime·debug.efence || StackFromSystem) {
		v = runtime·sysAlloc(ROUND(n, PageSize), &mstats.stacks_sys);
		if(v == nil)
			runtime·throw("out of memory (stackalloc)");
		return (Stack){(uintptr)v, (uintptr)v+n};
	}

	// Small stacks are allocated with a fixed-size free-list allocator.
	// If we need a stack of a bigger size, we fall back on allocating
	// a dedicated span.
	if(StackCache && n < FixedStack << NumStackOrders && n < StackCacheSize) {
		order = 0;
		n2 = n;
		while(n2 > FixedStack) {
			order++;
			n2 >>= 1;
		}
		c = g->m->mcache;
		if(c == nil || g->m->gcing || g->m->helpgc) {
			// c == nil can happen in the guts of exitsyscall or
			// procresize. Just get a stack from the global pool.
			// Also don't touch stackcache during gc
			// as it's flushed concurrently.
			runtime·lock(&runtime·stackpoolmu);
			x = poolalloc(order);
			runtime·unlock(&runtime·stackpoolmu);
		} else {
			x = c->stackcache[order].list;
			if(x == nil) {
				stackcacherefill(c, order);
				x = c->stackcache[order].list;
			}
			c->stackcache[order].list = x->next;
			c->stackcache[order].size -= n;
		}
		v = (byte*)x;
	} else {
		s = runtime·MHeap_AllocStack(&runtime·mheap, ROUND(n, PageSize) >> PageShift);
		if(s == nil)
			runtime·throw("out of memory");
#ifdef GOOS_openbsd
		runtime·sysMarkStack((void *)(s->start << PageShift), s->npages << PageShift);
#endif
		v = (byte*)(s->start<<PageShift);
	}
	
	if(raceenabled)
		runtime·racemalloc(v, n);
	if(StackDebug >= 1)
		runtime·printf("  allocated %p\n", v);
	return (Stack){(uintptr)v, (uintptr)v+n};
}

void
runtime·stackfree(Stack stk)
{
	uint8 order;
	uintptr n, n2;
	MSpan *s;
	MLink *x;
	MCache *c;
	void *v;
	
	n = stk.hi - stk.lo;
	v = (void*)stk.lo;
	if(n & (n-1))
		runtime·throw("stack not a power of 2");
	if(StackDebug >= 1) {
		runtime·printf("stackfree %p %d\n", v, (int32)n);
		runtime·memclr(v, n); // for testing, clobber stack data
	}
	if(runtime·debug.efence || StackFromSystem) {
		if(runtime·debug.efence || StackFaultOnFree)
			runtime·SysFault(v, n);
		else
			runtime·SysFree(v, n, &mstats.stacks_sys);
		return;
	}
	if(StackCache && n < FixedStack << NumStackOrders && n < StackCacheSize) {
		order = 0;
		n2 = n;
		while(n2 > FixedStack) {
			order++;
			n2 >>= 1;
		}
		x = (MLink*)v;
		c = g->m->mcache;
		if(c == nil || g->m->gcing || g->m->helpgc) {
			runtime·lock(&runtime·stackpoolmu);
			poolfree(x, order);
			runtime·unlock(&runtime·stackpoolmu);
		} else {
			if(c->stackcache[order].size >= StackCacheSize)
				stackcacherelease(c, order);
			x->next = c->stackcache[order].list;
			c->stackcache[order].list = x;
			c->stackcache[order].size += n;
		}
	} else {
		s = runtime·MHeap_Lookup(&runtime·mheap, v);
		if(s->state != MSpanStack) {
			runtime·printf("%p %p\n", s->start<<PageShift, v);
			runtime·throw("bad span state");
		}
#ifdef GOOS_openbsd
		runtime·sysUnmarkStack((void *)(s->start << PageShift), s->npages << PageShift);
#endif
		runtime·MHeap_FreeStack(&runtime·mheap, s);
	}
}

uintptr runtime·maxstacksize = 1<<20; // enough until runtime.main sets it for real

static uint8*
mapnames[] = {
	(uint8*)"---",
	(uint8*)"scalar",
	(uint8*)"ptr",
	(uint8*)"multi",
};

// Stack frame layout
//
// (x86)
// +------------------+
// | args from caller |
// +------------------+ <- frame->argp
// |  return address  |
// +------------------+ <- frame->varp
// |     locals       |
// +------------------+
// |  args to callee  |
// +------------------+ <- frame->sp
//
// (arm)
// +------------------+
// | args from caller |
// +------------------+ <- frame->argp
// | caller's retaddr |
// +------------------+ <- frame->varp
// |     locals       |
// +------------------+
// |  args to callee  |
// +------------------+
// |  return address  |
// +------------------+ <- frame->sp

void runtime·main(void);
void runtime·switchtoM(void(*)(void));

typedef struct AdjustInfo AdjustInfo;
struct AdjustInfo {
	Stack old;
	uintptr delta;  // ptr distance from old to new stack (newbase - oldbase)
};

// Adjustpointer checks whether *vpp is in the old stack described by adjinfo.
// If so, it rewrites *vpp to point into the new stack.
static void
adjustpointer(AdjustInfo *adjinfo, void *vpp)
{
	byte **pp, *p;
	
	pp = vpp;
	p = *pp;
	if(StackDebug >= 4)
		runtime·printf("        %p:%p\n", pp, p);
	if(adjinfo->old.lo <= (uintptr)p && (uintptr)p < adjinfo->old.hi) {
		*pp = p + adjinfo->delta;
		if(StackDebug >= 3)
			runtime·printf("        adjust ptr %p: %p -> %p\n", pp, p, *pp);
	}
}

// bv describes the memory starting at address scanp.
// Adjust any pointers contained therein.
static void
adjustpointers(byte **scanp, BitVector *bv, AdjustInfo *adjinfo, Func *f)
{
	uintptr delta;
	int32 num, i;
	byte *p, *minp, *maxp;
	Type *t;
	Itab *tab;
	
	minp = (byte*)adjinfo->old.lo;
	maxp = (byte*)adjinfo->old.hi;
	delta = adjinfo->delta;
	num = bv->n / BitsPerPointer;
	for(i = 0; i < num; i++) {
		if(StackDebug >= 4)
			runtime·printf("        %p:%s:%p\n", &scanp[i], mapnames[bv->bytedata[i / (8 / BitsPerPointer)] >> (i * BitsPerPointer & 7) & 3], scanp[i]);
		switch(bv->bytedata[i / (8 / BitsPerPointer)] >> (i * BitsPerPointer & 7) & 3) {
		case BitsDead:
			if(runtime·debug.gcdead)
				scanp[i] = (byte*)PoisonStack;
			break;
		case BitsScalar:
			break;
		case BitsPointer:
			p = scanp[i];
			if(f != nil && (byte*)0 < p && (p < (byte*)PageSize && runtime·invalidptr || (uintptr)p == PoisonGC || (uintptr)p == PoisonStack)) {
				// Looks like a junk value in a pointer slot.
				// Live analysis wrong?
				g->m->traceback = 2;
				runtime·printf("runtime: bad pointer in frame %s at %p: %p\n", runtime·funcname(f), &scanp[i], p);
				runtime·throw("invalid stack pointer");
			}
			if(minp <= p && p < maxp) {
				if(StackDebug >= 3)
					runtime·printf("adjust ptr %p %s\n", p, runtime·funcname(f));
				scanp[i] = p + delta;
			}
			break;
		case BitsMultiWord:
			switch(bv->bytedata[(i+1) / (8 / BitsPerPointer)] >> ((i+1) * BitsPerPointer & 7) & 3) {
			default:
				runtime·throw("unexpected garbage collection bits");
			case BitsEface:
				t = (Type*)scanp[i];
				if(t != nil && ((t->kind & KindDirectIface) == 0 || (t->kind & KindNoPointers) == 0)) {
					p = scanp[i+1];
					if(minp <= p && p < maxp) {
						if(StackDebug >= 3)
							runtime·printf("adjust eface %p\n", p);
						if(t->size > PtrSize) // currently we always allocate such objects on the heap
							runtime·throw("large interface value found on stack");
						scanp[i+1] = p + delta;
					}
				}
				i++;
				break;
			case BitsIface:
				tab = (Itab*)scanp[i];
				if(tab != nil) {
					t = tab->type;
					//runtime·printf("          type=%p\n", t);
					if((t->kind & KindDirectIface) == 0 || (t->kind & KindNoPointers) == 0) {
						p = scanp[i+1];
						if(minp <= p && p < maxp) {
							if(StackDebug >= 3)
								runtime·printf("adjust iface %p\n", p);
							if(t->size > PtrSize) // currently we always allocate such objects on the heap
								runtime·throw("large interface value found on stack");
							scanp[i+1] = p + delta;
						}
					}
				}
				i++;
				break;
			}
			break;
		}
	}
}

// Note: the argument/return area is adjusted by the callee.
static bool
adjustframe(Stkframe *frame, void *arg)
{
	AdjustInfo *adjinfo;
	Func *f;
	StackMap *stackmap;
	int32 pcdata;
	BitVector bv;
	uintptr targetpc, size, minsize;

	adjinfo = arg;
	targetpc = frame->continpc;
	if(targetpc == 0) {
		// Frame is dead.
		return true;
	}
	f = frame->fn;
	if(StackDebug >= 2)
		runtime·printf("    adjusting %s frame=[%p,%p] pc=%p continpc=%p\n", runtime·funcname(f), frame->sp, frame->fp, frame->pc, frame->continpc);
	if(f->entry == (uintptr)runtime·switchtoM) {
		// A special routine at the bottom of stack of a goroutine that does an onM call.
		// We will allow it to be copied even though we don't
		// have full GC info for it (because it is written in asm).
		return true;
	}
	if(targetpc != f->entry)
		targetpc--;
	pcdata = runtime·pcdatavalue(f, PCDATA_StackMapIndex, targetpc);
	if(pcdata == -1)
		pcdata = 0; // in prologue

	// Adjust local variables if stack frame has been allocated.
	size = frame->varp - frame->sp;
	if(thechar != '6' && thechar != '8')
		minsize = sizeof(uintptr);
	else
		minsize = 0;
	if(size > minsize) {
		stackmap = runtime·funcdata(f, FUNCDATA_LocalsPointerMaps);
		if(stackmap == nil || stackmap->n <= 0) {
			runtime·printf("runtime: frame %s untyped locals %p+%p\n", runtime·funcname(f), (byte*)(frame->varp-size), size);
			runtime·throw("missing stackmap");
		}
		// Locals bitmap information, scan just the pointers in locals.
		if(pcdata < 0 || pcdata >= stackmap->n) {
			// don't know where we are
			runtime·printf("runtime: pcdata is %d and %d locals stack map entries for %s (targetpc=%p)\n",
				pcdata, stackmap->n, runtime·funcname(f), targetpc);
			runtime·throw("bad symbol table");
		}
		bv = runtime·stackmapdata(stackmap, pcdata);
		size = (bv.n * PtrSize) / BitsPerPointer;
		if(StackDebug >= 3)
			runtime·printf("      locals\n");
		adjustpointers((byte**)(frame->varp - size), &bv, adjinfo, f);
	}
	
	// Adjust arguments.
	if(frame->arglen > 0) {
		if(frame->argmap != nil) {
			bv = *frame->argmap;
		} else {
			stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps);
			if(stackmap == nil || stackmap->n <= 0) {
				runtime·printf("runtime: frame %s untyped args %p+%p\n", runtime·funcname(f), frame->argp, (uintptr)frame->arglen);
				runtime·throw("missing stackmap");
			}
			if(pcdata < 0 || pcdata >= stackmap->n) {
				// don't know where we are
				runtime·printf("runtime: pcdata is %d and %d args stack map entries for %s (targetpc=%p)\n",
					pcdata, stackmap->n, runtime·funcname(f), targetpc);
				runtime·throw("bad symbol table");
			}
			bv = runtime·stackmapdata(stackmap, pcdata);
		}
		if(StackDebug >= 3)
			runtime·printf("      args\n");
		adjustpointers((byte**)frame->argp, &bv, adjinfo, nil);
	}
	
	return true;
}

static void
adjustctxt(G *gp, AdjustInfo *adjinfo)
{
	adjustpointer(adjinfo, &gp->sched.ctxt);
}

static void
adjustdefers(G *gp, AdjustInfo *adjinfo)
{
	Defer *d;
	bool (*cb)(Stkframe*, void*);

	// Adjust defer argument blocks the same way we adjust active stack frames.
	cb = adjustframe;
	runtime·tracebackdefers(gp, &cb, adjinfo);

	// Adjust pointers in the Defer structs.
	// Defer structs themselves are never on the stack.
	for(d = gp->defer; d != nil; d = d->link) {
		adjustpointer(adjinfo, &d->fn);
		adjustpointer(adjinfo, &d->argp);
		adjustpointer(adjinfo, &d->panic);
	}
}

static void
adjustpanics(G *gp, AdjustInfo *adjinfo)
{
	// Panics are on stack and already adjusted.
	// Update pointer to head of list in G.
	adjustpointer(adjinfo, &gp->panic);
}

static void
adjustsudogs(G *gp, AdjustInfo *adjinfo)
{
	SudoG *s;

	// the data elements pointed to by a SudoG structure
	// might be in the stack.
	for(s = gp->waiting; s != nil; s = s->waitlink) {
		adjustpointer(adjinfo, &s->elem);
		adjustpointer(adjinfo, &s->selectdone);
	}
}

// Copies gp's stack to a new stack of a different size.
static void
copystack(G *gp, uintptr newsize)
{
	Stack old, new;
	uintptr used;
	AdjustInfo adjinfo;
	uint32 oldstatus;
	bool (*cb)(Stkframe*, void*);
	byte *p, *ep;

	if(gp->syscallsp != 0)
		runtime·throw("stack growth not allowed in system call");
	old = gp->stack;
	if(old.lo == 0)
		runtime·throw("nil stackbase");
	used = old.hi - gp->sched.sp;

	// allocate new stack
	new = runtime·stackalloc(newsize);
	if(StackPoisonCopy) {
		p = (byte*)new.lo;
		ep = (byte*)new.hi;
		while(p < ep)
			*p++ = 0xfd;
	}

	if(StackDebug >= 1)
		runtime·printf("copystack gp=%p [%p %p %p]/%d -> [%p %p %p]/%d\n", gp, old.lo, old.hi-used, old.hi, (int32)(old.hi-old.lo), new.lo, new.hi-used, new.hi, (int32)newsize);
	
	// adjust pointers in the to-be-copied frames
	adjinfo.old = old;
	adjinfo.delta = new.hi - old.hi;
	cb = adjustframe;
	runtime·gentraceback(~(uintptr)0, ~(uintptr)0, 0, gp, 0, nil, 0x7fffffff, &cb, &adjinfo, 0);
	
	// adjust other miscellaneous things that have pointers into stacks.
	adjustctxt(gp, &adjinfo);
	adjustdefers(gp, &adjinfo);
	adjustpanics(gp, &adjinfo);
	adjustsudogs(gp, &adjinfo);
	
	// copy the stack to the new location
	if(StackPoisonCopy) {
		p = (byte*)new.lo;
		ep = (byte*)new.hi;
		while(p < ep)
			*p++ = 0xfb;
	}
	runtime·memmove((byte*)new.hi - used, (byte*)old.hi - used, used);

	oldstatus = runtime·casgcopystack(gp); // cas from Gwaiting or Grunnable to Gcopystack, return old status

	// Swap out old stack for new one
	gp->stack = new;
	gp->stackguard0 = new.lo + StackGuard; // NOTE: might clobber a preempt request
	gp->sched.sp = new.hi - used;

	runtime·casgstatus(gp, Gcopystack, oldstatus); // oldstatus is Gwaiting or Grunnable

	// free old stack
	if(StackPoisonCopy) {
		p = (byte*)old.lo;
		ep = (byte*)old.hi;
		while(p < ep)
			*p++ = 0xfc;
	}
	if(newsize > old.hi-old.lo) {
		// growing, free stack immediately
		runtime·stackfree(old);
	} else {
		// shrinking, queue up free operation.  We can't actually free the stack
		// just yet because we might run into the following situation:
		// 1) GC starts, scans a SudoG but does not yet mark the SudoG.elem pointer
		// 2) The stack that pointer points to is shrunk
		// 3) The old stack is freed
		// 4) The containing span is marked free
		// 5) GC attempts to mark the SudoG.elem pointer.  The marking fails because
		//    the pointer looks like a pointer into a free span.
		// By not freeing, we prevent step #4 until GC is done.
		runtime·lock(&runtime·stackpoolmu);
		*(Stack*)old.lo = stackfreequeue;
		stackfreequeue = old;
		runtime·unlock(&runtime·stackpoolmu);
	}
}

// round x up to a power of 2.
int32
runtime·round2(int32 x)
{
	int32 s;

	s = 0;
	while((1 << s) < x)
		s++;
	return 1 << s;
}

// Called from runtime·morestack when more stack is needed.
// Allocate larger stack and relocate to new stack.
// Stack growth is multiplicative, for constant amortized cost.
//
// g->atomicstatus will be Grunning or Gscanrunning upon entry. 
// If the GC is trying to stop this g then it will set preemptscan to true.
void
runtime·newstack(void)
{
	int32 oldsize, newsize;
	uintptr sp;
	G *gp;
	Gobuf morebuf;

	if(g->m->morebuf.g->stackguard0 == (uintptr)StackFork)
		runtime·throw("stack growth after fork");
	if(g->m->morebuf.g != g->m->curg) {
		runtime·printf("runtime: newstack called from g=%p\n"
			"\tm=%p m->curg=%p m->g0=%p m->gsignal=%p\n",
			g->m->morebuf.g, g->m, g->m->curg, g->m->g0, g->m->gsignal);
		morebuf = g->m->morebuf;
		runtime·traceback(morebuf.pc, morebuf.sp, morebuf.lr, morebuf.g);
		runtime·throw("runtime: wrong goroutine in newstack");
	}
	if(g->m->curg->throwsplit)
		runtime·throw("runtime: stack split at bad time");

	// The goroutine must be executing in order to call newstack,
	// so it must be Grunning or Gscanrunning.

	gp = g->m->curg;
	morebuf = g->m->morebuf;
	g->m->morebuf.pc = (uintptr)nil;
	g->m->morebuf.lr = (uintptr)nil;
	g->m->morebuf.sp = (uintptr)nil;
	g->m->morebuf.g = (G*)nil;

	runtime·casgstatus(gp, Grunning, Gwaiting);
	gp->waitreason = runtime·gostringnocopy((byte*)"stack growth");

	runtime·rewindmorestack(&gp->sched);

	if(gp->stack.lo == 0)
		runtime·throw("missing stack in newstack");
	sp = gp->sched.sp;
	if(thechar == '6' || thechar == '8') {
		// The call to morestack cost a word.
		sp -= sizeof(uintreg);
	}
	if(StackDebug >= 1 || sp < gp->stack.lo) {
		runtime·printf("runtime: newstack sp=%p stack=[%p, %p]\n"
			"\tmorebuf={pc:%p sp:%p lr:%p}\n"
			"\tsched={pc:%p sp:%p lr:%p ctxt:%p}\n",
			sp, gp->stack.lo, gp->stack.hi,
			g->m->morebuf.pc, g->m->morebuf.sp, g->m->morebuf.lr,
			gp->sched.pc, gp->sched.sp, gp->sched.lr, gp->sched.ctxt);
	}
	if(sp < gp->stack.lo) {
		runtime·printf("runtime: gp=%p, gp->status=%d\n ", (void*)gp, runtime·readgstatus(gp));
		runtime·printf("runtime: split stack overflow: %p < %p\n", sp, gp->stack.lo);
		runtime·throw("runtime: split stack overflow");
	}

	if(gp->stackguard0 == (uintptr)StackPreempt) {
		if(gp == g->m->g0)
			runtime·throw("runtime: preempt g0");
		if(g->m->p == nil && g->m->locks == 0)
			runtime·throw("runtime: g is running but p is not");
		if(gp->preemptscan) {
			runtime·gcphasework(gp);
			runtime·casgstatus(gp, Gwaiting, Grunning);
			gp->stackguard0 = gp->stack.lo + StackGuard;
			gp->preempt = false; 
			gp->preemptscan = false;        // Tells the GC premption was successful.
			runtime·gogo(&gp->sched);	// never return 
		}

		// Be conservative about where we preempt.
		// We are interested in preempting user Go code, not runtime code.
		if(g->m->locks || g->m->mallocing || g->m->gcing || g->m->p->status != Prunning) {
			// Let the goroutine keep running for now.
			// gp->preempt is set, so it will be preempted next time.
			gp->stackguard0 = gp->stack.lo + StackGuard;
			runtime·casgstatus(gp, Gwaiting, Grunning);
			runtime·gogo(&gp->sched);	// never return
		}
		// Act like goroutine called runtime.Gosched.
		runtime·casgstatus(gp, Gwaiting, Grunning);
		runtime·gosched_m(gp);	// never return
	}

	// Allocate a bigger segment and move the stack.
	oldsize = gp->stack.hi - gp->stack.lo;
	newsize = oldsize * 2;
	if(newsize > runtime·maxstacksize) {
		runtime·printf("runtime: goroutine stack exceeds %D-byte limit\n", (uint64)runtime·maxstacksize);
		runtime·throw("stack overflow");
	}

	// Note that the concurrent GC might be scanning the stack as we try to replace it.
	// copystack takes care of the appropriate coordination with the stack scanner.
	copystack(gp, newsize);
	if(StackDebug >= 1)
		runtime·printf("stack grow done\n");
	runtime·casgstatus(gp, Gwaiting, Grunning);
	runtime·gogo(&gp->sched);
}

#pragma textflag NOSPLIT
void
runtime·nilfunc(void)
{
	*(byte*)0 = 0;
}

// adjust Gobuf as if it executed a call to fn
// and then did an immediate gosave.
void
runtime·gostartcallfn(Gobuf *gobuf, FuncVal *fv)
{
	void *fn;

	if(fv != nil)
		fn = fv->fn;
	else
		fn = runtime·nilfunc;
	runtime·gostartcall(gobuf, fn, fv);
}

// Maybe shrink the stack being used by gp.
// Called at garbage collection time.
void
runtime·shrinkstack(G *gp)
{
	uintptr used, oldsize, newsize;

	if(runtime·readgstatus(gp) == Gdead) {
		if(gp->stack.lo != 0) {
			// Free whole stack - it will get reallocated
			// if G is used again.
			runtime·stackfree(gp->stack);
			gp->stack.lo = 0;
			gp->stack.hi = 0;
		}
		return;
	}
	if(gp->stack.lo == 0)
		runtime·throw("missing stack in shrinkstack");

	oldsize = gp->stack.hi - gp->stack.lo;
	newsize = oldsize / 2;
	if(newsize < FixedStack)
		return; // don't shrink below the minimum-sized stack
	used = gp->stack.hi - gp->sched.sp;
	if(used >= oldsize / 4)
		return; // still using at least 1/4 of the segment.

	// We can't copy the stack if we're in a syscall.
	// The syscall might have pointers into the stack.
	if(gp->syscallsp != 0)
		return;

#ifdef GOOS_windows
	if(gp->m != nil && gp->m->libcallsp != 0)
		return;
#endif
	if(StackDebug > 0)
		runtime·printf("shrinking stack %D->%D\n", (uint64)oldsize, (uint64)newsize);
	copystack(gp, newsize);
}

// Do any delayed stack freeing that was queued up during GC.
void
runtime·shrinkfinish(void)
{
	Stack s, t;

	runtime·lock(&runtime·stackpoolmu);
	s = stackfreequeue;
	stackfreequeue = (Stack){0,0};
	runtime·unlock(&runtime·stackpoolmu);
	while(s.lo != 0) {
		t = *(Stack*)s.lo;
		runtime·stackfree(s);
		s = t;
	}
}

static void badc(void);

#pragma textflag NOSPLIT
void
runtime·morestackc(void)
{
	void (*fn)(void);
	
	fn = badc;
	runtime·onM(&fn);
}

static void
badc(void)
{
	runtime·throw("attempt to execute C code on Go stack");
}
