[Local GC] FEATURE_EVENT_TRACE 2/n: Scaffolding for emitting known events (#15957)
authorSean Gillespie <segilles@microsoft.com>
Wed, 24 Jan 2018 18:04:56 +0000 (10:04 -0800)
committerGitHub <noreply@github.com>
Wed, 24 Jan 2018 18:04:56 +0000 (10:04 -0800)
* [Local GC] FEATURE_EVENT_TRACE 2/n: Scaffolding for porting known events to callbacks on GCToEEInterface

* Code review feedback: remove `descriptor` system for known events and instead use the gcevents xmacro to generate calls to `GCEventStatus::IsEnabled` with known constants

* Remove more event descriptor code

12 files changed:
src/gc/env/gcenv.ee.h
src/gc/gcenv.ee.standalone.inl
src/gc/gcevents.h [new file with mode: 0644]
src/gc/gceventstatus.h
src/gc/gcinterface.ee.h
src/vm/CMakeLists.txt
src/vm/gcenv.ee.cpp
src/vm/gcenv.ee.h
src/vm/gcenv.ee.standalone.cpp
src/vm/gcenv.ee.static.cpp
src/vm/gctoclreventsink.cpp [new file with mode: 0644]
src/vm/gctoclreventsink.h [new file with mode: 0644]

index 44828b7..5f2b890 100644 (file)
@@ -82,6 +82,7 @@ public:
     static bool CreateThread(void (*threadStart)(void*), void* arg, bool is_suspendable, const char* name);
     static void WalkAsyncPinnedForPromotion(Object* object, ScanContext* sc, promote_func* callback);
     static void WalkAsyncPinned(Object* object, void* context, void(*callback)(Object*, Object*, void*));
+    static IGCToCLREventSink* EventSink();
 };
 
 #endif // __GCENV_EE_H__
index c114b33..675e7fa 100644 (file)
@@ -270,4 +270,10 @@ inline void GCToEEInterface::WalkAsyncPinned(Object* object, void* context, void
     return g_theGCToCLR->WalkAsyncPinned(object, context, callback);
 }
 
+inline IGCToCLREventSink* GCToEEInterface::EventSink()
+{
+    assert(g_theGCToCLR != nullptr);
+    return g_theGCToCLR->EventSink();
+}
+
 #endif // __GCTOENV_EE_STANDALONE_INL__
diff --git a/src/gc/gcevents.h b/src/gc/gcevents.h
new file mode 100644 (file)
index 0000000..cfc1571
--- /dev/null
@@ -0,0 +1,13 @@
+// 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 KNOWN_EVENT
+ #define KNOWN_EVENT(name, provider, level, keyword)
+#endif // KNOWN_EVENT
+
+#ifndef DYNAMIC_EVENT
+ #define DYNAMIC_EVENT(name, provider, level, keyword, ...)
+#endif // DYNAMIC_EVENT
+
+#undef KNOWN_EVENT
+#undef DYNAMIC_EVENT
index 4b7310b..1d992fc 100644 (file)
@@ -187,4 +187,26 @@ private:
     GCEventStatus() = delete;
 };
 
+class GCDynamicEvent
+{
+    /* TODO(segilles) - Not Yet Implemented */
+};
+
+#if FEATURE_EVENT_TRACE
+#define KNOWN_EVENT(name, _provider, _level, _keyword)   \
+  inline bool GCEventEnabled##name() { return GCEventStatus::IsEnabled(_provider, _level, _keyword); }
+#include "gcevents.h"
+
+#define EVENT_ENABLED(name) GCEventEnabled##name()
+#define FIRE_EVENT(name, ...) \
+  do {                                                      \
+    IGCToCLREventSink* sink = GCToEEInterface::EventSink(); \
+    assert(sink != nullptr);                                \
+    sink->Fire##name(__VA_ARGS__);                          \
+  } while(0)
+#else
+#define EVENT_ENABLED(name) false
+#define FIRE_EVENT(name, ...) 0
+#endif // FEATURE_EVENT_TRACE
+
 #endif // __GCEVENTSTATUS_H__
