@@ -1061,6 +1061,11 @@ protected virtual string DoCommand(string command, StatusBar worker, out Action
10611061 return DoCommand ( command , worker ) ;
10621062 }
10631063
1064+ protected virtual string DoCommand ( Uri commandUri , StatusBar worker , out Action continuation )
1065+ {
1066+ return DoCommand ( commandUri . LocalPath , worker , out continuation ) ;
1067+ }
1068+
10641069 public override void Open ( Window parentWindow , StatusBar worker , Action doAfter )
10651070 {
10661071 if ( Viewer == null )
@@ -1087,7 +1092,7 @@ public override void Open(Window parentWindow, StatusBar worker, Action doAfter)
10871092 Viewer . StatusBar . StartWork ( "Following Hyperlink" , delegate ( )
10881093 {
10891094 Action continuation ;
1090- var message = DoCommand ( e . Uri . LocalPath , Viewer . StatusBar , out continuation ) ;
1095+ var message = DoCommand ( e . Uri , Viewer . StatusBar , out continuation ) ;
10911096 Viewer . StatusBar . EndWork ( delegate ( )
10921097 {
10931098 if ( message != null )
@@ -3531,6 +3536,82 @@ protected override void WriteHtmlBody(TraceLog dataFile, TextWriter writer, stri
35313536 private Dictionary < int /*pid*/ , Microsoft . Diagnostics . Tracing . Analysis . TraceProcess > m_gcStats ;
35323537 }
35333538
3539+ public class PerfViewRuntimeLoaderStats : PerfViewHtmlReport
3540+ {
3541+ public PerfViewRuntimeLoaderStats ( PerfViewFile dataFile ) : base ( dataFile , "Runtime Loader" ) { }
3542+ protected override string DoCommand ( Uri commandUri , StatusBar worker , out Action continuation )
3543+ {
3544+ continuation = null ;
3545+
3546+ string command = commandUri . LocalPath ;
3547+ string textStr = "txt/" ;
3548+ string csvStr = "csv/" ;
3549+ bool text = command . StartsWith ( textStr ) ;
3550+ bool csv = command . StartsWith ( csvStr ) ;
3551+
3552+ if ( text || csv )
3553+ {
3554+ var rest = command . Substring ( textStr . Length ) ;
3555+
3556+
3557+ bool tree = true ;
3558+ List < string > filters = null ;
3559+ if ( ! String . IsNullOrEmpty ( commandUri . Query ) )
3560+ {
3561+ filters = new List < string > ( ) ;
3562+ tree = commandUri . Query . Contains ( "TreeView" ) ;
3563+ if ( commandUri . Query . Contains ( "JIT" ) )
3564+ filters . Add ( "JIT" ) ;
3565+ if ( commandUri . Query . Contains ( "R2R_Found" ) )
3566+ filters . Add ( "R2R_Found" ) ;
3567+ if ( commandUri . Query . Contains ( "R2R_Failed" ) )
3568+ filters . Add ( "R2R_Failed" ) ;
3569+ if ( commandUri . Query . Contains ( "TypeLoad" ) )
3570+ filters . Add ( "TypeLoad" ) ;
3571+ if ( commandUri . Query . Contains ( "AssemblyLoad" ) )
3572+ filters . Add ( "AssemblyLoad" ) ;
3573+ }
3574+ string identifier = $ "{ ( tree ? "Tree" : "Flat" ) } _";
3575+ if ( filters != null )
3576+ {
3577+ foreach ( var filter in filters )
3578+ {
3579+ identifier = identifier + "_" + filter ;
3580+ }
3581+ }
3582+
3583+ var startMSec = double . Parse ( rest . Substring ( rest . IndexOf ( ',' ) + 1 ) ) ;
3584+ var processId = int . Parse ( rest . Substring ( 0 , rest . IndexOf ( ',' ) ) ) ;
3585+ var processData = m_runtimeData . GetProcessDataFromProcessIDAndTimestamp ( processId , startMSec ) ;
3586+
3587+ var txtFile = CacheFiles . FindFile ( FilePath , ".runtimeLoaderstats." + processId . ToString ( ) + "_" + ( ( long ) startMSec ) . ToString ( ) + "_" + identifier + ( csv ? ".csv" : ".txt" ) ) ;
3588+ if ( ! File . Exists ( txtFile ) || File . GetLastWriteTimeUtc ( txtFile ) < File . GetLastWriteTimeUtc ( FilePath ) ||
3589+ File . GetLastWriteTimeUtc ( txtFile ) < File . GetLastWriteTimeUtc ( SupportFiles . MainAssemblyPath ) )
3590+ {
3591+ Stats . RuntimeLoaderStats . ToTxt ( txtFile , processData , filters . ToArray ( ) , tree ) ;
3592+ }
3593+ Command . Run ( Command . Quote ( txtFile ) , new CommandOptions ( ) . AddStart ( ) . AddTimeout ( CommandOptions . Infinite ) ) ;
3594+ System . Threading . Thread . Sleep ( 500 ) ; // Give it time to start a bit.
3595+ return "Opening Txt " + txtFile ;
3596+ }
3597+ return "Unknown command " + command ;
3598+ }
3599+
3600+ protected override void WriteHtmlBody ( TraceLog dataFile , TextWriter writer , string fileName , TextWriter log )
3601+ {
3602+ using ( var source = dataFile . Events . GetSource ( ) )
3603+ {
3604+ Microsoft . Diagnostics . Tracing . Analysis . TraceLoadedDotNetRuntimeExtensions . NeedLoadedDotNetRuntimes ( source ) ;
3605+ CLRRuntimeActivityComputer runtimeLoaderComputer = new CLRRuntimeActivityComputer ( source ) ;
3606+ source . Process ( ) ;
3607+ m_runtimeData = runtimeLoaderComputer . RuntimeLoaderData ;
3608+ Stats . ClrStats . ToHtml ( writer , Microsoft . Diagnostics . Tracing . Analysis . TraceProcessesExtensions . Processes ( source ) . ToList ( ) , fileName , "Runtime Loader" , Stats . ClrStats . ReportType . RuntimeLoader , true , runtimeOpsStats : m_runtimeData ) ;
3609+ }
3610+ }
3611+
3612+ private RuntimeLoaderStatsData m_runtimeData ;
3613+ }
3614+
35343615 public class PerfViewJitStats : PerfViewHtmlReport
35353616 {
35363617 public PerfViewJitStats ( PerfViewFile dataFile ) : base ( dataFile , "JITStats" ) { }
@@ -6921,6 +7002,9 @@ protected override Action<Action> OpenImpl(Window parentWindow, StatusBar worker
69217002 bool hasGCEvents = false ;
69227003 bool hasProjectNExecutionTracingEvents = false ;
69237004 bool hasDefenderEvents = false ;
7005+ bool hasTypeLoad = false ;
7006+ bool hasAssemblyLoad = false ;
7007+ bool hasJIT = false ;
69247008
69257009 var stackEvents = new List < TraceEventCounts > ( ) ;
69267010 foreach ( var counts in tracelog . Stats )
@@ -6981,6 +7065,19 @@ protected override Action<Action> OpenImpl(Window parentWindow, StatusBar worker
69817065 hasDefenderEvents = true ;
69827066 }
69837067
7068+ if ( name . StartsWith ( "Method/JittingStarted" ) )
7069+ {
7070+ hasJIT = true ;
7071+ }
7072+ if ( name . StartsWith ( "TypeLoad/Start" ) )
7073+ {
7074+ hasTypeLoad = true ;
7075+ }
7076+ if ( name . StartsWith ( "Loader/AssemblyLoad" ) )
7077+ {
7078+ hasAssemblyLoad = true ;
7079+ }
7080+
69847081 if ( counts . StackCount > 0 )
69857082 {
69867083 hasAnyStacks = true ;
@@ -7288,6 +7385,11 @@ protected override Action<Action> OpenImpl(Window parentWindow, StatusBar worker
72887385
72897386 advanced . Children . Add ( new PerfViewJitStats ( this ) ) ;
72907387
7388+ if ( hasJIT || hasAssemblyLoad || hasTypeLoad )
7389+ {
7390+ advanced . Children . Add ( new PerfViewRuntimeLoaderStats ( this ) ) ;
7391+ }
7392+
72917393 advanced . Children . Add ( new PerfViewEventStats ( this ) ) ;
72927394
72937395 m_Children . Add ( new PerfViewEventSource ( this ) ) ;
@@ -8420,6 +8522,8 @@ protected override Action<Action> OpenImpl(Window parentWindow, StatusBar worker
84208522
84218523 bool hasGC = false ;
84228524 bool hasJIT = false ;
8525+ bool hasTypeLoad = false ;
8526+ bool hasAssemblyLoad = false ;
84238527 if ( m_traceLog != null )
84248528 {
84258529 foreach ( TraceEventCounts eventStats in m_traceLog . Stats )
@@ -8432,6 +8536,14 @@ protected override Action<Action> OpenImpl(Window parentWindow, StatusBar worker
84328536 {
84338537 hasJIT = true ;
84348538 }
8539+ else if ( eventStats . EventName . StartsWith ( "TypeLoad/Start" ) )
8540+ {
8541+ hasTypeLoad = true ;
8542+ }
8543+ else if ( eventStats . EventName . StartsWith ( "Loader/AssemblyLoad" ) )
8544+ {
8545+ hasAssemblyLoad = true ;
8546+ }
84358547 }
84368548 }
84378549
@@ -8466,6 +8578,11 @@ protected override Action<Action> OpenImpl(Window parentWindow, StatusBar worker
84668578 {
84678579 advanced . AddChild ( new PerfViewJitStats ( this ) ) ;
84688580 }
8581+
8582+ if ( hasJIT || hasTypeLoad || hasAssemblyLoad )
8583+ {
8584+ advanced . AddChild ( new PerfViewRuntimeLoaderStats ( this ) ) ;
8585+ }
84698586 }
84708587
84718588 if ( memory . Children . Count > 0 )
@@ -8633,6 +8750,8 @@ protected override Action<Action> OpenImpl(Window parentWindow, StatusBar worker
86338750 bool hasGCAllocationTicks = false ;
86348751 bool hasObjectUpdate = false ;
86358752 bool hasMemAllocStacks = false ;
8753+ bool hasTypeLoad = false ;
8754+ bool hasAssemblyLoad = false ;
86368755 if ( m_traceLog != null )
86378756 {
86388757 foreach ( TraceEventCounts eventStats in m_traceLog . Stats )
@@ -8666,6 +8785,14 @@ protected override Action<Action> OpenImpl(Window parentWindow, StatusBar worker
86668785 {
86678786 hasMemAllocStacks = true ;
86688787 }
8788+ else if ( eventStats . EventName . StartsWith ( "TypeLoad/Start" ) )
8789+ {
8790+ hasTypeLoad = true ;
8791+ }
8792+ else if ( eventStats . EventName . StartsWith ( "Loader/AssemblyLoad" ) )
8793+ {
8794+ hasAssemblyLoad = true ;
8795+ }
86698796 }
86708797 }
86718798
@@ -8712,6 +8839,11 @@ protected override Action<Action> OpenImpl(Window parentWindow, StatusBar worker
87128839 {
87138840 advanced . AddChild ( new PerfViewJitStats ( this ) ) ;
87148841 }
8842+
8843+ if ( hasJIT || hasTypeLoad || hasAssemblyLoad )
8844+ {
8845+ advanced . AddChild ( new PerfViewRuntimeLoaderStats ( this ) ) ;
8846+ }
87158847 }
87168848
87178849 if ( memory . Children . Count > 0 )
0 commit comments