diff options
author | Peter Kukol <pkukol@users.noreply.github.com> | 2016-09-28 18:29:33 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-09-28 18:29:33 -0700 |
commit | f20f51697d2c61ce998ed7514a327e3c1e1936bc (patch) | |
tree | e0285a495133411d5d993a9ba65a1e3d22a4756d /src/gc | |
parent | 0d46a91f2f48282fd004a35c8a28ddb24432237e (diff) | |
download | coreclr-f20f51697d2c61ce998ed7514a327e3c1e1936bc.tar.gz coreclr-f20f51697d2c61ce998ed7514a327e3c1e1936bc.tar.bz2 coreclr-f20f51697d2c61ce998ed7514a327e3c1e1936bc.zip |
Add option to measure time spent inside calls to the CLR. (#7357)
* Add option to measure time spent inside calls to the CLR (off by default).
Diffstat (limited to 'src/gc')
-rw-r--r-- | src/gc/env/gcenv.ee.h | 27 | ||||
-rw-r--r-- | src/gc/gc.cpp | 12 | ||||
-rw-r--r-- | src/gc/gc.h | 4 | ||||
-rw-r--r-- | src/gc/gccommon.cpp | 13 | ||||
-rw-r--r-- | src/gc/gcenv.ee.standalone.inl | 128 | ||||
-rw-r--r-- | src/gc/gcinterface.ee.h | 97 | ||||
-rw-r--r-- | src/gc/gcinterface.h | 32 | ||||
-rw-r--r-- | src/gc/sample/gcenv.ee.cpp | 2 | ||||
-rw-r--r-- | src/gc/sample/gcenv.h | 8 |
9 files changed, 36 insertions, 287 deletions
diff --git a/src/gc/env/gcenv.ee.h b/src/gc/env/gcenv.ee.h index dc6c1d84bb..f71380e1a1 100644 --- a/src/gc/env/gcenv.ee.h +++ b/src/gc/env/gcenv.ee.h @@ -7,11 +7,36 @@ #ifndef __GCENV_EE_H__ #define __GCENV_EE_H__ -#include "gcinterface.h" +struct ScanContext; +class CrawlFrame; +struct gc_alloc_context; + +typedef void promote_func(PTR_PTR_Object, ScanContext*, uint32_t); + +typedef void enum_alloc_context_func(gc_alloc_context*, void*); + +typedef struct +{ + promote_func* f; + ScanContext* sc; + CrawlFrame * cf; +} GCCONTEXT; + +// GC background thread function prototype +typedef uint32_t (__stdcall *GCBackgroundThreadFunction)(void* param); class GCToEEInterface { public: + // + // Suspend/Resume callbacks + // + typedef enum + { + SUSPEND_FOR_GC = 1, + SUSPEND_FOR_GC_PREP = 6 + } SUSPEND_REASON; + static void SuspendEE(SUSPEND_REASON reason); static void RestartEE(bool bFinishedGC); //resume threads. diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp index 205adee7d8..ea392c2178 100644 --- a/src/gc/gc.cpp +++ b/src/gc/gc.cpp @@ -5231,7 +5231,7 @@ void gc_heap::gc_thread_function () gc_heap::ee_suspend_event.Wait(INFINITE, FALSE); BEGIN_TIMING(suspend_ee_during_log); - GCToEEInterface::SuspendEE(SUSPEND_FOR_GC); + GCToEEInterface::SuspendEE(GCToEEInterface::SUSPEND_FOR_GC); END_TIMING(suspend_ee_during_log); proceed_with_gc_p = TRUE; @@ -26046,9 +26046,9 @@ gc_heap::suspend_EE () dprintf (2, ("suspend_EE")); #ifdef MULTIPLE_HEAPS gc_heap* hp = gc_heap::g_heaps[0]; - GCToEEInterface::SuspendEE(SUSPEND_FOR_GC_PREP); + GCToEEInterface::SuspendEE(GCToEEInterface::SUSPEND_FOR_GC_PREP); #else - GCToEEInterface::SuspendEE(SUSPEND_FOR_GC_PREP); + GCToEEInterface::SuspendEE(GCToEEInterface::SUSPEND_FOR_GC_PREP); #endif //MULTIPLE_HEAPS } @@ -26062,7 +26062,7 @@ gc_heap::bgc_suspend_EE () } gc_started = TRUE; dprintf (2, ("bgc_suspend_EE")); - GCToEEInterface::SuspendEE(SUSPEND_FOR_GC_PREP); + GCToEEInterface::SuspendEE(GCToEEInterface::SUSPEND_FOR_GC_PREP); gc_started = FALSE; for (int i = 0; i < n_heaps; i++) @@ -26077,7 +26077,7 @@ gc_heap::bgc_suspend_EE () reset_gc_done(); gc_started = TRUE; dprintf (2, ("bgc_suspend_EE")); - GCToEEInterface::SuspendEE(SUSPEND_FOR_GC_PREP); + GCToEEInterface::SuspendEE(GCToEEInterface::SUSPEND_FOR_GC_PREP); gc_started = FALSE; set_gc_done(); } @@ -35204,7 +35204,7 @@ GCHeap::GarbageCollectGeneration (unsigned int gen, gc_reason reason) dprintf (2, ("Suspending EE")); BEGIN_TIMING(suspend_ee_during_log); - GCToEEInterface::SuspendEE(SUSPEND_FOR_GC); + GCToEEInterface::SuspendEE(GCToEEInterface::SUSPEND_FOR_GC); END_TIMING(suspend_ee_during_log); gc_heap::proceed_with_gc_p = gc_heap::should_proceed_with_gc(); gc_heap::disable_preemptive (current_thread, cooperative_mode); diff --git a/src/gc/gc.h b/src/gc/gc.h index ca9c28d8fc..9c64587694 100644 --- a/src/gc/gc.h +++ b/src/gc/gc.h @@ -15,11 +15,7 @@ Module Name: #define __GC_H #include "gcinterface.h" -#include "env/gcenv.ee.h" -#ifdef FEATURE_STANDALONE_GC -#include "gcenv.ee.standalone.inl" -#endif // FEATURE_STANDALONE_GC /* * Promotion Function Prototypes diff --git a/src/gc/gccommon.cpp b/src/gc/gccommon.cpp index 3a951ccda3..f6afc5f221 100644 --- a/src/gc/gccommon.cpp +++ b/src/gc/gccommon.cpp @@ -22,10 +22,6 @@ SVAL_IMPL_INIT(uint32_t,IGCHeap,maxGeneration,2); IGCHeapInternal* g_theGCHeap; -#ifdef FEATURE_STANDALONE_GC -IGCToCLR* g_theGCToCLR; -#endif // FEATURE_STANDALONE_GC - /* global versions of the card table and brick table */ GPTR_IMPL(uint32_t,g_card_table); @@ -141,6 +137,7 @@ void InitializeHeapType(bool bServerHeap) IGCHeap* InitializeGarbageCollector(IGCToCLR* clrToGC) { LIMITED_METHOD_CONTRACT; + UNREFERENCED_PARAMETER(clrToGC); IGCHeapInternal* heap; #ifdef FEATURE_SVR_GC @@ -151,14 +148,6 @@ IGCHeap* InitializeGarbageCollector(IGCToCLR* clrToGC) #endif g_theGCHeap = heap; - -#ifdef FEATURE_STANDALONE_GC - assert(clrToGC != nullptr); - g_theGCToCLR = clrToGC; -#else - assert(clrToGC == nullptr); -#endif - return heap; } diff --git a/src/gc/gcenv.ee.standalone.inl b/src/gc/gcenv.ee.standalone.inl deleted file mode 100644 index 2ecc6fc83d..0000000000 --- a/src/gc/gcenv.ee.standalone.inl +++ /dev/null @@ -1,128 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#ifndef __GCTOENV_EE_STANDALONE_INL__ -#define __GCTOENV_EE_STANDALONE_INL__ - -#include "env/gcenv.ee.h" - -// The singular interface instance. All calls in GCToEEInterface -// will be fowarded to this interface instance. -extern IGCToCLR* g_theGCToCLR; - -// When we are building the GC in a standalone environment, we -// will be dispatching virtually against g_theGCToCLR to call -// into the EE. This class provides an identical API to the existing -// GCToEEInterface, but only forwards the call onto the global -// g_theGCToCLR instance. -inline void GCToEEInterface::SuspendEE(SUSPEND_REASON reason) -{ - assert(g_theGCToCLR != nullptr); - g_theGCToCLR->SuspendEE(reason); -} - -inline void GCToEEInterface::RestartEE(bool bFinishedGC) -{ - assert(g_theGCToCLR != nullptr); - g_theGCToCLR->RestartEE(bFinishedGC); -} - -inline void GCToEEInterface::GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc) -{ - assert(g_theGCToCLR != nullptr); - g_theGCToCLR->GcScanRoots(fn, condemned, max_gen, sc); -} - -inline void GCToEEInterface::GcStartWork(int condemned, int max_gen) -{ - assert(g_theGCToCLR != nullptr); - g_theGCToCLR->GcStartWork(condemned, max_gen); -} - -inline void GCToEEInterface::AfterGcScanRoots(int condemned, int max_gen, ScanContext* sc) -{ - assert(g_theGCToCLR != nullptr); - g_theGCToCLR->AfterGcScanRoots(condemned, max_gen, sc); -} - -inline void GCToEEInterface::GcBeforeBGCSweepWork() -{ - assert(g_theGCToCLR != nullptr); - g_theGCToCLR->GcBeforeBGCSweepWork(); -} - -inline void GCToEEInterface::GcDone(int condemned) -{ - assert(g_theGCToCLR != nullptr); - g_theGCToCLR->GcDone(condemned); -} - -inline bool GCToEEInterface::RefCountedHandleCallbacks(Object * pObject) -{ - assert(g_theGCToCLR != nullptr); - return g_theGCToCLR->RefCountedHandleCallbacks(pObject); -} - -inline void GCToEEInterface::SyncBlockCacheWeakPtrScan(HANDLESCANPROC scanProc, uintptr_t lp1, uintptr_t lp2) -{ - assert(g_theGCToCLR != nullptr); - g_theGCToCLR->SyncBlockCacheWeakPtrScan(scanProc, lp1, lp2); -} - -inline void GCToEEInterface::SyncBlockCacheDemote(int max_gen) -{ - assert(g_theGCToCLR != nullptr); - g_theGCToCLR->SyncBlockCacheDemote(max_gen); -} - -inline void GCToEEInterface::SyncBlockCachePromotionsGranted(int max_gen) -{ - assert(g_theGCToCLR != nullptr); - g_theGCToCLR->SyncBlockCachePromotionsGranted(max_gen); -} - -inline bool GCToEEInterface::IsPreemptiveGCDisabled(Thread * pThread) -{ - assert(g_theGCToCLR != nullptr); - return g_theGCToCLR->IsPreemptiveGCDisabled(pThread); -} - - -inline void GCToEEInterface::EnablePreemptiveGC(Thread * pThread) -{ - assert(g_theGCToCLR != nullptr); - g_theGCToCLR->EnablePreemptiveGC(pThread); -} - -inline void GCToEEInterface::DisablePreemptiveGC(Thread * pThread) -{ - assert(g_theGCToCLR != nullptr); - g_theGCToCLR->DisablePreemptiveGC(pThread); -} - -inline gc_alloc_context * GCToEEInterface::GetAllocContext(Thread * pThread) -{ - assert(g_theGCToCLR != nullptr); - return g_theGCToCLR->GetAllocContext(pThread); -} - -inline bool GCToEEInterface::CatchAtSafePoint(Thread * pThread) -{ - assert(g_theGCToCLR != nullptr); - return g_theGCToCLR->CatchAtSafePoint(pThread); -} - -inline void GCToEEInterface::GcEnumAllocContexts(enum_alloc_context_func* fn, void* param) -{ - assert(g_theGCToCLR != nullptr); - g_theGCToCLR->GcEnumAllocContexts(fn, param); -} - -inline Thread* GCToEEInterface::CreateBackgroundThread(GCBackgroundThreadFunction threadStart, void* arg) -{ - assert(g_theGCToCLR != nullptr); - return g_theGCToCLR->CreateBackgroundThread(threadStart, arg); -} - -#endif // __GCTOENV_EE_STANDALONE_INL__ diff --git a/src/gc/gcinterface.ee.h b/src/gc/gcinterface.ee.h deleted file mode 100644 index 36d20c7195..0000000000 --- a/src/gc/gcinterface.ee.h +++ /dev/null @@ -1,97 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#ifndef _GCINTERFACE_EE_H_ -#define _GCINTERFACE_EE_H_ - -// This interface provides the interface that the GC will use to speak to the rest -// of the execution engine. Everything that the GC does that requires the EE -// to be informed or that requires EE action must go through this interface. -// -// When FEATURE_STANDALONE_GC is defined, this class is named IGCToCLR and is -// an abstract class. The EE will provide a class that fulfills this interface, -// and the GC will dispatch virtually on it to call into the EE. When FEATURE_STANDALONE_GC -// is not defined, this class is named GCToEEInterface and the GC will dispatch statically on it. -class IGCToCLR { -public: - // Suspends the EE for the given reason. - virtual - void SuspendEE(SUSPEND_REASON reason) = 0; - - // Resumes all paused threads, with a boolean indicating - // if the EE is being restarted because a GC is complete. - virtual - void RestartEE(bool bFinishedGC) = 0; - - // Performs a stack walk of all managed threads and invokes the given promote_func - // on all GC roots encountered on the stack. Depending on the condemned generation, - // this function may also enumerate all static GC refs if necessary. - virtual - void GcScanRoots(promote_func* fn, int condemned, int max_gen, 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; - - // Callback from the GC informing the EE that it has completed the managed stack - // scan. User threads are still suspended at this point. - virtual - void AfterGcScanRoots(int condemned, int max_gen, ScanContext* sc) = 0; - - // Callback from the GC informing the EE that the background sweep phase of a BGC is - // about to begin. - virtual - void GcBeforeBGCSweepWork() = 0; - - // Callback from the GC informing the EE that a GC has completed. - virtual - void GcDone(int condemned) = 0; - - // Predicate for the GC to query whether or not a given refcounted handle should - // be promoted. - virtual - bool RefCountedHandleCallbacks(Object * pObject) = 0; - - // Performs a weak pointer scan of the sync block cache. - virtual - void SyncBlockCacheWeakPtrScan(HANDLESCANPROC scanProc, uintptr_t lp1, uintptr_t lp2) = 0; - - // Indicates to the EE that the GC intends to demote objects in the sync block cache. - virtual - void SyncBlockCacheDemote(int max_gen) = 0; - - // Indicates to the EE that the GC has granted promotion to objects in the sync block cache. - virtual - void SyncBlockCachePromotionsGranted(int max_gen) = 0; - - // Queries whether or not the given thread has preemptive GC disabled. - virtual - bool IsPreemptiveGCDisabled(Thread * pThread) = 0; - - // Enables preemptive GC on the given thread. - virtual - void EnablePreemptiveGC(Thread * pThread) = 0; - - // Disables preemptive GC on the given thread. - virtual - void DisablePreemptiveGC(Thread * pThread) = 0; - - // Retrieves the alloc context associated with a given thread. - virtual - gc_alloc_context * GetAllocContext(Thread * pThread) = 0; - - // Returns true if this thread is waiting to reach a safe point. - virtual - bool CatchAtSafePoint(Thread * pThread) = 0; - - // Calls the given enum_alloc_context_func with every active alloc context. - virtual - void GcEnumAllocContexts(enum_alloc_context_func* fn, void* param) = 0; - - // Creates and returns a new background thread. - virtual - Thread* CreateBackgroundThread(GCBackgroundThreadFunction threadStart, void* arg) = 0; -}; - -#endif // _GCINTERFACE_EE_H_ diff --git a/src/gc/gcinterface.h b/src/gc/gcinterface.h index f9ff098436..e27646c30c 100644 --- a/src/gc/gcinterface.h +++ b/src/gc/gcinterface.h @@ -5,37 +5,6 @@ #ifndef _GC_INTERFACE_H_ #define _GC_INTERFACE_H_ -struct ScanContext; -struct gc_alloc_context; -class CrawlFrame; - -// Callback passed to GcScanRoots. -typedef void promote_func(PTR_PTR_Object, ScanContext*, uint32_t); - -// Callback passed to GcEnumAllocContexts. -typedef void enum_alloc_context_func(gc_alloc_context*, void*); - -// Callback passed to CreateBackgroundThread. -typedef uint32_t (__stdcall *GCBackgroundThreadFunction)(void* param); - -// Struct often used as a parameter to callbacks. -typedef struct -{ - promote_func* f; - ScanContext* sc; - CrawlFrame * cf; -} GCCONTEXT; - -// SUSPEND_REASON is the reason why the GC wishes to suspend the EE, -// used as an argument to IGCToCLR::SuspendEE. -typedef enum -{ - SUSPEND_FOR_GC = 1, - SUSPEND_FOR_GC_PREP = 6 -} SUSPEND_REASON; - -#include "gcinterface.ee.h" - // The allocation context must be known to the VM for use in the allocation // fast path and known to the GC for performing the allocation. Every Thread // has its own allocation context that it hands to the GC when allocating. @@ -86,6 +55,7 @@ struct segment_info class Object; class IGCHeap; +class IGCToCLR; // Initializes the garbage collector. Should only be called // once, during EE startup. diff --git a/src/gc/sample/gcenv.ee.cpp b/src/gc/sample/gcenv.ee.cpp index 25d829e79e..691004d988 100644 --- a/src/gc/sample/gcenv.ee.cpp +++ b/src/gc/sample/gcenv.ee.cpp @@ -129,7 +129,7 @@ void ThreadStore::AttachCurrentThread() g_pThreadList = pThread; } -void GCToEEInterface::SuspendEE(SUSPEND_REASON reason) +void GCToEEInterface::SuspendEE(GCToEEInterface::SUSPEND_REASON reason) { g_theGCHeap->SetGCInProgress(TRUE); diff --git a/src/gc/sample/gcenv.h b/src/gc/sample/gcenv.h index 94d6939e9f..3f43a3ffeb 100644 --- a/src/gc/sample/gcenv.h +++ b/src/gc/sample/gcenv.h @@ -2,12 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -// The sample is to be kept simple, so building the sample -// in tandem with a standalone GC is currently not supported. -#ifdef FEATURE_STANDALONE_GC -#undef FEATURE_STANDALONE_GC -#endif // FEATURE_STANDALONE_GC - #if defined(_DEBUG) #ifndef _DEBUG_IMPL #define _DEBUG_IMPL 1 @@ -23,12 +17,12 @@ #include "gcenv.structs.h" #include "gcenv.base.h" +#include "gcenv.ee.h" #include "gcenv.os.h" #include "gcenv.interlocked.h" #include "gcenv.interlocked.inl" #include "gcenv.object.h" #include "gcenv.sync.h" -#include "gcenv.ee.h" #define MAX_LONGPATH 1024 |