1
0
Fork 0
mirror of https://github.com/VSadov/Satori.git synced 2025-06-11 02:13:38 +09:00

scan current stack

This commit is contained in:
vsadov 2020-06-16 12:57:33 -07:00
parent 7da8d69379
commit cd4ed29a53
9 changed files with 111 additions and 4 deletions

View file

@ -15,9 +15,10 @@ public:
static void RestartEE(bool bFinishedGC); //resume threads.
//
// The GC roots enumeration callback
// The GC roots enumeration callbacks
//
static void GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc);
static void GcScanCurrentStackRoots(promote_func* fn, ScanContext* sc);
//
// Callbacks issues during GC that the execution engine can do its own bookeeping

View file

@ -28,6 +28,12 @@ inline void GCToEEInterface::RestartEE(bool bFinishedGC)
g_theGCToCLR->RestartEE(bFinishedGC);
}
inline void GCToEEInterface::GcScanCurrentStackRoots(promote_func* fn, ScanContext* sc)
{
assert(g_theGCToCLR != nullptr);
g_theGCToCLR->GcScanCurrentStackRoots(fn, sc);
}
inline void GCToEEInterface::GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc)
{
assert(g_theGCToCLR != nullptr);

View file

@ -191,6 +191,11 @@ public:
virtual
void GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc) = 0;
// Performs a stack walk of current thread and invokes the given promote_func
// on all GC roots encountered on the stack.
virtual
void GcScanCurrentStackRoots(promote_func* fn, ScanContext* sc) = 0;
// Callback from the GC informing the EE that it is preparing to start working.
virtual
void GcStartWork(int condemned, int max_gen) = 0;

View file

@ -158,9 +158,11 @@ Object* SatoriAllocator::AllocSmall(SatoriAllocationContext* context, size_t siz
// unclaim unused.
context->alloc_bytes -= context->alloc_limit - context->alloc_ptr;
// make parsable?
_ASSERTE((size_t)context->alloc_ptr < region->End());
SatoriUtil::MakeFreeObject((Object*)context->alloc_ptr, region->End() - (size_t)context->alloc_ptr);
// TODO: VS try compact current
region->MarkThreadLocal();
m_heap->Recycler()->AddRegion(region);
context->alloc_ptr = context->alloc_limit = nullptr;

View file

@ -9,6 +9,7 @@
#include "gcenv.h"
#include "../env/gcenv.os.h"
#include "../env/gcenv.ee.h"
#include "SatoriGCHeap.h"
#include "SatoriAllocator.h"
#include "SatoriRecycler.h"
@ -204,7 +205,7 @@ void SatoriRegion::Coalesce(SatoriRegion* next)
m_end = next->m_end;
m_committed = next->m_committed;
m_zeroInitedAfter = next->m_zeroInitedAfter;
m_allocEnd = next->m_allocEnd;
m_allocEnd = next->m_allocEnd;
}
size_t SatoriRegion::Allocate(size_t size, bool ensureZeroInited)
@ -296,3 +297,61 @@ size_t SatoriRegion::AllocateHuge(size_t size, bool ensureZeroInited)
m_zeroInitedAfter = max(m_zeroInitedAfter, allocEnd);
return result;
}
Object* SatoriRegion::FindObject(size_t location)
{
_ASSERTE(location >= (size_t)FistObject() && location <= End());
// TODO: VS use index
Object* current = FistObject();
Object* next = SatoriUtil::Next(current);
while ((size_t)next <= location)
{
current = next;
next = SatoriUtil::Next(current);
}
return SatoriUtil::IsFreeObject(current) ? nullptr : current;
}
void SatoriRegion::MarkFn(PTR_PTR_Object ppObject, ScanContext* sc, uint32_t flags)
{
SatoriRegion* region = (SatoriRegion*)sc->_unused1;
size_t location = (size_t)*ppObject;
if (location < (size_t)region->FistObject() || location > region->End())
{
return;
}
Object* obj;
if (flags & GC_CALL_INTERIOR)
{
obj = region->FindObject(location);
if (obj == nullptr)
{
return;
}
}
else
{
obj = (Object*)location;
}
if (flags & GC_CALL_PINNED)
{
// PinObject(obj);
}
// MarkObject(obj);
};
void SatoriRegion::MarkThreadLocal()
{
ScanContext sc;
sc.promotion = TRUE;
sc._unused1 = this;
GCToEEInterface::GcScanCurrentStackRoots((promote_func*)MarkFn, &sc);
}

