Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/coreclr/src/gc/env/gcenv.ee.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class GCToEEInterface
static uint32_t GetTotalNumSizedRefHandles();

static bool AnalyzeSurvivorsRequested(int condemnedGeneration);
static void AnalyzeSurvivorsFinished(int condemnedGeneration);
static void AnalyzeSurvivorsFinished(size_t gcIndex, int condemnedGeneration, uint64_t promoted_bytes, void (*reportGenerationBounds)());

static void VerifySyncTableEntry();
static void UpdateGCEventStatus(int publicLevel, int publicKeywords, int privateLevel, int privateKeywords);
Expand Down
12 changes: 11 additions & 1 deletion src/coreclr/src/gc/gc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20909,9 +20909,19 @@ void gc_heap::mark_phase (int condemned_gen_number, BOOL mark_only_p)
if (gc_t_join.joined())
#endif //MULTIPLE_HEAPS
{
uint64_t promoted_bytes_global = 0;
#ifdef HEAP_ANALYZE
heap_analyze_enabled = FALSE;
GCToEEInterface::AnalyzeSurvivorsFinished(condemned_gen_number);
#ifdef MULTIPLE_HEAPS
for (int i = 0; i < n_heaps; i++)
{
promoted_bytes_global += promoted_bytes (i);
}
#else
promoted_bytes_global = promoted_bytes (0);
#endif //MULTIPLE_HEAPS

GCToEEInterface::AnalyzeSurvivorsFinished (settings.gc_index, condemned_gen_number, promoted_bytes_global, GCHeap::ReportGenerationBounds);
#endif // HEAP_ANALYZE
GCToEEInterface::AfterGcScanRoots (condemned_gen_number, max_generation, &sc);

Expand Down
12 changes: 6 additions & 6 deletions src/coreclr/src/gc/gcee.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ void GCHeap::UpdatePreGCCounters()
#endif // BACKGROUND_GC

FIRE_EVENT(GCStart_V2, count, depth, reason, static_cast<uint32_t>(type));
ReportGenerationBounds();
}

void GCHeap::ReportGenerationBounds()
{
g_theGCHeap->DiagDescrGenerations([](void*, int generation, uint8_t* rangeStart, uint8_t* rangeEnd, uint8_t* rangeEndReserved)
{
uint64_t range = static_cast<uint64_t>(rangeEnd - rangeStart);
Expand Down Expand Up @@ -148,12 +153,7 @@ void GCHeap::UpdatePostGCCounters()
#endif //FEATURE_EVENT_TRACE

#ifdef FEATURE_EVENT_TRACE
g_theGCHeap->DiagDescrGenerations([](void*, int generation, uint8_t* rangeStart, uint8_t* rangeEnd, uint8_t* rangeEndReserved)
{
uint64_t range = static_cast<uint64_t>(rangeEnd - rangeStart);
uint64_t rangeReserved = static_cast<uint64_t>(rangeEndReserved - rangeStart);
FIRE_EVENT(GCGenerationRange, generation, rangeStart, range, rangeReserved);
}, nullptr);
ReportGenerationBounds();

FIRE_EVENT(GCEnd_V1, static_cast<uint32_t>(pSettings->gc_index), condemned_gen);

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/src/gc/gcenv.ee.standalone.inl
Original file line number Diff line number Diff line change
Expand Up @@ -274,10 +274,10 @@ inline bool GCToEEInterface::AnalyzeSurvivorsRequested(int condemnedGeneration)
return g_theGCToCLR->AnalyzeSurvivorsRequested(condemnedGeneration);
}

inline void GCToEEInterface::AnalyzeSurvivorsFinished(int condemnedGeneration)
inline void GCToEEInterface::AnalyzeSurvivorsFinished(size_t gcIndex, int condemnedGeneration, uint64_t promoted_bytes, void (*reportGenerationBounds)())
{
assert(g_theGCToCLR != nullptr);
g_theGCToCLR->AnalyzeSurvivorsFinished(condemnedGeneration);
g_theGCToCLR->AnalyzeSurvivorsFinished(gcIndex, condemnedGeneration, promoted_bytes, reportGenerationBounds);
}

inline void GCToEEInterface::VerifySyncTableEntry()
Expand Down
6 changes: 4 additions & 2 deletions src/coreclr/src/gc/gcimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ inline void deleteGCShadow() {}
inline void checkGCWriteBarrier() {}
#endif

void GCProfileWalkHeap();
void GCProfileWalkHeap(bool etwOnly);

class gc_heap;
class CFinalize;
Expand All @@ -57,7 +57,7 @@ class GCHeap : public IGCHeapInternal
friend void EnterAllocLock();
friend void LeaveAllocLock();
friend void ProfScanRootsHelper(Object** object, ScanContext *pSC, uint32_t dwFlags);
friend void GCProfileWalkHeap();
friend void GCProfileWalkHeap(bool etwOnly);

public:
//In order to keep gc.cpp cleaner, ugly EE specific code is relegated to methods.
Expand Down Expand Up @@ -315,6 +315,8 @@ class GCHeap : public IGCHeapInternal
size_t GetLastGCGenerationSize(int gen);

virtual void Shutdown();

static void ReportGenerationBounds();
};

#endif // GCIMPL_H_
2 changes: 1 addition & 1 deletion src/coreclr/src/gc/gcinterface.ee.h
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ class IGCToCLR {
bool AnalyzeSurvivorsRequested(int condemnedGeneration) = 0;

virtual
void AnalyzeSurvivorsFinished(int condemnedGeneration) = 0;
void AnalyzeSurvivorsFinished(size_t gcIndex, int condemnedGeneration, uint64_t promoted_bytes, void (*reportGenerationBounds)()) = 0;

virtual
void VerifySyncTableEntry() = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/src/gc/sample/gcenv.ee.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ inline bool GCToEEInterface::AnalyzeSurvivorsRequested(int condemnedGeneration)
return false;
}

inline void GCToEEInterface::AnalyzeSurvivorsFinished(int condemnedGeneration)
inline void GCToEEInterface::AnalyzeSurvivorsFinished(size_t gcIndex, int condemnedGeneration, uint64_t promoted_bytes, void (*reportGenerationBounds)())
{

}
7 changes: 7 additions & 0 deletions src/coreclr/src/inc/clrconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,13 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeRundown, W("EventPipeRundown"), 1, "E
RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeCircularMB, W("EventPipeCircularMB"), 1024, "The EventPipe circular buffer size in megabytes.")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeProcNumbers, W("EventPipeProcNumbers"), 0, "Enable/disable capturing processor numbers in EventPipe event headers")

//
// Generational Aware Analysis
//
RETAIL_CONFIG_DWORD_INFO(INTERNAL_GCGenAnalysisGen, W("GCGenAnalysisGen"), 0, "The generation to trigger generational aware analysis")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_GCGenAnalysisBytes, W("GCGenAnalysisBytes"), 0, "The number of bytes to trigger generational aware analysis")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_GCGenAnalysisIndex, W("GCGenAnalysisIndex"), 0, "The gc index to trigger generational aware analysis")

//
// Diagnostics Ports
//
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/src/vm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ set(VM_SOURCES_WKS
gcenv.ee.common.cpp
gcenv.os.cpp
gchelpers.cpp
genanalysis.cpp
genmeth.cpp
hosting.cpp
ibclogger.cpp
Expand Down
9 changes: 9 additions & 0 deletions src/coreclr/src/vm/ClrEtwAll.man
Original file line number Diff line number Diff line change
Expand Up @@ -3795,6 +3795,13 @@
task="AssemblyLoader"
symbol="KnownPathProbed" message="$(string.RuntimePublisher.KnownPathProbedEventMessage)"/>

<event value="297" version="0" level="win:Informational"
keywords ="GCHeapDumpKeyword"
symbol="GenAwareBegin" message="$(string.RuntimePublisher.GenAwareBeginEventMessage)"/>

<event value="298" version="0" level="win:Informational"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a corresponding change to TraceEvent? If so it might be good to link it from the PR.

keywords ="GCHeapDumpKeyword"
symbol="GenAwareEnd" message="$(string.RuntimePublisher.GenAwareEndEventMessage)"/>
</events>
</provider>

Expand Down Expand Up @@ -7548,6 +7555,8 @@
<string id="RuntimePublisher.CompilationDiagnosticKeywordMessage" value="CompilationDiagnostic" />
<string id="RuntimePublisher.MethodDiagnosticKeywordMessage" value="MethodDiagnostic" />
<string id="RuntimePublisher.TypeDiagnosticKeywordMessage" value="TypeDiagnostic" />
<string id="RuntimePublisher.GenAwareBeginEventMessage" value="NONE" />
<string id="RuntimePublisher.GenAwareEndEventMessage" value="NONE" />
<string id="RundownPublisher.LoaderKeywordMessage" value="Loader" />
<string id="RundownPublisher.JitKeywordMessage" value="Jit" />
<string id="RundownPublisher.JittedMethodILToNativeMapRundownKeywordMessage" value="JittedMethodILToNativeMapRundown" />
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/src/vm/ceemain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@
#include "gdbjit.h"
#endif // FEATURE_GDBJIT

#include "genanalysis.h"

#ifndef CROSSGEN_COMPILE
static int GetThreadUICultureId(__out LocaleIDValue* pLocale); // TODO: This shouldn't use the LCID. We should rely on name instead

Expand Down Expand Up @@ -676,6 +678,7 @@ void EEStartupHelper()
// Initialize the event pipe.
EventPipe::Initialize();
#endif // FEATURE_PERFTRACING
GenAnalysis::Initialize();

#ifdef TARGET_UNIX
PAL_SetShutdownCallback(EESocketCleanupHelper);
Expand Down
4 changes: 3 additions & 1 deletion src/coreclr/src/vm/eventpipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "win32threadpool.h"
#include "ceemain.h"
#include "configuration.h"
#include "genanalysis.h"

#ifdef TARGET_UNIX
#include "pal.h"
Expand Down Expand Up @@ -164,7 +165,7 @@ void EventPipe::EnableViaEnvironmentVariables()
{
outputPath = configOutputPath;
}
auto configuration = XplatEventLoggerConfiguration();

LPWSTR configToParse = eventpipeConfig;
int providerCnt = 0;

Expand All @@ -183,6 +184,7 @@ void EventPipe::EnableViaEnvironmentVariables()
}
else
{
auto configuration = XplatEventLoggerConfiguration();
// Count how many providers there are to parse
static WCHAR comma = W(',');
while (*configToParse != '\0')
Expand Down
16 changes: 16 additions & 0 deletions src/coreclr/src/vm/eventpipesession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ EventPipeSession::EventPipeSession(

GetSystemTimeAsFileTime(&m_sessionStartTime);
QueryPerformanceCounter(&m_sessionStartTimeStamp);
this->m_paused = false;
}

EventPipeSession::~EventPipeSession()
Expand Down Expand Up @@ -315,6 +316,16 @@ bool EventPipeSession::WriteAllBuffersToFile(bool *pEventsWritten)
return !m_pFile->HasErrors();
}

