Beispiel #1
0
PyrGC::PyrGC(VMGlobals *g, AllocPool *inPool, PyrClass *mainProcessClass, long poolSize)
{
	mVMGlobals = g;
	mPool = inPool;
	//mCurSet = 0;
	mNumToScan = 0;

	mFlips = 0;
	mCollects = 0;
	mAllocTotal = 0;
	mNumAllocs = 0;
	mScans = 0;
	mStackScans = 0;
	mNumPartialScans = 0;
	mSlotsScanned = 0;

	mGreyColor = 3<<2;
	mBlackColor = 2<<2;
	mWhiteColor = 1<<2;
	mFreeColor = 0;

	mRunning = false;

	mCanSweep = false;
	mPartialScanObj = NULL;
	mPartialScanSlot = 0;

	mGrey.classptr = NULL;
	mGrey.obj_sizeclass = 0;
	mGrey.size = 0;
	mGrey.gc_color = obj_gcmarker;

	mGrey.prev = &mGrey;
	mGrey.next = &mGrey;

	mNumGrey = 0;

	mNewPool.Init(mPool, poolSize, poolSize, 9000);

	// initialize treadmills
	for (int i=0; i<kNumGCSets; ++i) {
		mSets[i].Init(i);
	}

	mProcess = newPyrProcess(g, mainProcessClass);

	mStack = mProcess->mainThread.uot->stack.uo;
	ToBlack(mStack);
	SetNil(&mProcess->mainThread.uot->stack);

	mNumGrey = 0;
	ToGrey2(mProcess);
	g->sp = mStack->slots - 1;
	g->process = mProcess;
	mRunning = true;

	SanityCheck();
	//assert(SanityCheck());

}
Beispiel #2
0
void PyrGC::Flip()
{
#ifdef GC_SANITYCHECK
	SanityCheck();
#endif

	ScanFinalizers();

	GCSet *gcs = mSets;
	if ((mFlips & 3) == 0) {
		// major flip
		for (int i=0; i<kNumGCSets; ++i, ++gcs) {
			gcs->MajorFlip();
		}

		// advance colors
		mBlackColor += 4;
		mWhiteColor += 4;
		mGreyColor += 4;
		mFreeColor += 4;
	} else {
		// minor flip
		for (int i=0; i<kNumGCSets; ++i, ++gcs) {
			gcs->MinorFlip();
		}
	}
	// move root to grey area
	mNumGrey = 0;
	ToGrey2(mProcess);

	ToBlack(mStack);

	// reset counts
	mNumToScan = 0;
	mCanSweep = true;

	mFlips++;
	//post("flips %d  collects %d   nalloc %d   alloc %d   grey %d\n", mFlips, mCollects, mNumAllocs, mAllocTotal, mNumGrey);

#ifdef GC_SANITYCHECK
	SanityCheck();
#endif
}
Beispiel #3
0
HOT bool PyrGC::ScanOneObj()
{
	// Find a set that has a grey object
	PyrObject* obj;
	obj = (PyrObject*)mGrey.next;
	if (IsMarker(obj)) {
		if (mNumGrey) fatalerror("grey count error\n");
		return false;
	}

	/*if (!IsGrey(obj)) {
		postfl("Object on grey list not grey  %d %d\n", obj->gc_color, mGreyColor);
		fatalerror("C1");
	}*/

	mScans++;

	//post("-> scan %d %d %d\n", mNumGrey, IsGrey(obj), mNumToScan);
	// Found a grey object
	// move obj from grey to black

	ToBlack(obj);

	int32 size = ScanSize(obj);
	//post("<- scan %d %d %d %d\n", mNumGrey, IsGrey(obj), mNumToScan, size);
	if (size > mNumToScan + 32)
	{
		mPartialScanObj = obj;
		mPartialScanSlot = 0;
		DoPartialScan(size);
	}
	else if (size > 0)
	{
		ScanSlots(obj->slots, size);
		mNumToScan -= 1L << obj->obj_sizeclass;
		if (mNumToScan < 0) mNumToScan = 0;
	} else {
		mNumToScan -= 1L << obj->obj_sizeclass;
		if (mNumToScan < 0) mNumToScan = 0;
	}
	return true;
}
Beispiel #4
0
void PyrGC::ScanFrames()
{
	VMGlobals *g = mVMGlobals;
	PyrFrame* frame = g->frame;
	while (frame) {
#if 1
		// this is more incremental
		if (IsWhite(frame)) {
			ToGrey2(frame);
		}
#else
		// this is more efficient
		if (!IsBlack(frame)) {
			ToBlack(frame);
			int32 size = ScanSize(frame);
			PyrSlot *slots = ((PyrObject*)frame)->slots;
			ScanSlots(slots, size);
		}
#endif
		frame = slotRawFrame(&frame->caller);
	}
}