Skip to content

Commit 56a2808

Browse files
committed
Add sealed. Refactor modules
1 parent 9862b9f commit 56a2808

20 files changed

+118
-49
lines changed

src/Ultra.Core/Model/Markers/GCAllocationTickTraceMarker.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Ultra.Core.Model;
77
/// <summary>
88
/// Represents a garbage collection allocation tick profile marker.
99
/// </summary>
10-
public record GCAllocationTickTraceMarker : UTraceMarker
10+
public sealed record GCAllocationTickTraceMarker : UTraceMarker
1111
{
1212
/// <summary>
1313
/// Gets or sets the amount of memory allocated.

src/Ultra.Core/Model/Markers/GCHeapStatsTraceMarker.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Ultra.Core.Model;
77
/// <summary>
88
/// Represents a garbage collection heap stats event marker payload for Firefox Profiler.
99
/// </summary>
10-
public record GCHeapStatsTraceMarker : UTraceMarker
10+
public sealed record GCHeapStatsTraceMarker : UTraceMarker
1111
{
1212
/// <summary>
1313
/// Gets or sets the total heap size.

src/Ultra.Core/Model/Markers/GCRestartExecutionEngineTraceMarker.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ namespace Ultra.Core.Model;
77
/// <summary>
88
/// Represents an event that indicates the .NET garbage collector has restarted the execution engine.
99
/// </summary>
10-
public record GCRestartExecutionEngineTraceMarker : UTraceMarker;
10+
public sealed record GCRestartExecutionEngineTraceMarker : UTraceMarker;

src/Ultra.Core/Model/Markers/GCSuspendExecutionEngineTraceMarker.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Ultra.Core.Model;
77
/// <summary>
88
/// Represents an event that marks the suspension of the execution engine by the garbage collector.
99
/// </summary>
10-
public record GCSuspendExecutionEngineTraceMarker : UTraceMarker
10+
public sealed record GCSuspendExecutionEngineTraceMarker : UTraceMarker
1111
{
1212
/// <summary>
1313
/// Gets or sets the reason for the suspension.

src/Ultra.Core/Model/Markers/GCTraceMarker.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Ultra.Core.Model;
77
/// <summary>
88
/// Represents a garbage collection event marker payload for Firefox Profiler.
99
/// </summary>
10-
public record GCTraceMarker : UTraceMarker
10+
public sealed record GCTraceMarker : UTraceMarker
1111
{
1212
/// <summary>
1313
/// Gets or sets the reason for the garbage collection.

src/Ultra.Core/Model/Markers/JitCompileTraceMarker.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Ultra.Core.Model;
77
/// <summary>
88
/// Represents a JIT compile event marker payload for the Firefox Profiler.
99
/// </summary>
10-
public record JitCompileTraceMarker : UTraceMarker
10+
public sealed record JitCompileTraceMarker : UTraceMarker
1111
{
1212
/// <summary>
1313
/// Gets or sets the full name of the method.

src/Ultra.Core/Model/UCallStackList.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Ultra.Core.Model;
99
/// <summary>
1010
/// Represents a list of <see cref="UCallStackFrame"/> instances.
1111
/// </summary>
12-
public class UCallStackList : UGenericList<UCallStackFrame>
12+
public sealed class UCallStackList : UGenericList<UCallStackFrame>
1313
{
1414
private UnsafeDictionary<UCallStackFrame, UCallStackIndex> _uniqueStacks = new(65536);
1515

src/Ultra.Core/Model/UCodeAddressList.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Ultra.Core.Model;
77
/// <summary>
88
/// Represents a list of <see cref="UAddress"/> each associated with a unique <see cref="UCodeAddressIndex"/>.
99
/// </summary>
10-
public class UCodeAddressList : UGenericList<UAddress>
10+
public sealed class UCodeAddressList : UGenericList<UAddress>
1111
{
1212
private readonly Dictionary<UAddress, UCodeAddressIndex> _mapAddressToIndex = new();
1313

src/Ultra.Core/Model/UTraceManagedMethod.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Ultra.Core.Model;
99
/// <summary>
1010
/// Represents a managed method in a traced process.
1111
/// </summary>
12-
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)
12+
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)
1313
{
1414
/// <summary>
1515
/// Gets or sets the native IL offsets for the method.

src/Ultra.Core/Model/UTraceManagedMethodList.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace Ultra.Core.Model;
1111
/// <summary>
1212
/// Represents a list of <see cref="UTraceManagedMethod"/> instances.
1313
/// </summary>
14-
public class UTraceManagedMethodList : UGenericList<UTraceManagedMethod>
14+
public sealed class UTraceManagedMethodList : UGenericList<UTraceManagedMethod>
1515
{
1616
private UnsafeDictionary<UAddress, int> _mapMethodAddressToMethodIndex = new();
1717
private UnsafeDictionary<long, int> _mapManagedMethodIDToMethodIndex = new();

src/Ultra.Core/Model/UTraceManagedModule.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ namespace Ultra.Core.Model;
77
/// <summary>
88
/// Represents a managed module in the traced process.
99
/// </summary>
10-
public record UTraceManagedModule(long ModuleID, long AssemblyId, UTraceModuleFile ModuleFile, UAddress BaseAddress, USize CodeSize) : UTraceLoadedModule(ModuleFile, BaseAddress, CodeSize)
10+
public sealed record UTraceManagedModule(long ModuleID, long AssemblyId, UTraceModuleFile ModuleFile) : UTraceModule(ModuleFile)
1111
{
1212
/// <summary>
1313
/// Gets or sets the native module if available.
1414
/// </summary>
15-
public UTraceLoadedModule? NativeModule { get; set; }
15+
public UTraceNativeModule? NativeModule { get; set; }
1616
}

src/Ultra.Core/Model/UTraceModule.cs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright (c) Alexandre Mutel. All rights reserved.
2+
// Licensed under the BSD-Clause 2 license.
3+
// See license.txt file in the project root for full license information.
4+
5+
namespace Ultra.Core.Model;
6+
7+
/// <summary>
8+
/// Represents a loaded module in the traced process.
9+
/// </summary>
10+
public abstract record UTraceModule(UTraceModuleFile ModuleFile)
11+
{
12+
/// <summary>
13+
/// Gets or sets the load time of the module. Time is relative to the start of the session.
14+
/// </summary>
15+
public UTimeSpan LoadTime { get; set; }
16+
17+
/// <summary>
18+
/// Gets or sets the unload time of the module. Time is relative to the start of the session.
19+
/// </summary>
20+
public UTimeSpan UnloadTime { get; set; }
21+
}

src/Ultra.Core/Model/UTraceModuleFile.cs

+1-11
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Ultra.Core.Model;
77
/// <summary>
88
/// Represents a module file that is loaded in the traced process.
99
/// </summary>
10-
public record UTraceModuleFile(string FilePath)
10+
public sealed record UTraceModuleFile(string FilePath)
1111
{
1212
/// <summary>
1313
/// Gets or sets the module file index.
@@ -23,14 +23,4 @@ public record UTraceModuleFile(string FilePath)
2323
/// Gets or sets the symbol file path for the module.
2424
/// </summary>
2525
public string? SymbolFilePath { get; set; }
26-
27-
/// <summary>
28-
/// Gets or sets the load time of the module. Time is relative to the start of the session.
29-
/// </summary>
30-
public UTimeSpan LoadTime { get; set; }
31-
32-
/// <summary>
33-
/// Gets or sets the unload time of the module. Time is relative to the start of the session.
34-
/// </summary>
35-
public UTimeSpan UnloadTime { get; set; }
3626
}

src/Ultra.Core/Model/UTraceModuleList.cs

+13-15
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
namespace Ultra.Core.Model;
99

1010
/// <summary>
11-
/// Represents a list of <see cref="UTraceLoadedModule"/> instances.
11+
/// Represents a list of <see cref="UTraceModule"/> instances.
1212
/// </summary>
13-
public class UTraceModuleList : UGenericList<UTraceLoadedModule>
13+
public sealed class UTraceModuleList : UGenericList<UTraceModule>
1414
{
1515
private UnsafeDictionary<string, UTraceModuleFileIndex> _mapModulePathToIndex = new();
1616
private UnsafeList<UTraceModuleFile> _moduleFiles = new();
@@ -64,19 +64,19 @@ public bool TryGetManagedModule(long moduleID, [NotNullWhen(true)] out UTraceMan
6464
/// <summary>
6565
/// Gets or creates a loaded module based on the file path, base address, and code size.
6666
/// </summary>
67-
/// <param name="filePath">The file path of the module.</param>
6867
/// <param name="baseAddress">The base address of the module.</param>
6968
/// <param name="codeSize">The size of the code.</param>
70-
/// <returns>The <see cref="UTraceLoadedModule"/> instance.</returns>
71-
public UTraceLoadedModule GetOrCreateLoadedModule(string filePath, UAddress baseAddress, USize codeSize)
69+
/// <param name="moduleFilePath">The file path of the module.</param>
70+
/// <returns>The <see cref="UTraceModule"/> instance.</returns>
71+
public UTraceModule GetOrCreateNativeModule(UAddress baseAddress, USize codeSize, string moduleFilePath)
7272
{
7373
if (_mapModuleAddressToLoadedModule.TryGetValue(baseAddress, out var loadedModuleIndex))
7474
{
7575
return List[loadedModuleIndex];
7676
}
7777

78-
var moduleFile = GetOrCreateModuleFile(filePath);
79-
var loadedModule = new UTraceLoadedModule(moduleFile, baseAddress, codeSize);
78+
var moduleFile = GetOrCreateModuleFile(moduleFilePath);
79+
var loadedModule = new UTraceNativeModule(moduleFile, baseAddress, codeSize);
8080
loadedModuleIndex = List.Count;
8181
_mapModuleAddressToLoadedModule.Add(baseAddress, loadedModuleIndex);
8282
List.Add(loadedModule);
@@ -93,14 +93,14 @@ public UTraceLoadedModule GetOrCreateLoadedModule(string filePath, UAddress base
9393
/// <param name="address">The address of the module.</param>
9494
/// <param name="module">The module found, if any.</param>
9595
/// <returns>True if the module was found, otherwise false.</returns>
96-
public bool TryFindModuleByAddress(UAddress address, [NotNullWhen(true)] out UTraceLoadedModule? module)
96+
public bool TryFindNativeModuleByAddress(UAddress address, [NotNullWhen(true)] out UTraceNativeModule? module)
9797
{
9898
var ranges = _loadedModuleAddressRanges.AsSpan();
9999
var comparer = new UAddressRangeFinder(address);
100100
var index = ranges.BinarySearch(comparer);
101101
if (index >= 0)
102102
{
103-
module = List[ranges[index].Index];
103+
module = (UTraceNativeModule)List[ranges[index].Index];
104104
return true;
105105
}
106106
module = null;
@@ -112,18 +112,16 @@ public bool TryFindModuleByAddress(UAddress address, [NotNullWhen(true)] out UTr
112112
/// </summary>
113113
/// <param name="moduleID">The module ID.</param>
114114
/// <param name="assemblyId">The assembly ID.</param>
115-
/// <param name="filePath">The file path of the module.</param>
116-
/// <param name="baseAddress">The base address of the module.</param>
117-
/// <param name="codeSize">The size of the module.</param>
115+
/// <param name="moduleFilePath">The file path of the module.</param>
118116
/// <returns>The <see cref="UTraceManagedModule"/> instance.</returns>
119-
public UTraceManagedModule GetOrCreateManagedModule(long moduleID, long assemblyId, string filePath, UAddress baseAddress, USize codeSize)
117+
public UTraceManagedModule GetOrCreateManagedModule(long moduleID, long assemblyId, string moduleFilePath)
120118
{
121119
if (_mapModuleIDToManagedModule.TryGetValue(moduleID, out var managedModuleIndex))
122120
{
123121
return (UTraceManagedModule)List[managedModuleIndex];
124122
}
125-
var moduleFile = GetOrCreateModuleFile(filePath);
126-
var managedModule = new UTraceManagedModule(moduleID, assemblyId, moduleFile, baseAddress, codeSize);
123+
var moduleFile = GetOrCreateModuleFile(moduleFilePath);
124+
var managedModule = new UTraceManagedModule(moduleID, assemblyId, moduleFile);
127125
_mapModuleIDToManagedModule.Add(moduleID, List.Count);
128126
List.Add(managedModule);
129127
return managedModule;

src/Ultra.Core/Model/UTraceLoadedModule.cs src/Ultra.Core/Model/UTraceNativeModule.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ namespace Ultra.Core.Model;
77
/// <summary>
88
/// Represents a loaded module in the traced process.
99
/// </summary>
10-
public record UTraceLoadedModule(UTraceModuleFile ModuleFile, UAddress BaseAddress, USize CodeSize);
10+
public sealed record UTraceNativeModule(UTraceModuleFile ModuleFile, UAddress BaseAddress, USize CodeSize) : UTraceModule(ModuleFile);

src/Ultra.Core/Model/UTraceProcess.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace Ultra.Core.Model;
1111
/// <summary>
1212
/// Represents a process being traced.
1313
/// </summary>
14-
public class UTraceProcess
14+
public sealed class UTraceProcess
1515
{
1616
/// <summary>
1717
/// Gets or sets the process ID.
@@ -52,4 +52,4 @@ public class UTraceProcess
5252
/// Gets the list of call stacks in the traced process.
5353
/// </summary>
5454
public UCallStackList CallStacks { get; } = new();
55-
}
55+
}

src/Ultra.Core/Model/UTraceSession.cs

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// Copyright (c) Alexandre Mutel. All rights reserved.
2+
// Licensed under the BSD-Clause 2 license.
3+
// See license.txt file in the project root for full license information.
4+
5+
namespace Ultra.Core.Model;
6+
7+
/// <summary>
8+
/// Represents a session of tracing.
9+
/// </summary>
10+
public sealed class UTraceSession
11+
{
12+
/// <summary>
13+
/// Gets or sets the number of processor used for the session.
14+
/// </summary>
15+
public int NumberOfProcessors { get; set; }
16+
17+
/// <summary>
18+
/// Gets or sets the CPU speed in MHz.
19+
/// </summary>
20+
public int CpuSpeedMHz { get; set; }
21+
22+
/// <summary>
23+
/// Gets or sets the start time of the session.
24+
/// </summary>
25+
public DateTime StartTime { get; set; }
26+
27+
/// <summary>
28+
/// Gets or sets the duration of the session.
29+
/// </summary>
30+
public UTimeSpan Duration { get; set; }
31+
32+
/// <summary>
33+
/// Gets or sets the process being traced.
34+
/// </summary>
35+
public List<UTraceProcess> Processes { get; } = new();
36+
}

src/Ultra.Core/Model/UTraceThread.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Ultra.Core.Model;
99
/// <summary>
1010
/// Represents a thread in a traced process.
1111
/// </summary>
12-
public record UTraceThread(ulong ThreadID)
12+
public sealed record UTraceThread(ulong ThreadID)
1313
{
1414
private UnsafeList<UTraceSample> _samples = new(1024);
1515

src/Ultra.Core/Model/UTraceThreadList.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace Ultra.Core.Model;
1010
/// <summary>
1111
/// Represents a list of <see cref="UTraceThread"/> instances.
1212
/// </summary>
13-
public class UTraceThreadList : UGenericList<UTraceThread>
13+
public sealed class UTraceThreadList : UGenericList<UTraceThread>
1414
{
1515
private readonly Dictionary<ulong, int> _mapThreadIDToIndex = new();
1616

src/Ultra.Core/Parser/UltraEventPipeProcessor.cs

+30-6
Original file line numberDiff line numberDiff line change
@@ -137,24 +137,40 @@ private void ProcessMethodLoadVerbose(MethodLoadUnloadVerboseTraceData method)
137137

138138
private void ProcessModuleLoadUnload(ModuleLoadUnloadTraceData data, bool isLoad, bool isDCStartStop)
139139
{
140+
var module = _modules.GetOrCreateManagedModule(data.ModuleID, data.AssemblyID, data.ModuleILPath);
141+
142+
module.ModuleFile.SymbolUuid = data.ManagedPdbSignature;
143+
module.ModuleFile.SymbolFilePath = data.ManagedPdbBuildPath;
144+
145+
if (!isDCStartStop)
146+
{
147+
if (isLoad)
148+
{
149+
module.LoadTime = UTimeSpan.FromMilliseconds(data.TimeStampRelativeMSec);
150+
}
151+
else
152+
{
153+
module.UnloadTime = UTimeSpan.FromMilliseconds(data.TimeStampRelativeMSec);
154+
}
155+
}
140156
}
141157

142158
private void SamplerParserOnEventNativeModule(UltraNativeModuleTraceEvent evt)
143159
{
144160
if (evt.ModulePath is not null)
145161
{
146-
var module = _modules.GetOrCreateLoadedModule(evt.ModulePath, evt.LoadAddress, evt.Size);
162+
var module = _modules.GetOrCreateNativeModule(evt.LoadAddress, evt.Size, evt.ModulePath);
147163

148164
if (evt.NativeModuleEventKind == UltraSamplerNativeModuleEventKind.Unloaded)
149165
{
150166
// TODO: how to support remove?
151167
//_mapModuleNameToIndex.Remove(evt.ModulePath);
152-
module.ModuleFile.UnloadTime = UTimeSpan.FromMilliseconds(evt.TimeStampRelativeMSec);
168+
module.UnloadTime = UTimeSpan.FromMilliseconds(evt.TimeStampRelativeMSec);
153169
}
154170
else
155171
{
156172
module.ModuleFile.SymbolUuid = evt.Uuid;
157-
module.ModuleFile.LoadTime = UTimeSpan.FromMilliseconds(evt.TimeStampRelativeMSec);
173+
module.LoadTime = UTimeSpan.FromMilliseconds(evt.TimeStampRelativeMSec);
158174
}
159175
}
160176

@@ -192,7 +208,7 @@ private void PrintCallStack(UltraNativeCallstackTraceEvent callstackTraceEvent)
192208
//}
193209
}
194210

195-
public UTraceProcess Run()
211+
public UTraceSession Run()
196212
{
197213
// Run CLR if available
198214
_clrEventSource?.Process();
@@ -201,8 +217,16 @@ public UTraceProcess Run()
201217

202218
// Run sampler before CLR
203219
_samplerEventSource.Process();
204-
205-
return _process;
220+
221+
var session = new UTraceSession();
222+
session.Processes.Add(_process);
223+
224+
session.NumberOfProcessors = _samplerEventSource.NumberOfProcessors;
225+
session.StartTime = _samplerEventSource.SessionStartTime;
226+
session.Duration = _samplerEventSource.SessionDuration;
227+
session.CpuSpeedMHz = _samplerEventSource.CpuSpeedMHz;
228+
229+
return session;
206230
}
207231

208232
private ThreadSamplerState GetThreadSamplingState(ulong threadID)

0 commit comments

Comments
 (0)