diff options
author | Sung Yoon Whang <suwhang@microsoft.com> | 2019-03-07 18:34:17 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-07 18:34:17 -0800 |
commit | 4685a1e008ad7cf4118e8778d89e63d87ca5b7b6 (patch) | |
tree | 7bb44141fc537f864c69b1168630dcc9becd12ea | |
parent | a2865ead29cc8ef73307927976c3dbaad1298d44 (diff) | |
download | coreclr-4685a1e008ad7cf4118e8778d89e63d87ca5b7b6.tar.gz coreclr-4685a1e008ad7cf4118e8778d89e63d87ca5b7b6.tar.bz2 coreclr-4685a1e008ad7cf4118e8778d89e63d87ca5b7b6.zip |
Fix how we check whether events are enabled via LTTng (#22707)
* Fix how we check whether events are enabled via LTTng
* Add GCToEEInterface::UpdateGCEventStatus
* Fix build errors
* Finished hooking it up to post_gc
* Some comments about the event keyword/level detection logic
* Fix windows build
* Fix Prv provider keyword logic
* forgot to add one more ifdef
* Fix OSX build
* one more ifdef to fix
* Addressing PR feedback
* Update GCEventStatus at gc_heap::initialize_gc too
-rw-r--r-- | src/gc/env/gcenv.ee.h | 1 | ||||
-rw-r--r-- | src/gc/gc.cpp | 13 | ||||
-rw-r--r-- | src/gc/gcenv.ee.standalone.inl | 8 | ||||
-rw-r--r-- | src/gc/gceventstatus.h | 29 | ||||
-rw-r--r-- | src/gc/gcinterface.ee.h | 3 | ||||
-rw-r--r-- | src/gc/gcinterface.h | 10 | ||||
-rw-r--r-- | src/vm/gcenv.ee.cpp | 47 | ||||
-rw-r--r-- | src/vm/gcenv.ee.h | 15 |
8 files changed, 116 insertions, 10 deletions
diff --git a/src/gc/env/gcenv.ee.h b/src/gc/env/gcenv.ee.h index ec72517bec..c91eadb6de 100644 --- a/src/gc/env/gcenv.ee.h +++ b/src/gc/env/gcenv.ee.h @@ -96,6 +96,7 @@ public: static void AnalyzeSurvivorsFinished(int condemnedGeneration); static void VerifySyncTableEntry(); + static void UpdateGCEventStatus(int publicLevel, int publicKeywords, int privateLevel, int privateKeywords); }; #endif // __GCENV_EE_H__ diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp index 95fe21ccb6..a26ad8d24f 100644 --- a/src/gc/gc.cpp +++ b/src/gc/gc.cpp @@ -10192,6 +10192,13 @@ HRESULT gc_heap::initialize_gc (size_t segment_size, yp_spin_count_unit = 32 * g_num_processors; #endif //MULTIPLE_HEAPS +#if defined(__linux__) + GCToEEInterface::UpdateGCEventStatus(static_cast<int>(GCEventStatus::GetEnabledLevel(GCEventProvider_Default)), + static_cast<int>(GCEventStatus::GetEnabledKeywords(GCEventProvider_Default)), + static_cast<int>(GCEventStatus::GetEnabledLevel(GCEventProvider_Private)), + static_cast<int>(GCEventStatus::GetEnabledKeywords(GCEventProvider_Private))); +#endif // __linux__ + if (!init_semi_shared()) { hres = E_FAIL; @@ -35553,6 +35560,12 @@ void gc_heap::do_pre_gc() last_gc_index = VolatileLoad(&settings.gc_index); GCHeap::UpdatePreGCCounters(); +#if defined(__linux__) + GCToEEInterface::UpdateGCEventStatus(static_cast<int>(GCEventStatus::GetEnabledLevel(GCEventProvider_Default)), + static_cast<int>(GCEventStatus::GetEnabledKeywords(GCEventProvider_Default)), + static_cast<int>(GCEventStatus::GetEnabledLevel(GCEventProvider_Private)), + static_cast<int>(GCEventStatus::GetEnabledKeywords(GCEventProvider_Private))); +#endif // __linux__ if (settings.concurrent) { diff --git a/src/gc/gcenv.ee.standalone.inl b/src/gc/gcenv.ee.standalone.inl index b000dadcbc..b5c2c764b6 100644 --- a/src/gc/gcenv.ee.standalone.inl +++ b/src/gc/gcenv.ee.standalone.inl @@ -323,4 +323,12 @@ inline void GCToEEInterface::VerifySyncTableEntry() g_theGCToCLR->VerifySyncTableEntry(); } +inline void GCToEEInterface::UpdateGCEventStatus(int publicLevel, int publicKeywords, int privateLevel, int privateKeywords) +{ + assert(g_theGCToCLR != nullptr); +#if defined(__linux__) + g_theGCToCLR->UpdateGCEventStatus(publicLevel, publicKeywords, privateLevel, privateKeywords); +#endif // __linux__ +} + #endif // __GCTOENV_EE_STANDALONE_INL__ diff --git a/src/gc/gceventstatus.h b/src/gc/gceventstatus.h index c49e767171..1f31d424be 100644 --- a/src/gc/gceventstatus.h +++ b/src/gc/gceventstatus.h @@ -32,15 +32,6 @@ // Uncomment this define to print out event state changes to standard error. // #define TRACE_GC_EVENT_STATE 1 -/* - * GCEventProvider represents one of the two providers that the GC can - * fire events from: the default and private providers. - */ -enum GCEventProvider -{ - GCEventProvider_Default = 0, - GCEventProvider_Private = 1 -}; /* * GCEventStatus maintains all eventing state for the GC. It consists @@ -98,6 +89,22 @@ public: #endif // TRACE_GC_EVENT_STATE } + /* + * Returns currently enabled levels + */ + static inline GCEventLevel GetEnabledLevel(GCEventProvider provider) + { + return enabledLevels[static_cast<size_t>(provider)].LoadWithoutBarrier(); + } + + /* + * Returns currently enabled keywords in GCPublic + */ + static inline GCEventKeyword GetEnabledKeywords(GCEventProvider provider) + { + return enabledKeywords[static_cast<size_t>(provider)].LoadWithoutBarrier(); + } + #if TRACE_GC_EVENT_STATE private: static void DebugDumpState(GCEventProvider provider) @@ -236,6 +243,7 @@ void FireDynamicEvent(const char* name, EventArgument... arguments) * payload. Known events will delegate to IGCToCLREventSink::Fire##name. */ #if FEATURE_EVENT_TRACE + #define KNOWN_EVENT(name, provider, level, keyword) \ inline bool GCEventEnabled##name() { return GCEventStatus::IsEnabled(provider, keyword, level); } \ template<typename... EventActualArgument> \ @@ -258,7 +266,8 @@ void FireDynamicEvent(const char* name, EventArgument... arguments) #define EVENT_ENABLED(name) GCEventEnabled##name() #define FIRE_EVENT(name, ...) GCEventFire##name(__VA_ARGS__) -#else + +#else // FEATURE_EVENT_TRACE #define EVENT_ENABLED(name) false #define FIRE_EVENT(name, ...) 0 #endif // FEATURE_EVENT_TRACE diff --git a/src/gc/gcinterface.ee.h b/src/gc/gcinterface.ee.h index 228bb37075..4ce9203ab0 100644 --- a/src/gc/gcinterface.ee.h +++ b/src/gc/gcinterface.ee.h @@ -435,6 +435,9 @@ public: virtual void VerifySyncTableEntry() = 0; + + virtual + void UpdateGCEventStatus(int publicLevel, int publicKeywords, int privateLEvel, int privateKeywords) = 0; }; #endif // _GCINTERFACE_EE_H_ diff --git a/src/gc/gcinterface.h b/src/gc/gcinterface.h index 249466aee4..9744eb0f38 100644 --- a/src/gc/gcinterface.h +++ b/src/gc/gcinterface.h @@ -199,6 +199,16 @@ extern uint8_t* g_GCShadowEnd; extern uint8_t* g_shadow_lowest_address; #endif +/* + * GCEventProvider represents one of the two providers that the GC can + * fire events from: the default and private providers. + */ +enum GCEventProvider +{ + GCEventProvider_Default = 0, + GCEventProvider_Private = 1 +}; + // Event levels corresponding to events that can be fired by the GC. enum GCEventLevel { diff --git a/src/vm/gcenv.ee.cpp b/src/vm/gcenv.ee.cpp index f27d3f32c8..7788022374 100644 --- a/src/vm/gcenv.ee.cpp +++ b/src/vm/gcenv.ee.cpp @@ -1558,3 +1558,50 @@ void GCToEEInterface::VerifySyncTableEntry() SyncBlockCache::GetSyncBlockCache()->VerifySyncTableEntry(); #endif // VERIFY_HEAP } + +void GCToEEInterface::UpdateGCEventStatus(int currentPublicLevel, int currentPublicKeywords, int currentPrivateLevel, int currentPrivateKeywords) +{ +#if defined(__linux__) + LIMITED_METHOD_CONTRACT; + // LTTng does not have a notion of enabling events via "keyword"/"level" but we have to + // somehow implement a similar behavior to it. + + // To do this, we manaully check for events that are enabled via different provider/keywords/level. + // Ex 1. GCJoin_V2 is what we use to check whether the GC keyword is enabled in verbose level in the public provider + // Ex 2. SetGCHandle is what we use to check whether the GCHandle keyword is enabled in informational level in the public provider + // Refer to the comments in src/vm/gcenv.ee.h next to the EXTERN C definitions to see which events are enabled. + + // WARNING: To change an event's GC level, perfcollect script needs to be updated simultaneously to reflect it. + BOOL keyword_gc_verbose = EventXplatEnabledGCJoin_V2(); + BOOL keyword_gc_informational = EventXplatEnabledGCStart(); + + BOOL keyword_gc_heapsurvival_and_movement_informational = EventXplatEnabledGCGenerationRange(); + BOOL keyword_gchandle_informational = EventXplatEnabledSetGCHandle(); + BOOL keyword_gchandle_prv_informational = EventXplatEnabledPrvSetGCHandle(); + + BOOL prv_gcprv_informational = EventXplatEnabledBGCBegin(); + BOOL prv_gcprv_verbose = EventXplatEnabledPinPlugAtGCTime(); + + int publicProviderLevel = keyword_gc_verbose ? GCEventLevel_Verbose : (keyword_gc_informational ? GCEventLevel_Information : GCEventLevel_None); + int publicProviderKeywords = (keyword_gc_informational ? GCEventKeyword_GC : GCEventKeyword_None) | + (keyword_gchandle_informational ? GCEventKeyword_GCHandle : GCEventKeyword_None) | + (keyword_gc_heapsurvival_and_movement_informational ? GCEventKeyword_GCHeapSurvivalAndMovement : GCEventKeyword_None); + + int privateProviderLevel = prv_gcprv_verbose ? GCEventLevel_Verbose : (prv_gcprv_informational ? GCEventLevel_Information : GCEventLevel_None); + int privateProviderKeywords = (prv_gcprv_informational ? GCEventKeyword_GCPrivate : GCEventKeyword_None) | + (keyword_gchandle_prv_informational ? GCEventKeyword_GCHandlePrivate : GCEventKeyword_None); + + if (publicProviderLevel != currentPublicLevel || publicProviderKeywords != currentPublicKeywords) + { + GCEventLevel publicLevel = static_cast<GCEventLevel>(publicProviderLevel); + GCEventKeyword publicKeywords = static_cast<GCEventKeyword>(publicProviderKeywords); + GCHeapUtilities::RecordEventStateChange(true, publicKeywords, publicLevel); + } + if (privateProviderLevel != currentPrivateLevel || privateProviderKeywords != currentPrivateKeywords) + { + GCEventLevel privateLevel = static_cast<GCEventLevel>(privateProviderLevel); + GCEventKeyword privateKeywords = static_cast<GCEventKeyword>(privateProviderKeywords); + GCHeapUtilities::RecordEventStateChange(false, privateKeywords, privateLevel); + } +#endif // __linux__ +} diff --git a/src/vm/gcenv.ee.h b/src/vm/gcenv.ee.h index 08f9021640..0b542ef291 100644 --- a/src/vm/gcenv.ee.h +++ b/src/vm/gcenv.ee.h @@ -9,6 +9,19 @@ #ifdef FEATURE_STANDALONE_GC +#if defined(__linux__) +extern "C" BOOL EventXplatEnabledGCStart(); // GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC +extern "C" BOOL EventXPlatEnabledGCJoin_V2(); // GCEventProvider_Default, GCEventLevel_Verbose, GCEventKeyword_GC + +extern "C" BOOL EventXplatEnabledGCGenerationRange(); // GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GCHeapSurvivalAndMovement + +extern "C" BOOL EventXplatEnabledSetGCHandle(); // GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GCHandle +extern "C" BOOL EventXplatEnabledPrvSetGCHandle();; // GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCHandlePrivate + +extern "C" BOOL EventXplatEnabledBGCBegin(); // GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate +extern "C" BOOL EventXplatEnabledPinPlugAtGCTime(); // GCEventProvider_Private, GCEventLevel_Verbose, GCEventKeyword_GC +#endif // __linux__ + namespace standalone { @@ -74,6 +87,8 @@ public: void AnalyzeSurvivorsFinished(int condemnedGeneration); void VerifySyncTableEntry(); + + void UpdateGCEventStatus(int publicLevel, int publicKeywords, int privateLevel, int privateKeywords); }; } // namespace standalone |