diff options
author | Maoni Stephens <Maoni0@users.noreply.github.com> | 2019-02-27 16:35:03 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-27 16:35:03 -0800 |
commit | ea099fba14da84c3e81eb8d5ad93ecae7c659489 (patch) | |
tree | 1bc50d932d45bf72a4680249365557c93159ccc2 | |
parent | d0743a467c1df473f511ca0ab73eaf1d119a309b (diff) | |
download | coreclr-ea099fba14da84c3e81eb8d5ad93ecae7c659489.tar.gz coreclr-ea099fba14da84c3e81eb8d5ad93ecae7c659489.tar.bz2 coreclr-ea099fba14da84c3e81eb8d5ad93ecae7c659489.zip |
added a lightweight GC profiling option (#22866)
added a profiling event mask in the high 32-bit, COR_PRF_HIGH_BASIC_GC, for basic GC monitoring. it can be set via `ICorProfilerInfo5::SetEventMask2`. all this gives you is
* GC start callback
* GC end callback
* update generational bounds
note that one different behavior between this and the existing COR_PRF_MONITOR_GC is, aside from the obvious that it doesn't give you any info beyond the above, is that the GC end callback + update generational bounds are enabled for _all_ GCs, not just non concurrent GCs. I kept the behavior the same for COR_PRF_MONITOR_GC because I don't want to risk breaking existing profiling tools that do not anticipate these for concurrent GCs.
-rw-r--r-- | src/inc/corprof.idl | 6 | ||||
-rw-r--r-- | src/inc/profilepriv.inl | 14 | ||||
-rw-r--r-- | src/pal/prebuilt/inc/corprof.h | 3 | ||||
-rw-r--r-- | src/vm/eetoprofinterfaceimpl.cpp | 4 | ||||
-rw-r--r-- | src/vm/gcenv.ee.cpp | 9 | ||||
-rw-r--r-- | src/vm/proftoeeinterfaceimpl.cpp | 6 |
6 files changed, 34 insertions, 8 deletions
diff --git a/src/inc/corprof.idl b/src/inc/corprof.idl index feeac08c51..1062248299 100644 --- a/src/inc/corprof.idl +++ b/src/inc/corprof.idl @@ -627,9 +627,13 @@ typedef enum COR_PRF_HIGH_DISABLE_TIERED_COMPILATION = 0x00000008, + COR_PRF_HIGH_BASIC_GC = 0x00000010, + COR_PRF_HIGH_REQUIRE_PROFILE_IMAGE = 0, - COR_PRF_HIGH_ALLOWABLE_AFTER_ATTACH = COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED | COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS, + COR_PRF_HIGH_ALLOWABLE_AFTER_ATTACH = COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED | + COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS | + COR_PRF_HIGH_BASIC_GC, // MONITOR_IMMUTABLE represents all flags that may only be set during initialization. // Trying to change any of these flags elsewhere will result in a diff --git a/src/inc/profilepriv.inl b/src/inc/profilepriv.inl index ac52521b36..095c9f9368 100644 --- a/src/inc/profilepriv.inl +++ b/src/inc/profilepriv.inl @@ -727,6 +727,20 @@ inline BOOL CORProfilerDisableTieredCompilation() ((&g_profControlBlock)->dwEventMaskHigh & COR_PRF_HIGH_DISABLE_TIERED_COMPILATION)); } +inline BOOL CORProfilerTrackBasicGC() +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + CANNOT_TAKE_LOCK; + } + CONTRACTL_END; + + return (CORProfilerPresent() && + ((&g_profControlBlock)->dwEventMaskHigh & COR_PRF_HIGH_BASIC_GC)); +} + #if defined(PROFILING_SUPPORTED) && !defined(CROSSGEN_COMPILE) #if defined(FEATURE_PROFAPI_ATTACH_DETACH) diff --git a/src/pal/prebuilt/inc/corprof.h b/src/pal/prebuilt/inc/corprof.h index 2e18c12283..c7839ddbcf 100644 --- a/src/pal/prebuilt/inc/corprof.h +++ b/src/pal/prebuilt/inc/corprof.h @@ -544,8 +544,9 @@ enum __MIDL___MIDL_itf_corprof_0000_0000_0006 COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED = 0x2, COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS = 0x4, COR_PRF_HIGH_DISABLE_TIERED_COMPILATION = 0x8, + COR_PRF_HIGH_BASIC_GC = 0x10, COR_PRF_HIGH_REQUIRE_PROFILE_IMAGE = 0, - COR_PRF_HIGH_ALLOWABLE_AFTER_ATTACH = ( COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED | COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS ) , + COR_PRF_HIGH_ALLOWABLE_AFTER_ATTACH = ( COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED | COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS | COR_PRF_HIGH_BASIC_GC) , COR_PRF_HIGH_MONITOR_IMMUTABLE = COR_PRF_HIGH_DISABLE_TIERED_COMPILATION } COR_PRF_HIGH_MONITOR; diff --git a/src/vm/eetoprofinterfaceimpl.cpp b/src/vm/eetoprofinterfaceimpl.cpp index 1b06eaeb94..40b863f93e 100644 --- a/src/vm/eetoprofinterfaceimpl.cpp +++ b/src/vm/eetoprofinterfaceimpl.cpp @@ -6196,7 +6196,7 @@ HRESULT EEToProfInterfaceImpl::GarbageCollectionStarted(int cGenerations, BOOL g LL_INFO10000, "**PROF: GarbageCollectionStarted.\n")); - _ASSERTE(!GCHeapUtilities::GetGCHeap()->IsConcurrentGCEnabled()); + _ASSERTE(!CORProfilerTrackGC() || !GCHeapUtilities::GetGCHeap()->IsConcurrentGCEnabled()); { // All callbacks are really NOTHROW, but that's enforced partially by the profiler, @@ -6233,7 +6233,7 @@ HRESULT EEToProfInterfaceImpl::GarbageCollectionFinished() LL_INFO10000, "**PROF: GarbageCollectionFinished.\n")); - _ASSERTE(!GCHeapUtilities::GetGCHeap()->IsConcurrentGCEnabled()); + _ASSERTE(!CORProfilerTrackGC() || !GCHeapUtilities::GetGCHeap()->IsConcurrentGCEnabled()); { // All callbacks are really NOTHROW, but that's enforced partially by the profiler, diff --git a/src/vm/gcenv.ee.cpp b/src/vm/gcenv.ee.cpp index 6ecd325a08..f27d3f32c8 100644 --- a/src/vm/gcenv.ee.cpp +++ b/src/vm/gcenv.ee.cpp @@ -742,7 +742,7 @@ void GCToEEInterface::DiagGCStart(int gen, bool isInduced) void GCToEEInterface::DiagUpdateGenerationBounds() { #ifdef GC_PROFILING - if (CORProfilerTrackGC()) + if (CORProfilerTrackGC() || CORProfilerTrackBasicGC()) UpdateGenerationBounds(); #endif // GC_PROFILING } @@ -750,9 +750,16 @@ void GCToEEInterface::DiagUpdateGenerationBounds() void GCToEEInterface::DiagGCEnd(size_t index, int gen, int reason, bool fConcurrent) { #ifdef GC_PROFILING + // We were only doing generation bounds and GC finish callback for non concurrent GCs so + // I am keeping that behavior to not break profilers. But if BasicGC monitoring is enabled + // we will do these for all GCs. if (!fConcurrent) { GCProfileWalkHeap(); + } + + if (CORProfilerTrackBasicGC() || (!fConcurrent && CORProfilerTrackGC())) + { DiagUpdateGenerationBounds(); GarbageCollectionFinishedCallback(); } diff --git a/src/vm/proftoeeinterfaceimpl.cpp b/src/vm/proftoeeinterfaceimpl.cpp index c142651496..663b82f403 100644 --- a/src/vm/proftoeeinterfaceimpl.cpp +++ b/src/vm/proftoeeinterfaceimpl.cpp @@ -684,7 +684,7 @@ void __stdcall GarbageCollectionStartedCallback(int generation, BOOL induced) // Notify the profiler of start of the collection { - BEGIN_PIN_PROFILER(CORProfilerTrackGC()); + BEGIN_PIN_PROFILER(CORProfilerTrackGC() || CORProfilerTrackBasicGC()); BOOL generationCollected[COR_PRF_GC_LARGE_OBJECT_HEAP+1]; if (generation == COR_PRF_GC_GEN_2) generation = COR_PRF_GC_LARGE_OBJECT_HEAP; @@ -718,7 +718,7 @@ void __stdcall GarbageCollectionFinishedCallback() #ifdef PROFILING_SUPPORTED // Notify the profiler of end of the collection { - BEGIN_PIN_PROFILER(CORProfilerTrackGC()); + BEGIN_PIN_PROFILER(CORProfilerTrackGC() || CORProfilerTrackBasicGC()); g_profControlBlock.pProfInterface->GarbageCollectionFinished(); END_PIN_PROFILER(); } @@ -858,7 +858,7 @@ void __stdcall UpdateGenerationBounds() #ifdef PROFILING_SUPPORTED // Notify the profiler of start of the collection - if (CORProfilerTrackGC()) + if (CORProfilerTrackGC() || CORProfilerTrackBasicGC()) { // generate a new generation table GenerationTable *newGenerationTable = new (nothrow) GenerationTable(); |