@@ -282,9 +282,12 @@ public FirefoxProfiler.Profile Convert(string traceFilePath, List<int> processId
282282
283283 var threadVisited = new HashSet < int > ( ) ;
284284
285+ var processName = $ "{ process . Name } ({ process . ProcessID } )";
286+
285287 // Add threads
286- foreach ( var thread in threads )
288+ for ( var threadIndex = 0 ; threadIndex < threads . Count ; threadIndex ++ )
287289 {
290+ var thread = threads [ threadIndex ] ;
288291 // Skip threads that have already been visited
289292 // TODO: for some reasons we have some threads that are duplicated?
290293 if ( ! threadVisited . Add ( thread . ThreadID ) )
@@ -301,9 +304,15 @@ public FirefoxProfiler.Profile Convert(string traceFilePath, List<int> processId
301304 gcSuspendEEEvents . Clear ( ) ;
302305 gcRestartEEEvents . Clear ( ) ;
303306
307+ var threadBaseName = thread . ThreadInfo is not null
308+ ? $ "{ thread . ThreadInfo } ({ thread . ThreadID } )"
309+ : $ "Thread ({ thread . ThreadID } )";
310+ var threadName = $ "{ threadIndex } - { threadBaseName } ";
311+
304312 var profileThread = new FirefoxProfiler . Thread
305313 {
306- Name = thread . ThreadInfo is not null ? $ "{ thread . ThreadInfo } ({ thread . ThreadID } )" : $ "Thread ({ thread . ThreadID } )",
314+ Name = threadName ,
315+ ProcessName = processName ,
307316 ProcessStartupTime = thread . StartTimeRelativeMSec ,
308317 RegisterTime = thread . StartTimeRelativeMSec ,
309318 ProcessShutdownTime = thread . EndTimeRelativeMSec ,
@@ -323,26 +332,26 @@ public FirefoxProfiler.Profile Convert(string traceFilePath, List<int> processId
323332 samples . TimeDeltas = new List < double > ( ) ;
324333 samples . WeightType = "samples" ;
325334
326- const TraceEventID GCStartEventID = ( TraceEventID ) 1 ;
327- const TraceEventID GCStopEventID = ( TraceEventID ) 2 ;
328- const TraceEventID GCRestartEEStopEventID = ( TraceEventID ) 3 ;
329- const TraceEventID GCHeapStatsEventID = ( TraceEventID ) 4 ;
330- const TraceEventID GCCreateSegmentEventID = ( TraceEventID ) 5 ;
331- const TraceEventID GCFreeSegmentEventID = ( TraceEventID ) 6 ;
332- const TraceEventID GCRestartEEStartEventID = ( TraceEventID ) 7 ;
333- const TraceEventID GCSuspendEEStopEventID = ( TraceEventID ) 8 ;
334- const TraceEventID GCSuspendEEStartEventID = ( TraceEventID ) 9 ;
335- const TraceEventID GCAllocationTickEventID = ( TraceEventID ) 10 ;
335+ const TraceEventID GCStartEventID = ( TraceEventID ) 1 ;
336+ const TraceEventID GCStopEventID = ( TraceEventID ) 2 ;
337+ const TraceEventID GCRestartEEStopEventID = ( TraceEventID ) 3 ;
338+ const TraceEventID GCHeapStatsEventID = ( TraceEventID ) 4 ;
339+ const TraceEventID GCCreateSegmentEventID = ( TraceEventID ) 5 ;
340+ const TraceEventID GCFreeSegmentEventID = ( TraceEventID ) 6 ;
341+ const TraceEventID GCRestartEEStartEventID = ( TraceEventID ) 7 ;
342+ const TraceEventID GCSuspendEEStopEventID = ( TraceEventID ) 8 ;
343+ const TraceEventID GCSuspendEEStartEventID = ( TraceEventID ) 9 ;
344+ const TraceEventID GCAllocationTickEventID = ( TraceEventID ) 10 ;
336345
337346 double startTime = 0 ;
338347 int currentThread = - 1 ;
339348 double switchTimeInMsec = 0.0 ;
340349 //double switchTimeOutMsec = 0.0;
341350 foreach ( var evt in thread . EventsInThread )
342351 {
343- if ( evt . Opcode != ( TraceEventOpcode ) 46 )
352+ if ( evt . Opcode != ( TraceEventOpcode ) 46 )
344353 {
345- if ( evt . Opcode == ( TraceEventOpcode ) 0x24 && evt is CSwitchTraceData switchTraceData )
354+ if ( evt . Opcode == ( TraceEventOpcode ) 0x24 && evt is CSwitchTraceData switchTraceData )
346355 {
347356 if ( evt . ThreadID == thread . ThreadID && switchTraceData . OldThreadID != thread . ThreadID )
348357 {
@@ -371,15 +380,18 @@ public FirefoxProfiler.Profile Convert(string traceFilePath, List<int> processId
371380
372381 var jitCompile = new JitCompileEvent
373382 {
374- FullName = $ "{ methodJittingStarted . MethodNamespace } .{ methodJittingStarted . MethodName } { signature } ",
383+ FullName =
384+ $ "{ methodJittingStarted . MethodNamespace } .{ methodJittingStarted . MethodName } { signature } ",
375385 MethodILSize = methodJittingStarted . MethodILSize
376386 } ;
377387
378- jitCompilePendingMethodId [ methodJittingStarted . MethodID ] = ( jitCompile , evt . TimeStampRelativeMSec ) ;
388+ jitCompilePendingMethodId [ methodJittingStarted . MethodID ] =
389+ ( jitCompile , evt . TimeStampRelativeMSec ) ;
379390 }
380391 else if ( evt is MethodLoadUnloadTraceDataBase methodLoadUnloadVerbose )
381392 {
382- if ( jitCompilePendingMethodId . TryGetValue ( methodLoadUnloadVerbose . MethodID , out var jitCompilePair ) )
393+ if ( jitCompilePendingMethodId . TryGetValue ( methodLoadUnloadVerbose . MethodID ,
394+ out var jitCompilePair ) )
383395 {
384396 jitCompilePendingMethodId . Remove ( methodLoadUnloadVerbose . MethodID ) ;
385397
@@ -435,7 +447,7 @@ public FirefoxProfiler.Profile Convert(string traceFilePath, List<int> processId
435447 markers . Category . Add ( CategoryGC ) ;
436448 markers . Phase . Add ( FirefoxProfiler . MarkerPhase . Instance ) ;
437449 markers . ThreadId . Add ( profileThreadIndex ) ;
438- markers . Name . Add ( GetFirefoxString ( $ "GC Alloc ({ thread . ThreadID } )", profileThread ) ) ;
450+ markers . Name . Add ( GetFirefoxString ( $ "{ threadIndex } - GC Alloc ({ thread . ThreadID } )", profileThread ) ) ;
439451
440452 var allocationTickEvent = new GCAllocationTickEvent
441453 {
@@ -490,7 +502,8 @@ public FirefoxProfiler.Profile Convert(string traceFilePath, List<int> processId
490502
491503 gcSuspendEEEvents . Push ( ( evt . TimeStampRelativeMSec , gcSuspendEEEvent ) ) ;
492504 }
493- else if ( evt . ID == GCSuspendEEStopEventID && evt is GCNoUserDataTraceData && gcSuspendEEEvents . Count > 0 )
505+ else if ( evt . ID == GCSuspendEEStopEventID && evt is GCNoUserDataTraceData &&
506+ gcSuspendEEEvents . Count > 0 )
494507 {
495508 var ( gcSuspendEEEventStartTime , gcSuspendEEEvent ) = gcSuspendEEEvents . Pop ( ) ;
496509
@@ -507,7 +520,8 @@ public FirefoxProfiler.Profile Convert(string traceFilePath, List<int> processId
507520 {
508521 gcRestartEEEvents . Push ( evt . TimeStampRelativeMSec ) ;
509522 }
510- else if ( evt . ID == GCRestartEEStopEventID && evt is GCNoUserDataTraceData && gcRestartEEEvents . Count > 0 )
523+ else if ( evt . ID == GCRestartEEStopEventID && evt is GCNoUserDataTraceData &&
524+ gcRestartEEEvents . Count > 0 )
511525 {
512526 var gcRestartEEEventStartTime = gcRestartEEEvents . Pop ( ) ;
513527
@@ -545,15 +559,16 @@ public FirefoxProfiler.Profile Convert(string traceFilePath, List<int> processId
545559 var deltaTime = evt . TimeStampRelativeMSec - startTime ;
546560 samples . TimeDeltas . Add ( deltaTime ) ;
547561 samples . Stack . Add ( firefoxCallStackIndex ) ;
548- var cpuDeltaMs = ( long ) ( ( evt . TimeStampRelativeMSec - switchTimeInMsec ) * 1_000_000.0 ) ;
562+ var cpuDeltaMs = ( long ) ( ( evt . TimeStampRelativeMSec - switchTimeInMsec ) * 1_000_000.0 ) ;
549563 if ( cpuDeltaMs > 0 )
550564 {
551- samples . ThreadCPUDelta . Add ( ( int ) cpuDeltaMs ) ;
565+ samples . ThreadCPUDelta . Add ( ( int ) cpuDeltaMs ) ;
552566 }
553567 else
554568 {
555569 samples . ThreadCPUDelta . Add ( 0 ) ;
556570 }
571+
557572 switchTimeInMsec = evt . TimeStampRelativeMSec ;
558573 samples . Length ++ ;
559574 startTime = evt . TimeStampRelativeMSec ;
@@ -599,6 +614,14 @@ public FirefoxProfiler.Profile Convert(string traceFilePath, List<int> processId
599614
600615 long previousTotalHeapSize = 0 ;
601616
617+ // Bug in Memory, they discard the first sample
618+ // and it is then not recording the first TotalHeapSize which is the initial value
619+ // So we force to create a dummy empty entry
620+ // https://github.com/firefox-devtools/profiler/blob/e9fe870f2a85b1c8771b1d671eb316bd1f5723ec/src/profile-logic/profile-data.js#L1732-L1753
621+ gcHeapStatsCounter . Samples . Time ! . Add ( 0 ) ;
622+ gcHeapStatsCounter . Samples . Count . Add ( 0 ) ;
623+ gcHeapStatsCounter . Samples . Length ++ ;
624+
602625 foreach ( var evt in gcHeapStatsEvents )
603626 {
604627 gcHeapStatsCounter . Samples . Time ! . Add ( evt . Item1 ) ;
0 commit comments