Bug 702300 (part 6) - Move some code around in aboutMemory.js. r=jschoenick.
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 16 Feb 2012 22:10:39 -0800
changeset 87262 d5598ffb1aafdb5f5b7843461349096dd50b73b5
parent 87261 21fc99c3762676b8d99aed93b88f25af10067263
child 87263 4edde0ad19d888dcc68420bf6531ca8a8fc7ed12
push id22103
push userbmo@edmorley.co.uk
push dateTue, 21 Feb 2012 12:01:45 +0000
treeherdermozilla-central@4038ffaa5d82 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjschoenick
bugs702300
milestone13.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 702300 (part 6) - Move some code around in aboutMemory.js. r=jschoenick.
toolkit/components/aboutmemory/content/aboutMemory.js
--- a/toolkit/components/aboutmemory/content/aboutMemory.js
+++ b/toolkit/components/aboutmemory/content/aboutMemory.js
@@ -37,39 +37,135 @@
  * ***** END LICENSE BLOCK ***** */
 
 "use strict";
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
-const gVerbose = location.href === "about:memory?verbose";
-
 let gAddedObserver = false;
 
 const KIND_NONHEAP           = Ci.nsIMemoryReporter.KIND_NONHEAP;
 const KIND_HEAP              = Ci.nsIMemoryReporter.KIND_HEAP;
 const KIND_OTHER             = Ci.nsIMemoryReporter.KIND_OTHER;
 const UNITS_BYTES            = Ci.nsIMemoryReporter.UNITS_BYTES;
 const UNITS_COUNT            = Ci.nsIMemoryReporter.UNITS_COUNT;
 const UNITS_COUNT_CUMULATIVE = Ci.nsIMemoryReporter.UNITS_COUNT_CUMULATIVE;
 const UNITS_PERCENTAGE       = Ci.nsIMemoryReporter.UNITS_PERCENTAGE;
 
-const kUnknown = -1;    // used for an unknown _amount
-
 // Forward slashes in URLs in paths are represented with backslashes to avoid
 // being mistaken for path separators.  Paths/names/descriptions where this
 // hasn't been undone are prefixed with "unsafe"; the rest are prefixed with
 // "safe".
 function makeSafe(aUnsafeStr)
 {
   return aUnsafeStr.replace(/\\/g, '/');
 }
 
+function assert(aCond, aMsg)
+{
+  if (!aCond) {
+    throw("assertion failed: " + aMsg);
+  }
+}
+
+function debug(x)
+{
+  let content = document.getElementById("content");
+  appendElementWithText(content, "div", "legend", JSON.stringify(x));
+}
+
+//---------------------------------------------------------------------------
+
+function onLoad()
+{
+  let os = Cc["@mozilla.org/observer-service;1"].
+      getService(Ci.nsIObserverService);
+  os.notifyObservers(null, "child-memory-reporter-request", null);
+
+  os.addObserver(ChildMemoryListener, "child-memory-reporter-update", false);
+  gAddedObserver = true;
+
+  update();
+}
+
+function onUnload()
+{
+  // We need to check if the observer has been added before removing; in some
+  // circumstances (eg. reloading the page quickly) it might not have because
+  // onLoad might not fire.
+  if (gAddedObserver) {
+    let os = Cc["@mozilla.org/observer-service;1"].
+        getService(Ci.nsIObserverService);
+    os.removeObserver(ChildMemoryListener, "child-memory-reporter-update");
+  }
+}
+
+// For maximum effect, this returns to the event loop between each
+// notification.  See bug 610166 comment 12 for an explanation.
+// Ideally a single notification would be enough.
+function sendHeapMinNotifications()
+{
+  function runSoon(f)
+  {
+    let tm = Cc["@mozilla.org/thread-manager;1"]
+              .getService(Ci.nsIThreadManager);
+
+    tm.mainThread.dispatch({ run: f }, Ci.nsIThread.DISPATCH_NORMAL);
+  }
+
+  function sendHeapMinNotificationsInner()
+  {
+    let os = Cc["@mozilla.org/observer-service;1"]
+             .getService(Ci.nsIObserverService);
+    os.notifyObservers(null, "memory-pressure", "heap-minimize");
+
+    if (++j < 3)
+      runSoon(sendHeapMinNotificationsInner);
+    else
+      runSoon(update);
+  }
+
+  let j = 0;
+  sendHeapMinNotificationsInner();
+}
+
+//---------------------------------------------------------------------------
+
+function appendTextNode(aP, aText)
+{
+  let e = document.createTextNode(aText);
+  aP.appendChild(e);
+  return e;
+}
+
+function appendElement(aP, aTagName, aClassName)
+{
+  let e = document.createElement(aTagName);
+  if (aClassName) {
+    e.className = aClassName;
+  }
+  aP.appendChild(e);
+  return e;
+}
+
+function appendElementWithText(aP, aTagName, aClassName, aText)
+{
+  let e = appendElement(aP, aTagName, aClassName);
+  appendTextNode(e, aText);
+  return e;
+}
+
+//---------------------------------------------------------------------------
+
+const gVerbose = location.href === "about:memory?verbose";
+
+const kUnknown = -1;    // used for an unknown _amount
+
 const kTreeUnsafeDescriptions = {
   'explicit' :
 "This tree covers explicit memory allocations by the application, both at the \
 operating system level (via calls to functions such as VirtualAlloc, \
 vm_allocate, and mmap), and at the heap allocation level (via functions such \
 as malloc, calloc, realloc, memalign, operator new, and operator new[]).\
 \n\n\
 It excludes memory that is mapped implicitly such as code and data segments, \
@@ -122,39 +218,17 @@ const kTreeNames = {
   'vsize':    'Virtual Size Breakdown',
   'swap':     'Swap Usage Breakdown',
   'other':    'Other Measurements'
 };
 
 const kMapTreePaths =
   ['smaps/resident', 'smaps/pss', 'smaps/vsize', 'smaps/swap'];
 
