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

// Stack scanning code for the garbage collector.

#include "runtime.h"

#ifdef USING_SPLIT_STACK

extern void * __splitstack_find (void *, void *, size_t *, void **, void **,
				 void **);

extern void * __splitstack_find_context (void *context[10], size_t *, void **,
					 void **, void **);

#endif

// Calling unwind_init in doscanstack only works if it does not do a
// tail call to doscanstack1.
#pragma GCC optimize ("-fno-optimize-sibling-calls")

extern void scanstackblock(void *addr, uintptr size, void *gcw)
  __asm__("runtime.scanstackblock");

static bool doscanstack1(G*, void*)
  __attribute__ ((noinline));

// Scan gp's stack, passing stack chunks to scanstackblock.
bool doscanstack(G *gp, void* gcw) {
	// Save registers on the stack, so that if we are scanning our
	// own stack we will see them.
	if (!runtime_usestackmaps) {
		__builtin_unwind_init();
		flush_registers_to_secondary_stack();
	}

	return doscanstack1(gp, gcw);
}

// Scan gp's stack after saving registers.
static bool doscanstack1(G *gp, void *gcw) {
#ifdef USING_SPLIT_STACK
	void* sp;
	size_t spsize;
	void* next_segment;
	void* next_sp;
	void* initial_sp;
	G* _g_;

	_g_ = runtime_g();
	if (runtime_usestackmaps) {
		// If stack map is enabled, we get here only when we can unwind
		// the stack being scanned. That is, either we are scanning our
		// own stack, or we are scanning through a signal handler.
		__go_assert((_g_ == gp) || ((_g_ == gp->m->gsignal) && (gp == gp->m->curg)));
		return scanstackwithmap(gcw);
	}
	if (_g_ == gp) {
		// Scanning our own stack.
		// If we are on a signal stack, it can unwind through the signal
		// handler and see the g stack, so just scan our own stack.
		sp = __splitstack_find(nil, nil, &spsize, &next_segment,
				       &next_sp, &initial_sp);
	} else {
		// Scanning another goroutine's stack.
		// The goroutine is usually asleep (the world is stopped).

		// The exception is that if the goroutine is about to enter or might
		// have just exited a system call, it may be executing code such
		// as schedlock and may have needed to start a new stack segment.
		// Use the stack segment and stack pointer at the time of
		// the system call instead, since that won't change underfoot.
		if(gp->gcstack != 0) {
			sp = (void*)(gp->gcstack);
			spsize = gp->gcstacksize;
			next_segment = (void*)(gp->gcnextsegment);
			next_sp = (void*)(gp->gcnextsp);
			initial_sp = (void*)(gp->gcinitialsp);
		} else {
			sp = __splitstack_find_context((void**)(&gp->stackcontext[0]),
						       &spsize, &next_segment,
						       &next_sp, &initial_sp);
		}
	}
	if(sp != nil) {
		scanstackblock(sp, (uintptr)(spsize), gcw);
		while((sp = __splitstack_find(next_segment, next_sp,
					      &spsize, &next_segment,
					      &next_sp, &initial_sp)) != nil)
			scanstackblock(sp, (uintptr)(spsize), gcw);
	}
#else
	byte* bottom;
	byte* top;
	byte* nextsp2;
	byte* initialsp2;

	if(gp == runtime_g()) {
		// Scanning our own stack.
		bottom = (byte*)&gp;
		nextsp2 = secondary_stack_pointer();
	} else {
		// Scanning another goroutine's stack.
		// The goroutine is usually asleep (the world is stopped).
		bottom = (void*)gp->gcnextsp;
		if(bottom == nil)
			return true;
		nextsp2 = (void*)gp->gcnextsp2;
	}
	top = (byte*)(void*)(gp->gcinitialsp) + gp->gcstacksize;
	if(top > bottom)
		scanstackblock(bottom, (uintptr)(top - bottom), gcw);
	else
		scanstackblock(top, (uintptr)(bottom - top), gcw);
	if (nextsp2 != nil) {
		initialsp2 = (byte*)(void*)(gp->gcinitialsp2);
		if(initialsp2 > nextsp2)
			scanstackblock(nextsp2, (uintptr)(initialsp2 - nextsp2), gcw);
		else
			scanstackblock(initialsp2, (uintptr)(nextsp2 - initialsp2), gcw);
	}
#endif
	return true;
}
