public void CallTreeNodeToTextConverter_HandlesMessageAndSnippet() { string snippet = " int x = 42;"; string message = "my_function"; var callTreeNode = new CallTreeNode { Location = new ThreadFlowLocation { Location = new Location { Message = new Message { Text = message }, PhysicalLocation = new PhysicalLocation { Region = new Region { StartLine = 42, Snippet = new ArtifactContent { Text = snippet } } } } } }; VerifyConversion(callTreeNode, message); }
public void CallTreeNodeToTextConverter_HandlesNullSnippet() { string snippet = null; string sourceFile = @"file:///c:/dir1/dir%202\source%20file.cpp"; var callTreeNode = new CallTreeNode { Location = new AnnotatedCodeLocation { Kind = AnnotatedCodeLocationKind.Call, Snippet = snippet, Target = "my_function", PhysicalLocation = new PhysicalLocation { Uri = new System.Uri(sourceFile), Region = new Region { StartLine = 42 } } } }; VerifyConversion(callTreeNode, "my_function"); }
public void CallTreeNodeToTextConverter_HandlesRegionSnippet() { string snippet = " int x = 42;"; var callTreeNode = new CallTreeNode { Location = new ThreadFlowLocation { Location = new Location { PhysicalLocation = new PhysicalLocation { Region = new Region { StartLine = 42, Snippet = new ArtifactContent { Text = snippet } } } } } }; VerifyConversion(callTreeNode, snippet.Trim()); }
public void CallTreeNodeToTextConverter_HandlesNullMessage() { string snippet = " contentStores[0] = contentStores[index];"; string message = null; string sourceFile = @"file:///c:/dir1/dir%202\source%20file.cpp"; var callTreeNode = new CallTreeNode { Location = new AnnotatedCodeLocation { Kind = AnnotatedCodeLocationKind.Call, Snippet = snippet, Message = message, Target = "my_function", PhysicalLocation = new PhysicalLocation { Uri = new System.Uri(sourceFile), Region = new Region { StartLine = 42 } } } }; VerifyConversion(callTreeNode, snippet.Trim()); }
CallTreeNode GetStateMachineNode(StateMachine sm, Stack <object> stack) { if (!stack.Contains(sm)) { stack.Push(sm); var rootNode = new CallTreeNode(sm, CallTreeNodeType.StateMachine, sm.gameObject.name); var type = sm.GetType(); foreach (var field in type.GetFields()) { // Find Fields that are State[] if (field.FieldType.IsAssignableFrom(typeof(State[]))) { // Add Callables from this Callable[] array var value = (State[])field.GetValue(sm); foreach (var state in value) { if (state != null) { rootNode.Children.Add(GetStateNode(state, stack)); } else { AddErroneous(rootNode.Target); } } } } return(rootNode); } else { return(new CallTreeNode(sm, GetType(sm), $"RECURSED :{sm.gameObject.name}")); } }
public TreeNode(CallTreeNode template) { if (template == null) { ThrowHelper.ThrowArgumentNullException(nameof(template)); } this.ParentContextId = string.Empty; this.Id = template.Name; this.ParentId = string.Empty; this.ContextId = this.Id; this.Name = template.Name; this.InclusiveMetric = template.InclusiveMetric; this.InclusiveCount = template.InclusiveCount; this.ExclusiveMetric = template.ExclusiveMetric; this.ExclusiveCount = template.ExclusiveCount; this.ExclusiveFoldedMetric = template.ExclusiveFoldedMetric; this.ExclusiveFoldedCount = template.ExclusiveFoldedCount; this.InclusiveMetricByTimeString = template.InclusiveMetricByTimeString; this.FirstTimeRelativeMSec = template.FirstTimeRelativeMSec; this.LastTimeRelativeMSec = template.LastTimeRelativeMSec; this.InclusiveMetricPercent = template.InclusiveMetric * 100 / template.CallTree.PercentageBasis; this.ExclusiveMetricPercent = template.ExclusiveMetric * 100 / template.CallTree.PercentageBasis; this.ExclusiveFoldedMetricPercent = template.ExclusiveFoldedMetric * 100 / template.CallTree.PercentageBasis; this.HasChildren = template.HasChildren; this.BackingNode = template; this.backingNodeWithChildren = template; }
// Iterates through CallTreeNodes in preorder (parent first, then children), this 'flattens' the tree. private CallTreeNode NextNode(CallTreeNode node) { // After me is my first child (if it exists) // In the search, we assume that graph nodes have no children. This avoids infinite search. if (!node.IsGraphNode) { var callees = DisplayCallees(node); if (callees != null && callees.Count > 0) { return(callees[0]); } } // Otherwise it is my next sibling while (node != null) { var nextSibling = NextSibling(node); if (nextSibling != null) { return(nextSibling); } node = node.Caller; } return(null); }
CallTreeNode GetStateNode(State st, Stack <object> stack) { if (!stack.Contains(st)) { stack.Push(st); var rootNode = new CallTreeNode(st, CallTreeNodeType.State, st.gameObject.name); var type = st.GetType(); foreach (var field in type.GetFields()) { // Find Fields that are Callable[] if (field.FieldType.IsAssignableFrom(typeof(Callable[]))) { var node = new CallTreeNode(st, CallTreeNodeType.Callable, field.Name); rootNode.Children.Add(node); // Add Callables from this Callable[] array var value = (Callable[])field.GetValue(st); foreach (var call in value) { node.Children.Add(GetNode(call, stack)); } } } return(rootNode); } else { return(new CallTreeNode(st, GetType(st), $"RECURSED :{st.gameObject.name}")); } }
public void CallTree_TryGetPreviousSibling_SkipNonVisibleNodes() { List <CallTreeNode> list = new List <CallTreeNode>(); CallTreeNode target = new CallTreeNode(); list.Add(new CallTreeNode() { FilePath = Expected }); list.Add(new CallTreeNode() { Visibility = Visibility.Collapsed }); list.Add(new CallTreeNode() { Visibility = Visibility.Hidden }); list.Add(target); list.Add(new CallTreeNode()); CallTreeNode resultNode; bool result = CallTree.TryGetPreviousSibling(list, target, out resultNode); result.Should().BeTrue(); resultNode.FilePath.Should().Be(Expected); }
private static void Swap(ref CallTreeNode node1, ref CallTreeNode node2) { CallTreeNode temp = node1; node1 = node2; node2 = temp; }
CallTreeNode GetCallableNode(Callable c, Stack <object> stack) { if (!stack.Contains(c)) { stack.Push(c); var rootNode = new CallTreeNode(c, GetType(c), $"{c.Name} ({c.gameObject.name} : {c.GetType().Name})"); var type = c.GetType(); foreach (var field in type.GetFields()) { // Find Fields that are Callable[] if (field.FieldType.IsAssignableFrom(typeof(Callable[]))) { var node = new CallTreeNode(c, CallTreeNodeType.Callable, field.Name); var value = (Callable[])field.GetValue(c); if (value != null && value.Length > 0) { rootNode.Children.Add(node); // Add Callables from this Callable[] array foreach (var call in value) { node.Children.Add(GetCallableNode(call, stack)); } } } } return(rootNode); } else { return(new CallTreeNode(c, GetType(c), $"RECURSED : {c.Name} ({c.gameObject.name} : {c.GetType().Name})")); } }
public void CallTreeNodeToTextConverter_HandlesNullMessage() { string snippet = " int x = 42;"; string message = null; var callTreeNode = new CallTreeNode { Location = new ThreadFlowLocation { Location = new Location { Message = new Message { Text = message }, PhysicalLocation = new PhysicalLocation { Region = new Region { StartLine = 42, Snippet = new FileContent { Text = snippet } } } } } }; VerifyConversion(callTreeNode, snippet.Trim()); }
public void Dump(int indent) { for (int i = 0; i < indent; i++) { Console.Write(" "); } if (TracepointAnalysis.AddRefReleaseDeltasCalculated) { string deltaPrefix = this.Function.DeltaValue > 0 ? "+" : string.Empty; Console.WriteLine("{0} (Hit Count = {1}; Delta = {2}{3})", this.Function.Name, this.m_hitCount, deltaPrefix, this.Function.DeltaValue); } else { Console.WriteLine("{0} ({1})", this.Function.Name, this.m_hitCount); } CallTreeNode[] children = new CallTreeNode[this.Children.Count]; this.Children.Values.CopyTo(children, 0); Array.Sort <CallTreeNode>(children, new HitCountSorter()); foreach (CallTreeNode child in children) { child.Dump(indent + 1); } }
public TreeNode(CallTreeNode template) { if (template == null) { ThrowHelper.ThrowArgumentNullException(nameof(template)); } this.Path = string.Empty; this.Base64EncodedId = Base64UrlTextEncoder.Encode(Encoding.UTF8.GetBytes(template.Name)); this.Name = template.Name; this.InclusiveMetric = template.InclusiveMetric.ToString("N3"); this.InclusiveCount = template.InclusiveCount.ToString("N0"); this.ExclusiveMetric = template.ExclusiveMetric.ToString("N3"); this.ExclusiveCount = template.ExclusiveCount.ToString("N0"); this.ExclusiveFoldedMetric = template.ExclusiveFoldedMetric.ToString("N0"); this.ExclusiveFoldedCount = template.ExclusiveFoldedCount.ToString("N0"); this.InclusiveMetricByTimeString = template.InclusiveMetricByTimeString; this.FirstTimeRelativeMSec = template.FirstTimeRelativeMSec.ToString("N3"); this.LastTimeRelativeMSec = template.LastTimeRelativeMSec.ToString("N3"); this.InclusiveMetricPercent = (template.InclusiveMetric * 100 / template.CallTree.PercentageBasis).ToString("N2"); this.ExclusiveMetricPercent = (template.ExclusiveMetric * 100 / template.CallTree.PercentageBasis).ToString("N2"); this.ExclusiveFoldedMetricPercent = (template.ExclusiveFoldedMetric * 100 / template.CallTree.PercentageBasis).ToString("N2"); this.HasChildren = template.HasChildren; this.BackingNode = template; this.backingNodeWithChildren = template; }
/// <summary> /// Computes the AddRef/Release delta (CountOf(AddRef callstacks)-CountOf(Release callstacks)) for each function /// in the call tree. Call tree display will then include this information. /// </summary> /// <param name="callTreeRoots"></param> public static void ComputeAddRefReleaseDeltas(List <CallTreeNode> callTreeRoots) { if (AddRefReleaseDeltasCalculated) { throw new InvalidOperationException("Deltas already calculated"); } AddRefReleaseDeltasCalculated = true; if (callTreeRoots.Count != 2) { throw new ArgumentException("Call tree should have two root nodes - one for AddRef, one for Release"); } CallTreeNode addRefNode = callTreeRoots[0]; CallTreeNode releaseNode = callTreeRoots[1]; if (!IsAddRefOrReleaseNode(addRefNode, "AddRef")) { Swap(ref addRefNode, ref releaseNode); } if (!IsAddRefOrReleaseNode(addRefNode, "AddRef") || !IsAddRefOrReleaseNode(releaseNode, "Release")) { throw new ArgumentException("Call tree should have two root nodes - one for AddRef, one for Release"); } ApplyDelta(addRefNode, 1, false, callTreeRoots); ApplyDelta(releaseNode, -1, false, callTreeRoots); }
private static string MakeDisplayString(CallTreeNode node) { // Use the following preferences for the CallTreeNode text. // 1. CodeFlowLocation.Location.Message.Text // 2. CodeFlowLocation.Location.PhysicalLocation.Region.Snippet.Text // 3. "Continuing" string text = string.Empty; CodeFlowLocation codeFlowLocation = node.Location; if (codeFlowLocation != null) { if (!String.IsNullOrWhiteSpace(codeFlowLocation.Location?.Message?.Text)) { text = codeFlowLocation.Location.Message.Text; } else if (!String.IsNullOrWhiteSpace(codeFlowLocation.Location?.PhysicalLocation?.Region?.Snippet?.Text)) { text = codeFlowLocation.Location.PhysicalLocation.Region.Snippet.Text.Trim(); } else { text = Resources.ContinuingCallTreeNodeMessage; } } return(text); }
private void BuildNode(List <TreeViewItem> items, CallTreeNode callTree, int depth) { var id = items.Count; items.Add(new TreeViewItem { id = id, depth = depth, displayName = callTree.GetPrettyName(true) }); m_CallTreeDictionary.Add(id, callTree); // if the tree is too deep, serialization will exceed the 7 levels limit. if (!callTree.HasValidChildren()) { items.Add(new TreeViewItem { id = id + 1, depth = depth + 1, displayName = "<Serialization Limit>" }); } else { for (int i = 0; i < callTree.GetNumChildren(); i++) { BuildNode(items, callTree.GetChild(i), depth + 1); } } }
/// <summary> /// I did not make this a property because it is too profound an operation (heavy) /// This sets the root of the tree. This is how you change the display to a new tree. /// </summary> public void SetRoot(CallTreeNode root) { List <CallTreeViewNode> newFlattenedTree = new List <CallTreeViewNode>(); newFlattenedTree.Add(new CallTreeViewNode(this, root, 0)); // Copy over the nodes to the new flattened tree (as best we can) if (m_flattenedTree.Count > 0 && m_flattenedTree[0].Data.DisplayName == root.DisplayName) { CallTreeViewNode.CopyExpandedStateForNode(newFlattenedTree, 0, m_flattenedTree, 0); } // Destroy old nodes (to save memory because GUI keeps references to them) foreach (var node in m_flattenedTree) { node.Dispose(); } // Update the whole tree with the new tree. m_flattenedTree.ReplaceRange(0, m_flattenedTree.Count, newFlattenedTree); Validate(); m_root = root; m_curPosition = null; m_endPosition = null; // Expand the root element var rootView = InsureVisible(m_root); rootView.IsExpanded = true; }
public TreeNode(CallTreeNode template) { if (template == null) { ThrowHelper.ThrowArgumentNullException(nameof(template)); } this.ParentContextId = string.Empty; this.Id = template.Name; this.ParentId = string.Empty; this.ParentNode = null; this.ContextId = this.Id; this.Name = template.Name; this.FindFlag = string.Empty; this.Visited = false; this.InclusiveMetric = template.InclusiveMetric; this.InclusiveCount = template.InclusiveCount; this.ExclusiveMetric = template.ExclusiveMetric; this.ExclusiveCount = template.ExclusiveCount; this.ExclusiveFoldedMetric = template.ExclusiveFoldedMetric; this.ExclusiveFoldedCount = template.ExclusiveFoldedCount; this.FirstTimeRelativeMSec = template.FirstTimeRelativeMSec; this.LastTimeRelativeMSec = template.LastTimeRelativeMSec; this.InclusiveMetricPercent = template.InclusiveMetric * 100 / template.CallTree.PercentageBasis; this.ExclusiveMetricPercent = template.ExclusiveMetric * 100 / template.CallTree.PercentageBasis; this.ExclusiveFoldedMetricPercent = template.ExclusiveFoldedMetric * 100 / template.CallTree.PercentageBasis; this.HasChildren = template.HasChildren; this.BackingNode = template; this.backingNodeWithChildren = template; //System.Diagnostics.Debug.WriteLine("\n2\n" + template.InclusiveMetricByTimeString + "\n\n"); }
internal CallTreeViewNode(CallTreeView treeView, CallTreeNode data, int depth) { m_treeView = treeView; Data = data; m_isExpanded = !HasChildren; m_depth = depth; }
public void CallTreeNodeToTextConverter_HandlesLocationMessage() { string message = "my_function"; var callTreeNode = new CallTreeNode { Location = new ThreadFlowLocation { Location = new Location { Message = new Message { Text = message }, PhysicalLocation = new PhysicalLocation { Region = new Region { StartLine = 42 } } } } }; VerifyConversion(callTreeNode, message); }
public void TestOrderByNameMappingName() { CallTreeNode root = provider.GetRoot(0, 0); var query = root.Children.OrderBy(f => f.NameMapping.Name); Assert.AreEqual("AllCalls.Filter(c => (c.ParentID == 0)).MergeByName().Sort(f => f.NameMapping.Name)", SQLiteQueryProvider.OptimizeQuery(query.Expression).ToString()); }
public override bool Equals(CallTreeNode other) { if (other is UnmanagedCallTreeNode64) { UnmanagedCallTreeNode64 node = other as UnmanagedCallTreeNode64; return node.data == this.data; } return false; }
public FlameBox(CallTreeNode node, double width, double height, double x, double y) { Node = node; Width = width; Height = height; X = x; Y = y; }
private static void VerifyConversion(CallTreeNode callTreeNode, string expectedText) { var converter = new CallTreeNodeToTextConverter(); string text = (string)converter.Convert(callTreeNode, typeof(string), null, CultureInfo.CurrentCulture); text.Should().Be(expectedText); }
public FlameBox(CallTreeNode node, double width, double height, double x, double y) { Node = node; TooltipText = $"Method: {node.DisplayName} ({node.InclusiveCount} inclusive samples, {node.InclusiveMetricPercent:F}%)"; Width = width; Height = height; X = x; Y = y; }
public void TestOrderByWithMultiLevelUnsupporedThenBy() { CallTreeNode root = provider.GetRoot(0, 0); var query = root.Children.OrderBy(f => f.CallCount).ThenBy(f => f.NameMapping.Name).ThenBy(f => f.Ancestors.Count()); Assert.AreEqual("AllCalls.Filter(c => (c.ParentID == 0)).MergeByName()" + ".OrderBy(f => f.CallCount).ThenBy(f => f.NameMapping.Name).ThenBy(f => f.Ancestors.Count())", SQLiteQueryProvider.OptimizeQuery(query.Expression).ToString()); }
private static bool IsAddRefOrReleaseNode(CallTreeNode node, string name) { while (node.Function.Name.Contains("Interlocked") && node.Children.Count == 1) { node = node.Children.Values.First <CallTreeNode>(); } return(node.Function.Name.Contains(name)); }
public void TestOrderBySupportedThenByButUnsupportedConverter() { CallTreeNode root = provider.GetRoot(0, 0); var query = root.Children.OrderBy(f => f.CallCount).ThenBy(f => f.NameMapping.Name, StringComparer.CurrentCultureIgnoreCase); Assert.AreEqual("AllCalls.Filter(c => (c.ParentID == 0)).MergeByName()" + ".OrderBy(f => f.CallCount).ThenBy(f => f.NameMapping.Name, value(System.CultureAwareComparer))", SQLiteQueryProvider.OptimizeQuery(query.Expression).ToString()); }
/// <inheritdoc/> public override bool Equals(CallTreeNode other) { UnitTestRootCallTreeNode node = other as UnitTestRootCallTreeNode; if (node != null && unitTests != null) { return node.unitTests.SequenceEqual(unitTests); } return false; }
public void CallTreeNode_SelectedHighlightColor() { var callTreeNode = new CallTreeNode { Location = new ThreadFlowLocation(), }; callTreeNode.Location.Importance = ThreadFlowLocationImportance.Essential; callTreeNode.SelectedSourceHighlightColor.Should().Be("CodeAnalysisCurrentStatementSelection"); }
public CallTreeNodeViewModel(CallTreeNode node, CallTreeNodeViewModel parent) { if (node == null) { throw new ArgumentNullException("node"); } this.node = node; this.parent = parent; this.level = (this.parent == null) ? 1 : this.parent.level + 1; }
void FindUnitTests(CallTreeNode parentNode, IList<CallTreeNode> list) { if (IsUnitTest(parentNode.NameMapping)) { list.Add(parentNode); return; } foreach (var node in parentNode.Children) { FindUnitTests(node, list); } }
void InsertTree(SQLiteCommand cmd, CallTreeNode node, int parentId, IProfilingDataSet dataSet, FunctionDataParams dataParams) { int thisID = functionInfoCount++; foreach (CallTreeNode child in node.Children) { InsertTree(cmd, child, thisID, dataSet, dataParams); } // we sometimes saw invalid data with the 0x0080000000000000L bit set if (node.CpuCyclesSpent > 0x0007ffffffffffffL || node.CpuCyclesSpent < 0) { throw new InvalidOperationException("Too large CpuCyclesSpent - there's something wrong in the data"); } dataParams.callCount.Value = node.RawCallCount; dataParams.isActiveAtStart.Value = node.IsActiveAtStart; dataParams.cpuCyclesSpent.Value = node.CpuCyclesSpent; dataParams.dataSetId.Value = dataSetCount; dataParams.functionInfoId.Value = thisID; dataParams.nameId.Value = node.NameMapping.Id; dataParams.parentId.Value = parentId; dataParams.endId.Value = functionInfoCount - 1; cmd.ExecuteNonQuery(); }
void InsertCalls(SQLiteCommand cmd, CallTreeNode node, int parentId, CallsParams dataParams) { int thisID = functionInfoCount++; foreach (CallTreeNode child in node.Children) { InsertCalls(cmd, child, thisID, dataParams); } long cpuCycles = node.CpuCyclesSpent; long cpuCyclesSelf = node.CpuCyclesSpentSelf; // we sometimes saw invalid data with the 0x0080000000000000L bit set if (cpuCycles > 0x0007ffffffffffffL || cpuCycles < 0) { throw new InvalidOperationException("Too large CpuCyclesSpent - there's something wrong in the data"); } if (node.NameMapping.Id != 0 && (cpuCyclesSelf > cpuCycles || cpuCyclesSelf < 0)) { throw new InvalidOperationException("Too large/small CpuCyclesSpentSelf (" + cpuCyclesSelf + ") - there's something wrong in the data"); } dataParams.callCount.Value = node.RawCallCount; dataParams.isActiveAtStart.Value = node.IsActiveAtStart; dataParams.cpuCyclesSpent.Value = cpuCycles; dataParams.cpuCyclesSpentSelf.Value = cpuCyclesSelf; dataParams.functionInfoId.Value = thisID; dataParams.nameId.Value = node.NameMapping.Id; dataParams.parentId.Value = parentId; dataParams.endId.Value = functionInfoCount - 1; cmd.ExecuteNonQuery(); }
public UnitTestDataSet(CallTreeNode root, bool isFirst) { this.RootNode = root; this.IsFirst = isFirst; }
/// <summary> /// Creates a new CallTreeNode. /// </summary> public SQLiteCallTreeNode(int nameId, CallTreeNode parent, SQLiteQueryProvider provider) { this.nameId = nameId; this.parent = parent; this.provider = provider; }
public override bool Equals(CallTreeNode other) { UnmanagedCallTreeNode32 node = other as UnmanagedCallTreeNode32; if (node != null) { return node.data == data; } return false; }
public Node CreateView(double totalTime) { CallTreeNode n = new CallTreeNode(this, totalTime); n.Collapse(); List<Function> fns = new List<Function>(roots.Values); fns.Sort(Function.ByTimeDecreasing); foreach (Function f in fns) n.Add(f.CreateView(time)); return n; }
public override bool Equals(CallTreeNode other) { SQLiteCallTreeNode node = other as SQLiteCallTreeNode; if (node != null) { int[] a = this.IdList; int[] b = node.IdList; if (a.Length != b.Length) return false; for (int i = 0; i < a.Length; i++) { if (a[i] != b[i]) return false; } return true; } return false; }
/// <inheritdoc/> public override bool Equals(CallTreeNode other) { return (other is UnitTestRootCallTreeNode) && (other as UnitTestRootCallTreeNode).unitTests.SequenceEqual(unitTests); }
internal UnmanagedCallTreeNode64(UnmanagedProfilingDataSet dataSet, FunctionInfo* data, CallTreeNode parent) { this.data = data; this.dataSet = dataSet; this.parent = parent; }
public override bool Equals(CallTreeNode other) { if (other is SQLiteCallTreeNode) { SQLiteCallTreeNode node = other as SQLiteCallTreeNode; if (node.ids.Count != this.ids.Count) return false; for (int i = 0; i < this.ids.Count; i++) { if (node.ids[i] != this.ids[i]) return false; } return true; } return false; }
/// <summary> /// Creates a new CallTreeNode. /// </summary> public SQLiteCallTreeNode(int nameId, CallTreeNode parent, ProfilingDataSQLiteProvider provider) { this.nameId = nameId; this.parent = parent; this.provider = provider; }
bool FindUnitTestsAndInsert(SQLiteCommand cmd, CallTreeNode node, IProfilingDataSet dataSet, FunctionDataParams dataParams) { List<CallTreeNode> list = new List<CallTreeNode>(); FindUnitTests(node, list); if (list.Count > 0) { InsertTree(cmd, new UnitTestRootCallTreeNode(list), -1, dataSet, dataParams); return true; } return false; }