-function onLoad()
-{
-  let os = Cc["@mozilla.org/observer-service;1"].
-      getService(Ci.nsIObserverService);
-  os.notifyObservers(null, "child-memory-reporter-request", null);
-
-  os.addObserver(ChildMemoryListener, "child-memory-reporter-update", false);
-  gAddedObserver = true;
-
-  update();
-}
-
-function onUnload()
-{
-  // We need to check if the observer has been added before removing; in some
-  // circumstances (eg. reloading the page quickly) it might not have because
-  // onLoad might not fire.
-  if (gAddedObserver) {
-    let os = Cc["@mozilla.org/observer-service;1"].
-        getService(Ci.nsIObserverService);
-    os.removeObserver(ChildMemoryListener, "child-memory-reporter-update");
-  }
-}
+//---------------------------------------------------------------------------
 
 function ChildMemoryListener(aSubject, aTopic, aData)
 {
   update();
 }
 
 function doGlobalGC()
 {
@@ -171,45 +245,99 @@ function doCC()
         .getInterface(Ci.nsIDOMWindowUtils)
         .cycleCollect();
   let os = Cc["@mozilla.org/observer-service;1"]
             .getService(Ci.nsIObserverService);
   os.notifyObservers(null, "child-cc-request", null);
   update();
 }
 
