From 0bdf138318b737884fec898b0af68661172fa4da Mon Sep 17 00:00:00 2001 From: David Mason Date: Wed, 31 Jan 2018 16:56:27 -0800 Subject: [PATCH] [local gc] Enable eventing (#16120) * move GC etw enums to gcinterface.ee.h * add GetActiveSyncBlockCount * refactor reference to ETW::GCLog::ShouldTrackMovementForEtw() * mov g_dwHandles to gc side * enable FEATURE_EVENT_TRACE for gc --- src/gc/CMakeLists.txt | 3 --- src/gc/env/gcenv.ee.h | 1 + src/gc/gc.cpp | 8 +++++--- src/gc/gc.h | 6 ++++++ src/gc/gcee.cpp | 2 +- src/gc/gcenv.ee.standalone.inl | 7 +++++++ src/gc/gcinterface.ee.h | 18 ++++++++++++++++++ src/gc/gcinterface.h | 6 +++--- src/gc/handletable.cpp | 12 ++++++++++++ src/inc/eventtracebase.h | 16 ---------------- src/vm/eetoprofinterfaceimpl.h | 1 + src/vm/gcenv.ee.cpp | 12 ++++++++++++ src/vm/gcenv.ee.h | 1 + src/vm/gchandleutilities.cpp | 8 -------- src/vm/vars.cpp | 4 ---- src/vm/vars.hpp | 6 ------ 16 files changed, 67 insertions(+), 44 deletions(-) diff --git a/src/gc/CMakeLists.txt b/src/gc/CMakeLists.txt index e7aacdb..caecdba 100644 --- a/src/gc/CMakeLists.txt +++ b/src/gc/CMakeLists.txt @@ -2,9 +2,6 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) # Local GC meta-issue: https://github.com/dotnet/coreclr/issues/11518 -# https://github.com/dotnet/coreclr/issues/11514 -remove_definitions(-DFEATURE_EVENT_TRACE=1) - # https://github.com/dotnet/coreclr/issues/11517 remove_definitions(-DFEATURE_APPDOMAIN_RESOURCE_MONITORING) diff --git a/src/gc/env/gcenv.ee.h b/src/gc/env/gcenv.ee.h index 5f2b890..4ef1b93 100644 --- a/src/gc/env/gcenv.ee.h +++ b/src/gc/env/gcenv.ee.h @@ -44,6 +44,7 @@ public: static void SyncBlockCacheWeakPtrScan(HANDLESCANPROC scanProc, uintptr_t lp1, uintptr_t lp2); static void SyncBlockCacheDemote(int max_gen); static void SyncBlockCachePromotionsGranted(int max_gen); + static uint32_t GetActiveSyncBlockCount(); // Thread functions static bool IsPreemptiveGCDisabled(Thread * pThread); diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp index d6ab65a..dd26a54 100644 --- a/src/gc/gc.cpp +++ b/src/gc/gc.cpp @@ -13231,7 +13231,7 @@ int gc_heap::try_allocate_more_space (alloc_context* acontext, size_t size, // Unfortunately some of the ETW macros do not check whether the ETW feature is enabled. // The ones that do are much less efficient. #if defined(FEATURE_EVENT_TRACE) - if (EventEnabledGCAllocationTick_V3()) + if (EVENT_ENABLED(GCAllocationTick_V3)) { fire_etw_allocation_event (etw_allocation_running_amount[etw_allocation_index], gen_number, acontext->alloc_ptr); } @@ -19972,7 +19972,7 @@ void gc_heap::pin_object (uint8_t* o, uint8_t** ppObject, uint8_t* low, uint8_t* set_pinned (o); #ifdef FEATURE_EVENT_TRACE - if(EventEnabledPinObjectAtGCTime()) + if(EVENT_ENABLED(PinObjectAtGCTime)) { fire_etw_pin_object_event(o, ppObject); } @@ -31352,7 +31352,9 @@ void gc_heap::background_sweep() #endif //MULTIPLE_HEAPS { #ifdef FEATURE_EVENT_TRACE - bgc_heap_walk_for_etw_p = ETW::GCLog::ShouldTrackMovementForEtw(); + bgc_heap_walk_for_etw_p = GCEventStatus::IsEnabled(GCEventProvider_Default, + GCEventKeyword_GCHeapSurvivalAndMovement, + GCEventLevel_Information); #endif //FEATURE_EVENT_TRACE leave_spin_lock (&gc_lock); diff --git a/src/gc/gc.h b/src/gc/gc.h index 6641f0b..a0e09cd 100644 --- a/src/gc/gc.h +++ b/src/gc/gc.h @@ -122,6 +122,12 @@ class DacHeapWalker; extern "C" uint32_t* g_gc_card_bundle_table; #endif +#if defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE) +// Note this is not updated in a thread safe way so the value may not be accurate. We get +// it accurately in full GCs if the handle count is requested. +extern DWORD g_dwHandles; +#endif // ENABLE_PERF_COUNTERS || FEATURE_EVENT_TRACE + extern "C" uint32_t* g_gc_card_table; extern "C" uint8_t* g_gc_lowest_address; extern "C" uint8_t* g_gc_highest_address; diff --git a/src/gc/gcee.cpp b/src/gc/gcee.cpp index 358b40c..b399cde 100644 --- a/src/gc/gcee.cpp +++ b/src/gc/gcee.cpp @@ -132,7 +132,7 @@ void GCHeap::UpdatePostGCCounters() memset (g_GenerationPromotedSizes, 0, sizeof (g_GenerationPromotedSizes)); size_t total_num_gc_handles = g_dwHandles; - uint32_t total_num_sync_blocks = SyncBlockCache::GetSyncBlockCache()->GetActiveCount(); + uint32_t total_num_sync_blocks = GCToEEInterface::GetActiveSyncBlockCount(); // Note this is however for perf counter only, for legacy reasons. What we showed // in perf counters for "gen0 size" was really the gen0 budget which made diff --git a/src/gc/gcenv.ee.standalone.inl b/src/gc/gcenv.ee.standalone.inl index 675e7fa..665bd32 100644 --- a/src/gc/gcenv.ee.standalone.inl +++ b/src/gc/gcenv.ee.standalone.inl @@ -83,6 +83,13 @@ inline void GCToEEInterface::SyncBlockCachePromotionsGranted(int max_gen) g_theGCToCLR->SyncBlockCachePromotionsGranted(max_gen); } + +inline uint32_t GCToEEInterface::GetActiveSyncBlockCount() +{ + assert(g_theGCToCLR != nullptr); + return g_theGCToCLR->GetActiveSyncBlockCount(); +} + inline bool GCToEEInterface::IsPreemptiveGCDisabled(Thread * pThread) { assert(g_theGCToCLR != nullptr); diff --git a/src/gc/gcinterface.ee.h b/src/gc/gcinterface.ee.h index a79043e..e6e3bca 100644 --- a/src/gc/gcinterface.ee.h +++ b/src/gc/gcinterface.ee.h @@ -5,6 +5,21 @@ #ifndef _GCINTERFACE_EE_H_ #define _GCINTERFACE_EE_H_ +enum EtwGCRootFlags +{ + kEtwGCRootFlagsPinning = 0x1, + kEtwGCRootFlagsWeakRef = 0x2, + kEtwGCRootFlagsInterior = 0x4, + kEtwGCRootFlagsRefCounted = 0x8, +}; + +enum EtwGCRootKind +{ + kEtwGCRootKindStack = 0, + kEtwGCRootKindFinalizer = 1, + kEtwGCRootKindHandle = 2, + kEtwGCRootKindOther = 3, +}; // This interface provides functions that the GC can use to fire events. // Events fired on this interface are split into two categories: "known" @@ -203,6 +218,9 @@ public: virtual void SyncBlockCachePromotionsGranted(int max_gen) = 0; + virtual + uint32_t GetActiveSyncBlockCount() = 0; + // Queries whether or not the given thread has preemptive GC disabled. virtual bool IsPreemptiveGCDisabled(Thread * pThread) = 0; diff --git a/src/gc/gcinterface.h b/src/gc/gcinterface.h index 2b98385..4c03811 100644 --- a/src/gc/gcinterface.h +++ b/src/gc/gcinterface.h @@ -914,7 +914,7 @@ struct ScanContext #if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE) EtwGCRootKind dwEtwRootKind; #else - int _unused3; + EtwGCRootKind _unused3; #endif // GC_PROFILING || FEATURE_EVENT_TRACE ScanContext() @@ -929,9 +929,9 @@ struct ScanContext #ifdef GC_PROFILING pMD = NULL; #endif //GC_PROFILING -#ifdef FEATURE_EVENT_TRACE +#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE) dwEtwRootKind = kEtwGCRootKindOther; -#endif // FEATURE_EVENT_TRACE +#endif } }; diff --git a/src/gc/handletable.cpp b/src/gc/handletable.cpp index 4d42dda..0ae2b03 100644 --- a/src/gc/handletable.cpp +++ b/src/gc/handletable.cpp @@ -21,6 +21,10 @@ #include "objecthandle.h" #include "handletablepriv.h" +#if defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE) +DWORD g_dwHandles = 0; +#endif // ENABLE_PERF_COUNTERS || FEATURE_EVENT_TRACE + /**************************************************************************** * * FORWARD DECLARATIONS @@ -342,6 +346,10 @@ OBJECTHANDLE HndCreateHandle(HHANDLETABLE hTable, uint32_t uType, OBJECTREF obje HandleQuickSetUserData(handle, lExtraInfo); } +#if defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE) + g_dwHandles++; +#endif // defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE) + // store the reference HndAssignHandle(handle, object); STRESS_LOG2(LF_GC, LL_INFO1000, "CreateHandle: %p, type=%d\n", handle, uType); @@ -464,6 +472,10 @@ void HndDestroyHandle(HHANDLETABLE hTable, uint32_t uType, OBJECTHANDLE handle) // return the handle to the table's cache TableFreeSingleHandleToCache(pTable, uType, handle); + +#if defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE) + g_dwHandles--; +#endif // defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE) } diff --git a/src/inc/eventtracebase.h b/src/inc/eventtracebase.h index d73d72a..c29308d 100644 --- a/src/inc/eventtracebase.h +++ b/src/inc/eventtracebase.h @@ -38,22 +38,6 @@ void InitializeEventTracing(); // These flags need to be defined either when FEATURE_EVENT_TRACE is enabled or the // PROFILING_SUPPORTED is set, since they are used both by event tracing and profiling. -enum EtwGCRootFlags -{ - kEtwGCRootFlagsPinning = 0x1, - kEtwGCRootFlagsWeakRef = 0x2, - kEtwGCRootFlagsInterior = 0x4, - kEtwGCRootFlagsRefCounted = 0x8, -}; - -enum EtwGCRootKind -{ - kEtwGCRootKindStack = 0, - kEtwGCRootKindFinalizer = 1, - kEtwGCRootKindHandle = 2, - kEtwGCRootKindOther = 3, -}; - enum EtwTypeFlags { kEtwTypeFlagsDelegate = 0x1, diff --git a/src/vm/eetoprofinterfaceimpl.h b/src/vm/eetoprofinterfaceimpl.h index 63d1cad..6b67674 100644 --- a/src/vm/eetoprofinterfaceimpl.h +++ b/src/vm/eetoprofinterfaceimpl.h @@ -21,6 +21,7 @@ #include "eeprofinterfaces.h" #include "shash.h" #include "eventtracebase.h" +#include "gcinterface.h" class SimpleRWLock; diff --git a/src/vm/gcenv.ee.cpp b/src/vm/gcenv.ee.cpp index 7c6f940..8e2594b 100644 --- a/src/vm/gcenv.ee.cpp +++ b/src/vm/gcenv.ee.cpp @@ -303,6 +303,18 @@ void GCToEEInterface::SyncBlockCachePromotionsGranted(int max_gen) SyncBlockCache::GetSyncBlockCache()->GCDone(FALSE, max_gen); } +uint32_t GCToEEInterface::GetActiveSyncBlockCount() +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + } + CONTRACTL_END; + + return SyncBlockCache::GetSyncBlockCache()->GetActiveCount(); +} + gc_alloc_context * GCToEEInterface::GetAllocContext(Thread * pThread) { WRAPPER_NO_CONTRACT; diff --git a/src/vm/gcenv.ee.h b/src/vm/gcenv.ee.h index dc09618..4529669 100644 --- a/src/vm/gcenv.ee.h +++ b/src/vm/gcenv.ee.h @@ -28,6 +28,7 @@ public: void SyncBlockCacheWeakPtrScan(HANDLESCANPROC scanProc, uintptr_t lp1, uintptr_t lp2); void SyncBlockCacheDemote(int max_gen); void SyncBlockCachePromotionsGranted(int max_gen); + uint32_t GetActiveSyncBlockCount(); bool IsPreemptiveGCDisabled(Thread * pThread); void EnablePreemptiveGC(Thread * pThread); void DisablePreemptiveGC(Thread * pThread); diff --git a/src/vm/gchandleutilities.cpp b/src/vm/gchandleutilities.cpp index 9345a18..4361778 100644 --- a/src/vm/gchandleutilities.cpp +++ b/src/vm/gchandleutilities.cpp @@ -48,10 +48,6 @@ void ValidateHandleAssignment(OBJECTHANDLE handle, OBJECTREF objRef) void DiagHandleCreated(OBJECTHANDLE handle, OBJECTREF objRef) { -#if defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE) - g_dwHandles++; -#endif // defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE) - #ifdef GC_PROFILING BEGIN_PIN_PROFILER(CORProfilerTrackGC()); g_profControlBlock.pProfInterface->HandleCreated((uintptr_t)handle, (ObjectID)OBJECTREF_TO_UNCHECKED_OBJECTREF(objRef)); @@ -71,8 +67,4 @@ void DiagHandleDestroyed(OBJECTHANDLE handle) #else UNREFERENCED_PARAMETER(handle); #endif // GC_PROFILING - -#if defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE) - g_dwHandles--; -#endif // defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE) } diff --git a/src/vm/vars.cpp b/src/vm/vars.cpp index 3c54029..fac4cc5 100644 --- a/src/vm/vars.cpp +++ b/src/vm/vars.cpp @@ -107,10 +107,6 @@ GPTR_IMPL(Thread,g_pSuspensionThread); // Global SyncBlock cache GPTR_IMPL(SyncTableEntry,g_pSyncTable); -#if defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE) -DWORD g_dwHandles = 0; -#endif // ENABLE_PERF_COUNTERS || FEATURE_EVENT_TRACE - #ifdef STRESS_LOG GPTR_IMPL_INIT(StressLog, g_pStressLog, &StressLog::theLog); #endif diff --git a/src/vm/vars.hpp b/src/vm/vars.hpp index 820260a..b102b28 100644 --- a/src/vm/vars.hpp +++ b/src/vm/vars.hpp @@ -435,12 +435,6 @@ GPTR_DECL(Thread,g_pSuspensionThread); typedef DPTR(SyncTableEntry) PTR_SyncTableEntry; GPTR_DECL(SyncTableEntry, g_pSyncTable); -#if defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE) -// Note this is not updated in a thread safe way so the value may not be accurate. We get -// it accurately in full GCs if the handle count is requested. -extern DWORD g_dwHandles; -#endif // ENABLE_PERF_COUNTERS || FEATURE_EVENT_TRACE - #ifdef FEATURE_COMINTEROP // Global RCW cleanup list typedef DPTR(RCWCleanupList) PTR_RCWCleanupList; -- 2.7.4