diff options
author | Jan Kotas <jkotas@microsoft.com> | 2015-12-08 20:46:46 -0800 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2015-12-08 20:46:46 -0800 |
commit | 58060b21799c81515f42872bafd5acd21e09311b (patch) | |
tree | 24bdfe3cae5f7b2a6fc1a7dc0cf1c76e26cceef1 | |
parent | 9e874596ae7858591bbc6ce14c5a94e503e95151 (diff) | |
parent | 8058b6ab287d6b93b975d951384209b5fd0173eb (diff) | |
download | coreclr-58060b21799c81515f42872bafd5acd21e09311b.tar.gz coreclr-58060b21799c81515f42872bafd5acd21e09311b.tar.bz2 coreclr-58060b21799c81515f42872bafd5acd21e09311b.zip |
Merge pull request #2272 from jkotas/gc-update
Update GC from CoreRT
-rw-r--r-- | src/gc/env/gcenv.base.h | 11 | ||||
-rw-r--r-- | src/gc/gc.cpp | 40 | ||||
-rw-r--r-- | src/gc/gcscan.cpp | 71 | ||||
-rw-r--r-- | src/gc/gcscan.h | 9 | ||||
-rw-r--r-- | src/gc/sample/GCSample.cpp | 8 | ||||
-rw-r--r-- | src/gc/sample/gcenv.cpp | 15 | ||||
-rw-r--r-- | src/gc/sample/gcenv.h | 4 | ||||
-rw-r--r-- | src/vm/gcenv.cpp | 64 | ||||
-rw-r--r-- | src/vm/gcenv.h | 9 |
9 files changed, 111 insertions, 120 deletions
diff --git a/src/gc/env/gcenv.base.h b/src/gc/env/gcenv.base.h index 57fbb0460b..5b8f5f7dd3 100644 --- a/src/gc/env/gcenv.base.h +++ b/src/gc/env/gcenv.base.h @@ -602,6 +602,8 @@ typedef void promote_func(PTR_PTR_Object, ScanContext*, uint32_t); typedef void (CALLBACK *HANDLESCANPROC)(PTR_UNCHECKED_OBJECTREF pref, uintptr_t *pExtraInfo, uintptr_t param1, uintptr_t param2); +typedef void enum_alloc_context_func(alloc_context*, void*); + class GCToEEInterface { public: @@ -620,10 +622,7 @@ public: // // The stack 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 @@ -655,12 +654,12 @@ public: static void EnablePreemptiveGC(Thread * pThread); static void DisablePreemptiveGC(Thread * pThread); static void SetGCSpecial(Thread * pThread); - static alloc_context * GetAllocContext(Thread * pThread); static bool CatchAtSafePoint(Thread * pThread); + static alloc_context * GetAllocContext(Thread * pThread); // ThreadStore functions static void AttachCurrentThread(); // does not acquire thread store lock - static Thread * GetThreadList(Thread * pThread); + static void GcEnumAllocContexts (enum_alloc_context_func* fn, void* param); }; class FinalizerThread diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp index 44450c0b1b..db878fbd8e 100644 --- a/src/gc/gc.cpp +++ b/src/gc/gc.cpp @@ -5767,7 +5767,7 @@ void gc_heap::fix_allocation_context (alloc_context* acontext, BOOL for_gc_p, //used by the heap verification for concurrent gc. //it nulls out the words set by fix_allocation_context for heap_verification -void repair_allocation (alloc_context* acontext) +void repair_allocation (alloc_context* acontext, void*) { uint8_t* point = acontext->alloc_ptr; @@ -5780,7 +5780,7 @@ void repair_allocation (alloc_context* acontext) } } -void void_allocation (alloc_context* acontext) +void void_allocation (alloc_context* acontext, void*) { uint8_t* point = acontext->alloc_ptr; @@ -5793,22 +5793,38 @@ void void_allocation (alloc_context* acontext) } } -void gc_heap::fix_allocation_contexts (BOOL for_gc_p) -{ - CNameSpace::GcFixAllocContexts ((void*)(size_t)for_gc_p, __this); - fix_youngest_allocation_area (for_gc_p); - fix_large_allocation_area (for_gc_p); -} - void gc_heap::repair_allocation_contexts (BOOL repair_p) { - CNameSpace::GcEnumAllocContexts (repair_p ? repair_allocation : void_allocation); + GCToEEInterface::GcEnumAllocContexts (repair_p ? repair_allocation : void_allocation, NULL); alloc_context* acontext = generation_alloc_context (youngest_generation); if (repair_p) - repair_allocation (acontext); + repair_allocation (acontext, NULL); else - void_allocation (acontext); + void_allocation (acontext, NULL); +} + +struct fix_alloc_context_args +{ + BOOL for_gc_p; + void* heap; +}; + +void fix_alloc_context(alloc_context* acontext, void* param) +{ + fix_alloc_context_args* args = (fix_alloc_context_args*)param; + GCHeap::GetGCHeap()->FixAllocContext(acontext, FALSE, (void*)(size_t)(args->for_gc_p), args->heap); +} + +void gc_heap::fix_allocation_contexts(BOOL for_gc_p) +{ + fix_alloc_context_args args; + args.for_gc_p = for_gc_p; + args.heap = __this; + GCToEEInterface::GcEnumAllocContexts(fix_alloc_context, &args); + + fix_youngest_allocation_area(for_gc_p); + fix_large_allocation_area(for_gc_p); } void gc_heap::fix_older_allocation_area (generation* older_gen) diff --git a/src/gc/gcscan.cpp b/src/gc/gcscan.cpp index 50b76f54cd..dd7b4c1be6 100644 --- a/src/gc/gcscan.cpp +++ b/src/gc/gcscan.cpp @@ -36,11 +36,16 @@ bool CNameSpace::GetGcRuntimeStructuresValid () } #ifdef DACCESS_COMPILE + +#ifndef FEATURE_REDHAWK void CNameSpace::EnumMemoryRegions(CLRDataEnumMemoryFlags flags) { + UNREFERENCED_PARAMETER(flags); m_GcStructuresInvalidCnt.EnumMem(); } +#endif + #else // @@ -119,7 +124,7 @@ void CNameSpace::GcWeakPtrScan( promote_func* fn, int condemned, int max_gen, Sc Ref_ScanDependentHandlesForClearing(condemned, max_gen, sc, fn); } -static void CALLBACK CheckPromoted(_UNCHECKED_OBJECTREF *pObjRef, uintptr_t *pExtraInfo, uintptr_t lp1, uintptr_t lp2) +static void CALLBACK CheckPromoted(_UNCHECKED_OBJECTREF *pObjRef, uintptr_t * /*pExtraInfo*/, uintptr_t /*lp1*/, uintptr_t /*lp2*/) { LIMITED_METHOD_CONTRACT; @@ -140,6 +145,8 @@ static void CALLBACK CheckPromoted(_UNCHECKED_OBJECTREF *pObjRef, uintptr_t *pEx void CNameSpace::GcWeakPtrScanBySingleThread( int condemned, int max_gen, ScanContext* sc ) { + UNREFERENCED_PARAMETER(condemned); + UNREFERENCED_PARAMETER(max_gen); GCToEEInterface::SyncBlockCacheWeakPtrScan(&CheckPromoted, (uintptr_t)sc, 0); } @@ -151,6 +158,7 @@ void CNameSpace::GcScanSizedRefs(promote_func* fn, int condemned, int max_gen, S void CNameSpace::GcShortWeakPtrScan(promote_func* fn, int condemned, int max_gen, ScanContext* sc) { + UNREFERENCED_PARAMETER(fn); Ref_CheckAlive(condemned, max_gen, (uintptr_t)sc); } @@ -166,37 +174,7 @@ void CNameSpace::GcScanRoots(promote_func* fn, int condemned, int max_gen, PAL_TRY #endif // _DEBUG && CATCH_GC { - 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) - { - GCToEEInterface::ScanStaticGCRefsOpportunistically(fn, sc); - } - } - - Thread* pThread = NULL; - while ((pThread = GCToEEInterface::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 - GCToEEInterface::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()); - } - } + GCToEEInterface::GcScanRoots(fn, condemned, max_gen, sc); } #if defined ( _DEBUG) && defined (CATCH_GC) PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -318,35 +296,6 @@ void CNameSpace::GcPromotionsGranted (int condemned, int max_gen, ScanContext* s } -void CNameSpace::GcFixAllocContexts (void* arg, void *heap) -{ - LIMITED_METHOD_CONTRACT; - - if (GCHeap::UseAllocationContexts()) - { - Thread *thread = NULL; - while ((thread = GCToEEInterface::GetThreadList(thread)) != NULL) - { - GCHeap::GetGCHeap()->FixAllocContext(GCToEEInterface::GetAllocContext(thread), FALSE, arg, heap); - } - } -} - -void CNameSpace::GcEnumAllocContexts (enum_alloc_context_func* fn) -{ - LIMITED_METHOD_CONTRACT; - - if (GCHeap::UseAllocationContexts()) - { - Thread *thread = NULL; - while ((thread = GCToEEInterface::GetThreadList(thread)) != NULL) - { - (*fn) (GCToEEInterface::GetAllocContext(thread)); - } - } -} - - size_t CNameSpace::AskForMoreReservedMemory (size_t old_size, size_t need_size) { LIMITED_METHOD_CONTRACT; diff --git a/src/gc/gcscan.h b/src/gc/gcscan.h index 956622abb4..0fddf3540e 100644 --- a/src/gc/gcscan.h +++ b/src/gc/gcscan.h @@ -39,17 +39,12 @@ struct DhContext // something like GCDomain.... // </TODO> -typedef void enum_alloc_context_func(alloc_context*); - class CNameSpace { friend struct ::_DacGlobals; public: - // Called on gc start - static void GcStartDoWork(); - static void GcScanSizedRefs(promote_func* fn, int condemned, int max_gen, ScanContext* sc); // Regular stack Roots @@ -99,10 +94,6 @@ class CNameSpace // post-promotions callback some roots were demoted static void GcDemote (int condemned, int max_gen, ScanContext* sc); - - static void GcEnumAllocContexts (enum_alloc_context_func* fn); - - static void GcFixAllocContexts (void* arg, void *heap); static size_t AskForMoreReservedMemory (size_t old_size, size_t need_size); diff --git a/src/gc/sample/GCSample.cpp b/src/gc/sample/GCSample.cpp index 7ae6c2d115..446956110a 100644 --- a/src/gc/sample/GCSample.cpp +++ b/src/gc/sample/GCSample.cpp @@ -26,11 +26,11 @@ // static void SuspendEE(SUSPEND_REASON reason); // static void RestartEE(bool bFinishedGC); //resume threads. // -// * Enumeration of threads that are running managed code: -// static Thread * GetThreadList(Thread * pThread); +// * Enumeration of thread-local allocators: +// static void GcEnumAllocContexts (enum_alloc_context_func* fn, void* param); // -// * Scanning of stack roots of given thread: -// static void ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc); +// * Scanning of stack roots: +// static void GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc); // // The sample has trivial implementation for these methods. It is single threaded, and there are no stack roots to // be reported. There are number of other callbacks that GC calls to optionally allow the execution engine to do its diff --git a/src/gc/sample/gcenv.cpp b/src/gc/sample/gcenv.cpp index f1d6cfad0f..2164fb0c5e 100644 --- a/src/gc/sample/gcenv.cpp +++ b/src/gc/sample/gcenv.cpp @@ -60,15 +60,11 @@ void GCToEEInterface::RestartEE(bool bFinishedGC) GCHeap::GetGCHeap()->SetGCInProgress(FALSE); } -void GCToEEInterface::ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc) +void GCToEEInterface::GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc) { // TODO: Implement - Scan stack roots on given thread } -void GCToEEInterface::ScanStaticGCRefsOpportunistically(promote_func* fn, ScanContext* sc) -{ -} - void GCToEEInterface::GcStartWork(int condemned, int max_gen) { } @@ -126,11 +122,16 @@ void GCToEEInterface::AttachCurrentThread() ThreadStore::AttachCurrentThread(); } -Thread * GCToEEInterface::GetThreadList(Thread * pThread) +void GCToEEInterface::GcEnumAllocContexts (enum_alloc_context_func* fn, void* param) { - return ThreadStore::GetThreadList(pThread); + Thread * pThread = NULL; + while ((pThread = ThreadStore::GetThreadList(pThread)) != NULL) + { + fn(pThread->GetAllocContext(), param); + } } + void FinalizerThread::EnableFinalization() { // Signal to finalizer thread that there are objects to finalize diff --git a/src/gc/sample/gcenv.h b/src/gc/sample/gcenv.h index 1a9fac5717..1e391ab80c 100644 --- a/src/gc/sample/gcenv.h +++ b/src/gc/sample/gcenv.h @@ -16,6 +16,7 @@ #define _ASSERTE(_expr) ASSERT(_expr) #endif +#include "gcenv.structs.h" #include "gcenv.base.h" #include "gcenv.object.h" #include "gcenv.sync.h" @@ -139,3 +140,6 @@ public: }; extern EEConfig * g_pConfig; + +#include "etmdummy.h" +#define ETW_EVENT_ENABLED(e,f) false diff --git a/src/vm/gcenv.cpp b/src/vm/gcenv.cpp index 5188e424e8..99880b54a1 100644 --- a/src/vm/gcenv.cpp +++ b/src/vm/gcenv.cpp @@ -466,23 +466,11 @@ VOID GCToEEInterface::AfterGcScanRoots (int condemned, int max_gen, #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; @@ -557,6 +545,40 @@ VOID GCToEEInterface::ScanStackRoots(Thread * pThread, promote_func* fn, ScanCon } } +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 @@ -689,8 +711,18 @@ bool GCToEEInterface::CatchAtSafePoint(Thread * pThread) 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); + } } diff --git a/src/vm/gcenv.h b/src/vm/gcenv.h index 93d41850a7..73e65852a7 100644 --- a/src/vm/gcenv.h +++ b/src/vm/gcenv.h @@ -51,6 +51,8 @@ class CrawlFrame; typedef void promote_func(PTR_PTR_Object, ScanContext*, uint32_t); +typedef void enum_alloc_context_func(alloc_context*, void*); + typedef struct { promote_func* f; @@ -77,10 +79,7 @@ public: // // 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 @@ -130,7 +129,7 @@ public: 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 |