-// For maximum effect, this returns to the event loop between each
-// notification.  See bug 610166 comment 12 for an explanation.
-// Ideally a single notification would be enough.
-function sendHeapMinNotifications()
+//---------------------------------------------------------------------------
+
+/**
+ * Top-level function that does the work of generating the page.
+ */
+function update()
 {
-  function runSoon(f)
-  {
-    let tm = Cc["@mozilla.org/thread-manager;1"]
-              .getService(Ci.nsIThreadManager);
+  // First, clear the page contents.  Necessary because update() might be
+  // called more than once due to ChildMemoryListener.
+  let oldContent = document.getElementById("content");
+  let content = oldContent.cloneNode(false);
+  oldContent.parentNode.replaceChild(content, oldContent);
+  content.classList.add(gVerbose ? 'verbose' : 'non-verbose');
+
+  let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
+      getService(Ci.nsIMemoryReporterManager);
 
-    tm.mainThread.dispatch({ run: f }, Ci.nsIThread.DISPATCH_NORMAL);
+  // Generate output for one process at a time.  Always start with the
+  // Main process.
+  let reportsByProcess = getReportsByProcess(mgr);
+  let hasMozMallocUsableSize = mgr.hasMozMallocUsableSize;
+  appendProcessElements(content, "Main", reportsByProcess["Main"],
+                        hasMozMallocUsableSize);
+  for (let process in reportsByProcess) {
+    if (process !== "Main") {
+      appendProcessElements(content, process, reportsByProcess[process],
+                            hasMozMallocUsableSize);
+    }
   }
 
-  function sendHeapMinNotificationsInner()
+  appendElement(content, "hr");
+
+  // Memory-related actions.
+  const UpDesc = "Re-measure.";
+  const GCDesc = "Do a global garbage collection.";
+  const CCDesc = "Do a cycle collection.";
+  const MPDesc = "Send three \"heap-minimize\" notifications in a " +
+                 "row.  Each notification triggers a global garbage " +
+                 "collection followed by a cycle collection, and causes the " +
+                 "process to reduce memory usage in other ways, e.g. by " +
+                 "flushing various caches.";
+
+  function appendButton(aTitle, aOnClick, aText, aId)
   {
-    let os = Cc["@mozilla.org/observer-service;1"]
-             .getService(Ci.nsIObserverService);
-    os.notifyObservers(null, "memory-pressure", "heap-minimize");
-
-    if (++j < 3)
-      runSoon(sendHeapMinNotificationsInner);
-    else
-      runSoon(update);
+    let b = appendElementWithText(content, "button", "", aText);
+    b.title = aTitle;
+    b.onclick = aOnClick
+    if (aId) {
+      b.id = aId;
+    }
   }
 
-  let j = 0;
-  sendHeapMinNotificationsInner();
+  // The "Update" button has an id so it can be clicked in a test.
+  appendButton(UpDesc, update,                   "Update", "updateButton");
+  appendButton(GCDesc, doGlobalGC,               "GC");
+  appendButton(CCDesc, doCC,                     "CC");
+  appendButton(MPDesc, sendHeapMinNotifications, "Minimize memory usage");
+
+  let div1 = appendElement(content, "div");
+  if (gVerbose) {
+    let a = appendElementWithText(div1, "a", "option", "Less verbose");
+    a.href = "about:memory";
+  } else {
+    let a = appendElementWithText(div1, "a", "option", "More verbose");
+    a.href = "about:memory?verbose";
+  }
+
+  let div2 = appendElement(content, "div");
+  let a = appendElementWithText(div2, "a", "option",
+                                "Troubleshooting information");
+  a.href = "about:support";
+
+  let legendText1 = "Click on a non-leaf node in a tree to expand ('++') " +
+                    "or collapse ('--') its children.";
+  let legendText2 = "Hover the pointer over the name of a memory report " +
+                    "to see a description of what it measures.";
+
+  appendElementWithText(content, "div", "legend", legendText1);
+  appendElementWithText(content, "div", "legend", legendText2);
 }
 
+//---------------------------------------------------------------------------
+
 function Report(aUnsafePath, aKind, aUnits, aAmount, aUnsafeDesc)
 {
   this._unsafePath  = aUnsafePath;
   this._kind        = aKind;
   this._units       = aUnits;
   this._amount      = aAmount;
   this._unsafeDescription = aUnsafeDesc;
   // this._nMerged is only defined if > 1
@@ -298,118 +426,17 @@ function getReportsByProcess(aMgr)
     catch(e) {
       debug("An error occurred when collecting a multi-reporter's results: " + e);
     }
   }
 
   return reportsByProcess;
 }
 
-function appendTextNode(aP, aText)
-{
-  let e = document.createTextNode(aText);
-  aP.appendChild(e);
-  return e;
-}
-
-function appendElement(aP, aTagName, aClassName)
-{
-  let e = document.createElement(aTagName);
-  if (aClassName) {
-    e.className = aClassName;
-  }
-  aP.appendChild(e);
-  return e;
-}
-
-function appendElementWithText(aP, aTagName, aClassName, aText)
-{
-  let e = appendElement(aP, aTagName, aClassName);
-  appendTextNode(e, aText);
-  return e;
-}
-
-/**
- * Top-level function that does the work of generating the page.
- */
-function update()
-{
-  // First, clear the page contents.  Necessary because update() might be
-  // called more than once due to ChildMemoryListener.
-  let oldContent = document.getElementById("content");
-  let content = oldContent.cloneNode(false);
-  oldContent.parentNode.replaceChild(content, oldContent);
-  content.classList.add(gVerbose ? 'verbose' : 'non-verbose');
-
-  let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
-      getService(Ci.nsIMemoryReporterManager);
-
-  // Generate output for one process at a time.  Always start with the
-  // Main process.
-  let reportsByProcess = getReportsByProcess(mgr);
-  let hasMozMallocUsableSize = mgr.hasMozMallocUsableSize;
-  appendProcessElements(content, "Main", reportsByProcess["Main"],
-                        hasMozMallocUsableSize);
-  for (let process in reportsByProcess) {
-    if (process !== "Main") {
-      appendProcessElements(content, process, reportsByProcess[process],
-                            hasMozMallocUsableSize);
-    }
-  }
-
-  appendElement(content, "hr");
-
-  // Memory-related actions.
-  const UpDesc = "Re-measure.";
-  const GCDesc = "Do a global garbage collection.";
-  const CCDesc = "Do a cycle collection.";
-  const MPDesc = "Send three \"heap-minimize\" notifications in a " +
-                 "row.  Each notification triggers a global garbage " +
-                 "collection followed by a cycle collection, and causes the " +
-                 "process to reduce memory usage in other ways, e.g. by " +
-                 "flushing various caches.";
-
-  function appendButton(aTitle, aOnClick, aText, aId)
-  {
-    let b = appendElementWithText(content, "button", "", aText);
-    b.title = aTitle;
-    b.onclick = aOnClick
-    if (aId) {
-      b.id = aId;
-    }
-  }
-
-  // The "Update" button has an id so it can be clicked in a test.
-  appendButton(UpDesc, update,                   "Update", "updateButton");
-  appendButton(GCDesc, doGlobalGC,               "GC");
-  appendButton(CCDesc, doCC,                     "CC");
-  appendButton(MPDesc, sendHeapMinNotifications, "Minimize memory usage");
-
-  let div1 = appendElement(content, "div");
-  if (gVerbose) {
-    let a = appendElementWithText(div1, "a", "option", "Less verbose");
-    a.href = "about:memory";
-  } else {
-    let a = appendElementWithText(div1, "a", "option", "More verbose");
-    a.href = "about:memory?verbose";
-  }
-
-  let div2 = appendElement(content, "div");
-  let a = appendElementWithText(div2, "a", "option",
-                                "Troubleshooting information");
-  a.href = "about:support";
-
-  let legendText1 = "Click on a non-leaf node in a tree to expand ('++') " +
-                    "or collapse ('--') its children.";
-  let legendText2 = "Hover the pointer over the name of a memory report " +
-                    "to see a description of what it measures.";
-
-  appendElementWithText(content, "div", "legend", legendText1);
-  appendElementWithText(content, "div", "legend", legendText2);
-}
+//---------------------------------------------------------------------------
 
 // There are two kinds of TreeNode.
 // - Leaf TreeNodes correspond to Reports and have more properties.
 // - Non-leaf TreeNodes are just scaffolding nodes for the tree;  their values
 //   are derived from their children.
 function TreeNode(aUnsafeName)
 {
   // Nb: _units is not needed, it's always UNITS_BYTES.
@@ -1232,16 +1259,18 @@ function appendTreeElements(aPOuter, aT,
 
   appendSectionHeader(aPOuter, kTreeNames[aT._unsafeName]);
  
   let pre = appendElement(aPOuter, "pre", "tree");
   appendTreeElements2(pre, /* prePath = */"", aT, [], "", rootStringLength);
   appendTextNode(aPOuter, "\n");  // gives nice spacing when we cut and paste
 }
 
+//---------------------------------------------------------------------------
+
 function OtherReport(aUnsafePath, aUnits, aAmount, aUnsafeDesc, aNMerged)
 {
   // Nb: _kind is not needed, it's always KIND_OTHER.
   this._unsafePath = aUnsafePath;
   this._units    = aUnits;
   if (aAmount === kUnknown) {
     this._amount     = 0;
     this._isUnknown = true;
@@ -1340,20 +1369,8 @@ function appendOtherElements(aP, aReport
 }
 
 function appendSectionHeader(aP, aText)
 {
   appendElementWithText(aP, "h2", "sectionHeader", aText);
   appendTextNode(aP, "\n");
 }
 
-function assert(aCond, aMsg)
-{
-  if (!aCond) {
-    throw("assertion failed: " + aMsg);
-  }
-}
-
-function debug(x)
-{
-  let content = document.getElementById("content");
-  appendElementWithText(content, "div", "legend", JSON.stringify(x));
-}