summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSung Yoon Whang <suwhang@microsoft.com>2019-03-07 18:34:17 -0800
committerGitHub <noreply@github.com>2019-03-07 18:34:17 -0800
commit4685a1e008ad7cf4118e8778d89e63d87ca5b7b6 (patch)
tree7bb44141fc537f864c69b1168630dcc9becd12ea
parenta2865ead29cc8ef73307927976c3dbaad1298d44 (diff)
downloadcoreclr-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.h1
-rw-r--r--src/gc/gc.cpp13
-rw-r--r--src/gc/gcenv.ee.standalone.inl8
-rw-r--r--src/gc/gceventstatus.h29
-rw-r--r--src/gc/gcinterface.ee.h3
-rw-r--r--src/gc/gcinterface.h10
-rw-r--r--src/vm/gcenv.ee.cpp47
-rw-r--r--src/vm/gcenv.ee.h15
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