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:
parent
7da8d69379
commit
cd4ed29a53
9 changed files with 111 additions and 4 deletions
3
src/coreclr/gc/env/gcenv.ee.h
vendored
3
src/coreclr/gc/env/gcenv.ee.h
vendored
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue