# Local GC meta-issue: https://github.com/dotnet/coreclr/issues/11518
-# https://github.com/dotnet/coreclr/issues/11514
-remove_definitions(-DFEATURE_EVENT_TRACE=1)
-
# https://github.com/dotnet/coreclr/issues/11517
remove_definitions(-DFEATURE_APPDOMAIN_RESOURCE_MONITORING)
static void SyncBlockCacheWeakPtrScan(HANDLESCANPROC scanProc, uintptr_t lp1, uintptr_t lp2);
static void SyncBlockCacheDemote(int max_gen);
static void SyncBlockCachePromotionsGranted(int max_gen);
+ static uint32_t GetActiveSyncBlockCount();
// Thread functions
static bool IsPreemptiveGCDisabled(Thread * pThread);
// Unfortunately some of the ETW macros do not check whether the ETW feature is enabled.
// The ones that do are much less efficient.
#if defined(FEATURE_EVENT_TRACE)
- if (EventEnabledGCAllocationTick_V3())
+ if (EVENT_ENABLED(GCAllocationTick_V3))
{
fire_etw_allocation_event (etw_allocation_running_amount[etw_allocation_index], gen_number, acontext->alloc_ptr);
}
set_pinned (o);
#ifdef FEATURE_EVENT_TRACE
- if(EventEnabledPinObjectAtGCTime())
+ if(EVENT_ENABLED(PinObjectAtGCTime))
{
fire_etw_pin_object_event(o, ppObject);
}
#endif //MULTIPLE_HEAPS
{
#ifdef FEATURE_EVENT_TRACE
- bgc_heap_walk_for_etw_p = ETW::GCLog::ShouldTrackMovementForEtw();
+ bgc_heap_walk_for_etw_p = GCEventStatus::IsEnabled(GCEventProvider_Default,
+ GCEventKeyword_GCHeapSurvivalAndMovement,
+ GCEventLevel_Information);
#endif //FEATURE_EVENT_TRACE
leave_spin_lock (&gc_lock);
extern "C" uint32_t* g_gc_card_bundle_table;
#endif
+#if defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE)
+// Note this is not updated in a thread safe way so the value may not be accurate. We get
+// it accurately in full GCs if the handle count is requested.
+extern DWORD g_dwHandles;
+#endif // ENABLE_PERF_COUNTERS || FEATURE_EVENT_TRACE
+
extern "C" uint32_t* g_gc_card_table;
extern "C" uint8_t* g_gc_lowest_address;
extern "C" uint8_t* g_gc_highest_address;
memset (g_GenerationPromotedSizes, 0, sizeof (g_GenerationPromotedSizes));
size_t total_num_gc_handles = g_dwHandles;
- uint32_t total_num_sync_blocks = SyncBlockCache::GetSyncBlockCache()->GetActiveCount();
+ uint32_t total_num_sync_blocks = GCToEEInterface::GetActiveSyncBlockCount();
// Note this is however for perf counter only, for legacy reasons. What we showed
// in perf counters for "gen0 size" was really the gen0 budget which made
g_theGCToCLR->SyncBlockCachePromotionsGranted(max_gen);
}
+
+inline uint32_t GCToEEInterface::GetActiveSyncBlockCount()
+{
+ assert(g_theGCToCLR != nullptr);
+ return g_theGCToCLR->GetActiveSyncBlockCount();
+}
+
inline bool GCToEEInterface::IsPreemptiveGCDisabled(Thread * pThread)
{
assert(g_theGCToCLR != nullptr);
#ifndef _GCINTERFACE_EE_H_
#define _GCINTERFACE_EE_H_
+enum EtwGCRootFlags
+{
+ kEtwGCRootFlagsPinning = 0x1,
+ kEtwGCRootFlagsWeakRef = 0x2,
+ kEtwGCRootFlagsInterior = 0x4,
+ kEtwGCRootFlagsRefCounted = 0x8,
+};
+
+enum EtwGCRootKind
+{
+ kEtwGCRootKindStack = 0,
+ kEtwGCRootKindFinalizer = 1,
+ kEtwGCRootKindHandle = 2,
+ kEtwGCRootKindOther = 3,
+};
// This interface provides functions that the GC can use to fire events.
// Events fired on this interface are split into two categories: "known"
virtual
void SyncBlockCachePromotionsGranted(int max_gen) = 0;
+ virtual
+ uint32_t GetActiveSyncBlockCount() = 0;
+
// Queries whether or not the given thread has preemptive GC disabled.
virtual
bool IsPreemptiveGCDisabled(Thread * pThread) = 0;
#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
EtwGCRootKind dwEtwRootKind;
#else
- int _unused3;
+ EtwGCRootKind _unused3;
#endif // GC_PROFILING || FEATURE_EVENT_TRACE
ScanContext()
#ifdef GC_PROFILING
pMD = NULL;
#endif //GC_PROFILING
-#ifdef FEATURE_EVENT_TRACE
+#if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
dwEtwRootKind = kEtwGCRootKindOther;
-#endif // FEATURE_EVENT_TRACE
+#endif
}
};
#include "objecthandle.h"
#include "handletablepriv.h"
+#if defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE)
+DWORD g_dwHandles = 0;
+#endif // ENABLE_PERF_COUNTERS || FEATURE_EVENT_TRACE
+
/****************************************************************************
*
* FORWARD DECLARATIONS
HandleQuickSetUserData(handle, lExtraInfo);
}
+#if defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE)
+ g_dwHandles++;
+#endif // defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE)
+
// store the reference
HndAssignHandle(handle, object);
STRESS_LOG2(LF_GC, LL_INFO1000, "CreateHandle: %p, type=%d\n", handle, uType);
// return the handle to the table's cache
TableFreeSingleHandleToCache(pTable, uType, handle);
+
+#if defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE)
+ g_dwHandles--;
+#endif // defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE)
}
// These flags need to be defined either when FEATURE_EVENT_TRACE is enabled or the
// PROFILING_SUPPORTED is set, since they are used both by event tracing and profiling.
-enum EtwGCRootFlags
-{
- kEtwGCRootFlagsPinning = 0x1,
- kEtwGCRootFlagsWeakRef = 0x2,
- kEtwGCRootFlagsInterior = 0x4,
- kEtwGCRootFlagsRefCounted = 0x8,
-};
-
-enum EtwGCRootKind
-{
- kEtwGCRootKindStack = 0,
- kEtwGCRootKindFinalizer = 1,
- kEtwGCRootKindHandle = 2,
- kEtwGCRootKindOther = 3,
-};
-
enum EtwTypeFlags
{
kEtwTypeFlagsDelegate = 0x1,
#include "eeprofinterfaces.h"
#include "shash.h"
#include "eventtracebase.h"
+#include "gcinterface.h"
class SimpleRWLock;
SyncBlockCache::GetSyncBlockCache()->GCDone(FALSE, max_gen);
}
+uint32_t GCToEEInterface::GetActiveSyncBlockCount()
+{
+ CONTRACTL
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ }
+ CONTRACTL_END;
+
+ return SyncBlockCache::GetSyncBlockCache()->GetActiveCount();
+}
+
gc_alloc_context * GCToEEInterface::GetAllocContext(Thread * pThread)
{
WRAPPER_NO_CONTRACT;
void SyncBlockCacheWeakPtrScan(HANDLESCANPROC scanProc, uintptr_t lp1, uintptr_t lp2);
void SyncBlockCacheDemote(int max_gen);
void SyncBlockCachePromotionsGranted(int max_gen);
+ uint32_t GetActiveSyncBlockCount();
bool IsPreemptiveGCDisabled(Thread * pThread);
void EnablePreemptiveGC(Thread * pThread);
void DisablePreemptiveGC(Thread * pThread);
void DiagHandleCreated(OBJECTHANDLE handle, OBJECTREF objRef)
{
-#if defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE)
- g_dwHandles++;
-#endif // defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE)
-
#ifdef GC_PROFILING
BEGIN_PIN_PROFILER(CORProfilerTrackGC());
g_profControlBlock.pProfInterface->HandleCreated((uintptr_t)handle, (ObjectID)OBJECTREF_TO_UNCHECKED_OBJECTREF(objRef));
#else
UNREFERENCED_PARAMETER(handle);
#endif // GC_PROFILING
-
-#if defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE)
- g_dwHandles--;
-#endif // defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE)
}
// Global SyncBlock cache
GPTR_IMPL(SyncTableEntry,g_pSyncTable);
-#if defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE)
-DWORD g_dwHandles = 0;
-#endif // ENABLE_PERF_COUNTERS || FEATURE_EVENT_TRACE
-
#ifdef STRESS_LOG
GPTR_IMPL_INIT(StressLog, g_pStressLog, &StressLog::theLog);
#endif
typedef DPTR(SyncTableEntry) PTR_SyncTableEntry;
GPTR_DECL(SyncTableEntry, g_pSyncTable);
-#if defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE)
-// Note this is not updated in a thread safe way so the value may not be accurate. We get
-// it accurately in full GCs if the handle count is requested.
-extern DWORD g_dwHandles;
-#endif // ENABLE_PERF_COUNTERS || FEATURE_EVENT_TRACE
-
#ifdef FEATURE_COMINTEROP
// Global RCW cleanup list
typedef DPTR(RCWCleanupList) PTR_RCWCleanupList;