Author: dsnell Date: 2006-08-27 04:10:30 -0400 (Sun, 27 Aug 2006) New Revision: 64427
Modified: branches/dmsnell/heap-buddy/analyzer/Gc.cs branches/dmsnell/heap-buddy/analyzer/GraphReport.cs branches/dmsnell/heap-buddy/analyzer/Makefile.am branches/dmsnell/heap-buddy/analyzer/Makefile.in branches/dmsnell/heap-buddy/analyzer/MemGraph.cs branches/dmsnell/heap-buddy/analyzer/OutfileReader.cs branches/dmsnell/heap-buddy/profiler/heap-buddy.c branches/dmsnell/heap-buddy/profiler/outfile-writer.c branches/dmsnell/heap-buddy/profiler/outfile-writer.h Log: More changes with better graphing and separated graph/logic code. Modified: branches/dmsnell/heap-buddy/analyzer/Gc.cs =================================================================== --- branches/dmsnell/heap-buddy/analyzer/Gc.cs 2006-08-27 07:14:37 UTC (rev 64426) +++ branches/dmsnell/heap-buddy/analyzer/Gc.cs 2006-08-27 08:10:30 UTC (rev 64427) @@ -35,6 +35,7 @@ public int Generation; public long TimeT; + public long UTimeT; public DateTime Timestamp; public long PreGcLiveBytes; Modified: branches/dmsnell/heap-buddy/analyzer/GraphReport.cs =================================================================== --- branches/dmsnell/heap-buddy/analyzer/GraphReport.cs 2006-08-27 07:14:37 UTC (rev 64426) +++ branches/dmsnell/heap-buddy/analyzer/GraphReport.cs 2006-08-27 08:10:30 UTC (rev 64427) @@ -1,313 +1,83 @@ -// -// Graph.cs -// based on BacktracesReport.cs -// - -// -// BacktracesReport.cs -// -// Copyright (C) 2005 Novell, Inc. -// - -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of version 2 of the GNU General Public -// License as published by the Free Software Foundation. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 -// USA. -// - -using System; -using System.Collections; using Cairo; -using Gtk; using Glade; +using Gtk; +using System; +using System.Collections; +using System.IO; +using Mono.Unix.Native; namespace HeapBuddy { - + public class GraphReport : Report { - + public GraphReport () : base ("Graph") { } - public Context Context; - public Gdk.Window Window; + private MemGraph Graph; + private OutfileReader Reader; - public OutfileReader Reader; - public ArrayList Stamps; - [Widget] VBox vbox1; [Widget] Gtk.Window MainWindow; override public void Run (OutfileReader reader, string [] args) { Reader = reader; - Stamps = new ArrayList (); - CollectStamps (); - Sort (); - + Application.Init (); - + Glade.XML gxml = new Glade.XML (null, "memgraph.glade", "MainWindow", null); gxml.Autoconnect (this); - - CairoGraph cg = new CairoGraph (this); - vbox1.Add (cg); + Graph = new MemGraph (); + PopulateGraph (); + + vbox1.Add (Graph); + MainWindow.ShowAll (); - MainWindow.Resize (640, 480); - MainWindow.DeleteEvent += QuitApplication; - + Application.Run (); } - public void SetContext (Context c, Gdk.Window w) + private void PopulateGraph () { - Context = c; - Window = w; + Stream stream = new FileStream ("outfile.types", FileMode.Open, FileAccess.Read); + BinaryReader reader = new BinaryReader (stream); - Continue (); - } - - public void Continue () - { - int x, y, w, h, d; - Window.GetGeometry (out x, out y, out w, out h, out d); - - Context c = Context; - - if (Stamps.Count <= 0) - return; + while (reader.PeekChar () != -1) { + Timeval t = new Timeval (); + t.tv_sec = reader.ReadInt64 (); + t.tv_usec = reader.ReadInt64 (); + + uint count = reader.ReadUInt32 (); + int bytes; + string name; - c.Color = new Color (1, 1, 1, 1); - c.Paint (); - - // Calculate our Time Span, bail if zero - long TimeSpan = ((MemStamp)Stamps [Stamps.Count - 1]).TimeT - ((MemStamp)Stamps [0]).TimeT; - if (TimeSpan == 0) - return; - - long LowBytes = ((MemStamp)Stamps [0]).LiveBytes; - long HighBytes = 0; - - foreach (MemStamp ms in Stamps) { - if (ms.LiveBytes < LowBytes) - LowBytes = ms.LiveBytes; - if (ms.LiveBytes > HighBytes) - HighBytes = ms.LiveBytes; - } - - //*********Scaling - - // How much room for the labels? - c.FontSize = 15 * w / 640; - if (15 * w / 640 > 20) - c.FontSize = 20; - - string label = Util.PrettySize (HighBytes); - double GOY = h - c.TextExtents (label).Height - 30; - - c.FontSize = 15 * h / 480; - if (15 * h / 480 > 20) - c.FontSize = 20; - - double GOX = c.TextExtents (label).Width + 15; - double GW = w - GOX - 10; - double GH = GOY - 10; - - double xscale = (double)TimeSpan / GW; - double yrange = HighBytes - LowBytes; - double yscale = yrange / GH; - - // Border - c.Color = new Color (0, 0, 0, 1); - c.LineWidth = 2; - c.Rectangle (GOX, GOY, GW, -GH); - c.Stroke (); - - // Memory line - c.MoveTo (GOX, GOY); - long LowTime = ((MemStamp)Stamps [0]).TimeT; - - Color Black = new Color (0, 0, 0, 1); - Color GcColor = new Color (0, 0, 1, 1); - Color ResizeColor = new Color (1, 0, 0, 1); - - double oldX = GOX; - double oldY = GOY; - double newX, newY; - - c.LineWidth = 1.5; - foreach (MemStamp ms in Stamps) { - switch (ms.Op) { - case MemAction.Gc: - c.Color = GcColor; - break; - - case MemAction.Resize: - c.Color = ResizeColor; - break; - - default: - c.Color = Black; - break; + for (; count > 0; count--) { + bytes = reader.ReadInt32 (); + name = reader.ReadString (); + + Graph.AddStamp (new MemStamp (t, name, bytes)); } - - newX = GOX + (double)(ms.TimeT - LowTime) / xscale; - newY = GOY - (double)(ms.LiveBytes - LowBytes) / yscale; - - c.MoveTo (oldX, oldY); - c.LineTo (newX, newY); - c.Stroke (); - - oldX = newX; - oldY = newY; } - c.Color = Black; - // Labels - c.LineWidth = 1; - c.FontSize = 15 * h / 480; - if (15 * h / 480 > 20) - c.FontSize = 20; - - // Memory - for (int i = 0; i <= 10; i++) { - c.MoveTo (GOX - 5, GOY - i * GH / 10); - c.LineTo (GOX, GOY - i * GH / 10); - c.Stroke (); - - label = Util.PrettySize (LowBytes + (i * (long)yrange / 10)); - TextExtents e = c.TextExtents (label); - c.MoveTo (GOX - 10 - e.Width, GOY - i * GH / 10 + 0.5 * e.Height); - c.ShowText (label); - } - - // Time - c.FontSize = 15 * w / 640; - if (15 * w / 640 > 20) - c.FontSize = 20; - - for (int i = 0; i < 15; i++) { - c.MoveTo (GOX + i * GW / 15, GOY); - c.LineTo (GOX + i * GW / 15, GOY + 5); - c.Stroke (); - - label = Util.PrettyTime (i * TimeSpan / 15); - TextExtents e = c.TextExtents (label); - c.MoveTo (GOX + i * GW / 15 - 0.5 * e.Width, GOY + 15 + e.Height); - c.ShowText (label); - } - } - - public enum MemAction { - NoOp, - Gc, - Resize - } - - public class MemStamp { - public long LiveBytes; - public long TimeT; - public MemAction Op; - - public MemStamp (long bytes, long time) { - LiveBytes = bytes; - TimeT = time; - Op = MemAction.NoOp; - } - - public MemStamp (long bytes, long time, MemAction op) { - LiveBytes = bytes; - TimeT = time; - Op = op; - } - } - - public class MemStampComparer : IComparer { - int IComparer.Compare (System.Object x, System.Object y) { - MemStamp a = (MemStamp)x; - MemStamp b = (MemStamp)y; - - if (a.TimeT > b.TimeT) return 1; - else if (a.TimeT < b.TimeT) return -1; - else return 0; - } - } - - public void CollectStamps () - { foreach (Gc gc in Reader.Gcs) { - Stamps.Add (new MemStamp (gc.PostGcLiveBytes, gc.TimeT, MemAction.Gc)); + Graph.AddStamp (new MemStamp (gc.TimeT, gc.PreGcLiveBytes)); } - foreach (Resize r in Reader.Resizes) { - Stamps.Add (new MemStamp (r.TotalLiveBytes, r.time_t, MemAction.Resize)); - } + Graph.Sort (); + + reader.Close (); } - - public void Sort () - { - IComparer ic = new MemStampComparer (); - Stamps.Sort (ic); - } protected void SaveGraph (object o, EventArgs e) { - FileChooserDialog chooser = new FileChooserDialog ("Save As", MainWindow, FileChooserAction.Save); - chooser.AddButton (Stock.Cancel, ResponseType.Cancel); - chooser.AddButton (Stock.Save, ResponseType.Ok); - - int response = chooser.Run (); - - if ((ResponseType)response == ResponseType.Ok) { - int x, y, w, h, d; - Window.GetGeometry (out x, out y, out w, out h, out d); - - Surface s = new ImageSurface (Format.RGB24, w, h); - Context.Target = s; - this.Continue (); - - s.WriteToPng (chooser.Filename); - s.Finish (); - } - - chooser.Destroy (); + } - + protected void QuitApplication (object o, EventArgs e) { Application.Quit (); } - - } - - public class CairoGraph : DrawingArea - { - public Cairo.Context Context; - public Gdk.Window Window; - public GraphReport GraphReport; - - public CairoGraph (GraphReport gr) - { - GraphReport = gr; - } - protected override bool OnExposeEvent (Gdk.EventExpose args) - { - Window = args.Window; - Context = Gdk.Context.CreateDrawable (Window); - - GraphReport.SetContext (Context, Window); - - return true; - } } + } Modified: branches/dmsnell/heap-buddy/analyzer/Makefile.am =================================================================== --- branches/dmsnell/heap-buddy/analyzer/Makefile.am 2006-08-27 07:14:37 UTC (rev 64426) +++ branches/dmsnell/heap-buddy/analyzer/Makefile.am 2006-08-27 08:10:30 UTC (rev 64427) @@ -1,6 +1,6 @@ CSC = mcs -debug -CSFLAGS = -target:exe -r:Mono.Cairo -pkg:gtk-sharp-2.0 -r:System.Drawing.dll -pkg:glade-sharp-2.0 -resource:memgraph.glade +CSFLAGS = -target:exe -r:Mono.Cairo -pkg:gtk-sharp-2.0 -r:System.Drawing.dll -pkg:glade-sharp-2.0 -resource:memgraph.glade -r:Mono.Posix TARGET = HeapBuddy.exe WRAPPER = heap-buddy @@ -29,6 +29,7 @@ TypeLog.cs \ MethodLog.cs \ Graphics.cs \ + MemGraph.cs \ $(REPORT_CSFILES) bin_SCRIPTS = \ Modified: branches/dmsnell/heap-buddy/analyzer/Makefile.in =================================================================== --- branches/dmsnell/heap-buddy/analyzer/Makefile.in 2006-08-27 07:14:37 UTC (rev 64426) +++ branches/dmsnell/heap-buddy/analyzer/Makefile.in 2006-08-27 08:10:30 UTC (rev 64427) @@ -153,7 +153,7 @@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ CSC = mcs -debug -CSFLAGS = -target:exe -r:Mono.Cairo -pkg:gtk-sharp-2.0 -r:System.Drawing.dll -pkg:glade-sharp-2.0 -resource:memgraph.glade +CSFLAGS = -target:exe -r:Mono.Cairo -pkg:gtk-sharp-2.0 -r:System.Drawing.dll -pkg:glade-sharp-2.0 -resource:memgraph.glade -r:Mono.Posix TARGET = HeapBuddy.exe WRAPPER = heap-buddy REPORT_CSFILES = \ @@ -180,6 +180,7 @@ TypeLog.cs \ MethodLog.cs \ Graphics.cs \ + MemGraph.cs \ $(REPORT_CSFILES) bin_SCRIPTS = \ Modified: branches/dmsnell/heap-buddy/analyzer/MemGraph.cs =================================================================== --- branches/dmsnell/heap-buddy/analyzer/MemGraph.cs 2006-08-27 07:14:37 UTC (rev 64426) +++ branches/dmsnell/heap-buddy/analyzer/MemGraph.cs 2006-08-27 08:10:30 UTC (rev 64427) @@ -1,186 +1,279 @@ +using Cairo; +using Gtk; +using Mono.Unix.Native; using System; using System.Collections; -using Cairo; -using Gtk; namespace HeapBuddy { + + public class MemStamp + { + public Timeval Time; + public string Type; + public long Bytes; + + public MemStamp (Timeval time, string type, long bytes) + { + Time = time; + Type = String.Intern (type); + Bytes = bytes; + } + + public MemStamp (long time, long bytes) + { + Time = new Timeval (); + Time.tv_sec = time; + Time.tv_usec = 0; + Type = null; + Bytes = bytes; + } + + public long Seconds { + get { + return Time.tv_sec; + } + } + + public long USeconds { + get { + return Time.tv_usec; + } + } + } - public class MemGraph { - - private class MemStamp { - public long LiveBytes; - public long TimeT; + public class MemStampComparer : IComparer { + int IComparer.Compare (System.Object x, System.Object y) { + MemStamp a = (MemStamp)x; + MemStamp b = (MemStamp)y; - public MemStamp (long bytes, long time) { - LiveBytes = bytes; - TimeT = time; + if (a.Seconds > b.Seconds) + return 1; + else if (a.Seconds < b.Seconds) + return -1; + else + { + if (a.USeconds > b.USeconds) + return 1; + else if (a.USeconds < b.USeconds) + return -1; + else + return 0; } } + } + + public class MemGraph : DrawingArea + { + + private Context myContext; + private ArrayList StampBook; + private bool isSorted; + private long HighTime = 0; + private long LowTime= (uint)-1; + private Gdk.Window myWindow; + private double Scale = 1; + private int x, y, w, h, d; - private class MemStampComparer : IComparer { - int IComparer.Compare (System.Object x, System.Object y) { - MemStamp a = (MemStamp)x; - MemStamp b = (MemStamp)y; + public MemGraph () + { + StampBook = new ArrayList (); + isSorted = false; - if (a.TimeT > b.TimeT) return 1; - else if (a.TimeT < b.TimeT) return -1; - else return 0; + Events = Events | Gdk.EventMask.ButtonPressMask + | Gdk.EventMask.ButtonReleaseMask; + ButtonPressEvent += ButtonPress; + ButtonReleaseEvent += ButtonRelease; + } + + public Cairo.Context Context { + get { + return myContext; } } - private ArrayList Stamps; - static DrawingArea da; - - public MemGraph (OutfileReader reader, string filename) - { - Stamps = new ArrayList (); - CollectStamps (reader); - Sort (); + public void AddStamp (MemStamp s) + { + StampBook.Add (s); + isSorted = false; - // If we don't have any data, bail - if (Stamps.Count <= 0) + if (s.Seconds == 0) return; - const int SurfaceWidth = 640; - const int SurfaceHeight = 480; + if (s.Type == null && s.Seconds < LowTime) + LowTime = s.Seconds; - // Generate our Cairo surface - ImageSurface surface = new ImageSurface (Format.RGB24, SurfaceWidth, SurfaceHeight); - Context c = new Context (surface); - - c.Color = new Color (1, 1, 1, 1); - c.Paint (); - - // Calculate our bounds - long domain = ((MemStamp)Stamps [Stamps.Count - 1]).TimeT - ((MemStamp)Stamps [0]).TimeT; - if (domain == 0) - return; + if (s.Type == null && s.Seconds > HighTime) + HighTime = s.Seconds; + } + + public void Sort () + { + IComparer ic = new MemStampComparer (); + StampBook.Sort (ic); + } + + public void Draw () + { + if (!isSorted) + Sort (); + + Context c = myContext; + + Color Black = new Color (0, 0, 0, 1); + Color White = new Color (1, 1, 1, 1); + Color Red = new Color (1, 0, 0, 1); + Color Blue = new Color (0, 0, 1, 1); - long lowBytes = ((MemStamp)Stamps [0]).LiveBytes; - long highBytes = 0; - - foreach (MemStamp ms in Stamps) { - if (ms.LiveBytes < lowBytes) - lowBytes = ms.LiveBytes; - if (ms.LiveBytes > highBytes) - highBytes = ms.LiveBytes; - } + c.Color = White; + c.MoveTo (x - 50, y - 50); + c.LineTo (x + w + 50, y - 50); + c.LineTo (x + w + 50, y + h + 50); + c.LineTo (x - 50, y + h + 50); + c.Clip (); + c.Fill (); + c.Paint (); + c.Stroke (); + + myWindow.GetGeometry (out x, out y, out w, out h, out d); + + long TimeSpan = HighTime - LowTime; + if (TimeSpan == 0) + return; + + long LowBytes = ((MemStamp)StampBook [0]).Bytes; + long HighBytes = 0; - const double GraphWidth = 570; - const double GraphHeight = 420; - const double GraphOriginX = SurfaceWidth - GraphWidth - 15; - const double GraphOriginY = 15; + foreach (MemStamp ms in StampBook) { + if (ms.Type != null) + continue; - // We need to scale this puppy... - double xscale = (double)domain / GraphWidth; - double yrange = highBytes - lowBytes; - double yscale = yrange / GraphHeight; - - //Matrix m = c.Matrix; - //m.Scale (xscale, yscale); - //c.Matrix = m; - - c.Color = new Color (0, 0, 0, 1); - - c.LineWidth = 2; - c.Rectangle (GraphOriginX, GraphOriginY, GraphWidth, GraphHeight); - - c.MoveTo (GraphOriginX, GraphOriginY + GraphHeight); - long lowTime = ((MemStamp)Stamps [0]).TimeT; - foreach (MemStamp ms in Stamps) { - c.LineTo (GraphOriginX + (double)(ms.TimeT - lowTime) / xscale, GraphOriginY + GraphHeight - (double)(ms.LiveBytes - lowBytes) / yscale); - } - c.LineWidth = 1.5; - c.Stroke (); - - // Draw the Memory Text - // Tick Marks... - c.FontSize = 15; - c.LineWidth = 1; + if (ms.Bytes < LowBytes) + LowBytes = ms.Bytes; + if (ms.Bytes > HighBytes) + HighBytes = ms.Bytes; + } + + double GOY; + double GOX; + double GW; + double GH; + double xscale; + double yscale; + double yrange; + string label; + + c.Scale (Scale, Scale); + + c.FontSize = 15 * w / 640; + if (15 * w / 640 > 20) + c.FontSize = 20; + + label = Util.PrettySize (HighBytes); + GOY = h - c.TextExtents (label).Height - 30; + + c.FontSize = 15 * h / 480; + if (15 * h / 480 > 20) + c.FontSize = 20; - for (int i = 0; i <= 10; i++) { - c.MoveTo (GraphOriginX - 5, GraphOriginY + GraphHeight - i * GraphHeight / 10); - c.LineTo (GraphOriginX, GraphOriginY + GraphHeight - i * GraphHeight / 10); - c.Stroke (); - - string s = Util.PrettySize (lowBytes + (i * (long)yrange / 10)); - TextExtents e = c.TextExtents (s); - c.MoveTo (GraphOriginX - e.Width - 10, GraphOriginY + GraphHeight - i * GraphHeight / 10 + 0.5 * e.Height); - c.ShowText (s); - } - - // Draw the time Text - for (int i = 0; i < 15; i++) { - c.MoveTo (GraphOriginX + i * GraphWidth / 10, GraphOriginY + GraphHeight); - c.LineTo (GraphOriginX + i * GraphWidth / 10, GraphOriginY + GraphHeight + 5); - c.Stroke (); + GOX = c.TextExtents (label).Width + 15; + GW = w - GOX - 10; + GH = GOY - 10; - string s = Util.PrettyTime (i * domain / 10); - TextExtents e = c.TextExtents (s); - c.MoveTo (GraphOriginX + i * GraphWidth / 10 - 0.5 * e.Width, GraphOriginY + GraphHeight + 10 + e.Height); - c.ShowText (s); - } - - Application.Init (); - - Window win = new Window ("Heap-Buddy"); - win.SetDefaultSize (640, 480); - - da = new CairoGraph (); - win.Add (da); - - win.ShowAll (); - - Application.Run (); + xscale = (double)TimeSpan / GW; + yrange = HighBytes - LowBytes; + yscale = yrange / GH; - if (filename == null) - filename = "memlog.png"; + c.MoveTo (GOX, GOY); - surface.WriteToPng (filename); - surface.Finish (); + double oldX = GOX; + double oldY = GOY; + double newX, newY; + + c.LineWidth = 1.5; + c.Color = Blue; + foreach (MemStamp ms in StampBook) { + if (ms.Type != null) + continue; + + newX = GOX + (double)(ms.Seconds + ms.USeconds / 1000 - LowTime) / xscale; + newY = GOY - (double)(ms.Bytes - LowBytes) / yscale; + + c.MoveTo (oldX, oldY); + c.LineTo (newX, newY); + c.Stroke (); + + oldX = newX; + oldY = newY; + } + + // Labels + c.Color = Black; + c.LineWidth = 1; + c.FontSize = 15 * h / 480; + if (15 * h / 480 > 20) + c.FontSize = 20; + + // Memory + for (int i = 0; i <= 10; i++) { + c.MoveTo (GOX - 5, GOY - i * GH / 10); + c.LineTo (GOX, GOY - i * GH / 10); + c.Stroke (); + + label = Util.PrettySize (LowBytes + (i * (long)yrange / 10)); + TextExtents e = c.TextExtents (label); + c.MoveTo (GOX - 10 - e.Width, GOY - i * GH / 10 + 0.5 * e.Height); + c.ShowText (label); + } + + // Time + c.FontSize = 15 * w / 640; + if (15 * w / 640 > 20) + c.FontSize = 20; + + for (int i = 0; i < 15; i++) { + c.MoveTo (GOX + i * GW / 15, GOY); + c.LineTo (GOX + i * GW / 15, GOY + 5); + c.Stroke (); + + label = Util.PrettyTime (i * TimeSpan / 15); + TextExtents e = c.TextExtents (label); + c.MoveTo (GOX + i * GW / 15 - 0.5 * e.Width, GOY + 15 + e.Height); + c.ShowText (label); + } + + //Border + c.Color = Black; + c.LineWidth = 2; + c.Rectangle (GOX, GOY, GW, -GH); + c.Stroke (); } - + protected void ButtonPress (object o, ButtonPressEventArgs e) + { + Scale = 2; + Draw (); + QueueDrawArea (x, y, w, h); + Console.Write ("Down : "); + } - private void CollectStamps (OutfileReader reader) + protected void ButtonRelease (object o, ButtonReleaseEventArgs e) { - foreach (Gc gc in reader.Gcs) { - Stamps.Add (new MemStamp (gc.PostGcLiveBytes, gc.TimeT)); - } - - foreach (Resize r in reader.Resizes) { - Stamps.Add (new MemStamp (r.TotalLiveBytes, r.time_t)); - } + Scale = 1; + Draw (); + QueueDrawArea (x, y, w, h); + Console.WriteLine ("Up"); } - - private void Sort () + + protected override bool OnExposeEvent (Gdk.EventExpose args) { - IComparer ic = new MemStampComparer (); - Stamps.Sort (ic); + myWindow = args.Window; + + myContext = Gdk.Context.CreateDrawable (myWindow); + Draw (); + + return true; } - + } } - -public class CairoGraph : DrawingArea -{ - protected override bool OnExposeEvent (Gdk.EventExpose args) - { - Gdk.Window win = args.Window; - - Cairo.Context g = Gdk.Context.CreateDrawable (win); - - g.ResetClip (); - g.Color = new Color (0, .6, .6, 1); - g.Paint (); - - g.Color = new Color (1, 1, 1, 1); - g.MoveTo (0, 0); - g.LineTo (500, 500); - g.LineWidth = 4; - g.Stroke (); - - return true; - } -} Modified: branches/dmsnell/heap-buddy/analyzer/OutfileReader.cs =================================================================== --- branches/dmsnell/heap-buddy/analyzer/OutfileReader.cs 2006-08-27 07:14:37 UTC (rev 64426) +++ branches/dmsnell/heap-buddy/analyzer/OutfileReader.cs 2006-08-27 08:10:30 UTC (rev 64427) @@ -32,8 +32,8 @@ public bool Debug = false; const uint magic_number = 0x4eabbdd1; - const int expected_log_version = 5; - const int expected_summary_version = 2; + const int expected_log_version = 6; + const int expected_summary_version = 3; const string log_file_label = "heap-buddy logfile"; const string summary_file_label = "heap-buddy summary"; @@ -473,6 +473,7 @@ gc.Generation = reader.ReadInt32 (); gc.TimeT = reader.ReadInt64 (); + gc.UTimeT = reader.ReadInt64 (); gc.Timestamp = Util.ConvertTimeT (gc.TimeT); gc.PreGcLiveBytes = reader.ReadInt64 (); gc.PreGcLiveObjects = reader.ReadInt32 (); @@ -962,6 +963,7 @@ gc.Generation = reader.ReadInt32 (); gc.TimeT = reader.ReadInt64 (); + gc.UTimeT = reader.ReadInt64 (); gc.Timestamp = Util.ConvertTimeT (gc.TimeT); gc.PreGcLiveBytes = reader.ReadInt64 (); gc.PreGcLiveObjects = reader.ReadInt32 (); @@ -1068,6 +1070,7 @@ for (int i = 0; i < gcs.Length; ++i) { writer.Write (gcs [i].Generation); writer.Write (gcs [i].TimeT); + writer.Write (gcs [i].UTimeT); writer.Write (gcs [i].PreGcLiveBytes); writer.Write (gcs [i].PreGcLiveObjects); writer.Write (gcs [i].PostGcLiveBytes); @@ -1158,7 +1161,9 @@ public GcData [] GetGcData (int generation) { - lazy_reader.BaseStream.Seek (gc_pos [generation], SeekOrigin.Begin); + try { + lazy_reader.BaseStream.Seek (gc_pos [generation], SeekOrigin.Begin); + } catch (Exception e) { } int length; length = lazy_reader.ReadInt32 (); Modified: branches/dmsnell/heap-buddy/profiler/heap-buddy.c =================================================================== --- branches/dmsnell/heap-buddy/profiler/heap-buddy.c 2006-08-27 07:14:37 UTC (rev 64426) +++ branches/dmsnell/heap-buddy/profiler/heap-buddy.c 2006-08-27 08:10:30 UTC (rev 64427) @@ -23,6 +23,8 @@ * USA. */ +#include <assert.h> +#include <stdlib.h> #include <string.h> #include <glib.h> #include <mono/metadata/assembly.h> @@ -66,6 +68,77 @@ /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ +GHashTable *memlog = NULL; +const char *memlog_name = "outfile.types"; +FILE *memlog_file = NULL; + +void +init_memory_logging ( ) +{ + memlog_file = fopen (memlog_name, "w+"); + + memlog = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); +} + +void +clear_memory_log ( ) +{ + g_hash_table_destroy (memlog); + memlog = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); +} + +void +close_memory_logging ( ) +{ + g_hash_table_destroy (memlog); + + fclose (memlog_file); +} + +void +memlog_add_alloc (MonoObject *obj, MonoClass *klass) +{ + const char *name; + gint32 *size; + + size = g_new0 (gint32, 1); + + *size = mono_object_get_size (obj); + name = mono_class_get_name (klass); + + //type = g_hash_table_lookup (memlog, name); + + gpointer old_key; + gpointer old_val; + + if (g_hash_table_lookup_extended (memlog, name, &old_key, &old_val)) + *(gint32 *)old_val += *size; + else + g_hash_table_insert (memlog, g_strdup (name), GINT_TO_POINTER(size)); + +} + +void +memlog_add_gc_obj (Accountant *acct) +{ + const char * name = mono_class_get_name (acct->klass); + + gpointer old_key; + gpointer old_val; + + if (g_hash_table_lookup_extended (memlog, name, &old_key, &old_val)) { + *(gint32 *)old_val = acct->n_allocated_bytes; + } +} + +void +memlog_update_log_file (gpointer key, gpointer val, gpointer data) +{ + type_writer_update_types (memlog_file, (const char *)key, *(gint32 *)val); +} + +/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ + static void heap_buddy_alloc_func (MonoProfiler *p, MonoObject *obj, MonoClass *klass) { @@ -90,6 +163,8 @@ p->total_live_bytes += size; p->total_allocated_objects++; p->total_live_objects++; + + memlog_add_alloc (obj, klass); mono_mutex_unlock (&p->lock); } @@ -112,6 +187,8 @@ { MonoProfiler *p = user_data; Accountant *acct = value; + + memlog_add_gc_obj (acct); // Only log the accountant's stats to the outfile if // something has changed since the last time it was logged. @@ -131,6 +208,8 @@ return; mono_mutex_lock (&p->lock); + + type_writer_start_types (memlog_file, memlog); prev_total_live_bytes = p->total_live_bytes; prev_total_live_objects = p->total_live_objects; @@ -151,6 +230,9 @@ p->total_allocated_objects, p->total_live_bytes, p->total_live_objects); + + g_hash_table_foreach (memlog, memlog_update_log_file, NULL); + clear_memory_log (); mono_mutex_unlock (&p->lock); } @@ -172,6 +254,8 @@ heap_buddy_gc_func (p, MONO_GC_EVENT_MARK_END, -1); outfile_writer_close (p->outfile_writer); + + close_memory_logging (); } void @@ -193,6 +277,8 @@ g_print ("*** Running with heap-buddy ***\n"); + init_memory_logging (); + mono_profiler_install_allocation (heap_buddy_alloc_func); mono_profiler_install_gc (heap_buddy_gc_func, heap_buddy_gc_resize_func); @@ -203,9 +289,3 @@ mono_profiler_install (p, heap_buddy_shutdown); } - -void -socket_init () -{ - -} Modified: branches/dmsnell/heap-buddy/profiler/outfile-writer.c =================================================================== --- branches/dmsnell/heap-buddy/profiler/outfile-writer.c 2006-08-27 07:14:37 UTC (rev 64426) +++ branches/dmsnell/heap-buddy/profiler/outfile-writer.c 2006-08-27 08:10:30 UTC (rev 64427) @@ -23,13 +23,16 @@ * USA. */ +#include <glib.h> #include <string.h> +#include <stdint.h> #include <time.h> +#include <sys/time.h> #include "outfile-writer.h" #define MAGIC_NUMBER 0x4eabbdd1 -#define FILE_FORMAT_VERSION 5 +#define FILE_FORMAT_VERSION 6 #define FILE_LABEL "heap-buddy logfile" #define TAG_TYPE 0x01 @@ -220,6 +223,28 @@ fflush (ofw->out); } +void +type_writer_start_types (FILE * file, GHashTable *g) +{ +// time_t timestamp; +// time (×tamp); + struct timeval time; + gettimeofday (&time, NULL); + + //fprintf (file, "%d elements\n", (int)g_hash_table_size (g)); + write_int64 (file, (gint64)time.tv_sec); + write_int64 (file, (gint64)time.tv_usec); + write_uint32 (file, (guint32)g_hash_table_size (g)); +} + +void +type_writer_update_types (FILE * file, const char *name, gint32 bytes) +{ + //fprintf (file, "\t%d bytes of %s\n", (int)bytes, name); + write_int32 (file, bytes); + write_string (file, name); +} + // total_live_bytes is the total size of all of the live objects // before the GC void @@ -229,12 +254,15 @@ gint32 total_live_objects, gint32 n_accountants) { - time_t timestamp; - time (×tamp); - + //time_t timestamp; + //time (×tamp); + struct timeval time; + gettimeofday (&time, NULL); + write_byte (ofw->out, TAG_GC); write_int32 (ofw->out, is_final ? -1 : ofw->gc_count); - write_int64 (ofw->out, (gint64) timestamp); + write_int64 (ofw->out, (gint64) time.tv_sec); + write_int64 (ofw->out, (gint64) time.tv_usec); write_int64 (ofw->out, total_live_bytes); write_int32 (ofw->out, total_live_objects); write_int32 (ofw->out, n_accountants); Modified: branches/dmsnell/heap-buddy/profiler/outfile-writer.h =================================================================== --- branches/dmsnell/heap-buddy/profiler/outfile-writer.h 2006-08-27 07:14:37 UTC (rev 64426) +++ branches/dmsnell/heap-buddy/profiler/outfile-writer.h 2006-08-27 08:10:30 UTC (rev 64427) @@ -47,6 +47,10 @@ void outfile_writer_add_accountant (OutfileWriter *ofw, Accountant *acct); +void type_writer_start_types (FILE * file, GHashTable *g); + +void type_writer_update_types (FILE * file, const char *name, gint32 bytes); + void outfile_writer_gc_begin (OutfileWriter *ofw, gboolean is_final, gint64 total_live_bytes, _______________________________________________ Mono-patches maillist - Mono-patches@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-patches