void EventPipeSession::Pause()
{
this->m_paused = true;
}

void EventPipeSession::Resume()
{
this->m_paused = false;
}

bool EventPipeSession::WriteEvent(
Thread *pThread,
EventPipeEvent &event,
Expand All @@ -332,6 +343,11 @@ bool EventPipeSession::WriteEvent(
}
CONTRACTL_END;

if (this->m_paused)
{
return true;
}

// Filter events specific to "this" session based on precomputed flag on provider/events.
if (event.IsEnabled(GetMask()))
{
Expand Down
32 changes: 32 additions & 0 deletions src/coreclr/src/vm/eventpipesession.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,20 @@ class EventPipeSession

void DisableIpcStreamingThread();

// Note - access to this field is NOT synchronized
//
// This field is currently modified in EventPipe::EnableViaEnvironmentVariables() during process startup
// and GCToEEInterface::AnalyzeSurvivorsFinished() while the GC has already synchronized all the threads.
//
// It is read in EventPipeSession::WriteEvent(). While it is possible for other preemptive threads to read
// the field while GC is happening, it should not happen because the only gcGenAwareSession only subscribe
// to GC events.
//
// This functionality is a workaround because we couldn't safely Enable()/Disable() the session where we wanted to due to lock-leveling.
// we expect to remove it in the future once that limitation is resolved
// other scenarios are discouraged from using this given that we plan to make it go away
bool m_paused;

public:
EventPipeSession(
uint32_t index,
Expand All @@ -111,6 +125,24 @@ class EventPipeSession

~EventPipeSession();

/**
* Please do not use this function, see EventPipeSession::m_paused for more information
*/
void Pause();

/**
* Please do not use this function, see EventPipeSession::m_paused for more information
*/
void Resume();

/**
* Please do not use this function, see EventPipeSession::m_paused for more information
*/
bool Paused()
{
return this->m_paused;
}

uint64_t GetMask() const
{
LIMITED_METHOD_CONTRACT;
Expand Down
22 changes: 19 additions & 3 deletions src/coreclr/src/vm/eventtrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1095,9 +1095,14 @@ void BulkComLogger::WriteRcw(RCW *pRcw, Object *obj)
_ASSERTE(m_currRcw < kMaxRcwCount);

#ifdef FEATURE_COMINTEROP
TypeHandle typeHandle = obj->GetGCSafeTypeHandleIfPossible();
if (typeHandle == NULL)
{
return;
}
EventRCWEntry &rcw = m_etwRcwData[m_currRcw];
rcw.ObjectID = (ULONGLONG)obj;
rcw.TypeID = (ULONGLONG)obj->GetTypeHandle().AsTAddr();
rcw.TypeID = (ULONGLONG)typeHandle.AsTAddr();
rcw.IUnk = (ULONGLONG)pRcw->GetIUnknown_NoAddRef();
rcw.VTable = (ULONGLONG)pRcw->GetVTablePtr();
rcw.RefCount = pRcw->GetRefCount();
Expand Down Expand Up @@ -1179,10 +1184,16 @@ void BulkComLogger::WriteCcw(ComCallWrapper *pCcw, Object **handle, Object *obj)
flags |= EventCCWEntry::Strong;
}

TypeHandle typeHandle = obj->GetGCSafeTypeHandleIfPossible();
if (typeHandle == NULL)
{
return;
}

EventCCWEntry &ccw = m_etwCcwData[m_currCcw++];
ccw.RootID = (ULONGLONG)handle;
ccw.ObjectID = (ULONGLONG)obj;
ccw.TypeID = (ULONGLONG)obj->GetTypeHandle().AsTAddr();
ccw.TypeID = (ULONGLONG)typeHandle.AsTAddr();
ccw.IUnk = (ULONGLONG)iUnk;
ccw.RefCount = refCount;
ccw.JupiterRefCount = 0;
Expand Down Expand Up @@ -1463,7 +1474,12 @@ void BulkStaticsLogger::WriteEntry(AppDomain *domain, Object **address, Object *
m_domain = domain;
}

ULONGLONG th = (ULONGLONG)obj->GetTypeHandle().AsTAddr();
TypeHandle typeHandle = obj->GetGCSafeTypeHandleIfPossible();
if (typeHandle == NULL)
{
return;
}
ULONGLONG th = (ULONGLONG)typeHandle.AsTAddr();
ETW::TypeSystemLog::LogTypeAndParametersIfNecessary(m_typeLogger, th, ETW::TypeSystemLog::kTypeLogBehaviorTakeLockAndLogIfFirstTime);

// We should have at least 512 characters remaining in the buffer here.
Expand Down
1 change: 0 additions & 1 deletion src/coreclr/src/vm/fastserializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ FileStreamWriter::FileStreamWriter(const SString &outputFilePath)
m_pFileStream = new CFileStream();
if (FAILED(m_pFileStream->OpenForWrite(outputFilePath)))
{
_ASSERTE(!"Unable to open file for write.");
delete m_pFileStream;
m_pFileStream = NULL;
return;
Expand Down
19 changes: 15 additions & 4 deletions src/coreclr/src/vm/finalizerthread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#include "finalizerthread.h"
#include "threadsuspend.h"
#include "jithost.h"
#include "eventpipe.h"
#include "eventpipesession.h"
#include "genanalysis.h"

#ifdef FEATURE_COMINTEROP
#include "runtimecallablewrapper.h"
Expand Down Expand Up @@ -214,12 +217,8 @@ void FinalizerThread::WaitForFinalizerEvent (CLREvent *event)
}
}



static BOOL s_FinalizerThreadOK = FALSE;



VOID FinalizerThread::FinalizerThreadWorker(void *args)
{
SCAN_IGNORE_THROW;
Expand Down Expand Up @@ -267,6 +266,18 @@ VOID FinalizerThread::FinalizerThreadWorker(void *args)
g_TriggerHeapDump = FALSE;
}
#endif
if (gcGenAnalysisState == GcGenAnalysisState::Done)
{
gcGenAnalysisState = GcGenAnalysisState::Disabled;
EventPipe::Disable(gcGenAnalysisEventPipeSessionId);
// Writing an empty file to indicate completion
fclose(fopen(GENAWARE_COMPLETION_FILE_NAME,"w+"));
#ifdef GEN_ANALYSIS_STRESS
{
GenAnalysis::EnableGenerationalAwareSession();
}
#endif
}

if (!bPriorityBoosted)
{
Expand Down
Loading