From f3f12666c822d8b4db8a9ca051618b6dc2420c68 Mon Sep 17 00:00:00 2001 From: Sean Gillespie Date: Wed, 24 Jan 2018 10:04:56 -0800 Subject: [Local GC] FEATURE_EVENT_TRACE 2/n: Scaffolding for emitting known events (#15957) * [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 --- src/gc/env/gcenv.ee.h | 1 + src/gc/gcenv.ee.standalone.inl | 6 ++++++ src/gc/gcevents.h | 13 +++++++++++++ src/gc/gceventstatus.h | 22 ++++++++++++++++++++++ src/gc/gcinterface.ee.h | 18 ++++++++++++++++++ src/vm/CMakeLists.txt | 1 + src/vm/gcenv.ee.cpp | 7 +++++++ src/vm/gcenv.ee.h | 1 + src/vm/gcenv.ee.standalone.cpp | 2 ++ src/vm/gcenv.ee.static.cpp | 2 ++ src/vm/gctoclreventsink.cpp | 8 ++++++++ src/vm/gctoclreventsink.h | 18 ++++++++++++++++++ 12 files changed, 99 insertions(+) create mode 100644 src/gc/gcevents.h create mode 100644 src/vm/gctoclreventsink.cpp create mode 100644 src/vm/gctoclreventsink.h diff --git a/src/gc/env/gcenv.ee.h b/src/gc/env/gcenv.ee.h index 44828b7551..5f2b890969 100644 --- a/src/gc/env/gcenv.ee.h +++ b/src/gc/env/gcenv.ee.h @@ -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__ diff --git a/src/gc/gcenv.ee.standalone.inl b/src/gc/gcenv.ee.standalone.inl index c114b33e9f..675e7fa1eb 100644 --- a/src/gc/gcenv.ee.standalone.inl +++ b/src/gc/gcenv.ee.standalone.inl @@ -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 index 0000000000..cfc1571418 --- /dev/null +++ b/src/gc/gcevents.h @@ -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 diff --git a/src/gc/gceventstatus.h b/src/gc/gceventstatus.h index 4b7310b8a7..1d992fcda3 100644 --- a/src/gc/gceventstatus.h +++ b/src/gc/gceventstatus.h @@ -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__ diff --git a/src/gc/gcinterface.ee.h b/src/gc/gcinterface.ee.h index 113af9de3d..f765362676 100644 --- a/src/gc/gcinterface.ee.h +++ b/src/gc/gcinterface.ee.h @@ -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_ diff --git a/src/vm/CMakeLists.txt b/src/vm/CMakeLists.txt index 4e2b8d6838..67aece1c8a 100644 --- a/src/vm/CMakeLists.txt +++ b/src/vm/CMakeLists.txt @@ -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 diff --git a/src/vm/gcenv.ee.cpp b/src/vm/gcenv.ee.cpp index a880fdbca6..7c6f9406f9 100644 --- a/src/vm/gcenv.ee.cpp +++ b/src/vm/gcenv.ee.cpp @@ -1384,3 +1384,10 @@ void GCToEEInterface::WalkAsyncPinned(Object* object, void* context, void (*call } } } + +IGCToCLREventSink* GCToEEInterface::EventSink() +{ + LIMITED_METHOD_CONTRACT; + + return &g_gcToClrEventSink; +} diff --git a/src/vm/gcenv.ee.h b/src/vm/gcenv.ee.h index e3867b7e98..dc09618554 100644 --- a/src/vm/gcenv.ee.h +++ b/src/vm/gcenv.ee.h @@ -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 diff --git a/src/vm/gcenv.ee.standalone.cpp b/src/vm/gcenv.ee.standalone.cpp index be8ceca0c1..85f6a698d2 100644 --- a/src/vm/gcenv.ee.standalone.cpp +++ b/src/vm/gcenv.ee.standalone.cpp @@ -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/gcenv.ee.static.cpp b/src/vm/gcenv.ee.static.cpp index 975decadf4..e04fd58ae6 100644 --- a/src/vm/gcenv.ee.static.cpp +++ b/src/vm/gcenv.ee.static.cpp @@ -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 index 0000000000..d305b5e8e7 --- /dev/null +++ b/src/vm/gctoclreventsink.cpp @@ -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 index 0000000000..32d12e84dd --- /dev/null +++ b/src/vm/gctoclreventsink.h @@ -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__ + -- cgit v1.2.3