changeset 18:08bddf757ed8

Added pseudo-weak-refs feed.
author Atul Varma <varmaa@toolness.com>
date Sat, 25 Apr 2009 13:38:25 -0700
parents f3e03596fcf9
children 900a2fabd11c
files pseudo-weak-refs/index.css pseudo-weak-refs/index.html pseudo-weak-refs/pseudo-weak-refs.js
diffstat 3 files changed, 174 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pseudo-weak-refs/index.css	Sat Apr 25 13:38:25 2009 -0700
@@ -0,0 +1,39 @@
+body {
+    font-family: monaco, andale mono, monospace;
+    font-size: 9pt;
+    text-align: center;
+}
+
+#container {
+    width: 60em;
+    text-align: left;
+    margin: 2em auto;
+}
+
+#content {
+    font-family: palatino, georgia, verdana, arial, sans-serif;
+    font-size: 10pt;
+    line-height: 1.4em;
+}
+
+h1 {
+    font-weight: normal;
+    line-height: 1.4em;
+}
+
+#tests {
+    font-family: monaco, andale mono, monospace;
+    font-size: 9pt;
+    white-space: pre;
+    padding-left: 2em;
+    display: block;
+}
+
+#messages {
+    display: none;
+}
+
+a {
+    color: black;
+    text-decoration: underline;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pseudo-weak-refs/index.html	Sat Apr 25 13:38:25 2009 -0700
@@ -0,0 +1,80 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+  <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+  <link rel="stylesheet" type="text/css" media="all"
+        href="index.css" />
+  <link rel="commands" href="pseudo-weak-refs.js"/>
+  <title>Pseudo Weak References for Web Content</title>
+</head>
+<body>
+<div id="container">
+<div id="content">
+<h1>Pseudo Weak References for Web Content</h1>
+<p>This Ubiquity feed provides pseudo weak reference functionality to
+web content, for the purpose of making it easier to debug memory
+management issues. Specifically, it adds two new functions to 
+the global <tt>window</tt> object of all web pages:</p>
+<ul>
+  <li><tt>PseudoWeakRef(object)</tt> is a constructor that makes a
+    pseudo-weak reference for the object.  The returned object has one
+    method, <tt>exists()</tt>, which returns whether or not the
+    referent still exists.</li>
+  <li><tt>forceGC()</tt> forces garbage collection.</li>
+</ul>
+<p>Here's some example code:</p>
+<script id="tests">
+function testExistsReturnsFalse() {
+  var object = new Object();
+  var weak = new PseudoWeakRef(object);
+
+  // Destroy our one strong reference to the object, leaving it available
+  // for garbage collection.
+  object = null;
+
+  forceGC();
+  if (weak.exists())
+    throw new Error("weak referent should not exist");
+}
+</script>
+<p>The above source code is actually part of the test suite for this
+feed.  <span id="test-result">If this feed were installed, the suite would
+run now.</span></p>
+<p>The source code for this feed can be viewed
+at <a href="pseudo-weak-refs.js">pseudo-weak-refs.js</a>.</p>
+</div>
+<div id="messages">
+<span id="tests-failed">The suite was run, but some tests failed.</span>
+<span id="tests-passed">The suite was run, and all tests passed.</span>
+</div>
+</div>
+<script>
+function testExistsReturnsTrue() {
+  var object = new Object();
+  var weak = new PseudoWeakRef(object);
+  forceGC();
+  if (!weak.exists())
+    throw new Error("weak referent should exist");
+}
+
+function onLoad() {
+  function $(id) { return document.getElementById(id); }
+
+  $("tests").innerHTML = $("tests").innerHTML.slice(1);
+  if (window.PseudoWeakRef && window.forceGC) {
+    try {
+      testExistsReturnsFalse();
+      testExistsReturnsTrue();
+    } catch (e) {
+      $("test-result").innerHTML = $("tests-failed").innerHTML;
+      throw e;
+    }
+    $("test-result").innerHTML = $("tests-passed").innerHTML;
+  }
+}
+
+window.addEventListener("load", onLoad, false);
+</script>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pseudo-weak-refs/pseudo-weak-refs.js	Sat Apr 25 13:38:25 2009 -0700
@@ -0,0 +1,55 @@
+// This Ubiquity page-load function injects the following functions for memory
+// debugging into webpages:
+//
+// * window.PseudoWeakRef(object) makes a pseudo-weak reference for the
+//   object.  It has one method, exists(), which returns whether or not
+//   the referent still exists (i.e., has not been garbage collected).
+//
+// * window.forceGC() forces garbage collection.
+
+function pageLoad_injectPseudoWeakRefs(document) {
+  var sandbox = Components.utils.Sandbox(document.defaultView);
+  var weakrefs = [];
+
+  function makePseudoWeakRef(object) {
+    var weakref = new Components.utils.getWeakReference(object);
+    object = null;
+    weakrefs.push(weakref);
+    return weakrefs.length - 1;
+  }
+
+  function isReferentAlive(id) {
+    if (typeof(id) == "number" && weakrefs[id]) {
+      if (weakrefs[id].get() != null)
+        return true;
+      else
+        delete weakrefs[id];
+    }
+    return false;
+  }
+
+  function forceGC() {
+    Components.utils.forceGC();
+  }
+
+  sandbox.importFunction(makePseudoWeakRef);
+  sandbox.importFunction(isReferentAlive);
+  sandbox.importFunction(forceGC);
+
+  function PseudoWeakRef(object) {
+    var id = makePseudoWeakRef(object);
+    object = null;
+    this.exists = function() {
+      return isReferentAlive(id);
+    };
+  }
+
+  Components.utils.evalInSandbox(PseudoWeakRef.toString(), sandbox);
+
+  sandbox.window = document.defaultView.wrappedJSObject;
+  Components.utils.evalInSandbox(
+    ("window.PseudoWeakRef = PseudoWeakRef;" +
+     "window.forceGC = forceGC;"),
+    sandbox
+  );
+}