зеркало из https://github.com/mozilla/pjs.git
Bug 693527 - tell the cycle collector about watchpoints. r=jorendorff
This commit is contained in:
Родитель
7d6baa84d7
Коммит
5276aa76e4
|
@ -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>
|
Загрузка…
Ссылка в новой задаче