mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 758278 - Sweep crossCompartmentWrappers of all compartments, not only GCed ones. r=billm
This commit is contained in:
parent
eaca72e8fd
commit
f21b878154
@ -372,18 +372,6 @@ JSCompartment::markCrossCompartmentWrappers(JSTracer *trc)
|
||||
MarkValueRoot(trc, &call, "cross-compartment wrapper");
|
||||
JS_ASSERT(call == GetProxyCall(wrapper));
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Strings don't have a private pointer to mark, so we use the
|
||||
* wrapper map key. (This does not work for wrappers because, in the
|
||||
* case of Location objects, the wrapper map key is not the same as
|
||||
* the proxy private slot. If we only marked the wrapper map key, we
|
||||
* would miss same-compartment wrappers for Location objects.)
|
||||
*/
|
||||
JS_ASSERT(v.isString());
|
||||
Value v = e.front().key;
|
||||
MarkValueRoot(trc, &v, "cross-compartment wrapper");
|
||||
JS_ASSERT(v == e.front().key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -463,17 +451,7 @@ JSCompartment::discardJitCode(FreeOp *fop)
|
||||
void
|
||||
JSCompartment::sweep(FreeOp *fop, bool releaseTypes)
|
||||
{
|
||||
/* Remove dead wrappers from the table. */
|
||||
for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) {
|
||||
Value key = e.front().key;
|
||||
bool keyMarked = IsValueMarked(&key);
|
||||
bool valMarked = IsValueMarked(e.front().value.unsafeGet());
|
||||
JS_ASSERT_IF(!keyMarked && valMarked, key.isString());
|
||||
if (!keyMarked || !valMarked)
|
||||
e.removeFront();
|
||||
else if (key != e.front().key)
|
||||
e.rekeyFront(key);
|
||||
}
|
||||
sweepCrossCompartmentWrappers();
|
||||
|
||||
/* Remove dead references held weakly by the compartment. */
|
||||
|
||||
@ -551,6 +529,27 @@ JSCompartment::sweep(FreeOp *fop, bool releaseTypes)
|
||||
active = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove dead wrappers from the table. We must sweep all compartments, since
|
||||
* string entries in the crossCompartmentWrappers table are not marked during
|
||||
* markCrossCompartmentWrappers.
|
||||
*/
|
||||
void
|
||||
JSCompartment::sweepCrossCompartmentWrappers()
|
||||
{
|
||||
/* Remove dead wrappers from the table. */
|
||||
for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) {
|
||||
Value key = e.front().key;
|
||||
bool keyMarked = IsValueMarked(&key);
|
||||
bool valMarked = IsValueMarked(e.front().value.unsafeGet());
|
||||
JS_ASSERT_IF(!keyMarked && valMarked, key.isString());
|
||||
if (!keyMarked || !valMarked)
|
||||
e.removeFront();
|
||||
else if (key != e.front().key)
|
||||
e.rekeyFront(key);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
JSCompartment::purge()
|
||||
{
|
||||
|
@ -262,6 +262,7 @@ struct JSCompartment
|
||||
void markTypes(JSTracer *trc);
|
||||
void discardJitCode(js::FreeOp *fop);
|
||||
void sweep(js::FreeOp *fop, bool releaseTypes);
|
||||
void sweepCrossCompartmentWrappers();
|
||||
void purge();
|
||||
|
||||
void setGCLastBytes(size_t lastBytes, size_t lastMallocBytes, js::JSGCInvocationKind gckind);
|
||||
|
@ -3255,8 +3255,12 @@ SweepPhase(JSRuntime *rt, JSGCInvocationKind gckind, bool *startBackgroundSweep)
|
||||
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP_COMPARTMENTS);
|
||||
|
||||
bool releaseTypes = ReleaseObservedTypes(rt);
|
||||
for (GCCompartmentsIter c(rt); !c.done(); c.next())
|
||||
c->sweep(&fop, releaseTypes);
|
||||
for (CompartmentsIter c(rt); !c.done(); c.next()) {
|
||||
if (c->isCollecting())
|
||||
c->sweep(&fop, releaseTypes);
|
||||
else
|
||||
c->sweepCrossCompartmentWrappers();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user