Skip to content

Commit fd385d6

Browse files
committed
It buidls but doesn't work
1 parent d483418 commit fd385d6

File tree

5 files changed

+551
-3
lines changed

5 files changed

+551
-3
lines changed

src/PerfView/PerfViewData.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4295,6 +4295,10 @@ protected internal override StackSource OpenStackSourceImpl(string streamName, T
42954295
{
42964296
return eventLog.ThreadTimeStacks();
42974297
}
4298+
else if (streamName == "Runtime Operations (Thread Time)")
4299+
{
4300+
return eventLog.RuntimeOperationsStacks();
4301+
}
42984302
else if (streamName == "Processes / Files / Registry")
42994303
{
43004304
return GetProcessFileRegistryStackSource(eventSource, log);
@@ -7288,6 +7292,11 @@ protected override Action<Action> OpenImpl(Window parentWindow, StatusBar worker
72887292

72897293
advanced.Children.Add(new PerfViewJitStats(this));
72907294

7295+
if (hasCPUStacks)
7296+
{
7297+
advanced.Children.Add(new PerfViewStackSource(this, "Runtime Operations (Thread Time)"));
7298+
}
7299+
72917300
advanced.Children.Add(new PerfViewEventStats(this));
72927301

72937302
m_Children.Add(new PerfViewEventSource(this));

src/PerfView/UserCommands.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,6 +1873,48 @@ public static MutableTraceEventStackSource ThreadTimeStacks(this TraceLog eventL
18731873

18741874
return stackSource;
18751875
}
1876+
1877+
public static MutableTraceEventStackSource RuntimeOperationsStacks(this TraceLog eventLog, TraceProcess process = null, Predicate<TraceEvent> predicate = null)
1878+
{
1879+
TraceEvents events;
1880+
if (process == null)
1881+
{
1882+
events = eventLog.Events.Filter((x) => ((predicate == null) || predicate(x)) && x is SampledProfileTraceData && x.ProcessID != 0);
1883+
}
1884+
else
1885+
{
1886+
events = process.EventsInProcess.Filter((x) => ((predicate == null) || predicate(x)) && x is SampledProfileTraceData);
1887+
}
1888+
1889+
var stackSource = new MutableTraceEventStackSource(eventLog);
1890+
stackSource.ShowUnknownAddresses = App.CommandLineArgs.ShowUnknownAddresses;
1891+
1892+
StackSourceSample sample = new StackSourceSample(stackSource);
1893+
foreach (var event_ in ((IEnumerable<TraceEvent>)events))
1894+
{
1895+
sample.TimeRelativeMSec = event_.TimeStampRelativeMSec;
1896+
sample.StackIndex = stackSource.GetCallStack(event_.CallStackIndex(), event_);
1897+
stackSource.AddSample(sample);
1898+
};
1899+
stackSource.DoneAddingSamples();
1900+
1901+
1902+
/*
1903+
var stackSource = new MutableTraceEventStackSource(eventLog);
1904+
stackSource.ShowUnknownAddresses = App.CommandLineArgs.ShowUnknownAddresses;
1905+
1906+
var computer = new ThreadTimeStackComputer(eventLog, App.GetSymbolReader(eventLog.FilePath));
1907+
computer.ExcludeReadyThread = true;
1908+
computer.GenerateThreadTimeStacks(stackSource);*/
1909+
1910+
CLRRuntimeActivityComputer runtimeOperationsComputer = new CLRRuntimeActivityComputer(eventLog.Events.GetSource());
1911+
1912+
var finalStackSource = new MutableTraceEventStackSource(eventLog);
1913+
StartStopStackMingledComputer mingledComputer = new StartStopStackMingledComputer(finalStackSource, stackSource, eventLog.Events.GetSource(), runtimeOperationsComputer.StartStopEvents);
1914+
1915+
return finalStackSource;
1916+
}
1917+
18761918
public static MutableTraceEventStackSource ThreadTimeWithReadyThreadStacks(this TraceLog eventLog, TraceProcess process = null)
18771919
{
18781920
var stackSource = new MutableTraceEventStackSource(eventLog);
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved
2+
// This file is best viewed using outline mode (Ctrl-M Ctrl-O)
3+
//
4+
// This program uses code hyperlinks available as part of the HyperAddin Visual Studio plug-in.
5+
// It is available from http://www.codeplex.com/hyperAddin
6+
// using Microsoft.Diagnostics.Tracing.Parsers;
7+
using Microsoft.Diagnostics.Tracing.Etlx;
8+
using Microsoft.Diagnostics.Tracing.Parsers;
9+
using Microsoft.Diagnostics.Tracing.Parsers.ApplicationServer;
10+
using Microsoft.Diagnostics.Tracing.Parsers.AspNet;
11+
using Microsoft.Diagnostics.Tracing.Parsers.Clr;
12+
using Microsoft.Diagnostics.Tracing.Session;
13+
using Microsoft.Diagnostics.Tracing.Stacks;
14+
using Microsoft.Diagnostics.Tracing.Analysis.JIT;
15+
using System;
16+
using System.Collections.Generic;
17+
using System.Diagnostics;
18+
using System.Text;
19+
using StartStopKey = System.Guid; // The start-stop key is unique in the trace. We incorperate the process as well as activity ID to achieve this.
20+
21+
namespace Microsoft.Diagnostics.Tracing
22+
{
23+
public class CLRRuntimeActivityComputer
24+
{
25+
struct IdOfIncompleteAction : IEquatable<IdOfIncompleteAction>
26+
{
27+
public long Identifier;
28+
public int ThreadID;
29+
30+
public override int GetHashCode()
31+
{
32+
return Identifier.GetHashCode();
33+
}
34+
35+
public override bool Equals(object obj)
36+
{
37+
if (!(obj is IdOfIncompleteAction))
38+
return false;
39+
40+
return Equals((IdOfIncompleteAction)obj);
41+
}
42+
43+
public bool Equals(IdOfIncompleteAction other)
44+
{
45+
return (Identifier == other.Identifier) && (ThreadID == other.ThreadID);
46+
}
47+
}
48+
49+
struct IncompleteActionDesc
50+
{
51+
public StartStopStackMingledComputer.EventUID Start;
52+
public string Name;
53+
}
54+
55+
Dictionary<IdOfIncompleteAction, IncompleteActionDesc> _incompleteJitEvents = new Dictionary<IdOfIncompleteAction, IncompleteActionDesc>();
56+
Dictionary<int, List<StartStopStackMingledComputer.StartStopThreadEventData>> _parsedData = new Dictionary<int, List<StartStopStackMingledComputer.StartStopThreadEventData>>();
57+
58+
public Dictionary<int, List<StartStopStackMingledComputer.StartStopThreadEventData>> StartStopEvents => _parsedData;
59+
60+
public CLRRuntimeActivityComputer(TraceLogEventSource source)
61+
{
62+
source.Clr.MethodJittingStarted += Clr_MethodJittingStarted;
63+
source.Clr.MethodLoadVerbose += Clr_MethodLoadVerbose;
64+
source.Clr.MethodLoad += Clr_MethodLoad;
65+
source.Process();
66+
source.Clr.MethodJittingStarted -= Clr_MethodJittingStarted;
67+
source.Clr.MethodLoadVerbose -= Clr_MethodLoadVerbose;
68+
source.Clr.MethodLoad -= Clr_MethodLoad;
69+
}
70+
71+
private void Clr_MethodLoad(MethodLoadUnloadTraceData obj)
72+
{
73+
MethodJittedEvent(obj, obj.MethodID);
74+
}
75+
76+
private void Clr_MethodLoadVerbose(MethodLoadUnloadVerboseTraceData obj)
77+
{
78+
MethodJittedEvent(obj, obj.MethodID);
79+
}
80+
81+
private void MethodJittedEvent(TraceEvent evt, long methodID)
82+
{
83+
IdOfIncompleteAction id = new IdOfIncompleteAction();
84+
id.Identifier = methodID;
85+
id.ThreadID = evt.ThreadID;
86+
if (_incompleteJitEvents.TryGetValue(id, out IncompleteActionDesc jitStartData))
87+
{
88+
// JitStart is processed, don't process it again.
89+
_incompleteJitEvents.Remove(id);
90+
91+
if (!_parsedData.ContainsKey(id.ThreadID))
92+
_parsedData[id.ThreadID] = new List<StartStopStackMingledComputer.StartStopThreadEventData>();
93+
94+
List<StartStopStackMingledComputer.StartStopThreadEventData> startStopData = _parsedData[id.ThreadID];
95+
startStopData.Add(new StartStopStackMingledComputer.StartStopThreadEventData(jitStartData.Start, new StartStopStackMingledComputer.EventUID(evt), jitStartData.Name));
96+
}
97+
}
98+
99+
private void Clr_MethodJittingStarted(MethodJittingStartedTraceData obj)
100+
{
101+
IncompleteActionDesc incompleteDesc = new IncompleteActionDesc();
102+
incompleteDesc.Start = new StartStopStackMingledComputer.EventUID(obj);
103+
incompleteDesc.Name = JITStats.GetMethodName(obj);
104+
105+
IdOfIncompleteAction id = new IdOfIncompleteAction();
106+
id.Identifier = obj.MethodID;
107+
id.ThreadID = obj.ThreadID;
108+
109+
_incompleteJitEvents[id] = incompleteDesc;
110+
}
111+
}
112+
}

0 commit comments

Comments
 (0)