Skip to content

Commit

Permalink
Add sealed. Refactor modules
Browse files Browse the repository at this point in the history
  • Loading branch information
xoofx committed Dec 21, 2024
1 parent 9862b9f commit 56a2808
Show file tree
Hide file tree
Showing 20 changed files with 118 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Ultra.Core.Model;
/// <summary>
/// Represents a garbage collection allocation tick profile marker.
/// </summary>
public record GCAllocationTickTraceMarker : UTraceMarker
public sealed record GCAllocationTickTraceMarker : UTraceMarker
{
/// <summary>
/// Gets or sets the amount of memory allocated.
Expand Down
2 changes: 1 addition & 1 deletion src/Ultra.Core/Model/Markers/GCHeapStatsTraceMarker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Ultra.Core.Model;
/// <summary>
/// Represents a garbage collection heap stats event marker payload for Firefox Profiler.
/// </summary>
public record GCHeapStatsTraceMarker : UTraceMarker
public sealed record GCHeapStatsTraceMarker : UTraceMarker
{
/// <summary>
/// Gets or sets the total heap size.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ namespace Ultra.Core.Model;
/// <summary>
/// Represents an event that indicates the .NET garbage collector has restarted the execution engine.
/// </summary>
public record GCRestartExecutionEngineTraceMarker : UTraceMarker;
public sealed record GCRestartExecutionEngineTraceMarker : UTraceMarker;
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Ultra.Core.Model;
/// <summary>
/// Represents an event that marks the suspension of the execution engine by the garbage collector.
/// </summary>
public record GCSuspendExecutionEngineTraceMarker : UTraceMarker
public sealed record GCSuspendExecutionEngineTraceMarker : UTraceMarker
{
/// <summary>
/// Gets or sets the reason for the suspension.
Expand Down
2 changes: 1 addition & 1 deletion src/Ultra.Core/Model/Markers/GCTraceMarker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Ultra.Core.Model;
/// <summary>
/// Represents a garbage collection event marker payload for Firefox Profiler.
/// </summary>
public record GCTraceMarker : UTraceMarker
public sealed record GCTraceMarker : UTraceMarker
{
/// <summary>
/// Gets or sets the reason for the garbage collection.
Expand Down
2 changes: 1 addition & 1 deletion src/Ultra.Core/Model/Markers/JitCompileTraceMarker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Ultra.Core.Model;
/// <summary>
/// Represents a JIT compile event marker payload for the Firefox Profiler.
/// </summary>
public record JitCompileTraceMarker : UTraceMarker
public sealed record JitCompileTraceMarker : UTraceMarker
{
/// <summary>
/// Gets or sets the full name of the method.
Expand Down
2 changes: 1 addition & 1 deletion src/Ultra.Core/Model/UCallStackList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Ultra.Core.Model;
/// <summary>
/// Represents a list of <see cref="UCallStackFrame"/> instances.
/// </summary>
public class UCallStackList : UGenericList<UCallStackFrame>
public sealed class UCallStackList : UGenericList<UCallStackFrame>
{
private UnsafeDictionary<UCallStackFrame, UCallStackIndex> _uniqueStacks = new(65536);

Expand Down
2 changes: 1 addition & 1 deletion src/Ultra.Core/Model/UCodeAddressList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Ultra.Core.Model;
/// <summary>
/// Represents a list of <see cref="UAddress"/> each associated with a unique <see cref="UCodeAddressIndex"/>.
/// </summary>
public class UCodeAddressList : UGenericList<UAddress>
public sealed class UCodeAddressList : UGenericList<UAddress>
{
private readonly Dictionary<UAddress, UCodeAddressIndex> _mapAddressToIndex = new();

Expand Down
2 changes: 1 addition & 1 deletion src/Ultra.Core/Model/UTraceManagedMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Ultra.Core.Model;
/// <summary>
/// Represents a managed method in a traced process.
/// </summary>
public record UTraceManagedMethod(int ThreadID, long ModuleID, long MethodID, string MethodNamespace, string MethodName, string MethodSignature, int MethodToken, MethodFlags MethodFlags, UAddress MethodStartAddress, USize MethodSize) : UTraceMethod(CreateFullName(MethodNamespace, MethodName), MethodStartAddress, MethodSize)
public sealed record UTraceManagedMethod(int ThreadID, long ModuleID, long MethodID, string MethodNamespace, string MethodName, string MethodSignature, int MethodToken, MethodFlags MethodFlags, UAddress MethodStartAddress, USize MethodSize) : UTraceMethod(CreateFullName(MethodNamespace, MethodName), MethodStartAddress, MethodSize)
{
/// <summary>
/// Gets or sets the native IL offsets for the method.
Expand Down
2 changes: 1 addition & 1 deletion src/Ultra.Core/Model/UTraceManagedMethodList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Ultra.Core.Model;
/// <summary>
/// Represents a list of <see cref="UTraceManagedMethod"/> instances.
/// </summary>
public class UTraceManagedMethodList : UGenericList<UTraceManagedMethod>
public sealed class UTraceManagedMethodList : UGenericList<UTraceManagedMethod>
{
private UnsafeDictionary<UAddress, int> _mapMethodAddressToMethodIndex = new();
private UnsafeDictionary<long, int> _mapManagedMethodIDToMethodIndex = new();
Expand Down
4 changes: 2 additions & 2 deletions src/Ultra.Core/Model/UTraceManagedModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ namespace Ultra.Core.Model;
/// <summary>
/// Represents a managed module in the traced process.
/// </summary>
public record UTraceManagedModule(long ModuleID, long AssemblyId, UTraceModuleFile ModuleFile, UAddress BaseAddress, USize CodeSize) : UTraceLoadedModule(ModuleFile, BaseAddress, CodeSize)
public sealed record UTraceManagedModule(long ModuleID, long AssemblyId, UTraceModuleFile ModuleFile) : UTraceModule(ModuleFile)
{
/// <summary>
/// Gets or sets the native module if available.
/// </summary>
public UTraceLoadedModule? NativeModule { get; set; }
public UTraceNativeModule? NativeModule { get; set; }
}
21 changes: 21 additions & 0 deletions src/Ultra.Core/Model/UTraceModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// Licensed under the BSD-Clause 2 license.
// See license.txt file in the project root for full license information.

namespace Ultra.Core.Model;

/// <summary>
/// Represents a loaded module in the traced process.
/// </summary>
public abstract record UTraceModule(UTraceModuleFile ModuleFile)
{
/// <summary>
/// Gets or sets the load time of the module. Time is relative to the start of the session.
/// </summary>
public UTimeSpan LoadTime { get; set; }

/// <summary>
/// Gets or sets the unload time of the module. Time is relative to the start of the session.
/// </summary>
public UTimeSpan UnloadTime { get; set; }
}
12 changes: 1 addition & 11 deletions src/Ultra.Core/Model/UTraceModuleFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Ultra.Core.Model;
/// <summary>
/// Represents a module file that is loaded in the traced process.
/// </summary>
public record UTraceModuleFile(string FilePath)
public sealed record UTraceModuleFile(string FilePath)
{
/// <summary>
/// Gets or sets the module file index.
Expand All @@ -23,14 +23,4 @@ public record UTraceModuleFile(string FilePath)
/// Gets or sets the symbol file path for the module.
/// </summary>
public string? SymbolFilePath { get; set; }

/// <summary>
/// Gets or sets the load time of the module. Time is relative to the start of the session.
/// </summary>
public UTimeSpan LoadTime { get; set; }

/// <summary>
/// Gets or sets the unload time of the module. Time is relative to the start of the session.
/// </summary>
public UTimeSpan UnloadTime { get; set; }
}
28 changes: 13 additions & 15 deletions src/Ultra.Core/Model/UTraceModuleList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
namespace Ultra.Core.Model;

/// <summary>
/// Represents a list of <see cref="UTraceLoadedModule"/> instances.
/// Represents a list of <see cref="UTraceModule"/> instances.
/// </summary>
public class UTraceModuleList : UGenericList<UTraceLoadedModule>
public sealed class UTraceModuleList : UGenericList<UTraceModule>
{
private UnsafeDictionary<string, UTraceModuleFileIndex> _mapModulePathToIndex = new();
private UnsafeList<UTraceModuleFile> _moduleFiles = new();
Expand Down Expand Up @@ -64,19 +64,19 @@ public bool TryGetManagedModule(long moduleID, [NotNullWhen(true)] out UTraceMan
/// <summary>
/// Gets or creates a loaded module based on the file path, base address, and code size.
/// </summary>
/// <param name="filePath">The file path of the module.</param>
/// <param name="baseAddress">The base address of the module.</param>
/// <param name="codeSize">The size of the code.</param>
/// <returns>The <see cref="UTraceLoadedModule"/> instance.</returns>
public UTraceLoadedModule GetOrCreateLoadedModule(string filePath, UAddress baseAddress, USize codeSize)
/// <param name="moduleFilePath">The file path of the module.</param>
/// <returns>The <see cref="UTraceModule"/> instance.</returns>
public UTraceModule GetOrCreateNativeModule(UAddress baseAddress, USize codeSize, string moduleFilePath)
{
if (_mapModuleAddressToLoadedModule.TryGetValue(baseAddress, out var loadedModuleIndex))
{
return List[loadedModuleIndex];
}

var moduleFile = GetOrCreateModuleFile(filePath);
var loadedModule = new UTraceLoadedModule(moduleFile, baseAddress, codeSize);
var moduleFile = GetOrCreateModuleFile(moduleFilePath);
var loadedModule = new UTraceNativeModule(moduleFile, baseAddress, codeSize);
loadedModuleIndex = List.Count;
_mapModuleAddressToLoadedModule.Add(baseAddress, loadedModuleIndex);
List.Add(loadedModule);
Expand All @@ -93,14 +93,14 @@ public UTraceLoadedModule GetOrCreateLoadedModule(string filePath, UAddress base
/// <param name="address">The address of the module.</param>
/// <param name="module">The module found, if any.</param>
/// <returns>True if the module was found, otherwise false.</returns>
public bool TryFindModuleByAddress(UAddress address, [NotNullWhen(true)] out UTraceLoadedModule? module)
public bool TryFindNativeModuleByAddress(UAddress address, [NotNullWhen(true)] out UTraceNativeModule? module)
{
var ranges = _loadedModuleAddressRanges.AsSpan();
var comparer = new UAddressRangeFinder(address);
var index = ranges.BinarySearch(comparer);
if (index >= 0)
{
module = List[ranges[index].Index];
module = (UTraceNativeModule)List[ranges[index].Index];
return true;
}
module = null;
Expand All @@ -112,18 +112,16 @@ public bool TryFindModuleByAddress(UAddress address, [NotNullWhen(true)] out UTr
/// </summary>
/// <param name="moduleID">The module ID.</param>
/// <param name="assemblyId">The assembly ID.</param>
/// <param name="filePath">The file path of the module.</param>
/// <param name="baseAddress">The base address of the module.</param>
/// <param name="codeSize">The size of the module.</param>
/// <param name="moduleFilePath">The file path of the module.</param>
/// <returns>The <see cref="UTraceManagedModule"/> instance.</returns>
public UTraceManagedModule GetOrCreateManagedModule(long moduleID, long assemblyId, string filePath, UAddress baseAddress, USize codeSize)
public UTraceManagedModule GetOrCreateManagedModule(long moduleID, long assemblyId, string moduleFilePath)
{
if (_mapModuleIDToManagedModule.TryGetValue(moduleID, out var managedModuleIndex))
{
return (UTraceManagedModule)List[managedModuleIndex];
}
var moduleFile = GetOrCreateModuleFile(filePath);
var managedModule = new UTraceManagedModule(moduleID, assemblyId, moduleFile, baseAddress, codeSize);
var moduleFile = GetOrCreateModuleFile(moduleFilePath);
var managedModule = new UTraceManagedModule(moduleID, assemblyId, moduleFile);
_mapModuleIDToManagedModule.Add(moduleID, List.Count);
List.Add(managedModule);
return managedModule;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ namespace Ultra.Core.Model;
/// <summary>
/// Represents a loaded module in the traced process.
/// </summary>
public record UTraceLoadedModule(UTraceModuleFile ModuleFile, UAddress BaseAddress, USize CodeSize);
public sealed record UTraceNativeModule(UTraceModuleFile ModuleFile, UAddress BaseAddress, USize CodeSize) : UTraceModule(ModuleFile);
4 changes: 2 additions & 2 deletions src/Ultra.Core/Model/UTraceProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Ultra.Core.Model;
/// <summary>
/// Represents a process being traced.
/// </summary>
public class UTraceProcess
public sealed class UTraceProcess
{
/// <summary>
/// Gets or sets the process ID.
Expand Down Expand Up @@ -52,4 +52,4 @@ public class UTraceProcess
/// Gets the list of call stacks in the traced process.
/// </summary>
public UCallStackList CallStacks { get; } = new();
}
}
36 changes: 36 additions & 0 deletions src/Ultra.Core/Model/UTraceSession.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) Alexandre Mutel. All rights reserved.
// Licensed under the BSD-Clause 2 license.
// See license.txt file in the project root for full license information.

namespace Ultra.Core.Model;

/// <summary>
/// Represents a session of tracing.
/// </summary>
public sealed class UTraceSession
{
/// <summary>
/// Gets or sets the number of processor used for the session.
/// </summary>
public int NumberOfProcessors { get; set; }

/// <summary>
/// Gets or sets the CPU speed in MHz.
/// </summary>
public int CpuSpeedMHz { get; set; }

/// <summary>
/// Gets or sets the start time of the session.
/// </summary>
public DateTime StartTime { get; set; }

/// <summary>
/// Gets or sets the duration of the session.
/// </summary>
public UTimeSpan Duration { get; set; }

/// <summary>
/// Gets or sets the process being traced.
/// </summary>
public List<UTraceProcess> Processes { get; } = new();
}
2 changes: 1 addition & 1 deletion src/Ultra.Core/Model/UTraceThread.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Ultra.Core.Model;
/// <summary>
/// Represents a thread in a traced process.
/// </summary>
public record UTraceThread(ulong ThreadID)
public sealed record UTraceThread(ulong ThreadID)
{
private UnsafeList<UTraceSample> _samples = new(1024);

Expand Down
2 changes: 1 addition & 1 deletion src/Ultra.Core/Model/UTraceThreadList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Ultra.Core.Model;
/// <summary>
/// Represents a list of <see cref="UTraceThread"/> instances.
/// </summary>
public class UTraceThreadList : UGenericList<UTraceThread>
public sealed class UTraceThreadList : UGenericList<UTraceThread>
{
private readonly Dictionary<ulong, int> _mapThreadIDToIndex = new();

Expand Down
36 changes: 30 additions & 6 deletions src/Ultra.Core/Parser/UltraEventPipeProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,24 +137,40 @@ private void ProcessMethodLoadVerbose(MethodLoadUnloadVerboseTraceData method)

private void ProcessModuleLoadUnload(ModuleLoadUnloadTraceData data, bool isLoad, bool isDCStartStop)
{
var module = _modules.GetOrCreateManagedModule(data.ModuleID, data.AssemblyID, data.ModuleILPath);

module.ModuleFile.SymbolUuid = data.ManagedPdbSignature;
module.ModuleFile.SymbolFilePath = data.ManagedPdbBuildPath;

if (!isDCStartStop)
{
if (isLoad)
{
module.LoadTime = UTimeSpan.FromMilliseconds(data.TimeStampRelativeMSec);
}
else
{
module.UnloadTime = UTimeSpan.FromMilliseconds(data.TimeStampRelativeMSec);
}
}
}

private void SamplerParserOnEventNativeModule(UltraNativeModuleTraceEvent evt)
{
if (evt.ModulePath is not null)
{
var module = _modules.GetOrCreateLoadedModule(evt.ModulePath, evt.LoadAddress, evt.Size);
var module = _modules.GetOrCreateNativeModule(evt.LoadAddress, evt.Size, evt.ModulePath);

if (evt.NativeModuleEventKind == UltraSamplerNativeModuleEventKind.Unloaded)
{
// TODO: how to support remove?
//_mapModuleNameToIndex.Remove(evt.ModulePath);
module.ModuleFile.UnloadTime = UTimeSpan.FromMilliseconds(evt.TimeStampRelativeMSec);
module.UnloadTime = UTimeSpan.FromMilliseconds(evt.TimeStampRelativeMSec);
}
else
{
module.ModuleFile.SymbolUuid = evt.Uuid;
module.ModuleFile.LoadTime = UTimeSpan.FromMilliseconds(evt.TimeStampRelativeMSec);
module.LoadTime = UTimeSpan.FromMilliseconds(evt.TimeStampRelativeMSec);
}
}

Expand Down Expand Up @@ -192,7 +208,7 @@ private void PrintCallStack(UltraNativeCallstackTraceEvent callstackTraceEvent)
//}
}

public UTraceProcess Run()
public UTraceSession Run()
{
// Run CLR if available
_clrEventSource?.Process();
Expand All @@ -201,8 +217,16 @@ public UTraceProcess Run()

// Run sampler before CLR
_samplerEventSource.Process();

return _process;

var session = new UTraceSession();
session.Processes.Add(_process);

session.NumberOfProcessors = _samplerEventSource.NumberOfProcessors;
session.StartTime = _samplerEventSource.SessionStartTime;
session.Duration = _samplerEventSource.SessionDuration;
session.CpuSpeedMHz = _samplerEventSource.CpuSpeedMHz;

return session;
}

private ThreadSamplerState GetThreadSamplingState(ulong threadID)
Expand Down

0 comments on commit 56a2808

Please sign in to comment.