mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
If a Debug.Object’s existence is somehow observable, keep it alive. This means it is alive if it has expandos or is a key of a live WeakMap. Since we have no way of telling when those things are true, simply mark as if each referent had a strong reference back to each corresponding Debug.Object.
This commit is contained in:
parent
8fde8c4bbc
commit
68b3652a25
27
js/src/jit-test/tests/debug/gc-03.js
Normal file
27
js/src/jit-test/tests/debug/gc-03.js
Normal file
@ -0,0 +1,27 @@
|
||||
// |jit-test| debug
|
||||
// Storing a property on a Debug.Object protects it from GC as long as the
|
||||
// referent is alive.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
var N = g.N = 3;
|
||||
var dbg = Debug(g);
|
||||
|
||||
var i = 0;
|
||||
dbg.hooks = {
|
||||
debuggerHandler: function (frame) {
|
||||
frame.arguments[0].id = i++;
|
||||
}
|
||||
};
|
||||
g.eval("function f(x) { debugger; }");
|
||||
g.eval("var arr = [], j; for (j = 0; j < N; j++) arr[j] = {};");
|
||||
g.eval("for (j = 0; j < N; j++) f(arr[j]);");
|
||||
assertEq(i, N);
|
||||
|
||||
gc(); gc();
|
||||
|
||||
i = 0;
|
||||
dbg.hooks.debuggerHandler = function (frame) {
|
||||
assertEq(frame.arguments[0].id, i++)
|
||||
}
|
||||
g.eval("for (j = 0; j < N; j++) f(arr[j]);");
|
||||
assertEq(i, N);
|
28
js/src/jit-test/tests/debug/gc-04.js
Normal file
28
js/src/jit-test/tests/debug/gc-04.js
Normal file
@ -0,0 +1,28 @@
|
||||
// |jit-test| debug
|
||||
// Storing a Debug.Object as a key in a WeakMap protects it from GC as long as
|
||||
// the referent is alive.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
var N = g.N = 10;
|
||||
var dbg = Debug(g);
|
||||
var cache = new WeakMap;
|
||||
|
||||
var i = 0;
|
||||
dbg.hooks = {
|
||||
debuggerHandler: function (frame) {
|
||||
cache.set(frame.arguments[0], i++);
|
||||
}
|
||||
};
|
||||
g.eval("function f(x) { debugger; }");
|
||||
g.eval("var arr = [], j; for (j = 0; j < N; j++) arr[j] = {};");
|
||||
g.eval("for (j = 0; j < N; j++) f(arr[j]);");
|
||||
assertEq(i, N);
|
||||
|
||||
gc(); gc();
|
||||
|
||||
i = 0;
|
||||
dbg.hooks.debuggerHandler = function (frame) {
|
||||
assertEq(cache.get(frame.arguments[0]), i++)
|
||||
};
|
||||
g.eval("for (j = 0; j < N; j++) f(arr[j]);");
|
||||
assertEq(i, N);
|
@ -483,8 +483,13 @@ Debug::mark(GCMarker *trc, JSCompartment *comp, JSGCInvocationKind gckind)
|
||||
//
|
||||
if (!comp || obj->compartment() == comp) {
|
||||
for (ObjectMap::Range r = dbg->objects.all(); !r.empty(); r.popFront()) {
|
||||
if (!r.front().value->isMarked() && (comp || r.front().key->isMarked())) {
|
||||
MarkObject(trc, *r.front().key, "Debug.Object with live referent");
|
||||
// The unwrap() call below has the following effect: we
|
||||
// mark the Debug.Object if the *referent* is alive,
|
||||
// even if the CCW of the referent seems unreachable.
|
||||
if (!r.front().value->isMarked() &&
|
||||
(comp || r.front().key->unwrap()->isMarked()))
|
||||
{
|
||||
MarkObject(trc, *r.front().value, "Debug.Object with live referent");
|
||||
markedAny = true;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user