コード例 #1
0
ファイル: stack.c プロジェクト: reeze/go-internals
runtime·stackalloc(uint32 n)
{
	uint32 pos;
	void *v;

	// 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(n == FixedStack || m->mallocing || m->gcing) {
		if(n != FixedStack) {
			runtime·printf("stackalloc: in malloc, size=%d want %d\n", FixedStack, n);
			runtime·throw("stackalloc");
		}
		if(m->stackcachecnt == 0)
			stackcacherefill();
		pos = m->stackcachepos;
		pos = (pos - 1) % StackCacheSize;
		v = m->stackcache[pos];
		m->stackcachepos = pos;
		m->stackcachecnt--;
		m->stackinuse++;
		return v;
	}
	return runtime·mallocgc(n, FlagNoProfiling|FlagNoGC, 0, 0);
}
コード例 #2
0
ファイル: stack.c プロジェクト: h8liu/golang
runtime·stackalloc(G *gp, uint32 n)
{
	uint32 pos;
	void *v;
	bool malloced;
	Stktop *top;

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

	gp->stacksize += 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 v;
	}

	// Minimum-sized stacks are allocated with a fixed-size free-list allocator,
	// but if we need a stack of a bigger size, we fall back on malloc
	// (assuming that inside malloc all the stack frames are small,
	// so that we do not deadlock).
	malloced = true;
	if(n == FixedStack || m->mallocing) {
		if(n != FixedStack) {
			runtime·printf("stackalloc: in malloc, size=%d want %d\n", FixedStack, n);
			runtime·throw("stackalloc");
		}
		if(m->stackcachecnt == 0)
			stackcacherefill();
		pos = m->stackcachepos;
		pos = (pos - 1) % StackCacheSize;
		v = m->stackcache[pos];
		m->stackcachepos = pos;
		m->stackcachecnt--;
		m->stackinuse++;
		malloced = false;
	} else
		v = runtime·mallocgc(n, 0, FlagNoProfiling|FlagNoGC|FlagNoZero|FlagNoInvokeGC);

	top = (Stktop*)((byte*)v+n-sizeof(Stktop));
	runtime·memclr((byte*)top, sizeof(*top));
	top->malloced = malloced;
	return v;
}