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
1 change: 1 addition & 0 deletions src/TraceEvent/Parsers/ClrTraceEventParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11956,6 +11956,7 @@ public abstract class MethodLoadUnloadTraceDataBase : TraceEvent
public bool IsDynamic { get { return (MethodFlags & MethodFlags.Dynamic) != 0; } }
public bool IsGeneric { get { return (MethodFlags & MethodFlags.Generic) != 0; } }
public bool IsJitted { get { return (MethodFlags & MethodFlags.Jitted) != 0; } }
public bool IsJitHelper { get { return (MethodFlags & MethodFlags.JitHelper) != 0; } }

public OptimizationTier OptimizationTier
{
Expand Down
76 changes: 57 additions & 19 deletions src/TraceEvent/TraceLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,8 @@ private void SetupInitialRundownCallbacks(EventPipeEventSource rawEvents)
TraceProcess process = processes.GetOrCreateProcess(data.ProcessID, data.TimeStampQPC);
process.InsertJITTEDMethod(data.MethodStartAddress, data.MethodSize, delegate ()
{
TraceManagedModule module = process.LoadedModules.GetOrCreateManagedModule(data.ModuleID, data.TimeStampQPC);
MethodIndex methodIndex = CodeAddresses.Methods.NewMethod(GetFullName(data), module.ModuleFile.ModuleFileIndex, data.MethodToken);
TraceModuleFile moduleFile = process.LoadedModules.GetOrCreateMethodModuleFile(data);
MethodIndex methodIndex = CodeAddresses.Methods.NewMethod(GetFullName(data), moduleFile.ModuleFileIndex, data.MethodToken);
return new TraceProcess.MethodLookupInfo(data.MethodStartAddress, data.MethodSize, methodIndex);
});
};
Expand Down Expand Up @@ -1363,7 +1363,7 @@ private unsafe void SetupCallbacks(TraceEventDispatcher rawEvents)
eventCount = 0;

// FIX NOW HACK, because Method and Module unload methods are missing.
jittedMethods = new List<MethodLoadUnloadVerboseTraceData>();
methodLoadEvents = new List<MethodLoadUnloadVerboseTraceData>();
jsJittedMethods = new List<MethodLoadUnloadJSTraceData>();
sourceFilesByID = new Dictionary<JavaScriptSourceKey, string>();

Expand Down Expand Up @@ -1684,17 +1684,17 @@ private unsafe void SetupCallbacks(TraceEventDispatcher rawEvents)
bookKeepingEvent = true;
}

if (data.IsJitted)
if (ShouldTrackMethodLoad(data.MethodFlags))
{
TraceProcess process = processes.GetOrCreateProcess(data.ProcessID, data.TimeStampQPC);
process.InsertJITTEDMethod(data.MethodStartAddress, data.MethodSize, delegate ()
{
TraceManagedModule module = process.LoadedModules.GetOrCreateManagedModule(data.ModuleID, data.TimeStampQPC);
MethodIndex methodIndex = CodeAddresses.Methods.NewMethod(TraceLog.GetFullName(data), module.ModuleFile.ModuleFileIndex, data.MethodToken);
TraceModuleFile moduleFile = process.LoadedModules.GetOrCreateMethodModuleFile(data);
MethodIndex methodIndex = CodeAddresses.Methods.NewMethod(TraceLog.GetFullName(data), moduleFile.ModuleFileIndex, data.MethodToken);
return new TraceProcess.MethodLookupInfo(data.MethodStartAddress, data.MethodSize, methodIndex);
});

jittedMethods.Add((MethodLoadUnloadVerboseTraceData)data.Clone());
methodLoadEvents.Add((MethodLoadUnloadVerboseTraceData)data.Clone());
}
};
rawEvents.Clr.MethodLoadVerbose += onMethodStart;
Expand Down Expand Up @@ -2427,9 +2427,9 @@ private unsafe void CopyRawEvents(TraceEventDispatcher rawEvents, IStreamWriter
userStackKeyToInfo = null;

// TODO FIX NOW hack because unloadMethod not present
foreach (var jittedMethod in jittedMethods)
foreach (var methodLoadEvent in methodLoadEvents)
{
codeAddresses.AddMethod(jittedMethod);
codeAddresses.AddMethod(methodLoadEvent);
}

foreach (var jsJittedMethod in jsJittedMethods)
Expand Down Expand Up @@ -3531,22 +3531,36 @@ internal void DebugWarn(bool condition, string message, TraceEvent data)
}
internal static string GetFullName(MethodLoadUnloadVerboseTraceData data)
{
string sig = data.MethodSignature;
int parens = sig.IndexOf('(');
return GetFullName(data.MethodFlags, data.MethodNamespace, data.MethodName, data.MethodSignature);
}