index 113af9d..f765362 100644 (file)
@@ -5,6 +5,20 @@
 #ifndef _GCINTERFACE_EE_H_
 #define _GCINTERFACE_EE_H_
 
+
+// This interface provides functions that the GC can use to fire events.
+// Events fired on this interface are split into two categories: "known"
+// events and "dynamic" events. Known events are events that are baked-in
+// to the hosting runtime's event manifest and are part of the GC/EE interface.
+// There is one callback on IGCToCLREventSink for each known event.
+//
+// Dynamic events are constructed at runtime by the GC and are not known
+// to the EE. ([LOCALGC TODO dynamic event implementation])
+class IGCToCLREventSink
+{
+    /* [LOCALGC TODO] This will be filled with events as they get ported */
+};
+
 // 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.
@@ -251,6 +265,10 @@ public:
     // This function is a no-op if "object" is not an OverlappedData object.
     virtual
     void WalkAsyncPinned(Object* object, void* context, void(*callback)(Object*, Object*, void*)) = 0;
+
+    // Returns an IGCToCLREventSink instance that can be used to fire events.
+    virtual
+    IGCToCLREventSink* EventSink() = 0;
 };
 
 #endif // _GCINTERFACE_EE_H_
index 4e2b8d6..67aece1 100644 (file)
@@ -69,6 +69,7 @@ set(VM_SOURCES_DAC_AND_WKS_COMMON
     formattype.cpp
     fptrstubs.cpp
     frames.cpp
+    gctoclreventsink.cpp
     gcheaputilities.cpp
     gchandleutilities.cpp
     genericdict.cpp
index a880fdb..7c6f940 100644 (file)
@@ -1384,3 +1384,10 @@ void GCToEEInterface::WalkAsyncPinned(Object* object, void* context, void (*call
         }
     }
 }
+
+IGCToCLREventSink* GCToEEInterface::EventSink()
+{
+    LIMITED_METHOD_CONTRACT;
+
+    return &g_gcToClrEventSink;
+}
index e3867b7..dc09618 100644 (file)
@@ -62,6 +62,7 @@ public:
     bool CreateThread(void (*threadStart)(void*), void* arg, bool is_suspendable, const char* name);
     void WalkAsyncPinnedForPromotion(Object* object, ScanContext* sc, promote_func* callback);
     void WalkAsyncPinned(Object* object, void* context, void(*callback)(Object*, Object*, void*));
+    IGCToCLREventSink* EventSink();
 };
 
 } // namespace standalone
index be8ceca..85f6a69 100644 (file)
@@ -14,6 +14,8 @@
 #include "comcallablewrapper.h"
 #endif // FEATURE_COMINTEROP
 
+#include "gctoclreventsink.h"
+
 // the method table for the WeakReference class
 extern MethodTable* pWeakReferenceMT;
 
index 975deca..e04fd58 100644 (file)
@@ -14,6 +14,8 @@
 #include "comcallablewrapper.h"
 #endif // FEATURE_COMINTEROP
 
+#include "gctoclreventsink.h"
+
 // the method table for the WeakReference class
 extern MethodTable* pWeakReferenceMT;
 
diff --git a/src/vm/gctoclreventsink.cpp b/src/vm/gctoclreventsink.cpp
new file mode 100644 (file)
index 0000000..d305b5e
--- /dev/null
@@ -0,0 +1,8 @@
+// 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.
+
+#include "common.h"
+#include "gctoclreventsink.h"
+
+GCToCLREventSink g_gcToClrEventSink;
diff --git a/src/vm/gctoclreventsink.h b/src/vm/gctoclreventsink.h
new file mode 100644 (file)
index 0000000..32d12e8
--- /dev/null
@@ -0,0 +1,18 @@
+// 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 __GCTOCLREVENTSINK_H__
+#define __GCTOCLREVENTSINK_H__
+
+#include "gcinterface.h"
+
+class GCToCLREventSink : public IGCToCLREventSink
+{
+    /* [LOCALGC TODO] This will be filled with events as they get ported */
+};
+
+extern GCToCLREventSink g_gcToClrEventSink;
+
+#endif // __GCTOCLREVENTSINK_H__
+