mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Fixed GC stack overflow issue
This commit is contained in:
parent
61b440ea36
commit
3483c9de58
2 changed files with 43 additions and 62 deletions
|
@ -539,13 +539,7 @@ void* BfObjectAllocate(intptr size, bf::System::Type* objType)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gBFGC.mAllocSinceLastGC += size;
|
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;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -591,6 +585,9 @@ BFGC::BFGC()
|
||||||
mSkipMark = false;
|
mSkipMark = false;
|
||||||
mGracelessShutdown = false;
|
mGracelessShutdown = false;
|
||||||
mMainThreadTLSPtr = NULL;
|
mMainThreadTLSPtr = NULL;
|
||||||
|
mHadPendingGCDataOverflow = false;
|
||||||
|
mCurPendingGCDepth = 0;
|
||||||
|
mMaxPendingGCDepth = 0;
|
||||||
|
|
||||||
mCollectIdx = 0;
|
mCollectIdx = 0;
|
||||||
mStackScanIdx = 0;
|
mStackScanIdx = 0;
|
||||||
|
@ -860,10 +857,15 @@ bool BFGC::HandlePendingGCData(Beefy::Array<bf::System::Object*>* pendingGCData)
|
||||||
|
|
||||||
while (!pendingGCData->IsEmpty())
|
while (!pendingGCData->IsEmpty())
|
||||||
{
|
{
|
||||||
|
mCurPendingGCDepth = 0;
|
||||||
|
|
||||||
bf::System::Object* obj = pendingGCData->back();
|
bf::System::Object* obj = pendingGCData->back();
|
||||||
pendingGCData->pop_back();
|
pendingGCData->pop_back();
|
||||||
MarkMembers(obj);
|
MarkMembers(obj);
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
|
if (mCurPendingGCDepth > mMaxPendingGCDepth)
|
||||||
|
mMaxPendingGCDepth = mCurPendingGCDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
return count > 0;
|
return count > 0;
|
||||||
|
@ -1818,9 +1820,18 @@ void BFGC::Run()
|
||||||
|
|
||||||
lastGCTick = tickNow;
|
lastGCTick = tickNow;
|
||||||
mCollectRequested = false;
|
mCollectRequested = false;
|
||||||
mPerformingCollection = true;
|
mPerformingCollection = true;
|
||||||
BF_FULL_MEMORY_FENCE();
|
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();
|
BF_FULL_MEMORY_FENCE();
|
||||||
mPerformingCollection = false;
|
mPerformingCollection = false;
|
||||||
BF_FULL_MEMORY_FENCE();
|
BF_FULL_MEMORY_FENCE();
|
||||||
|
@ -1907,15 +1918,12 @@ void BFGC::Init()
|
||||||
|
|
||||||
void BFGC::Start()
|
void BFGC::Start()
|
||||||
{
|
{
|
||||||
#ifndef BF_GC_DISABLED
|
#ifndef BF_GC_DISABLED
|
||||||
//mEphemeronTombstone = Object::BFCreate();
|
|
||||||
//RegisterRoot(mEphemeronTombstone);
|
|
||||||
mRunning = true;
|
mRunning = true;
|
||||||
|
|
||||||
#ifdef BF_DEBUG
|
#ifdef BF_DEBUG
|
||||||
// More stack space is needed in debug version
|
// 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);
|
||||||
mGCThread = BfpThread_Create(RunStub, (void*)this, 256*1024, (BfpThreadCreateFlags)(BfpThreadCreateFlag_Suspended | BfpThreadCreateFlag_StackSizeReserve), &mThreadId);
|
|
||||||
#else
|
#else
|
||||||
mGCThread = BfpThread_Create(RunStub, (void*)this, 64 * 1024, (BfpThreadCreateFlags)(BfpThreadCreateFlag_Suspended | BfpThreadCreateFlag_StackSizeReserve), &mThreadId);
|
mGCThread = BfpThread_Create(RunStub, (void*)this, 64 * 1024, (BfpThreadCreateFlags)(BfpThreadCreateFlag_Suspended | BfpThreadCreateFlag_StackSizeReserve), &mThreadId);
|
||||||
#endif
|
#endif
|
||||||
|
@ -2304,7 +2312,7 @@ void BFGC::PerformCollection()
|
||||||
BOOL worked = ::VirtualProtect(mallocAddr, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
|
BOOL worked = ::VirtualProtect(mallocAddr, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||||
uint8 oldCode = *mallocAddr;
|
uint8 oldCode = *mallocAddr;
|
||||||
*mallocAddr = 0xCC;*/
|
*mallocAddr = 0xCC;*/
|
||||||
|
|
||||||
mPendingGCData.Reserve(BF_GC_MAX_PENDING_OBJECT_COUNT);
|
mPendingGCData.Reserve(BF_GC_MAX_PENDING_OBJECT_COUNT);
|
||||||
|
|
||||||
uint32 suspendStartTick = BFTickCount();
|
uint32 suspendStartTick = BFTickCount();
|
||||||
|
@ -2341,7 +2349,8 @@ void BFGC::PerformCollection()
|
||||||
//BFGCLogWrite();
|
//BFGCLogWrite();
|
||||||
|
|
||||||
mFinalizeList.Clear();
|
mFinalizeList.Clear();
|
||||||
Sweep();
|
if (!mHadPendingGCDataOverflow)
|
||||||
|
Sweep();
|
||||||
|
|
||||||
#ifdef BF_GC_DEBUGSWEEP
|
#ifdef BF_GC_DEBUGSWEEP
|
||||||
ResumeThreads();
|
ResumeThreads();
|
||||||
|
@ -2565,54 +2574,23 @@ void BFGC::MarkFromGCThread(bf::System::Object* obj)
|
||||||
parentObj = gMarkingObject[mMarkDepthCount-1];
|
parentObj = gMarkingObject[mMarkDepthCount-1];
|
||||||
BFLOG3(GCLog::EVENT_MARK, (intptr)obj, obj->mObjectFlags, (intptr)parentObj);
|
BFLOG3(GCLog::EVENT_MARK, (intptr)obj, obj->mObjectFlags, (intptr)parentObj);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int maxMarkDepth = 256;
|
|
||||||
//int maxMarkDepth = 1;
|
|
||||||
|
|
||||||
obj->mObjectFlags = (BfObjectFlags)((obj->mObjectFlags & ~BF_OBJECTFLAG_MARK_ID_MASK) | mCurMarkId);
|
obj->mObjectFlags = (BfObjectFlags)((obj->mObjectFlags & ~BF_OBJECTFLAG_MARK_ID_MASK) | mCurMarkId);
|
||||||
mCurGCMarkCount++;
|
mCurGCMarkCount++;
|
||||||
//if (obj->mBFVData->BFMarkMembers != NULL)
|
|
||||||
|
mCurGCObjectQueuedCount++;
|
||||||
|
mCurPendingGCDepth++;
|
||||||
|
|
||||||
|
bool allowQueue = true;
|
||||||
|
if (mPendingGCData.GetFreeCount() > 0)
|
||||||
{
|
{
|
||||||
mCurGCObjectQueuedCount++;
|
mPendingGCData.Add(obj);
|
||||||
|
}
|
||||||
#ifdef NO_QUEUE_OBJECTS
|
else
|
||||||
Beefy::AutoCrit autoCrit(mCritSect);
|
{
|
||||||
BFVCALL(obj, BFMarkMembers)();
|
mHadPendingGCDataOverflow = true;
|
||||||
#else
|
// No more room left -- we can't queue...
|
||||||
|
//MarkMembers(obj);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -302,6 +302,9 @@ public:
|
||||||
static int volatile sAllocFlags;
|
static int volatile sAllocFlags;
|
||||||
|
|
||||||
Beefy::Array<bf::System::Object*> mPendingGCData;
|
Beefy::Array<bf::System::Object*> mPendingGCData;
|
||||||
|
bool mHadPendingGCDataOverflow;
|
||||||
|
int mCurPendingGCDepth;
|
||||||
|
int mMaxPendingGCDepth;
|
||||||
Beefy::Array<ThreadInfo*> mThreadList;
|
Beefy::Array<ThreadInfo*> mThreadList;
|
||||||
int mCurMutatorMarkCount;
|
int mCurMutatorMarkCount;
|
||||||
int mCurGCMarkCount;
|
int mCurGCMarkCount;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue