Author: lluis
Date: 2006-11-22 12:38:12 -0500 (Wed, 22 Nov 2006)
New Revision: 68356
Modified:
trunk/heap-shot/ChangeLog
trunk/heap-shot/HeapShot.Gui.Widgets/ReferenceTreeViewer.cs
trunk/heap-shot/HeapShot.Gui.Widgets/gtk-gui/gui.stetic
trunk/heap-shot/HeapShot.Reader/ObjectMapFileReader.cs
trunk/heap-shot/HeapShot.Reader/ReferenceNode.cs
trunk/heap-shot/profiler/heap-shot.c
trunk/heap-shot/profiler/outfile-writer.c
Log:
* profiler/outfile-writer.c, profiler/heap-shot.c: Scan the whole type
hierarchy of a type when looking for references.
* HeapShot.Gui.Widgets/ReferenceTreeViewer.cs,
HeapShot.Reader/ReferenceNode.cs: Added column which shows the
reference count to the root type being inspected.
* HeapShot.Gui.Widgets/gtk-gui/gui.stetic: Updated.
* HeapShot.Reader/ObjectMapFileReader.cs: Added GetRoots method, not
used right now.
Modified: trunk/heap-shot/ChangeLog
===================================================================
--- trunk/heap-shot/ChangeLog 2006-11-22 17:16:43 UTC (rev 68355)
+++ trunk/heap-shot/ChangeLog 2006-11-22 17:38:12 UTC (rev 68356)
@@ -1,3 +1,14 @@
+2006-11-22 Lluis Sanchez Gual <[EMAIL PROTECTED]>
+
+ * profiler/outfile-writer.c, profiler/heap-shot.c: Scan the whole type
+ hierarchy of a type when looking for references.
+ * HeapShot.Gui.Widgets/ReferenceTreeViewer.cs,
+ HeapShot.Reader/ReferenceNode.cs: Added column which shows the
+ reference count to the root type being inspected.
+ * HeapShot.Gui.Widgets/gtk-gui/gui.stetic: Updated.
+ * HeapShot.Reader/ObjectMapFileReader.cs: Added GetRoots method, not
+ used right now.
+
2006-11-15 Lluis Sanchez Gual <[EMAIL PROTECTED]>
* HeapShot.Gui.Widgets/ReferenceTreeViewer.cs: Removed debug code.
Modified: trunk/heap-shot/HeapShot.Gui.Widgets/ReferenceTreeViewer.cs
===================================================================
--- trunk/heap-shot/HeapShot.Gui.Widgets/ReferenceTreeViewer.cs 2006-11-22
17:16:43 UTC (rev 68355)
+++ trunk/heap-shot/HeapShot.Gui.Widgets/ReferenceTreeViewer.cs 2006-11-22
17:38:12 UTC (rev 68356)
@@ -22,6 +22,7 @@
const int AvgSizeCol = 5;
const int InstancesCol = 6;
const int RefsCol = 7;
+ const int RootRefsCol = 8;
int TreeColRefs;
bool reloadRequested;
bool loading;
@@ -35,7 +36,7 @@
public ReferenceTreeViewer()
{
Stetic.Gui.Build(this,
typeof(HeapShot.Gui.Widgets.ReferenceTreeViewer));
- store = new Gtk.TreeStore (typeof(object),
typeof(string), typeof(string), typeof(bool), typeof(string), typeof(string),
typeof(string), typeof(string));
+ store = new Gtk.TreeStore (typeof(object),
typeof(string), typeof(string), typeof(bool), typeof(string), typeof(string),
typeof(string), typeof(string), typeof(string));
treeview.Model = store;
treeview.HeadersClickable = true;
@@ -55,17 +56,20 @@
treeview.AppendColumn (complete_column);
CellRendererText crt = new CellRendererText ();
crt.Xalign = 1;
- treeview.AppendColumn ("Instances", crt, "text",
InstancesCol).Clickable = true;
+ treeview.AppendColumn ("Instances", crt, "text",
InstancesCol);
crt = new CellRendererText ();
crt.Xalign = 1;
TreeColRefs = treeview.Columns.Length;
- treeview.AppendColumn ("References", crt, "text",
RefsCol).Clickable = true;
+ treeview.AppendColumn ("References", crt, "text",
RefsCol);
crt = new CellRendererText ();
crt.Xalign = 1;
- treeview.AppendColumn ("Memory Size", crt, "text",
SizeCol).Clickable = true;
+ treeview.AppendColumn ("Root Refs", crt, "text",
RootRefsCol);
crt = new CellRendererText ();
crt.Xalign = 1;
- treeview.AppendColumn ("Avg. Size", crt, "text",
AvgSizeCol).Clickable = true;
+ treeview.AppendColumn ("Memory Size", crt, "text",
SizeCol);
+ crt = new CellRendererText ();
+ crt.Xalign = 1;
+ treeview.AppendColumn ("Avg. Size", crt, "text",
AvgSizeCol);
treeview.TestExpandRow += new Gtk.TestExpandRowHandler
(OnTestExpandRow);
treeview.RowActivated += new Gtk.RowActivatedHandler
(OnNodeActivated);
@@ -114,6 +118,7 @@
this.typeName = null;
boxFilter.Visible = true;
treeview.Columns [TreeColRefs].Visible =
InverseReferences;
+ treeview.Columns [TreeColRefs+1].Visible =
InverseReferences;
if (loading) {
// If the tree is already being loaded, notify
that loading
@@ -153,6 +158,7 @@
store.Clear ();
boxFilter.Visible = false;
treeview.Columns [TreeColRefs].Visible =
InverseReferences;
+ treeview.Columns [TreeColRefs+1].Visible =
InverseReferences;
TreeIter iter = InternalFillType (file,
file.GetTypeFromName (typeName));
treeview.ExpandRow (store.GetPath (iter), false);
}
@@ -178,15 +184,16 @@
TreeIter iter;
if (parent.Equals (TreeIter.Zero)) {
- iter = store.AppendValues (node, "class",
node.TypeName, !node.HasReferences, node.TotalMemory.ToString("n0"),
node.AverageSize.ToString("n0"), node.RefCount.ToString ("n0"), "");
+ iter = store.AppendValues (node, "class",
node.TypeName, !node.HasReferences, node.TotalMemory.ToString("n0"),
node.AverageSize.ToString("n0"), node.RefCount.ToString ("n0"), "", "");
} else {
string refs = (InverseReferences ?
node.RefsToParent.ToString ("n0") : "");
- iter = store.AppendValues (parent, node,
"class", node.TypeName, !node.HasReferences, node.TotalMemory.ToString("n0"),
node.AverageSize.ToString("n0"), node.RefCount.ToString ("n0"), refs);
+ string rootRefs = (InverseReferences ?
node.RefsToRoot.ToString ("n0") : "");
+ iter = store.AppendValues (parent, node,
"class", node.TypeName, !node.HasReferences, node.TotalMemory.ToString("n0"),
node.AverageSize.ToString("n0"), node.RefCount.ToString ("n0"), refs, rootRefs);
}
if (node.HasReferences) {
// Add a dummy element to make the expansion
icon visible
- store.AppendValues (iter, null, "", "", true,
"", "", "", "");
+ store.AppendValues (iter, null, "", "", true,
"", "", "", "", "");
}
return iter;
}
@@ -194,9 +201,9 @@
TreeIter AddNode (TreeIter parent, FieldReference node)
{
if (parent.Equals (TreeIter.Zero))
- return store.AppendValues (node, "field",
node.FiledName, true, "", "", node.RefCount.ToString ("n0"), "");
+ return store.AppendValues (node, "field",
node.FiledName, true, "", "", node.RefCount.ToString ("n0"), "", "");
else
- return store.AppendValues (parent, node,
"field", node.FiledName, true, "", "", node.RefCount.ToString ("n0"), "");
+ return store.AppendValues (parent, node,
"field", node.FiledName, true, "", "", node.RefCount.ToString ("n0"), "", "");
}
private void OnTestExpandRow (object sender,
Gtk.TestExpandRowArgs args)
@@ -264,20 +271,21 @@
case 2:
return
nod1.RefsToParent.CompareTo (nod2.RefsToParent);
case 3:
+ return
nod1.RefsToRoot.CompareTo (nod2.RefsToRoot);
+ case 4:
return
nod1.TotalMemory.CompareTo (nod2.TotalMemory);
- case 4:
+ case 5:
return
nod1.AverageSize.CompareTo (nod2.AverageSize);
default:
- Console.WriteLine ("PPP: " +
col);
return 1;
// throw new
InvalidOperationException ();
}
} else if (o1 is FieldReference && o2 is
FieldReference) {
return ((FieldReference)o1).FiledName.CompareTo
(((FieldReference)o2).FiledName);
} else if (o1 is FieldReference) {
+ return 1;
+ } else {
return -1;
- } else {
- return 1;
}
}
Modified: trunk/heap-shot/HeapShot.Gui.Widgets/gtk-gui/gui.stetic
===================================================================
--- trunk/heap-shot/HeapShot.Gui.Widgets/gtk-gui/gui.stetic 2006-11-22
17:16:43 UTC (rev 68355)
+++ trunk/heap-shot/HeapShot.Gui.Widgets/gtk-gui/gui.stetic 2006-11-22
17:38:12 UTC (rev 68356)
@@ -13,27 +13,27 @@
</icon-set>
</icon-factory>
<widget class="Gtk.Bin" id="HeapShot.Gui.Widgets.ObjectMapViewer"
design-size="556 300">
+ <property name="MemberName" />
<property name="Events">ButtonPressMask</property>
- <property name="MemberName" />
<child>
<widget class="Gtk.HBox" id="hbox3">
<property name="Spacing">6</property>
+ <property name="MemberName" />
<property name="Events">0</property>
- <property name="MemberName" />
<child>
<widget class="Gtk.ScrolledWindow" id="scrolledwindow2">
<property name="VscrollbarPolicy">Automatic</property>
<property name="HscrollbarPolicy">Never</property>
<property name="ShadowType">In</property>
+ <property name="MemberName" />
<property name="CanFocus">True</property>
<property name="Events">0</property>
- <property name="MemberName" />
<child>
<widget class="Gtk.TreeView" id="fileList">
<property name="HeadersVisible">False</property>
+ <property name="MemberName">fileList</property>
<property name="CanFocus">True</property>
<property name="Events">0</property>
- <property name="MemberName">fileList</property>
</widget>
</child>
</widget>
@@ -47,9 +47,9 @@
<child>
<widget class="Gtk.Notebook" id="notebook">
<property name="Scrollable">True</property>
+ <property name="MemberName">notebook</property>
<property name="CanFocus">True</property>
<property name="Events">0</property>
- <property name="MemberName">notebook</property>
<child>
<widget class="Gtk.Table" id="table1">
<property name="NRows">3</property>
@@ -57,134 +57,134 @@
<property name="RowSpacing">6</property>
<property name="ColumnSpacing">6</property>
<property name="BorderWidth">12</property>
+ <property name="MemberName" />
<property name="Events">0</property>
- <property name="MemberName" />
<child>
- <widget class="Gtk.Label" id="labelMemory">
- <property name="LabelProp" />
+ <widget class="Gtk.Label" id="label3">
+ <property name="LabelProp" translatable="yes"
context="yes" comments="">|Name:</property>
<property name="Xalign">0</property>
+ <property name="MemberName" />
<property name="Events">0</property>
- <property name="MemberName">labelMemory</property>
</widget>
<packing>
- <property name="BottomAttach">3</property>
- <property name="LeftAttach">1</property>
- <property name="YExpand">False</property>
- <property name="RightAttach">2</property>
<property name="AutoSize">True</property>
- <property name="YShrink">False</property>
- <property name="TopAttach">2</property>
+ <property name="XOptions">Fill</property>
+ <property name="YOptions">Fill</property>
+ <property name="XExpand">False</property>
+ <property name="XFill">True</property>
<property name="XShrink">False</property>
- <property name="XExpand">False</property>
+ <property name="YExpand">False</property>
<property name="YFill">True</property>
- <property name="XFill">True</property>
- <property name="YOptions">Fill</property>
- <property name="XOptions">Fill</property>
+ <property name="YShrink">False</property>
</packing>
</child>
<child>
- <widget class="Gtk.Label" id="labelCount">
- <property name="LabelProp" />
+ <widget class="Gtk.Label" id="label4">
+ <property name="LabelProp" translatable="yes"
context="yes" comments="">|Object count:</property>
<property name="Xalign">0</property>
+ <property name="MemberName" />
<property name="Events">0</property>
- <property name="MemberName">labelCount</property>
</widget>
<packing>
+ <property name="TopAttach">1</property>
<property name="BottomAttach">2</property>
- <property name="LeftAttach">1</property>
- <property name="YExpand">False</property>
- <property name="RightAttach">2</property>
<property name="AutoSize">True</property>
- <property name="YShrink">False</property>
- <property name="TopAttach">1</property>
+ <property name="XOptions">Fill</property>
+ <property name="YOptions">Fill</property>
+ <property name="XExpand">False</property>
+ <property name="XFill">True</property>
<property name="XShrink">False</property>
- <property name="XExpand">False</property>
+ <property name="YExpand">False</property>
<property name="YFill">True</property>
- <property name="XFill">True</property>
- <property name="YOptions">Fill</property>
- <property name="XOptions">Fill</property>
+ <property name="YShrink">False</property>
</packing>
</child>
<child>
- <widget class="Gtk.Label" id="labelName">
- <property name="LabelProp" />
+ <widget class="Gtk.Label" id="label5">
+ <property name="LabelProp" translatable="yes"
context="yes" comments="">|Total memory:</property>
<property name="Xalign">0</property>
+ <property name="MemberName" />
<property name="Events">0</property>
- <property name="MemberName">labelName</property>
</widget>
<packing>
- <property name="LeftAttach">1</property>
- <property name="YExpand">False</property>
- <property name="RightAttach">2</property>
+ <property name="TopAttach">2</property>
+ <property name="BottomAttach">3</property>
<property name="AutoSize">True</property>
- <property name="YShrink">False</property>
+ <property name="XOptions">Fill</property>
+ <property name="YOptions">Fill</property>
+ <property name="XExpand">False</property>
+ <property name="XFill">True</property>
<property name="XShrink">False</property>
- <property name="XExpand">False</property>
+ <property name="YExpand">False</property>
<property name="YFill">True</property>
- <property name="XFill">True</property>
- <property name="YOptions">Fill</property>
- <property name="XOptions">Fill</property>
+ <property name="YShrink">False</property>
</packing>
</child>
<child>
- <widget class="Gtk.Label" id="label5">
- <property name="LabelProp" translatable="yes"
context="yes" comments="">|Total memory:</property>
+ <widget class="Gtk.Label" id="labelName">
+ <property name="LabelProp" />
<property name="Xalign">0</property>
+ <property name="MemberName">labelName</property>
<property name="Events">0</property>
- <property name="MemberName" />
</widget>
<packing>
- <property name="BottomAttach">3</property>
- <property name="YExpand">False</property>
+ <property name="LeftAttach">1</property>
+ <property name="RightAttach">2</property>
<property name="AutoSize">True</property>
- <property name="YShrink">False</property>
- <property name="TopAttach">2</property>
+ <property name="XOptions">Fill</property>
+ <property name="YOptions">Fill</property>
+ <property name="XExpand">False</property>
+ <property name="XFill">True</property>
<property name="XShrink">False</property>
- <property name="XExpand">False</property>
+ <property name="YExpand">False</property>
<property name="YFill">True</property>
- <property name="XFill">True</property>
- <property name="YOptions">Fill</property>
- <property name="XOptions">Fill</property>
+ <property name="YShrink">False</property>
</packing>
</child>
<child>
- <widget class="Gtk.Label" id="label4">
- <property name="LabelProp" translatable="yes"
context="yes" comments="">|Object count:</property>
+ <widget class="Gtk.Label" id="labelCount">
+ <property name="LabelProp" />
<property name="Xalign">0</property>
+ <property name="MemberName">labelCount</property>
<property name="Events">0</property>
- <property name="MemberName" />
</widget>
<packing>
+ <property name="TopAttach">1</property>
<property name="BottomAttach">2</property>
- <property name="YExpand">False</property>
+ <property name="LeftAttach">1</property>
+ <property name="RightAttach">2</property>
<property name="AutoSize">True</property>
- <property name="YShrink">False</property>
- <property name="TopAttach">1</property>
+ <property name="XOptions">Fill</property>
+ <property name="YOptions">Fill</property>
+ <property name="XExpand">False</property>
+ <property name="XFill">True</property>
<property name="XShrink">False</property>
- <property name="XExpand">False</property>
+ <property name="YExpand">False</property>
<property name="YFill">True</property>
- <property name="XFill">True</property>
- <property name="YOptions">Fill</property>
- <property name="XOptions">Fill</property>
+ <property name="YShrink">False</property>
</packing>
</child>
<child>
- <widget class="Gtk.Label" id="label3">
- <property name="LabelProp" translatable="yes"
context="yes" comments="">|Name:</property>
+ <widget class="Gtk.Label" id="labelMemory">
+ <property name="LabelProp" />
<property name="Xalign">0</property>
+ <property name="MemberName">labelMemory</property>
<property name="Events">0</property>
- <property name="MemberName" />
</widget>
<packing>
- <property name="YExpand">False</property>
+ <property name="TopAttach">2</property>
+ <property name="BottomAttach">3</property>
+ <property name="LeftAttach">1</property>
+ <property name="RightAttach">2</property>
<property name="AutoSize">True</property>
- <property name="YShrink">False</property>
+ <property name="XOptions">Fill</property>
+ <property name="YOptions">Fill</property>
+ <property name="XExpand">False</property>
+ <property name="XFill">True</property>
<property name="XShrink">False</property>
- <property name="XExpand">False</property>
+ <property name="YExpand">False</property>
<property name="YFill">True</property>
- <property name="XFill">True</property>
- <property name="YOptions">Fill</property>
- <property name="XOptions">Fill</property>
+ <property name="YShrink">False</property>
</packing>
</child>
</widget>
@@ -195,8 +195,8 @@
<child>
<widget class="Gtk.Label" id="label9">
<property name="LabelProp">Summary</property>
+ <property name="MemberName" />
<property name="Events">0</property>
- <property name="MemberName" />
</widget>
<packing>
<property name="type">tab</property>
@@ -216,8 +216,8 @@
<child>
<widget class="Gtk.Label" id="label2">
<property name="LabelProp">All objects</property>
+ <property name="MemberName" />
<property name="Events">0</property>
- <property name="MemberName" />
</widget>
<packing>
<property name="type">tab</property>
@@ -233,27 +233,27 @@
</child>
</widget>
<widget class="Gtk.Bin" id="HeapShot.Gui.Widgets.ReferenceTreeViewer"
design-size="480 300">
+ <property name="MemberName" />
<property name="Events">ButtonPressMask</property>
- <property name="MemberName" />
<child>
<widget class="Gtk.VBox" id="vbox1">
<property name="Spacing">6</property>
<property name="BorderWidth">6</property>
+ <property name="MemberName" />
<property name="Events">0</property>
- <property name="MemberName" />
<child>
<widget class="Gtk.ScrolledWindow" id="scrolledwindow1">
<property name="VscrollbarPolicy">Automatic</property>
<property name="HscrollbarPolicy">Automatic</property>
<property name="ShadowType">In</property>
+ <property name="MemberName" />
<property name="CanFocus">True</property>
<property name="Events">0</property>
- <property name="MemberName" />
<child>
<widget class="Gtk.TreeView" id="treeview">
+ <property name="MemberName">treeview</property>
<property name="CanFocus">True</property>
<property name="Events">0</property>
- <property name="MemberName">treeview</property>
</widget>
</child>
</widget>
@@ -265,20 +265,20 @@
<child>
<widget class="Gtk.HBox" id="hbox1">
<property name="Spacing">6</property>
+ <property name="MemberName" />
<property name="Events">0</property>
- <property name="MemberName" />
<child>
<widget class="Gtk.HBox" id="boxFilter">
<property name="Spacing">3</property>
+ <property name="MemberName">boxFilter</property>
<property name="Events">0</property>
- <property name="MemberName">boxFilter</property>
<child>
<widget class="Gtk.Entry" id="entryFilter">
<property name="IsEditable">True</property>
<property name="InvisibleChar">●</property>
+ <property name="MemberName">entryFilter</property>
<property name="CanFocus">True</property>
<property name="Events">0</property>
- <property name="MemberName">entryFilter</property>
<signal name="Activated" handler="OnEntryFilterActivated"
/>
</widget>
<packing>
@@ -291,9 +291,9 @@
<property name="Type">TextOnly</property>
<property name="Label">Filter</property>
<property name="IsDialogButton">False</property>
+ <property name="MemberName" />
<property name="CanFocus">True</property>
<property name="Events">0</property>
- <property name="MemberName" />
<signal name="Clicked" handler="OnButtonFilterClicked" />
</widget>
<packing>
@@ -314,9 +314,9 @@
<property name="Label">Inverse references</property>
<property name="DrawIndicator">True</property>
<property name="HasLabel">True</property>
+ <property name="MemberName">checkInverse</property>
<property name="CanFocus">True</property>
<property name="Events">0</property>
- <property name="MemberName">checkInverse</property>
<signal name="Clicked" handler="OnCheckInverseClicked" />
</widget>
<packing>
Modified: trunk/heap-shot/HeapShot.Reader/ObjectMapFileReader.cs
===================================================================
--- trunk/heap-shot/HeapShot.Reader/ObjectMapFileReader.cs 2006-11-22
17:16:43 UTC (rev 68355)
+++ trunk/heap-shot/HeapShot.Reader/ObjectMapFileReader.cs 2006-11-22
17:38:12 UTC (rev 68356)
@@ -423,6 +423,48 @@
return nod;
}
+ public List<List<int>> GetRoots (int type)
+ {
+ List<int> path = new List<int> ();
+ Dictionary<int,List<int>> roots = new
Dictionary<int,List<int>> ();
+ Dictionary<int,int> visited = new Dictionary<int,int>
();
+
+ foreach (int obj in GetObjectsByType (type)) {
+ FindRoot (visited, path, roots, obj);
+ visited.Clear ();
+ }
+
+ List<List<int>> res = new List<List<int>> ();
+ res.AddRange (roots.Values);
+ return res;
+ }
+
+ void FindRoot (Dictionary<int,int> visited, List<int> path,
Dictionary<int,List<int>> roots, int obj)
+ {
+ if (visited.ContainsKey (obj))
+ return;
+ visited [obj] = obj;
+ path.Add (obj);
+
+ bool hasrefs = false;
+ foreach (int oref in GetReferencers (obj)) {
+ hasrefs = true;
+ FindRoot (visited, path, roots, oref);
+ }
+
+ if (!hasrefs) {
+ // A root
+ if (!roots.ContainsKey (obj)) {
+ roots [obj] = new List<int> (path);
+ } else {
+ List<int> ep = roots [obj];
+ if (ep.Count > path.Count)
+ roots [obj] = new List<int>
(path);
+ }
+ }
+ path.RemoveAt (path.Count - 1);
+ }
+
public int GetTypeCount ()
{
return (int) numTypes;
Modified: trunk/heap-shot/HeapShot.Reader/ReferenceNode.cs
===================================================================
--- trunk/heap-shot/HeapShot.Reader/ReferenceNode.cs 2006-11-22 17:16:43 UTC
(rev 68355)
+++ trunk/heap-shot/HeapShot.Reader/ReferenceNode.cs 2006-11-22 17:38:12 UTC
(rev 68356)
@@ -36,6 +36,7 @@
public string TypeName;
public int RefCount;
public int RefsToParent;
+ public int RefsToRoot;
public uint TotalMemory;
int type;
bool globalRefs;
@@ -71,19 +72,15 @@
public void AddReference (int obj)
{
- AddReference (-1, obj, null);
+ AddReference (-1, obj, 1, null);
}
- public void AddReference (int parentObject, int obj)
+ void AddReference (int parentObject, int obj, int refsToRoot,
string fieldName)
{
- AddReference (parentObject, obj, (string) null);
- }
-
- void AddReference (int parentObject, int obj, string fieldName)
- {
if (parentObject != -1 && !parentObjects.ContainsKey
(parentObject)) {
parentObjects [parentObject] = parentObject;
RefsToParent++;
+ RefsToRoot += refsToRoot;
}
if (fieldName != null) {
@@ -108,12 +105,14 @@
}
}
- if (refObjects.ContainsKey (obj))
+ if (refObjects.ContainsKey (obj)) {
+ refObjects [obj] = refObjects [obj] +
refsToRoot;
return;
+ }
RefCount++;
- refObjects.Add (obj, obj);
+ refObjects.Add (obj, refsToRoot);
TotalMemory += map.GetObjectSize (obj);
}
@@ -138,18 +137,19 @@
}
references = new ArrayList ();
- foreach (int obj in refObjects.Keys) {
+ foreach (KeyValuePair<int,int> entry in
refObjects) {
+ int obj = entry.Key;
if (inverse) {
foreach (int oref in
map.GetReferencers (obj)) {
ReferenceNode cnode =
GetReferenceNode (oref);
string fname =
map.GetReferencerField (oref, obj);
- cnode.AddReference
(obj, oref, fname);
+ cnode.AddReference
(obj, oref, entry.Value, fname);
}
} else {
foreach (int oref in
map.GetReferences (obj)) {
ReferenceNode cnode =
GetReferenceNode (oref);
string fname =
map.GetReferencerField (obj, oref);
- cnode.AddReference
(obj, oref, fname);
+ cnode.AddReference
(obj, oref, 0, fname);
}
}
}
Modified: trunk/heap-shot/profiler/heap-shot.c
===================================================================
--- trunk/heap-shot/profiler/heap-shot.c 2006-11-22 17:16:43 UTC (rev
68355)
+++ trunk/heap-shot/profiler/heap-shot.c 2006-11-22 17:38:12 UTC (rev
68356)
@@ -123,43 +123,49 @@
static gboolean
heap_scan_object (MonoProfiler *p, MonoObject *obj, MonoClass *klass,
MonoClassField *parent_field)
{
- gpointer iter = NULL;
+ gpointer iter;
MonoClassField *field;
gboolean has_refs = FALSE;
+ MonoClass *cur_klass = klass;
- while ((field = mono_class_get_fields (klass, &iter)) != NULL) {
- MonoType* field_type = mono_field_get_type (field);
- // Skip static fields
- if (mono_field_get_flags (field) & 0x0010
/*FIELD_ATTRIBUTE_STATIC*/)
- continue;
+ do {
+ iter = NULL;
+ while ((field = mono_class_get_fields (cur_klass, &iter)) !=
NULL) {
+ MonoType* field_type = mono_field_get_type (field);
+ // Skip static fields
+ if (mono_field_get_flags (field) & 0x0010
/*FIELD_ATTRIBUTE_STATIC*/)
+ continue;
- if (MONO_TYPE_IS_REFERENCE (field_type)) {
- // Dump the object reference
- MonoObject* ref;
- has_refs = TRUE;
- mono_field_get_value (obj, field, &ref);
- if (ref && g_hash_table_lookup (p->work_objects_hash,
ref))
- outfile_writer_dump_object_add_reference
(p->dumpfile_writer, ref, parent_field);
- }
- else {
- MonoClass *fclass = mono_class_from_mono_type
(field_type);
- if (fclass && mono_class_is_valuetype (fclass)) {
- if (g_hash_table_lookup (p->exclude_class_hash,
fclass))
- continue;
- // It's a value type. Check if the class is big
enough to hold references
- int size = mono_class_value_size (fclass, NULL);
- if (size >= sizeof(gpointer) && fclass !=
klass) {
- // Get the object value and scan it
- char* vop = g_malloc (size);
- mono_field_get_value (obj, field, vop);
- // Recursively scan the object
- if (heap_scan_object (p,
(MonoObject*)(vop - sizeof(MonoObject)), fclass, parent_field))
- has_refs = TRUE;
- g_free (vop);
+ if (MONO_TYPE_IS_REFERENCE (field_type)) {
+ // Dump the object reference
+ MonoObject* ref;
+ has_refs = TRUE;
+ mono_field_get_value (obj, field, &ref);
+ if (ref && g_hash_table_lookup
(p->work_objects_hash, ref))
+
outfile_writer_dump_object_add_reference (p->dumpfile_writer, ref, parent_field
? parent_field : field);
+ }
+ else {
+ MonoClass *fclass = mono_class_from_mono_type
(field_type);
+ if (fclass && mono_class_is_valuetype (fclass))
{
+ if (g_hash_table_lookup
(p->exclude_class_hash, fclass))
+ continue;
+ // It's a value type. Check if the
class is big enough to hold references
+ int size = mono_class_value_size
(fclass, NULL);
+ if (size >= sizeof(gpointer) && fclass
!= cur_klass) {
+ // Get the object value and
scan it
+ char* vop = g_malloc (size);
+ mono_field_get_value (obj,
field, vop);
+ // Recursively scan the object
+ if (heap_scan_object (p,
(MonoObject*)(vop - sizeof(MonoObject)), fclass, parent_field))
+ has_refs = TRUE;
+ g_free (vop);
+ }
}
}
}
- }
+ cur_klass = mono_class_get_parent (cur_klass);
+ } while (cur_klass);
+
// If the class doesn't contain references, register in the
exclude_class_hash table,
// so it won't be scanned again.
if (!has_refs && !g_hash_table_lookup (p->exclude_class_hash, klass))
Modified: trunk/heap-shot/profiler/outfile-writer.c
===================================================================
--- trunk/heap-shot/profiler/outfile-writer.c 2006-11-22 17:16:43 UTC (rev
68355)
+++ trunk/heap-shot/profiler/outfile-writer.c 2006-11-22 17:38:12 UTC (rev
68356)
@@ -131,7 +131,8 @@
/* First, add this type if we haven't seen it before. */
if (g_hash_table_lookup (ofw->seen_items, klass) == NULL) {
MonoClassField *field;
- gpointer iter = NULL;
+ MonoClass *cur_klass = klass;
+ gpointer iter;
name = mono_type_full_name (mono_class_get_type (klass));
write_byte (ofw->out, TAG_TYPE);
@@ -142,11 +143,15 @@
++ofw->type_count;
// Write every field
- while ((field = mono_class_get_fields (klass,
&iter)) != NULL) {
- write_pointer (ofw->out, field);
- write_string (ofw->out, mono_field_get_name (field));
- ofw->field_count++;
- }
+ do {
+ iter = NULL;
+ while ((field = mono_class_get_fields
(cur_klass, &iter)) != NULL) {
+ write_pointer (ofw->out, field);
+ write_string (ofw->out, mono_field_get_name
(field));
+ ofw->field_count++;
+ }
+ cur_klass = mono_class_get_parent
(cur_klass);
+ } while (cur_klass);
write_pointer (ofw->out, NULL);
}
write_byte (ofw->out, TAG_OBJECT);
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches