#endif // FEATURE_COMINTEROP
}
-void GCToEEInterface::ScanStaticGCRefsOpportunistically(promote_func* fn, ScanContext* sc)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- SystemDomain::EnumAllStaticGCRefs(fn, sc);
-}
-
/*
* Scan all stack roots
*/
-VOID GCToEEInterface::ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc)
+static void ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc)
{
GCCONTEXT gcctx;
}
}
+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);
+
+ // In server GC, we should be competing for marking the statics
+ if (GCHeap::MarkShouldCompeteForStatics())
+ {
+ if (condemned == max_gen && sc->promotion)
+ {
+ SystemDomain::EnumAllStaticGCRefs(fn, sc);
+ }
+ }
+
+ Thread* pThread = NULL;
+ while ((pThread = ThreadStore::GetThreadList(pThread)) != NULL)
+ {
+ STRESS_LOG2(LF_GC | LF_GCROOTS, LL_INFO100, "{ Starting scan of Thread %p ID = %x\n", pThread, pThread->GetThreadId());
+
+ if (GCHeap::GetGCHeap()->IsThreadUsingAllocationContextHeap(
+ GCToEEInterface::GetAllocContext(pThread), sc->thread_number))
+ {
+ sc->thread_under_crawl = pThread;
+#ifdef FEATURE_EVENT_TRACE
+ sc->dwEtwRootKind = kEtwGCRootKindStack;
+#endif // FEATURE_EVENT_TRACE
+ ScanStackRoots(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::GcStartWork (int condemned, int max_gen)
{
CONTRACTL
return !!pThread->CatchAtSafePoint();
}
-Thread * GCToEEInterface::GetThreadList(Thread * pThread)
+void GCToEEInterface::GcEnumAllocContexts(enum_alloc_context_func* fn, void* param)
{
- WRAPPER_NO_CONTRACT;
- return ThreadStore::GetThreadList(pThread);
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ Thread * pThread = NULL;
+ while ((pThread = ThreadStore::GetThreadList(pThread)) != NULL)
+ {
+ fn(pThread->GetAllocContext(), param);
+ }
}
typedef void promote_func(PTR_PTR_Object, ScanContext*, uint32_t);
+typedef void enum_alloc_context_func(alloc_context*, void*);
+
typedef struct
{
promote_func* f;
//
// The GC roots enumeration callback
//
- static void ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc);
-
- // Optional static GC refs scanning for better parallelization of server GC marking
- static void ScanStaticGCRefsOpportunistically(promote_func* fn, ScanContext* sc);
+ static void GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc);
//
// Callbacks issues during GC that the execution engine can do its own bookeeping
static alloc_context * GetAllocContext(Thread * pThread);
static bool CatchAtSafePoint(Thread * pThread);
- static Thread * GetThreadList(Thread * pThread);
+ static void GcEnumAllocContexts(enum_alloc_context_func* fn, void* param);
};
#define GCMemoryStatus MEMORYSTATUSEX