View file

@ -77,11 +77,20 @@ public:
return m_allocEnd - m_allocStart;
}
Object* FistObject()
{
return &m_firstObject;
}
static SatoriRegion* RegionForObject(Object* obj)
{
return (SatoriRegion*)(((size_t)obj) >> Satori::REGION_BITS);
}
Object* FindObject(size_t location);
void MarkThreadLocal();
void Publish()
{
_ASSERTE(m_state == SatoriRegionState::allocating);
@ -114,6 +123,7 @@ private:
private:
void SplitCore(size_t regionSize, size_t& newStart, size_t& newCommitted, size_t& newZeroInitedAfter);
static void MarkFn(PTR_PTR_Object ppObject, ScanContext* sc, uint32_t flags);
bool IsEmpty();
};

View file

@ -36,7 +36,7 @@ namespace Satori
static const int LARGE_OBJECT_THRESHOLD = 85000;
// TODO: VS consider: in theory could be 2, but that would complicate walking.
static const size_t MIN_FREE_SIZE = 3;
static const size_t MIN_FREE_SIZE = 3 * sizeof(size_t);
static const size_t MIN_REGULAR_ALLOC = 1 << 12;
}

View file

@ -85,9 +85,11 @@ static void ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc)
// Either we are in a concurrent situation (in which case the thread is unknown to
// us), or we are performing a synchronous GC and we are the GC thread, holding
// the threadstore lock.
// Or we are scanning our own stack, which is always ok.
_ASSERTE(dbgOnly_IsSpecialEEThread() ||
GetThread() == NULL ||
GetThread() == sc->thread_under_crawl ||
// this is for background GC threads which always call this when EE is suspended.
IsGCSpecialThread() ||
(GetThread() == ThreadSuspend::GetSuspensionThread() && ThreadStore::HoldingThreadStore()));
@ -212,6 +214,27 @@ static void ScanTailCallArgBufferRoots(Thread* pThread, promote_func* fn, ScanCo
}
}
void GCToEEInterface::GcScanCurrentStackRoots(promote_func* fn, ScanContext* sc)
{
STRESS_LOG1(LF_GCROOTS, LL_INFO10, "GC Stack Scan: Promotion Phase = %d\n", sc->promotion);
Thread* pThread = GetThread();
sc->thread_under_crawl = pThread;
sc->concurrent = FALSE;
STRESS_LOG2(LF_GC | LF_GCROOTS, LL_INFO100, "{ Starting scan of Thread %p ID = %x\n", pThread, pThread->GetThreadId());
#ifdef FEATURE_EVENT_TRACE
sc->dwEtwRootKind = kEtwGCRootKindStack;
#endif // FEATURE_EVENT_TRACE
ScanStackRoots(pThread, fn, sc);
ScanTailCallArgBufferRoots(pThread, fn, sc);
#ifdef FEATURE_EVENT_TRACE
sc->dwEtwRootKind = kEtwGCRootKindOther;
#endif // FEATURE_EVENT_TRACE
STRESS_LOG2(LF_GC | LF_GCROOTS, LL_INFO100, "Ending scan of Thread %p ID = 0x%x }\n", pThread, pThread->GetThreadId());
}
void GCToEEInterface::GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc)
{
STRESS_LOG1(LF_GCROOTS, LL_INFO10, "GCScan: Promotion Phase = %d\n", sc->promotion);

View file

@ -32,6 +32,7 @@ public:
void SuspendEE(SUSPEND_REASON reason);
void RestartEE(bool bFinishedGC);
void GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc);
void GcScanCurrentStackRoots(promote_func* fn, ScanContext* sc);
void GcStartWork(int condemned, int max_gen);
void AfterGcScanRoots(int condemned, int max_gen, ScanContext* sc);
void GcBeforeBGCSweepWork();