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:
authorMike Kestner <mkestner@gmail.com>2009-06-10 01:44:01 +0400
committerMike Kestner <mkestner@gmail.com>2009-06-10 01:44:01 +0400
commit1b513aa3f540ecd227cdffb80575d9ac204b9600 (patch)
tree3a4533caa708b574ec5cd3a521161a163245e10f
parenta049cf80062dc0b4daa1514da4c4638bb488dd43 (diff)
2009-06-09 Mike Kestner <mkestner@novell.com>
* ObjectModel.cs: commit Massi's calls StackTrace logging. 2009-06-09 Mike Kestner <mkestner@novell.com> * Main.cs: commit Massi's new calls profile formatting code. 2009-06-09 Mike Kestner <mkestner@novell.com> * CallsStore.cs: use StackTrace objects to navigate the call tree and obtain context appropriate clicks info. Fix a bug in the GetIter path traversal logic for trees deeper than 2 levels. svn path=/trunk/mono-tools/; revision=135791
-rw-r--r--Mono.Profiler/Mono.Profiler.Widgets/CallsStore.cs33
-rw-r--r--Mono.Profiler/Mono.Profiler.Widgets/ChangeLog6
-rw-r--r--Mono.Profiler/profiler-decoder-library/ChangeLog3
-rw-r--r--Mono.Profiler/profiler-decoder-library/ObjectModel.cs75
-rw-r--r--Mono.Profiler/profiler-file-decoder/ChangeLog3
-rw-r--r--Mono.Profiler/profiler-file-decoder/Main.cs17
6 files changed, 118 insertions, 19 deletions
diff --git a/Mono.Profiler/Mono.Profiler.Widgets/CallsStore.cs b/Mono.Profiler/Mono.Profiler.Widgets/CallsStore.cs
index dc142a3d..457f90d7 100644
--- a/Mono.Profiler/Mono.Profiler.Widgets/CallsStore.cs
+++ b/Mono.Profiler/Mono.Profiler.Widgets/CallsStore.cs
@@ -11,17 +11,15 @@ namespace Mono.Profiler.Widgets {
class Node {
- ulong clicks;
Node parent;
List<Node> children;
- LoadedMethod method;
+ StackTrace frame;
GCHandle gch;
- public Node (Node parent, LoadedMethod method, ulong clicks)
+ public Node (Node parent, StackTrace frame)
{
this.parent = parent;
- this.method = method;
- this.clicks = clicks;
+ this.frame = frame;
gch = GCHandle.Alloc (this, GCHandleType.Weak);
}
@@ -29,19 +27,19 @@ namespace Mono.Profiler.Widgets {
get {
if (children == null) {
children = new List<Node> ();
- foreach (LoadedMethod.ClicksPerCalledMethod clicks in method.Methods)
- children.Add (new Node (this, clicks.Method, clicks.Clicks));
+ foreach (StackTrace child in frame.CalledFrames)
+ children.Add (new Node (this, child));
}
return children;
}
}
public ulong Clicks {
- get { return clicks; }
+ get { return frame.Clicks; }
}
public LoadedMethod Method {
- get { return method; }
+ get { return frame.TopMethod; }
}
public Node Parent {
@@ -86,10 +84,9 @@ namespace Mono.Profiler.Widgets {
return;
nodes = new List<Node> ();
- foreach (LoadedMethod m in data.LoadedElements.Methods) {
- total_clicks += m.Clicks;
- if (m.Callers.Length == 0)
- nodes.Add (new Node (null, m, m.Clicks));
+ foreach (StackTrace frame in StackTrace.RootFrames) {
+ total_clicks += frame.TopMethod.Clicks;
+ nodes.Add (new Node (null, frame));
}
}
@@ -121,14 +118,14 @@ namespace Mono.Profiler.Widgets {
iter = TreeIter.Zero;
if (path.Indices.Length == 0 || nodes.Count <= path.Indices [0])
return false;
+
Node node = nodes [path.Indices [0]];
- if (path.Indices.Length == 1)
- iter = (TreeIter) node;
- else {
- if (node.Children.Count <= path.Indices [1])
+ for (int i = 1; i < path.Indices.Length; i++) {
+ if (node.Children.Count <= path.Indices [i])
return false;
- iter = (TreeIter) node.Children [path.Indices [1]];
+ node = node.Children [path.Indices [i]];
}
+ iter = (TreeIter) node;
return true;
}
diff --git a/Mono.Profiler/Mono.Profiler.Widgets/ChangeLog b/Mono.Profiler/Mono.Profiler.Widgets/ChangeLog
index f346c318..18bbb9d4 100644
--- a/Mono.Profiler/Mono.Profiler.Widgets/ChangeLog
+++ b/Mono.Profiler/Mono.Profiler.Widgets/ChangeLog
@@ -1,3 +1,9 @@
+2009-06-09 Mike Kestner <mkestner@novell.com>
+
+ * CallsStore.cs: use StackTrace objects to navigate the call tree
+ and obtain context appropriate clicks info. Fix a bug in the GetIter
+ path traversal logic for trees deeper than 2 levels.
+
2009-05-21 Mike Kestner <mkestner@novell.com>
* *: initial checkin. beginnings of a widget library for profiler
diff --git a/Mono.Profiler/profiler-decoder-library/ChangeLog b/Mono.Profiler/profiler-decoder-library/ChangeLog
index 6a81617c..7fbf8edb 100644
--- a/Mono.Profiler/profiler-decoder-library/ChangeLog
+++ b/Mono.Profiler/profiler-decoder-library/ChangeLog
@@ -1,3 +1,6 @@
+2009-06-09 Mike Kestner <mkestner@novell.com>
+ * ObjectModel.cs: commit Massi's calls StackTrace logging.
+
2009-05-21 Mike Kestner <mkestner@novell.com>
* *: replace MD 1.0 solution files with 2.0 msbuild files, and turn
on makefile synchronization instead of generated makefiles.
diff --git a/Mono.Profiler/profiler-decoder-library/ObjectModel.cs b/Mono.Profiler/profiler-decoder-library/ObjectModel.cs
index bc15c22f..fd81e498 100644
--- a/Mono.Profiler/profiler-decoder-library/ObjectModel.cs
+++ b/Mono.Profiler/profiler-decoder-library/ObjectModel.cs
@@ -258,6 +258,66 @@ namespace Mono.Profiler {
}
}
+ ulong clicks;
+ public ulong Clicks {
+ get {
+ return clicks;
+ }
+ }
+ uint calls;
+ public ulong Calls {
+ get {
+ return calls;
+ }
+ }
+
+ public void ResetCalls () {
+ calls = 0;
+ clicks = 0;
+ }
+ public void RegisterCall (ulong clicks) {
+ this.clicks += clicks;
+ calls ++;
+ }
+
+ static StackTrace[] EmptyCalledFrames = new StackTrace [0];
+ List<StackTrace> calledFrames;
+ public StackTrace[] CalledFrames {
+ get {
+ if (calledFrames != null) {
+ StackTrace[] result = calledFrames.ToArray ();
+ Array.Sort (result, CompareByClicks);
+ Array.Reverse (result);
+ return result;
+ } else {
+ return EmptyCalledFrames;
+ }
+ }
+ }
+ void AddCalledFrame (StackTrace calledFrame) {
+ if (calledFrames == null) {
+ calledFrames = new List<StackTrace> ();
+ }
+ calledFrames.Add (calledFrame);
+ }
+
+ public static Comparison<StackTrace> CompareByClicks = delegate (StackTrace a, StackTrace b) {
+ return a.Clicks.CompareTo (b.Clicks);
+ };
+ public static Comparison<StackTrace> CompareByCalls = delegate (StackTrace a, StackTrace b) {
+ return a.Calls.CompareTo (b.Calls);
+ };
+
+ static List<StackTrace> rootFrames;
+ public static StackTrace[] RootFrames {
+ get {
+ StackTrace[] result = rootFrames.ToArray ();
+ Array.Sort (result, CompareByClicks);
+ Array.Reverse (result);
+ return result;
+ }
+ }
+
public void Write (TextWriter writer, int depth, string indentationString) {
writer.Write ("CallStack of id ");
writer.Write (id);
@@ -307,8 +367,16 @@ namespace Mono.Profiler {
}
StackTrace (LoadedMethod topMethod, StackTrace caller, bool methodIsBeingJitted) {
+ this.clicks = 0;
+ this.calls = 0;
+ this.calledFrames = null;
this.topMethod = topMethod;
this.caller = caller;
+ if (caller != null) {
+ caller.AddCalledFrame (this);
+ } else {
+ rootFrames.Add (this);
+ }
this.methodIsBeingJitted = methodIsBeingJitted;
this.level = caller != null ? caller.level + 1 : 1;
this.id = nextFreeId;
@@ -344,6 +412,7 @@ namespace Mono.Profiler {
static Dictionary<uint,List<StackTrace>> [] tracesByLevel;
public static readonly StackTrace StackTraceUnavailable;
static StackTrace () {
+ rootFrames = new List<StackTrace> ();
nextFreeId = 0;
tracesByLevel = new Dictionary<uint,List<StackTrace>> [64];
StackTraceUnavailable = NewStackTrace (CallStack.StackFrame.StackFrameUnavailable);
@@ -388,7 +457,7 @@ namespace Mono.Profiler {
}
class CallStack {
- internal class StackFrame {
+ public class StackFrame {
LoadedMethod method;
public LoadedMethod Method {
get {
@@ -510,6 +579,10 @@ namespace Mono.Profiler {
stackTop = StackFrame.FrameFactory (method, counter, false, stackTop);
}
internal void MethodExit (LoadedMethod method, ulong counter) {
+ StackTrace trace = StackTrace.NewStackTrace (this);
+ if (trace != null) {
+ trace.RegisterCall (counter);
+ }
PopMethod (method, counter, false);
}
internal void TopMethodExit (ulong counter) {
diff --git a/Mono.Profiler/profiler-file-decoder/ChangeLog b/Mono.Profiler/profiler-file-decoder/ChangeLog
index 532af7da..b9c658e6 100644
--- a/Mono.Profiler/profiler-file-decoder/ChangeLog
+++ b/Mono.Profiler/profiler-file-decoder/ChangeLog
@@ -1,3 +1,6 @@
+2009-06-09 Mike Kestner <mkestner@novell.com>
+ * Main.cs: commit Massi's new calls profile formatting code.
+
2009-05-21 Mike Kestner <mkestner@novell.com>
* *: replace MD 1.0 solution files with 2.0 msbuild files, and turn
on makefile synchronization instead of generated makefiles.
diff --git a/Mono.Profiler/profiler-file-decoder/Main.cs b/Mono.Profiler/profiler-file-decoder/Main.cs
index ad09377a..1cd7e669 100644
--- a/Mono.Profiler/profiler-file-decoder/Main.cs
+++ b/Mono.Profiler/profiler-file-decoder/Main.cs
@@ -113,6 +113,18 @@ namespace Mono.Profiler
}
+ static void PrintExecutionTimeByCallStack (TextWriter writer, ProfilerEventHandler data, StackTrace stackFrame, double callerSeconds, int indentationLevel) {
+ for (int i = 0; i < indentationLevel; i++) {
+ writer.Write (" ");
+ }
+ LoadedMethod currentMethod = stackFrame.TopMethod;
+ double currentSeconds = data.ClicksToSeconds (stackFrame.TopMethod.Clicks);
+ writer.WriteLine ("{0,5:F2}% ({1:F6}s, {2} calls) {3}.{4}", ((currentSeconds / callerSeconds) * 100), currentSeconds, stackFrame.Calls, currentMethod.Class.Name, currentMethod.Name);
+ foreach (StackTrace calledFrame in stackFrame.CalledFrames) {
+ PrintExecutionTimeByCallStack (writer, data, calledFrame, currentSeconds, indentationLevel + 1);
+ }
+ }
+
static void PrintData (TextWriter writer, ProfilerEventHandler data) {
LoadedClass[] classes = data.LoadedElements.Classes;
LoadedMethod[] methods = data.LoadedElements.Methods;
@@ -160,6 +172,11 @@ namespace Mono.Profiler
}
}
}
+
+ writer.WriteLine ("Reporting execution time by stack frame (on {0} methods)", methods.Length);
+ foreach (StackTrace rootFrame in StackTrace.RootFrames) {
+ PrintExecutionTimeByCallStack (writer, data, rootFrame, data.ClicksToSeconds (totalExecutionClicks), 0);
+ }
} else {
writer.WriteLine ("No execution time reported (on {0} methods)", methods.Length);
}