Bug 693527 - tell the cycle collector about watchpoints. r=jorendorff

This commit is contained in:
Andrew McCreight 2012-01-27 17:13:21 -08:00
Родитель 7d6baa84d7
Коммит 5276aa76e4
5 изменённых файлов: 103 добавлений и 0 удалений

Просмотреть файл

@ -42,6 +42,7 @@
#include "jsfriendapi.h"
#include "jswrapper.h"
#include "jsweakmap.h"
#include "jswatchpoint.h"
#include "mozilla/GuardObjects.h"
@ -374,6 +375,7 @@ void
js::TraceWeakMaps(WeakMapTracer *trc)
{
WeakMapBase::traceAllMappings(trc);
WatchpointMap::traceAll(trc);
}
JS_FRIEND_API(void)

Просмотреть файл

@ -261,3 +261,24 @@ WatchpointMap::sweep(JSContext *cx)
}
}
}
void
WatchpointMap::traceAll(WeakMapTracer *trc)
{
JSRuntime *rt = trc->context->runtime;
for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); ++c) {
if (WatchpointMap *wpmap = (*c)->watchpointMap)
wpmap->trace(trc);
}
}
void
WatchpointMap::trace(WeakMapTracer *trc)
{
for (Map::Range r = map.all(); !r.empty(); r.popFront()) {
Map::Entry &e = r.front();
trc->callback(trc, NULL,
e.key.object.get(), JSTRACE_OBJECT,
e.value.closure.get(), JSTRACE_OBJECT);
}
}

Просмотреть файл

@ -43,6 +43,7 @@
#include "jsalloc.h"
#include "jsprvtd.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "gc/Barrier.h"
#include "js/HashTable.h"
@ -93,6 +94,9 @@ class WatchpointMap {
static void sweepAll(JSContext *cx);
void sweep(JSContext *cx);
static void traceAll(WeakMapTracer *trc);
void trace(WeakMapTracer *trc);
private:
Map map;
};

Просмотреть файл

@ -75,6 +75,7 @@ _CHROME_FILES = \
test_getweakmapkeys.xul \
test_weakmaps.xul \
test_bug706301.xul \
test_watchpoints.xul \
$(NULL)
# Disabled until this test gets updated to test the new proxy based

Просмотреть файл

@ -0,0 +1,75 @@
<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=693527
-->
<window title="Mozilla Bug "
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml">
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id="
target="_blank">Mozilla Bug 693527</a>
</body>
<!-- test code goes here -->
<script type="application/javascript">
<![CDATA[
/** Test for Bug 693527 **/
let Cu = Components.utils;
let Ci = Components.interfaces;
/* Create a weak reference, with a single-element weak map. */
let make_weak_ref = function (obj) {
let m = new WeakMap;
m.set(obj, {});
return m;
};
/* Check to see if a weak reference is dead. */
let weak_ref_dead = function (r) {
return Cu.nondeterministicGetWeakMapKeys(r).length == 0;
}
let make_cycle = function () {
var p = document.createElement("p");
p.children.x = p;
var f = function() { };
p.watch("y", f);
var d = document.createElement("div");
d.appendChild(p);
f.loop = d;
f.bar = {}; // observing f directly makes the leak go away even without the CC somehow
return make_weak_ref(f.bar);
};
var cycle_ref = make_cycle();
/* set up for running precise GC/CC then checking the results */
SimpleTest.waitForExplicitFinish();
Cu.schedulePreciseGC(function () {
window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.cycleCollect();
window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.garbageCollect();
window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.garbageCollect();
ok(weak_ref_dead(cycle_ref), "Garbage gray watchpoint cycle should be collected.");
SimpleTest.finish();
});
]]>
</script>
</window>