Mercurial > my-ubiquity-commands
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 + ); +}