Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono-tools.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMassimiliano Mantione <massi@mono-cvs.ximian.com>2009-06-24 18:18:09 +0400
committerMassimiliano Mantione <massi@mono-cvs.ximian.com>2009-06-24 18:18:09 +0400
commita2b3b9690434e1da622bc8f907d774b56a668735 (patch)
tree69d51eb1db13bcc00813831c79edae2d48132e6f /Mono.Profiler
parent21a8dc7e6d773a99cab5265cd146d49a07902246 (diff)
Build direct and reverse call trees for statistical events.
svn path=/trunk/mono-tools/; revision=136769
Diffstat (limited to 'Mono.Profiler')
-rw-r--r--Mono.Profiler/profiler-decoder-library/ChangeLog4
-rw-r--r--Mono.Profiler/profiler-decoder-library/EventProcessor.cs73
-rw-r--r--Mono.Profiler/profiler-decoder-library/ObjectModel.cs89
3 files changed, 154 insertions, 12 deletions
diff --git a/Mono.Profiler/profiler-decoder-library/ChangeLog b/Mono.Profiler/profiler-decoder-library/ChangeLog
index d39ad7d0..ebd36c33 100644
--- a/Mono.Profiler/profiler-decoder-library/ChangeLog
+++ b/Mono.Profiler/profiler-decoder-library/ChangeLog
@@ -1,3 +1,7 @@
+2009-06-24 Massimiliano Mantione <massi@ximian.com>
+ * ObjectModel.cs, EventProcessor.cs:
+ Build direct and reverse call trees for statistical events.
+
2009-06-18 Massimiliano Mantione <massi@ximian.com>
* BaseTypes.cs, Decoder.cs, ObjectModel.cs, EventProcessor.cs:
Added assembly information to classes and wrapper flag to methods.
diff --git a/Mono.Profiler/profiler-decoder-library/EventProcessor.cs b/Mono.Profiler/profiler-decoder-library/EventProcessor.cs
index b987941b..b0f4ced8 100644
--- a/Mono.Profiler/profiler-decoder-library/EventProcessor.cs
+++ b/Mono.Profiler/profiler-decoder-library/EventProcessor.cs
@@ -317,30 +317,66 @@ namespace Mono.Profiler {
uint remainingCallersInChain;
IStatisticalHitItem lastCallee;
+ StatisticalHitItemTreeNode lastCalleeNode;
+ bool eventsArePartOfChain;
+ int currentChainIndex;
+ IStatisticalHitItem[] currentChain;
// Returns true if the hit must be counted (this is the first chain item)
bool HandleCallChain (IStatisticalHitItem caller) {
- bool result;
-
- if (remainingCallersInChain > 0) {
- remainingCallersInChain --;
+ if (eventsArePartOfChain) {
+ bool result;
+
if (lastCallee != null) {
- //Console.WriteLine ("HandleCallChain[{0}] {1} on {2}", remainingCallersInChain, caller.Name, lastCallee.Name);
lastCallee.CallCounts.AddCaller (caller);
caller.CallCounts.AddCallee (lastCallee);
}
- result = false;
+
+ if (lastCalleeNode != null) {
+ lastCalleeNode = lastCalleeNode.AddChild (caller);
+ } else {
+ lastCalleeNode = statisticalItemsByCaller.AddChild (caller);
+ }
+
+ currentChain [currentChainIndex] = caller;
+ currentChainIndex ++;
+
+ if (remainingCallersInChain > 0) {
+ //Console.WriteLine ("HandleCallChain[{0}] {1} on {2}", remainingCallersInChain, caller.Name, lastCallee.Name);
+ remainingCallersInChain --;
+ result = false;
+ } else {
+ //Console.WriteLine ("HandleCallChain[{0}] {1}", remainingCallersInChain, caller.Name);
+ result = true;
+
+ StatisticalHitItemTreeNode currentNode = statisticalItemsByCallee;
+ while (currentChainIndex > 0) {
+ currentChainIndex --;
+ currentNode = currentNode.AddChild (currentChain [currentChainIndex]);
+ }
+
+ eventsArePartOfChain = false;
+ Array.Clear (currentChain, 0, currentChain.Length);
+ }
+
+ lastCallee = caller;
+
+ return result;
} else {
- //Console.WriteLine ("HandleCallChain[{0}] {1}", remainingCallersInChain, caller.Name);
- result = true;
+ return true;
}
-
- lastCallee = caller;
-
- return result;
}
public override void StatisticalCallChainStart (uint chainDepth) {
+ lastCallee = null;
+ lastCalleeNode = null;
remainingCallersInChain = chainDepth;
+ eventsArePartOfChain = true;
+ currentChainIndex = 0;
+ if (currentChain != null) {
+ Array.Clear (currentChain, 0, currentChain.Length);
+ } else {
+ currentChain = new IStatisticalHitItem [32];
+ }
//Console.WriteLine ("StatisticalCallChainStart ({0})", chainDepth);
}
@@ -406,6 +442,19 @@ namespace Mono.Profiler {
}
}
+ StatisticalHitItemTreeNode statisticalItemsByCaller = new StatisticalHitItemTreeNode (null);
+ public StatisticalHitItemTreeNode[] StatisticalItemsByCaller {
+ get {
+ return statisticalItemsByCaller.Children;
+ }
+ }
+ StatisticalHitItemTreeNode statisticalItemsByCallee = new StatisticalHitItemTreeNode (null);
+ public StatisticalHitItemTreeNode[] StatisticalItemsByCallee {
+ get {
+ return statisticalItemsByCallee.Children;
+ }
+ }
+
public class GcStatistics {
ProfilerEventHandler data;
diff --git a/Mono.Profiler/profiler-decoder-library/ObjectModel.cs b/Mono.Profiler/profiler-decoder-library/ObjectModel.cs
index 41e7ae33..0579766d 100644
--- a/Mono.Profiler/profiler-decoder-library/ObjectModel.cs
+++ b/Mono.Profiler/profiler-decoder-library/ObjectModel.cs
@@ -729,6 +729,95 @@ namespace Mono.Profiler {
StatisticalHitItemCallCounts CallCounts {get;}
}
+ public class StatisticalHitItemTreeNode {
+ IStatisticalHitItem item;
+ public IStatisticalHitItem Item {
+ get {
+ return item;
+ }
+ }
+
+ public string Name {
+ get {
+ return item.Name;
+ }
+ }
+
+ uint hitCount;
+ void IncrementHitCount () {
+ hitCount ++;
+ }
+ public uint HitCount {
+ get {
+ return hitCount;
+ }
+ }
+
+ public static Comparison<StatisticalHitItemTreeNode> CompareByHitCount = delegate (StatisticalHitItemTreeNode a, StatisticalHitItemTreeNode b) {
+ int result = b.HitCount.CompareTo (a.HitCount);
+ if (result == 0) {
+ result = a.Name.CompareTo (b.Name);
+ }
+ return result;
+ };
+
+
+ Dictionary<string,StatisticalHitItemTreeNode> children;
+ static StatisticalHitItemTreeNode[] emptyChildren = new StatisticalHitItemTreeNode [0];
+ public int ChildrenCount {
+ get {
+ return (children != null) ? children.Count : 0;
+ }
+ }
+ public StatisticalHitItemTreeNode[] Children {
+ get {
+ if (children != null) {
+ StatisticalHitItemTreeNode[] result = new StatisticalHitItemTreeNode [children.Count];
+ int resultIndex = 0;
+ foreach (StatisticalHitItemTreeNode child in children.Values) {
+ result [resultIndex] = child;
+ resultIndex ++;
+ }
+ Array.Sort (result, CompareByHitCount);
+ return result;
+ } else {
+ return emptyChildren;
+ }
+ }
+ }
+
+ public StatisticalHitItemTreeNode AddChild (IStatisticalHitItem childItem) {
+ if (children == null) {
+ children = new Dictionary<string, StatisticalHitItemTreeNode> ();
+ }
+ StatisticalHitItemTreeNode child;
+ if (children.ContainsKey (childItem.Name)) {
+ child = children [childItem.Name];
+ } else {
+ child = new StatisticalHitItemTreeNode (childItem);
+ children [childItem.Name] = child;
+ }
+ child.IncrementHitCount ();
+ return child;
+ }
+
+ public void PrintTree (TextWriter writer, uint fatherHits, int level) {
+ for (int i = 0; i < level; i++) {
+ writer.Write (" ");
+ }
+ writer.WriteLine ("{0,5:F2}% ({1}) {2}", ((((double) HitCount) / fatherHits) * 100), HitCount, Name);
+ foreach (StatisticalHitItemTreeNode child in Children) {
+ child.PrintTree (writer, HitCount, level + 1);
+ }
+ }
+
+ public StatisticalHitItemTreeNode (IStatisticalHitItem item) {
+ this.item = item;
+ this.hitCount = 0;
+ this.children = null;
+ }
+ }
+
public class LoadedMethod : BaseLoadedMethod<LoadedClass>, IStatisticalHitItem, IHeapItemSetStatisticsSubject {
ulong clicks;
public ulong Clicks {