summaryrefslogtreecommitdiff
path: root/src/vm
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2016-01-31 14:23:12 -0800
committerJan Kotas <jkotas@microsoft.com>2016-01-31 14:23:12 -0800
commita7002caf91ce104ef2d5f12fc27544d7a9039abc (patch)
treed7a3d6d4a56ebd32ecb5554b41d0de4b65ffe146 /src/vm
parent1765a84c03a37c9bdb7541cb7db49adad5dae6db (diff)
parent4c375f4ddfb1d35fd57d6f208e9de30350b4dbdd (diff)
downloadcoreclr-a7002caf91ce104ef2d5f12fc27544d7a9039abc.tar.gz
coreclr-a7002caf91ce104ef2d5f12fc27544d7a9039abc.tar.bz2
coreclr-a7002caf91ce104ef2d5f12fc27544d7a9039abc.zip
Merge pull request #2520 from sperling/profiler
Enabling profiling on Unix/OS X
Diffstat (limited to 'src/vm')
-rw-r--r--src/vm/CMakeLists.txt4
-rw-r--r--src/vm/amd64/unixstubs.cpp15
-rw-r--r--src/vm/eetoprofinterfaceimpl.cpp5
-rw-r--r--src/vm/eetoprofinterfaceimpl.h3
-rw-r--r--src/vm/profilermetadataemitvalidator.cpp5
-rw-r--r--src/vm/profilermetadataemitvalidator.h3
-rw-r--r--src/vm/profilingenumerators.h61
-rw-r--r--src/vm/profilinghelper.cpp3
-rw-r--r--src/vm/profilinghelper.h6
-rw-r--r--src/vm/proftoeeinterfaceimpl.cpp24
-rw-r--r--src/vm/proftoeeinterfaceimpl.h2
11 files changed, 79 insertions, 52 deletions
diff --git a/src/vm/CMakeLists.txt b/src/vm/CMakeLists.txt
index c65416c7cd..550c2a3461 100644
--- a/src/vm/CMakeLists.txt
+++ b/src/vm/CMakeLists.txt
@@ -231,6 +231,7 @@ set(VM_SOURCES_WKS
profattachclient.cpp
profattachserver.cpp
profdetach.cpp
+ profilermetadataemitvalidator.cpp
profilingenumerators.cpp
profilinghelper.cpp
proftoeeinterfaceimpl.cpp
@@ -305,8 +306,7 @@ list(APPEND VM_SOURCES_WKS
microsoft.comservices_i.c
mngstdinterfaces.cpp
notifyexternals.cpp
- olecontexthelpers.cpp
- profilermetadataemitvalidator.cpp
+ olecontexthelpers.cpp
rcwrefcache.cpp
rtlfunctions.cpp
runtimecallablewrapper.cpp
diff --git a/src/vm/amd64/unixstubs.cpp b/src/vm/amd64/unixstubs.cpp
index 50e3d68f78..ef8508af9b 100644
--- a/src/vm/amd64/unixstubs.cpp
+++ b/src/vm/amd64/unixstubs.cpp
@@ -26,6 +26,21 @@ extern "C"
PORTABILITY_ASSERT("Implement for PAL");
}
+ void ProfileEnterNaked(FunctionIDOrClientID functionIDOrClientID)
+ {
+ PORTABILITY_ASSERT("Implement for PAL");
+ }
+
+ void ProfileLeaveNaked(FunctionIDOrClientID functionIDOrClientID)
+ {
+ PORTABILITY_ASSERT("Implement for PAL");
+ }
+
+ void ProfileTailcallNaked(FunctionIDOrClientID functionIDOrClientID)
+ {
+ PORTABILITY_ASSERT("Implement for PAL");
+ }
+
DWORD getcpuid(DWORD arg, unsigned char result[16])
{
DWORD eax;
diff --git a/src/vm/eetoprofinterfaceimpl.cpp b/src/vm/eetoprofinterfaceimpl.cpp
index b4ffd94d2f..0dbd697207 100644
--- a/src/vm/eetoprofinterfaceimpl.cpp
+++ b/src/vm/eetoprofinterfaceimpl.cpp
@@ -369,6 +369,11 @@ EEToProfInterfaceImpl::CHashTableImpl::CHashTableImpl(ULONG iBuckets)
WRAPPER_NO_CONTRACT;
}
+EEToProfInterfaceImpl::CHashTableImpl::~CHashTableImpl()
+{
+ WRAPPER_NO_CONTRACT;
+}
+
//---------------------------------------------------------------------------------------
//
// Comparison function for hash table of ClassIDs
diff --git a/src/vm/eetoprofinterfaceimpl.h b/src/vm/eetoprofinterfaceimpl.h
index bd788f5cd0..0390f942bb 100644
--- a/src/vm/eetoprofinterfaceimpl.h
+++ b/src/vm/eetoprofinterfaceimpl.h
@@ -487,7 +487,8 @@ private:
{
public:
CHashTableImpl(ULONG iBuckets);
-
+ virtual ~CHashTableImpl();
+
protected:
virtual BOOL Cmp(SIZE_T k1, const HASHENTRY * pc2);
};
diff --git a/src/vm/profilermetadataemitvalidator.cpp b/src/vm/profilermetadataemitvalidator.cpp
index 47dab0fe7a..007bffd2b4 100644
--- a/src/vm/profilermetadataemitvalidator.cpp
+++ b/src/vm/profilermetadataemitvalidator.cpp
@@ -34,6 +34,11 @@ m_cRefCount(0)
maxInitialGenericParam = TokenFromRid(m_pInnerInternalImport->GetCountWithTokenKind(mdtGenericParam), mdtGenericParam);
}
+ProfilerMetadataEmitValidator::~ProfilerMetadataEmitValidator()
+{
+ LIMITED_METHOD_CONTRACT;
+}
+
//IUnknown
HRESULT ProfilerMetadataEmitValidator::QueryInterface(REFIID riid, void** ppInterface)
{
diff --git a/src/vm/profilermetadataemitvalidator.h b/src/vm/profilermetadataemitvalidator.h
index ebd2f4f6dc..ae3f8b80df 100644
--- a/src/vm/profilermetadataemitvalidator.h
+++ b/src/vm/profilermetadataemitvalidator.h
@@ -14,7 +14,8 @@ class ProfilerMetadataEmitValidator : public IMetaDataEmit2, public IMetaDataAss
{
public:
ProfilerMetadataEmitValidator(IMetaDataEmit* pInnerEmit);
-
+ virtual ~ProfilerMetadataEmitValidator();
+
//IUnknown
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppInterface);
virtual ULONG STDMETHODCALLTYPE AddRef();
diff --git a/src/vm/profilingenumerators.h b/src/vm/profilingenumerators.h
index 1309f0b0e3..7162ba0552 100644
--- a/src/vm/profilingenumerators.h
+++ b/src/vm/profilingenumerators.h
@@ -28,17 +28,14 @@
// (e.g., ICorProfilerObjectEnum)
// Element -- the type of the objects this enumerator returns.
//
-// pEnumInterfaceIID -- pointer to the class ID for this interface
-// (you probably don't need to use this)
//
-//
-template< typename EnumInterface, typename Element, const IID* pEnumInterfaceIID = &__uuidof(EnumInterface) >
+template< typename EnumInterface, typename Element >
class ProfilerEnum : public EnumInterface
{
public:
ProfilerEnum(CDynArray< Element >* elements);
ProfilerEnum();
- ~ProfilerEnum();
+ virtual ~ProfilerEnum();
// IUnknown functions
@@ -66,8 +63,14 @@ protected:
CDynArray< Element > m_elements;
LONG m_refCount;
+
+private:
+ static const IID& m_pEnumInterfaceIID;
};
+template< typename EnumInterface, typename Element >
+const IID& ProfilerEnum< EnumInterface, Element >::m_pEnumInterfaceIID = __uuidof(EnumInterface);
+
//
//
// ProfilerEnum implementation
@@ -97,8 +100,8 @@ protected:
// </TODO>
//
//
-template< typename EnumInterface, typename Element, const IID* pEnumInterfaceIID >
-ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::ProfilerEnum(CDynArray< Element >* elements) :
+template< typename EnumInterface, typename Element >
+ProfilerEnum< EnumInterface, Element >::ProfilerEnum(CDynArray< Element >* elements) :
m_currentElement(0),
m_refCount(1)
{
@@ -119,8 +122,8 @@ ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::ProfilerEnum(CDynArra
}
}
-template< typename EnumInterface, typename Element, const IID* pEnumInterfaceIID >
-ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::ProfilerEnum() :
+template< typename EnumInterface, typename Element >
+ProfilerEnum< EnumInterface, Element >::ProfilerEnum() :
m_currentElement(0),
m_refCount(1)
{
@@ -139,8 +142,8 @@ ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::ProfilerEnum() :
// Returns
// None
//
-template< typename EnumInterface, typename Element, const IID* pEnumInterfaceIID >
-ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::~ProfilerEnum()
+template< typename EnumInterface, typename Element >
+ProfilerEnum< EnumInterface, Element >::~ProfilerEnum()
{
}
@@ -159,11 +162,11 @@ ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::~ProfilerEnum()
// E_NOINTERFACE -- if the enumerator does not implement the requested interface
//
-template< typename EnumInterface, typename Element, const IID* pEnumInterfaceIID >
+template< typename EnumInterface, typename Element >
HRESULT
-ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::QueryInterface(REFIID id, void** pInterface)
+ProfilerEnum< EnumInterface, Element >::QueryInterface(REFIID id, void** pInterface)
{
- if (*pEnumInterfaceIID == id)
+ if (m_pEnumInterfaceIID == id)
{
*pInterface = static_cast< EnumInterface* >(this);
}
@@ -181,16 +184,16 @@ ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::QueryInterface(REFIID
return S_OK;
}
-template< typename EnumInterface, typename Element, const IID* pEnumInterfaceIID >
+template< typename EnumInterface, typename Element >
ULONG
-ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::AddRef()
+ProfilerEnum< EnumInterface, Element >::AddRef()
{
return InterlockedIncrement(&m_refCount);
}
-template< typename EnumInterface, typename Element, const IID* pEnumInterfaceIID >
+template< typename EnumInterface, typename Element >
ULONG
-ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::Release()
+ProfilerEnum< EnumInterface, Element >::Release()
{
ULONG refCount = InterlockedDecrement(&m_refCount);
@@ -224,9 +227,9 @@ ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::Release()
// try to advance 1 item and return S_OK if it is successful
//
-template< typename EnumInterface, typename Element, const IID* pEnumInterfaceIID >
+template< typename EnumInterface, typename Element >
HRESULT
-ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::Next(ULONG elementsRequested,
+ProfilerEnum< EnumInterface, Element >::Next(ULONG elementsRequested,
Element elements[],
ULONG* elementsFetched)
{
@@ -306,9 +309,9 @@ ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::Next(ULONG elementsRe
//
//
-template< typename EnumInterface, typename Element, const IID* pEnumInterfaceIID >
+template< typename EnumInterface, typename Element >
HRESULT
-ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::GetCount(ULONG* count)
+ProfilerEnum< EnumInterface, Element >::GetCount(ULONG* count)
{
CONTRACTL
{
@@ -351,9 +354,9 @@ ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::GetCount(ULONG* count
// before and after calling Skip()
//
//
-template< typename EnumInterface, typename Element, const IID* pEnumInterfaceIID >
+template< typename EnumInterface, typename Element >
HRESULT
-ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::Skip(ULONG count)
+ProfilerEnum< EnumInterface, Element >::Skip(ULONG count)
{
CONTRACTL
{
@@ -391,9 +394,9 @@ ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::Skip(ULONG count)
//
//
-template< typename EnumInterface, typename Element, const IID* pEnumInterfaceIID >
+template< typename EnumInterface, typename Element >
HRESULT
-ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::Reset()
+ProfilerEnum< EnumInterface, Element >::Reset()
{
CONTRACTL
{
@@ -423,9 +426,9 @@ ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::Reset()
// E_INVALIDARG -- if pInterface is an invalid pointer
//
-template< typename EnumInterface, typename Element, const IID* pEnumInterfaceIID >
+template< typename EnumInterface, typename Element >
HRESULT
-ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::Clone(EnumInterface** pInterface)
+ProfilerEnum< EnumInterface, Element >::Clone(EnumInterface** pInterface)
{
CONTRACTL
{
@@ -445,7 +448,7 @@ ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >::Clone(EnumInterface**
HRESULT hr = S_OK;
EX_TRY
{
- *pInterface = new ProfilerEnum< EnumInterface, Element, pEnumInterfaceIID >(&m_elements);
+ *pInterface = new ProfilerEnum< EnumInterface, Element >(&m_elements);
}
EX_CATCH
{
diff --git a/src/vm/profilinghelper.cpp b/src/vm/profilinghelper.cpp
index 53c915f6a4..13d1c5d3fe 100644
--- a/src/vm/profilinghelper.cpp
+++ b/src/vm/profilinghelper.cpp
@@ -288,7 +288,6 @@ void CurrentProfilerStatus::Set(ProfilerStatus newProfStatus)
// See code:#LoadUnloadCallbackSynchronization.
CRITSEC_COOKIE ProfilingAPIUtility::s_csStatus = NULL;
-#ifndef FEATURE_PAL
SidBuffer * ProfilingAPIUtility::s_pSidBuffer = NULL;
@@ -337,8 +336,6 @@ void ProfilingAPIUtility::AppendSupplementaryInformation(int iStringResource, SS
iStringResource);
}
-#endif // !FEATURE_PAL
-
//---------------------------------------------------------------------------------------
//
// Helper function to log publicly-viewable errors about profiler loading and
diff --git a/src/vm/profilinghelper.h b/src/vm/profilinghelper.h
index 913e7eec75..04199bd927 100644
--- a/src/vm/profilinghelper.h
+++ b/src/vm/profilinghelper.h
@@ -37,9 +37,7 @@ enum ProfAPIFaultFlags
};
#endif // _DEBUG
-#ifndef FEATURE_PAL
class SidBuffer;
-#endif // !FEATURE_PAL
//---------------------------------------------------------------------------------------
// Static-only class to coordinate initialization of the various profiling API
@@ -82,11 +80,9 @@ private:
kAttachLoad,
};
-#ifndef FEATURE_PAL
// Allocated lazily the first time it's needed, and then remains allocated until the
// process exits.
static SidBuffer * s_pSidBuffer;
-#endif // !FEATURE_PAL
// See code:ProfilingAPIUtility::InitializeProfiling#LoadUnloadCallbackSynchronization
static CRITSEC_COOKIE s_csStatus;
@@ -106,9 +102,7 @@ private:
static HRESULT ProfilerCLSIDFromString(__inout_z LPWSTR wszClsid, CLSID * pClsid);
static HRESULT AttemptLoadProfilerForStartup();
-#ifndef FEATURE_PAL
static void AppendSupplementaryInformation(int iStringResource, SString * pString);
-#endif // !FEATURE_PAL
static void LogProfEventVA(
int iStringResourceID,
diff --git a/src/vm/proftoeeinterfaceimpl.cpp b/src/vm/proftoeeinterfaceimpl.cpp
index 4a31945300..fe091de5d6 100644
--- a/src/vm/proftoeeinterfaceimpl.cpp
+++ b/src/vm/proftoeeinterfaceimpl.cpp
@@ -1158,6 +1158,7 @@ BOOL HeapWalkHelper(Object * pBO, void * pvContext)
}
#endif
+#ifdef FEATURE_EVENT_TRACE
if (s_forcedGCInProgress &&
ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
TRACE_LEVEL_INFORMATION,
@@ -1171,6 +1172,7 @@ BOOL HeapWalkHelper(Object * pBO, void * pvContext)
(Object **) arrObjRef);
}
+#endif // FEATURE_EVENT_TRACE
// If the data was not allocated on the stack, need to clean it up.
if ((arrObjRef != NULL) && !bOnStack)
@@ -1307,6 +1309,7 @@ void ScanRootsHelper(Object** ppObject, ScanContext *pSC, uint32_t dwFlags)
}
#endif
+#ifdef FEATURE_EVENT_TRACE
// Notify ETW of the root
if (s_forcedGCInProgress &&
ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context,
@@ -1322,6 +1325,7 @@ void ScanRootsHelper(Object** ppObject, ScanContext *pSC, uint32_t dwFlags)
dwFlags, // dwGCFlags
dwEtwRootFlags);
}
+#endif // FEATURE_EVENT_TRACE
}
#endif // defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
@@ -4803,11 +4807,15 @@ HRESULT ProfToEEInterfaceImpl::ForceGC()
LL_INFO1000,
"**PROF: ForceGC.\n"));
+#ifdef FEATURE_EVENT_TRACE
// This helper, used by ETW and profAPI ensures a managed thread gets created for
// this thread before forcing the GC (to work around Jupiter issues where it's
// expected this thread is already managed before starting the GC).
HRESULT hr = ETW::GCLog::ForceGCForDiagnostics();
-
+#else // !FEATURE_EVENT_TRACE
+ HRESULT hr = E_FAIL;
+#endif // FEATURE_EVENT_TRACE
+
// If a Thread object was just created for this thread, remember the fact that it
// was a ForceGC() thread, so we can be more lenient when doing
// COR_PRF_CALLBACKSTATE_INCALLBACK later on from other APIs
@@ -6810,6 +6818,8 @@ StackWalkAction ProfilerStackWalkCallback(CrawlFrame *pCf, PROFILER_STACK_WALK_D
return SWA_ABORT;
}
+#ifdef _TARGET_X86_
+
//---------------------------------------------------------------------------------------
// Normally, calling GetFunction() on the frame is sufficient to ensure
// HelperMethodFrames are intialized. However, sometimes we need to be able to specify
@@ -6870,8 +6880,6 @@ static BOOL EnsureFrameInitialized(Frame * pFrame)
return FALSE;
}
-
-#ifdef _TARGET_X86_
//---------------------------------------------------------------------------------------
//
// Implements the COR_PRF_SNAPSHOT_X86_OPTIMIZED algorithm called by DoStackSnapshot.
@@ -7223,13 +7231,13 @@ HRESULT ProfToEEInterfaceImpl::DoStackSnapshot(ThreadID thread,
return E_NOTIMPL;
#endif
-#ifndef FEATURE_HIJACK
+#if !defined(FEATURE_HIJACK) || !defined(PLATFORM_SUPPORTS_SAFE_THREADSUSPEND)
// DoStackSnapshot needs Thread::Suspend/ResumeThread functionality.
// On platforms w/o support for these APIs return E_NOTIMPL.
return E_NOTIMPL;
-#else // FEATURE_HIJACK
+#else // !defined(FEATURE_HIJACK) || !defined(PLATFORM_SUPPORTS_SAFE_THREADSUSPEND)
CONTRACTL
{
@@ -7416,7 +7424,7 @@ HRESULT ProfToEEInterfaceImpl::DoStackSnapshot(ThreadID thread,
_ASSERTE(!"Profiler trying to walk destroyed thread");
EEPOLICY_HANDLE_FATAL_ERROR(CORPROF_E_STACKSNAPSHOT_INVALID_TGT_THREAD);
}
-
+
// Thread::SuspendThread() ensures that no one else should try to suspend us
// while we're suspending pThreadToSnapshot.
//
@@ -7667,7 +7675,7 @@ Cleanup:
return hr;
-#endif // FEATURE_HIJACK
+#endif // !defined(FEATURE_HIJACK) || !defined(PLATFORM_SUPPORTS_SAFE_THREADSUSPEND)
}
@@ -9065,8 +9073,6 @@ HRESULT ProfToEEInterfaceImpl::EnumNgenModuleMethodsInliningThisMethod(
PROFILER_TO_CLR_ENTRYPOINT_SYNC_EX(kP2EETriggers, (LF_CORPROF, LL_INFO1000, "**PROF: EnumNgenModuleMethodsInliningThisMethod.\n"));
- typedef DPTR(class MethodDesc) PTR_MethodDesc;
-
if (ppEnum == NULL)
{
return E_INVALIDARG;
diff --git a/src/vm/proftoeeinterfaceimpl.h b/src/vm/proftoeeinterfaceimpl.h
index 165f8b7e22..7bbd0bcf45 100644
--- a/src/vm/proftoeeinterfaceimpl.h
+++ b/src/vm/proftoeeinterfaceimpl.h
@@ -143,7 +143,7 @@ public:
static void ObjectRefCallback(void* context, void* objectRefUNSAFE);
ProfToEEInterfaceImpl();
- ~ProfToEEInterfaceImpl();
+ virtual ~ProfToEEInterfaceImpl();
HRESULT Init();
// IUnknown