Ejemplo n.º 1
0
static void
mark(void)
{
	uintptr blsize, nobj;
	struct root_list *pl;

	// Figure out how big an object stack we need.
	// Get a new one if we need more than we have
	// or we need significantly less than we have.
	nobj = mstats.heap_objects;
	if(nobj > (uintptr)(ebl - bl) || nobj < (uintptr)(ebl-bl)/4) {
		if(bl != nil)
			runtime_SysFree(bl, (byte*)ebl - (byte*)bl);
		
		// While we're allocated a new object stack,
		// add 20% headroom and also round up to
		// the nearest page boundary, since mmap
		// will anyway.
		nobj = nobj * 12/10;
		blsize = nobj * sizeof *bl;
		blsize = (blsize + 4095) & ~4095;
		nobj = blsize / sizeof *bl;
		bl = runtime_SysAlloc(blsize);
		ebl = bl + nobj;
	}

	for(pl = roots; pl != nil; pl = pl->next) {
		struct root* pr = &pl->roots[0];
		while(1) {
			void *decl = pr->decl;
			if(decl == nil)
				break;
			scanblock(decl, pr->size);
			pr++;
		}
	}

	scanblock((byte*)&m0, sizeof m0);
	scanblock((byte*)&finq, sizeof finq);
	runtime_MProf_Mark(scanblock);

	// mark stacks
	__go_scanstacks(scanblock);

	// mark things pointed at by objects with finalizers
	runtime_walkfintab(markfin, scanblock);
}
Ejemplo n.º 2
0
static void
scanblock(int32 depth, byte *b, int64 n)
{
	int32 off;
	void *obj;
	uintptr size;
	uint32 *refp, ref;
	void **vp;
	int64 i;

	if(Debug > 1)
		printf("%d scanblock %p %D\n", depth, b, n);
	off = (uint32)(uintptr)b & (PtrSize-1);
	if(off) {
		b += PtrSize - off;
		n -= PtrSize - off;
	}

	vp = (void**)b;
	n /= PtrSize;
	for(i=0; i<n; i++) {
		obj = vp[i];
		if(obj == nil)
			continue;
		if(mheap.closure_min != nil && mheap.closure_min <= (byte*)obj && (byte*)obj < mheap.closure_max) {
			if((((uintptr)obj) & 63) != 0)
				continue;

			// Looks like a Native Client closure.
			// Actual pointer is pointed at by address in first instruction.
			// Embedded pointer starts at byte 2.
			// If it is f4f4f4f4 then that space hasn't been
			// used for a closure yet (f4 is the HLT instruction).
			// See nacl/386/closure.c for more.
			void **pp;
			pp = *(void***)((byte*)obj+2);
			if(pp == (void**)0xf4f4f4f4)	// HLT... - not a closure after all
				continue;
			obj = *pp;
		}
		if(mheap.min <= (byte*)obj && (byte*)obj < mheap.max) {
			if(mlookup(obj, &obj, &size, nil, &refp)) {
				ref = *refp;
				switch(ref & ~RefFlags) {
				case RefNone:
					if(Debug > 1)
						printf("%d found at %p: ", depth, &vp[i]);
					*refp = RefSome | (ref & RefFlags);
					if(!(ref & RefNoPointers))
						scanblock(depth+1, obj, size);
					break;
				}
			}
		}
	}
}
Ejemplo n.º 3
0
static void
markfin(void *v)
{
	uintptr size;
	uint32 *refp;

	size = 0;
	refp = nil;
	if(!runtime_mlookup(v, (byte**)&v, &size, nil, &refp) || !(*refp & RefHasFinalizer))
		runtime_throw("mark - finalizer inconsistency");
	
	// do not mark the finalizer block itself.  just mark the things it points at.
	scanblock(v, size);
}
Ejemplo n.º 4
0
static void
mark(void)
{
	G *gp;

	// mark data+bss.
	// skip mheap itself, which has no interesting pointers
	// and is mostly zeroed and would not otherwise be paged in.
	scanblock(0, data, (byte*)&mheap - data);
	scanblock(0, (byte*)(&mheap+1), end - (byte*)(&mheap+1));

	// mark stacks
	for(gp=allg; gp!=nil; gp=gp->alllink) {
		switch(gp->status){
		default:
			printf("unexpected G.status %d\n", gp->status);
			throw("mark - bad status");
		case Gdead:
			break;
		case Grunning:
		case Grecovery:
			if(gp != g)
				throw("mark - world not stopped");
			scanstack(gp);
			break;
		case Grunnable:
		case Gsyscall:
		case Gwaiting:
			scanstack(gp);
			break;
		}
	}

	// mark things pointed at by objects with finalizers
	walkfintab(markfin);
}
Ejemplo n.º 5
0
static void
scanstack(G *gp)
{
	Stktop *stk;
	byte *sp;

	if(gp == g)
		sp = (byte*)&gp;
	else
		sp = gp->sched.sp;
	if(Debug > 1)
		printf("scanstack %d %p\n", gp->goid, sp);
	stk = (Stktop*)gp->stackbase;
	while(stk) {
		scanblock(0, sp, (byte*)stk - sp);
		sp = stk->gobuf.sp;
		stk = (Stktop*)stk->stackbase;
	}
}