summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMukul Sabharwal <mjsabby@gmail.com>2019-05-06 20:53:14 -0700
committerDavid Mason <davmason@microsoft.com>2019-05-06 20:53:13 -0700
commit633b20c3de5a030dd4629d6fa35c516f8560d816 (patch)
treeb00e80c471f28aecff5bcf434a6a367d621c8d0d
parente05a7fde46e9acb76dc5b45831b43c4b02e453f3 (diff)
downloadcoreclr-633b20c3de5a030dd4629d6fa35c516f8560d816.tar.gz
coreclr-633b20c3de5a030dd4629d6fa35c516f8560d816.tar.bz2
coreclr-633b20c3de5a030dd4629d6fa35c516f8560d816.zip
Add option to only notify profiler of LOH allocations (#24291)
-rw-r--r--src/inc/corprof.idl9
-rw-r--r--src/inc/profilepriv.inl15
-rw-r--r--src/pal/prebuilt/inc/corprof.h13
-rw-r--r--src/vm/eeprofinterfaces.inl9
-rw-r--r--src/vm/gchelpers.cpp25
-rw-r--r--src/vm/proftoeeinterfaceimpl.cpp42
-rw-r--r--src/vm/proftoeeinterfaceimpl.h2
7 files changed, 106 insertions, 9 deletions
diff --git a/src/inc/corprof.idl b/src/inc/corprof.idl
index b34fd311ca..fa1dfe8722 100644
--- a/src/inc/corprof.idl
+++ b/src/inc/corprof.idl
@@ -634,10 +634,14 @@ typedef enum
COR_PRF_HIGH_REQUIRE_PROFILE_IMAGE = 0,
+ // Enables the large object allocation monitoring according to the LOH threshold.
+ COR_PRF_HIGH_MONITOR_LARGEOBJECT_ALLOCATED = 0x00000040,
+
COR_PRF_HIGH_ALLOWABLE_AFTER_ATTACH = COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED |
COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS |
COR_PRF_HIGH_BASIC_GC |
- COR_PRF_HIGH_MONITOR_GC_MOVED_OBJECTS,
+ COR_PRF_HIGH_MONITOR_GC_MOVED_OBJECTS |
+ COR_PRF_HIGH_MONITOR_LARGEOBJECT_ALLOCATED,
// MONITOR_IMMUTABLE represents all flags that may only be set during initialization.
// Trying to change any of these flags elsewhere will result in a
@@ -3932,6 +3936,9 @@ interface ICorProfilerInfo10 : ICorProfilerInfo9
// Given an ObjectID, determines whether it is in a read only segment.
HRESULT IsFrozenObject(ObjectID objectId, BOOL *pbFrozen);
+
+ // Gets the value of the configured LOH Threshold.
+ HRESULT GetLOHObjectSizeThreshold(DWORD *pThreshold);
}
/*
diff --git a/src/inc/profilepriv.inl b/src/inc/profilepriv.inl
index 413090f211..912624180f 100644
--- a/src/inc/profilepriv.inl
+++ b/src/inc/profilepriv.inl
@@ -264,6 +264,21 @@ inline BOOL CORProfilerTrackAllocations()
((&g_profControlBlock)->dwEventMask & COR_PRF_MONITOR_OBJECT_ALLOCATED));
}
+inline BOOL CORProfilerTrackLargeAllocations()
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ return
+ (CORProfilerPresent() &&
+ ((&g_profControlBlock)->dwEventMaskHigh & COR_PRF_HIGH_MONITOR_LARGEOBJECT_ALLOCATED));
+}
+
inline BOOL CORProfilerEnableRejit()
{
CONTRACTL
diff --git a/src/pal/prebuilt/inc/corprof.h b/src/pal/prebuilt/inc/corprof.h
index 0963b030a5..9edfc35fa1 100644
--- a/src/pal/prebuilt/inc/corprof.h
+++ b/src/pal/prebuilt/inc/corprof.h
@@ -547,7 +547,8 @@ enum __MIDL___MIDL_itf_corprof_0000_0000_0006
COR_PRF_HIGH_BASIC_GC = 0x10,
COR_PRF_HIGH_MONITOR_GC_MOVED_OBJECTS = 0x20,
COR_PRF_HIGH_REQUIRE_PROFILE_IMAGE = 0,
- COR_PRF_HIGH_ALLOWABLE_AFTER_ATTACH = ( ( ( COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED | COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS ) | COR_PRF_HIGH_BASIC_GC ) | COR_PRF_HIGH_MONITOR_GC_MOVED_OBJECTS ) ,
+ COR_PRF_HIGH_MONITOR_LARGEOBJECT_ALLOCATED = 0x40,
+ COR_PRF_HIGH_ALLOWABLE_AFTER_ATTACH = ( ( ( ( COR_PRF_HIGH_IN_MEMORY_SYMBOLS_UPDATED | COR_PRF_HIGH_MONITOR_DYNAMIC_FUNCTION_UNLOADS ) | COR_PRF_HIGH_BASIC_GC ) | COR_PRF_HIGH_MONITOR_GC_MOVED_OBJECTS ) | COR_PRF_HIGH_MONITOR_LARGEOBJECT_ALLOCATED ) ,
COR_PRF_HIGH_MONITOR_IMMUTABLE = COR_PRF_HIGH_DISABLE_TIERED_COMPILATION
} COR_PRF_HIGH_MONITOR;
@@ -15195,6 +15196,9 @@ EXTERN_C const IID IID_ICorProfilerInfo10;
ObjectID objectId,
BOOL *pbFrozen) = 0;
+ virtual HRESULT STDMETHODCALLTYPE GetLOHObjectSizeThreshold(
+ DWORD *pThreshold) = 0;
+
};
@@ -15793,6 +15797,10 @@ EXTERN_C const IID IID_ICorProfilerInfo10;
ObjectID objectId,
BOOL *pbFrozen);
+ HRESULT ( STDMETHODCALLTYPE *GetLOHObjectSizeThreshold )(
+ ICorProfilerInfo10 * This,
+ DWORD *pThreshold);
+
END_INTERFACE
} ICorProfilerInfo10Vtbl;
@@ -16101,6 +16109,9 @@ EXTERN_C const IID IID_ICorProfilerInfo10;
#define ICorProfilerInfo10_IsFrozenObject(This,objectId,pbFrozen) \
( (This)->lpVtbl -> IsFrozenObject(This,objectId,pbFrozen) )
+#define ICorProfilerInfo10_GetLOHObjectSizeThreshold(This,pThreshold) \
+ ( (This)->lpVtbl -> GetLOHObjectSizeThreshold(This,pThreshold) )
+
#endif /* COBJMACROS */
diff --git a/src/vm/eeprofinterfaces.inl b/src/vm/eeprofinterfaces.inl
index a080002dd4..ea29edec77 100644
--- a/src/vm/eeprofinterfaces.inl
+++ b/src/vm/eeprofinterfaces.inl
@@ -23,5 +23,14 @@ FORCEINLINE BOOL TrackAllocations()
#endif // PROFILING_SUPPORTED
}
+FORCEINLINE BOOL TrackLargeAllocations()
+{
+#ifdef PROFILING_SUPPORTED
+ return CORProfilerTrackLargeAllocations();
+#else
+ return FALSE;
+#endif // PROFILING_SUPPORTED
+}
+
#endif
diff --git a/src/vm/gchelpers.cpp b/src/vm/gchelpers.cpp
index 8cb4fee9b0..22a1a5d39b 100644
--- a/src/vm/gchelpers.cpp
+++ b/src/vm/gchelpers.cpp
@@ -542,10 +542,13 @@ OBJECTREF AllocateSzArray(MethodTable* pArrayMT, INT32 cElements, GC_ALLOC_FLAGS
// Initialize Object
orArray->m_NumComponents = cElements;
+ bool bProfilerNotifyLargeAllocation = false;
+
if (bAllocateInLargeHeap ||
(totalSize >= g_pConfig->GetGCLOHThreshold()))
{
GCHeapUtilities::GetGCHeap()->PublishObject((BYTE*)orArray);
+ bProfilerNotifyLargeAllocation = TrackLargeAllocations();
}
#ifdef _LOGALLOC
@@ -566,7 +569,7 @@ OBJECTREF AllocateSzArray(MethodTable* pArrayMT, INT32 cElements, GC_ALLOC_FLAGS
// Notify the profiler of the allocation
// do this after initializing bounds so callback has size information
- if (TrackAllocations())
+ if (TrackAllocations() || bProfilerNotifyLargeAllocation)
{
ProfileTrackArrayAlloc(orArray);
}
@@ -768,10 +771,13 @@ OBJECTREF AllocateArrayEx(MethodTable *pArrayMT, INT32 *pArgs, DWORD dwNumArgs,
// Initialize Object
orArray->m_NumComponents = cElements;
+ bool bProfilerNotifyLargeAllocation = false;
+
if (bAllocateInLargeHeap ||
(totalSize >= g_pConfig->GetGCLOHThreshold()))
{
GCHeapUtilities::GetGCHeap()->PublishObject((BYTE*)orArray);
+ bProfilerNotifyLargeAllocation = TrackLargeAllocations();
}
#ifdef _LOGALLOC
@@ -804,7 +810,7 @@ OBJECTREF AllocateArrayEx(MethodTable *pArrayMT, INT32 *pArgs, DWORD dwNumArgs,
// Notify the profiler of the allocation
// do this after initializing bounds so callback has size information
- if (TrackAllocations())
+ if (TrackAllocations() || bProfilerNotifyLargeAllocation)
{
ProfileTrackArrayAlloc(orArray);
}
@@ -988,13 +994,15 @@ STRINGREF AllocateString( DWORD cchStringLength )
orObject->SetMethodTable( g_pStringClass );
orObject->SetStringLength( cchStringLength );
+ bool bProfilerNotifyLargeAllocation = false;
if (ObjectSize >= g_pConfig->GetGCLOHThreshold())
{
+ bProfilerNotifyLargeAllocation = TrackLargeAllocations();
GCHeapUtilities::GetGCHeap()->PublishObject((BYTE*)orObject);
}
// Notify the profiler of the allocation
- if (TrackAllocations())
+ if (TrackAllocations() || bProfilerNotifyLargeAllocation)
{
OBJECTREF objref = ObjectToOBJECTREF((Object*)orObject);
GCPROTECT_BEGIN(objref);
@@ -1062,13 +1070,16 @@ UTF8STRINGREF AllocateUtf8String(DWORD cchStringLength)
orObject->SetMethodTable(g_pUtf8StringClass);
orObject->SetLength(cchStringLength);
- if (ObjectSize >= LARGE_OBJECT_SIZE)
+ bool bProfilerNotifyLargeAllocation = false;
+
+ if (ObjectSize >= g_pConfig->GetGCLOHThreshold())
{
GCHeapUtilities::GetGCHeap()->PublishObject((BYTE*)orObject);
+ bProfilerNotifyLargeAllocation = TrackLargeAllocations();
}
// Notify the profiler of the allocation
- if (TrackAllocations())
+ if (TrackAllocations() || bProfilerNotifyLargeAllocation)
{
OBJECTREF objref = ObjectToOBJECTREF((Object*)orObject);
GCPROTECT_BEGIN(objref);
@@ -1192,9 +1203,11 @@ OBJECTREF AllocateObject(MethodTable *pMT
// verify zero'd memory (at least for sync block)
_ASSERTE( orObject->HasEmptySyncBlockInfo() );
+ bool bProfilerNotifyLargeAllocation = false;
if ((baseSize >= g_pConfig->GetGCLOHThreshold()))
{
orObject->SetMethodTableForLargeObject(pMT);
+ bProfilerNotifyLargeAllocation = TrackLargeAllocations();
GCHeapUtilities::GetGCHeap()->PublishObject((BYTE*)orObject);
}
else
@@ -1203,7 +1216,7 @@ OBJECTREF AllocateObject(MethodTable *pMT
}
// Notify the profiler of the allocation
- if (TrackAllocations())
+ if (TrackAllocations() || bProfilerNotifyLargeAllocation)
{
OBJECTREF objref = ObjectToOBJECTREF((Object*)orObject);
GCPROTECT_BEGIN(objref);
diff --git a/src/vm/proftoeeinterfaceimpl.cpp b/src/vm/proftoeeinterfaceimpl.cpp
index 467ab29292..b5ade592f7 100644
--- a/src/vm/proftoeeinterfaceimpl.cpp
+++ b/src/vm/proftoeeinterfaceimpl.cpp
@@ -649,7 +649,7 @@ void __stdcall ProfilerObjectAllocatedCallback(OBJECTREF objref, ClassID classId
// Notify the profiler of the allocation
{
- BEGIN_PIN_PROFILER(CORProfilerTrackAllocations());
+ BEGIN_PIN_PROFILER(CORProfilerTrackAllocations() || CORProfilerTrackLargeAllocations());
// Note that for generic code we always return uninstantiated ClassIDs and FunctionIDs.
// Thus we strip any instantiations of the ClassID (which is really a type handle) here.
g_profControlBlock.pProfInterface->ObjectAllocated(
@@ -6893,6 +6893,46 @@ HRESULT ProfToEEInterfaceImpl::IsFrozenObject(ObjectID objectId, BOOL *pbFrozen)
}
/*
+ * GetLOHObjectSizeThreshold
+ *
+ * Gets the value of the configured LOH Threshold.
+ *
+ * Parameters:
+ * pThreshold - value of the threshold in bytes
+ *
+ * Returns:
+ * S_OK if successful
+ *
+ */
+HRESULT ProfToEEInterfaceImpl::GetLOHObjectSizeThreshold(DWORD *pThreshold)
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ EE_THREAD_NOT_REQUIRED;
+ CANNOT_TAKE_LOCK;
+ }
+ CONTRACTL_END;
+
+ PROFILER_TO_CLR_ENTRYPOINT_SYNC_EX(
+ kP2EEAllowableAfterAttach,
+ (LF_CORPROF,
+ LL_INFO1000,
+ "**PROF: GetLOHObjectSizeThreshold\n"));
+
+ if (pThreshold == nullptr)
+ {
+ return E_INVALIDARG;
+ }
+
+ *pThreshold = g_pConfig->GetGCLOHThreshold();
+
+ return S_OK;
+}
+
+/*
* GetStringLayout
*
* This function describes to a profiler the internal layout of a string.
diff --git a/src/vm/proftoeeinterfaceimpl.h b/src/vm/proftoeeinterfaceimpl.h
index d41eec9120..ff5e46390f 100644
--- a/src/vm/proftoeeinterfaceimpl.h
+++ b/src/vm/proftoeeinterfaceimpl.h
@@ -611,6 +611,8 @@ public:
COM_METHOD IsFrozenObject(ObjectID objectId, BOOL *pbFrozen);
+ COM_METHOD GetLOHObjectSizeThreshold(DWORD *pThreshold);
+
// end ICorProfilerInfo10
protected: