1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48:20 +02:00

Fixed GC stack overflow issue

This commit is contained in:
Brian Fiete 2019-11-07 06:51:17 -08:00
parent 61b440ea36
commit 3483c9de58
2 changed files with 43 additions and 62 deletions

View file

@ -539,13 +539,7 @@ void* BfObjectAllocate(intptr size, bf::System::Type* objType)
#endif
gBFGC.mAllocSinceLastGC += size;
/*if ((uint32)gBFGC.mAllocSinceLastGC > (uint32)gBFGC.mAllocGCTrigger)
gBFGC.TriggerCollection();*/
//BfLog("AllocId %d ptr: %p Thread:%d\n", gBFGC.mTotalAllocs, obj, GetCurrentThreadId());
//gBFGC.TriggerCollection(true);
return obj;
}
@ -591,6 +585,9 @@ BFGC::BFGC()
mSkipMark = false;
mGracelessShutdown = false;
mMainThreadTLSPtr = NULL;
mHadPendingGCDataOverflow = false;
mCurPendingGCDepth = 0;
mMaxPendingGCDepth = 0;
mCollectIdx = 0;
mStackScanIdx = 0;
@ -860,10 +857,15 @@ bool BFGC::HandlePendingGCData(Beefy::Array<bf::System::Object*>* pendingGCData)
while (!pendingGCData->IsEmpty())
{
mCurPendingGCDepth = 0;
bf::System::Object* obj = pendingGCData->back();
pendingGCData->pop_back();
MarkMembers(obj);
count++;
if (mCurPendingGCDepth > mMaxPendingGCDepth)
mMaxPendingGCDepth = mCurPendingGCDepth;
}
return count > 0;
@ -1818,9 +1820,18 @@ void BFGC::Run()
lastGCTick = tickNow;
mCollectRequested = false;
mPerformingCollection = true;
mPerformingCollection = true;
BF_FULL_MEMORY_FENCE();
PerformCollection();
while (true)
{
mHadPendingGCDataOverflow = false;
mMaxPendingGCDepth = 0;
PerformCollection();
if (!mHadPendingGCDataOverflow)
break;
mPendingGCData.Reserve(BF_MAX(mPendingGCData.mAllocSize + mPendingGCData.mAllocSize / 2, mMaxPendingGCDepth + 256));
}
BF_FULL_MEMORY_FENCE();
mPerformingCollection = false;
BF_FULL_MEMORY_FENCE();
@ -1907,15 +1918,12 @@ void BFGC::Init()
void BFGC::Start()
{
#ifndef BF_GC_DISABLED
//mEphemeronTombstone = Object::BFCreate();
//RegisterRoot(mEphemeronTombstone);
#ifndef BF_GC_DISABLED
mRunning = true;
#ifdef BF_DEBUG
// More stack space is needed in debug version
//::CreateThread(NULL, 64*1024, (LPTHREAD_START_ROUTINE)&RunStub, (void*)this, 0, (DWORD*)&mThreadId);
mGCThread = BfpThread_Create(RunStub, (void*)this, 256*1024, (BfpThreadCreateFlags)(BfpThreadCreateFlag_Suspended | BfpThreadCreateFlag_StackSizeReserve), &mThreadId);
// More stack space is needed in debug version
mGCThread = BfpThread_Create(RunStub, (void*)this, 256 * 1024, (BfpThreadCreateFlags)(BfpThreadCreateFlag_Suspended | BfpThreadCreateFlag_StackSizeReserve), &mThreadId);
#else
mGCThread = BfpThread_Create(RunStub, (void*)this, 64 * 1024, (BfpThreadCreateFlags)(BfpThreadCreateFlag_Suspended | BfpThreadCreateFlag_StackSizeReserve), &mThreadId);
#endif
@ -2304,7 +2312,7 @@ void BFGC::PerformCollection()
BOOL worked = ::VirtualProtect(mallocAddr, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
uint8 oldCode = *mallocAddr;
*mallocAddr = 0xCC;*/
mPendingGCData.Reserve(BF_GC_MAX_PENDING_OBJECT_COUNT);
uint32 suspendStartTick = BFTickCount();
@ -2341,7 +2349,8 @@ void BFGC::PerformCollection()
//BFGCLogWrite();
mFinalizeList.Clear();
Sweep();
if (!mHadPendingGCDataOverflow)
Sweep();
#ifdef BF_GC_DEBUGSWEEP
ResumeThreads();
@ -2565,54 +2574,23 @@ void BFGC::MarkFromGCThread(bf::System::Object* obj)
parentObj = gMarkingObject[mMarkDepthCount-1];
BFLOG3(GCLog::EVENT_MARK, (intptr)obj, obj->mObjectFlags, (intptr)parentObj);
#endif
int maxMarkDepth = 256;
//int maxMarkDepth = 1;
obj->mObjectFlags = (BfObjectFlags)((obj->mObjectFlags & ~BF_OBJECTFLAG_MARK_ID_MASK) | mCurMarkId);
mCurGCMarkCount++;
//if (obj->mBFVData->BFMarkMembers != NULL)
mCurGCObjectQueuedCount++;
mCurPendingGCDepth++;
bool allowQueue = true;
if (mPendingGCData.GetFreeCount() > 0)
{
mCurGCObjectQueuedCount++;
#ifdef NO_QUEUE_OBJECTS
Beefy::AutoCrit autoCrit(mCritSect);
BFVCALL(obj, BFMarkMembers)();
#else
bool allowQueue = true;
//if ((!mQueueMarkObjects) && (mMarkDepthCount < maxMarkDepth))
if (mMarkDepthCount < maxMarkDepth)
{
#ifdef BF_GC_LOG_ENABLED
gMarkingObject[mMarkDepthCount] = obj;
#endif
mMarkDepthCount++;
// Try to clear off the list first
while (!mPendingGCData.IsEmpty())
{
bf::System::Object* queuedObj = mPendingGCData.back();
mPendingGCData.pop_back();
MarkMembers(queuedObj);
}
MarkMembers(obj);
mMarkDepthCount--;
}
else
{
if (mPendingGCData.GetFreeCount() > 0)
{
mPendingGCData.Add(obj);
}
else
{
// No more room left -- we can't queue...
MarkMembers(obj);
}
}
#endif
mPendingGCData.Add(obj);
}
else
{
mHadPendingGCDataOverflow = true;
// No more room left -- we can't queue...
//MarkMembers(obj);
}
#endif
}

View file

@ -302,6 +302,9 @@ public:
static int volatile sAllocFlags;
Beefy::Array<bf::System::Object*> mPendingGCData;
bool mHadPendingGCDataOverflow;
int mCurPendingGCDepth;
int mMaxPendingGCDepth;
Beefy::Array<ThreadInfo*> mThreadList;
int mCurMutatorMarkCount;
int mCurGCMarkCount;