private static string GetFullName(MethodFlags methodFlags, string methodNamespace, string methodName, string methodSignature)
{
if ((methodFlags & MethodFlags.JitHelper) != 0)
{
return methodName;
}

int parens = methodSignature.IndexOf('(');
string args;
if (parens >= 0)
{
args = sig.Substring(parens);
args = methodSignature.Substring(parens);
}
else
{
args = "";
}

string fullName = data.MethodNamespace + "." + data.MethodName + args;
string fullName = methodNamespace + "." + methodName + args;
return fullName;
}

private static bool ShouldTrackMethodLoad(MethodFlags methodFlags)
{
return (methodFlags & (MethodFlags.Jitted | MethodFlags.JitHelper)) != 0;
}

internal int FindPageIndex(long timeQPC)
{
int pageIndex;
Expand Down Expand Up @@ -4202,8 +4216,8 @@ int IFastSerializableVersion.MinimumReaderVersion
private bool noStack; // This event should never have a stack associated with it, so skip them if we every try to attach a stack.
private TraceThread thread; // cache of the TraceThread for the current event.

// TODO FIX NOW remove the jittedMethods ones.
private List<MethodLoadUnloadVerboseTraceData> jittedMethods;
// TODO FIX NOW remove the methodLoadEvents ones.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is this TODO FIX NOW still relevant? If so, maybe a more in-depth comment about what's going here would be helpful.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I don't think this is relevant anymore, but I need to check. There are a lot of these, and I've been thinking about doing a pass over them to clean things up. I'll plan to handle this as part of that pass.

private List<MethodLoadUnloadVerboseTraceData> methodLoadEvents;
private List<MethodLoadUnloadJSTraceData> jsJittedMethods;
private Dictionary<JavaScriptSourceKey, string> sourceFilesByID;

Expand Down Expand Up @@ -7225,6 +7239,29 @@ internal TraceManagedModule GetOrCreateManagedModule(long managedModuleID, long
}
return module;
}

internal TraceModuleFile GetOrCreateMethodModuleFile(MethodLoadUnloadVerboseTraceData data)
{
if (data.IsJitHelper)
{
return GetOrCreateJitHelperModuleFile();
}

return GetOrCreateManagedModule(data.ModuleID, data.TimeStampQPC).ModuleFile;
}

private TraceModuleFile GetOrCreateJitHelperModuleFile()
{
if (jitHelperModuleFile == null)
{
// Stash process-private, dynamically generated runtime helpers under an invalid file path
// so they are clearly synthetic while still displaying cleanly in stacks.
string modulePath = "[generatedruntimehelpers:processindex=" + process.ProcessIndex + "]\\generatedruntimehelpers.dll";
jitHelperModuleFile = process.Log.ModuleFiles.GetOrCreateModuleFile(modulePath, 0);
}

return jitHelperModuleFile;
}
/// <summary>
/// Finds the index and module for an a given managed module ID. If not found, new module
/// should be inserted at index + 1;
Expand Down Expand Up @@ -7411,6 +7448,7 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()

private TraceProcess process;
private GrowableArray<TraceLoadedModule> modules; // Contains unmanaged modules sorted by key
private TraceModuleFile jitHelperModuleFile;
#endregion
}

Expand Down Expand Up @@ -8536,7 +8574,7 @@ internal void AddMethod(MethodLoadUnloadVerboseTraceData data)
MethodIndex methodIndex = Microsoft.Diagnostics.Tracing.Etlx.MethodIndex.Invalid;
ILMapIndex ilMap = ILMapIndex.Invalid;
ModuleFileIndex moduleFileIndex = Microsoft.Diagnostics.Tracing.Etlx.ModuleFileIndex.Invalid;
TraceManagedModule module = null;
TraceModuleFile moduleFile = null;
TraceProcess process = log.Processes.GetOrCreateProcess(data.ProcessID, data.TimeStampQPC);
ForAllUnresolvedCodeAddressesInRange(process, data.MethodStartAddress, data.MethodSize, true, delegate (ref CodeAddressInfo info)
{
Expand All @@ -8545,10 +8583,10 @@ internal void AddMethod(MethodLoadUnloadVerboseTraceData data)
if (info.GetMethodIndex(this) == Microsoft.Diagnostics.Tracing.Etlx.MethodIndex.Invalid)
{
// Lazily create the method since many methods never have code samples in them.
if (module == null)
if (moduleFile == null)
{
module = process.LoadedModules.GetOrCreateManagedModule(data.ModuleID, data.TimeStampQPC);
moduleFileIndex = module.ModuleFile.ModuleFileIndex;
moduleFile = process.LoadedModules.GetOrCreateMethodModuleFile(data);
moduleFileIndex = moduleFile.ModuleFileIndex;
methodIndex = methods.NewMethod(TraceLog.GetFullName(data), moduleFileIndex, data.MethodToken);
if (data.IsJitted)
{
Expand Down