mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 01:05:45 +00:00
Bug 816784 part 2 - Optimize NukeCrossCompartmentWrappers() to iterate only the targetting wrappers. r=jonco
Changed the type of argument |targetFilter| of NukeCrossCompartmentWrappers() from CompartmentFilter to JSCompartment* because it is always a single target compartment, and we can optimize the iteration not to iterate the outer map. MozReview-Commit-ID: 7cDCgJI0H9z --HG-- extra : rebase_source : ee9341168a28b5e6f273c512b0562ee4ddc297bc extra : source : e80197b115673f259293d112da61c8dd9edc121e
This commit is contained in:
parent
5fe0cca12d
commit
e11749eeba
@ -9651,8 +9651,7 @@ public:
|
||||
: js::NukeWindowReferences);
|
||||
} else {
|
||||
// We only want to nuke wrappers for the chrome->content case
|
||||
js::NukeCrossCompartmentWrappers(cx, BrowserCompartmentMatcher(),
|
||||
js::SingleCompartment(cpt),
|
||||
js::NukeCrossCompartmentWrappers(cx, BrowserCompartmentMatcher(), cpt,
|
||||
win->IsInnerWindow() ? js::DontNukeWindowReferences
|
||||
: js::NukeWindowReferences,
|
||||
js::NukeIncomingReferences);
|
||||
|
@ -1229,7 +1229,7 @@ struct CompartmentsWithPrincipals : public CompartmentFilter {
|
||||
extern JS_FRIEND_API(bool)
|
||||
NukeCrossCompartmentWrappers(JSContext* cx,
|
||||
const CompartmentFilter& sourceFilter,
|
||||
const CompartmentFilter& targetFilter,
|
||||
JSCompartment* target,
|
||||
NukeReferencesToWindow nukeReferencesToWindow,
|
||||
NukeReferencesFromTarget nukeReferencesFromTarget);
|
||||
|
||||
|
@ -515,7 +515,7 @@ js::NukeCrossCompartmentWrapper(JSContext* cx, JSObject* wrapper)
|
||||
JS_FRIEND_API(bool)
|
||||
js::NukeCrossCompartmentWrappers(JSContext* cx,
|
||||
const CompartmentFilter& sourceFilter,
|
||||
const CompartmentFilter& targetFilter,
|
||||
JSCompartment* target,
|
||||
js::NukeReferencesToWindow nukeReferencesToWindow,
|
||||
js::NukeReferencesFromTarget nukeReferencesFromTarget)
|
||||
{
|
||||
@ -531,18 +531,30 @@ js::NukeCrossCompartmentWrappers(JSContext* cx,
|
||||
// If the compartment matches both the source and target filter, we may
|
||||
// want to cut both incoming and outgoing wrappers.
|
||||
bool nukeAll = (nukeReferencesFromTarget == NukeAllReferences &&
|
||||
targetFilter.match(c));
|
||||
target == c.get());
|
||||
|
||||
// Iterate the wrappers looking for anything interesting.
|
||||
for (JSCompartment::WrapperEnum e(c); !e.empty(); e.popFront()) {
|
||||
// Some cross-compartment wrappers are for strings. We're not
|
||||
// interested in those.
|
||||
const CrossCompartmentKey& k = e.front().key();
|
||||
// Iterate only the wrappers that have target compartment matched unless
|
||||
// |nukeAll| is true. The wrappers for strings that we're not interested
|
||||
// in won't be here because they have compartment nullptr. Use Maybe to
|
||||
// avoid copying from conditionally initializing WrapperEnum.
|
||||
mozilla::Maybe<JSCompartment::WrapperEnum> e;
|
||||
if (MOZ_LIKELY(!nukeAll))
|
||||
e.emplace(c, target);
|
||||
else
|
||||
e.emplace(c);
|
||||
for (; !e->empty(); e->popFront()) {
|
||||
// Skip debugger references because NukeCrossCompartmentWrapper()
|
||||
// doesn't know how to nuke them yet, see bug 1084626 for more
|
||||
// information.
|
||||
const CrossCompartmentKey& k = e->front().key();
|
||||
if (!k.is<JSObject*>())
|
||||
continue;
|
||||
|
||||
AutoWrapperRooter wobj(cx, WrapperValue(e));
|
||||
JSObject* wrapped = UncheckedUnwrap(wobj);
|
||||
AutoWrapperRooter wobj(cx, WrapperValue(*e));
|
||||
|
||||
// Unwrap from the wrapped object in CrossCompartmentKey instead of
|
||||
// the wrapper, this could save us a bit of time.
|
||||
JSObject* wrapped = UncheckedUnwrap(k.as<JSObject*>());
|
||||
|
||||
// We never nuke script source objects, since only ever used internally by the JS
|
||||
// engine, and are expected to remain valid throughout a scripts lifetime.
|
||||
@ -558,11 +570,9 @@ js::NukeCrossCompartmentWrappers(JSContext* cx,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (MOZ_UNLIKELY(nukeAll) || targetFilter.match(wrapped->compartment())) {
|
||||
// We found a wrapper to nuke.
|
||||
e.removeFront();
|
||||
NukeCrossCompartmentWrapper(cx, wobj);
|
||||
}
|
||||
// Now this is the wrapper we want to nuke.
|
||||
e->removeFront();
|
||||
NukeCrossCompartmentWrapper(cx, wobj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -591,8 +591,7 @@ NukeAllWrappersForCompartment(JSContext* cx, JSCompartment* compartment,
|
||||
// we need to be sure that we don't have any existing cross-compartment
|
||||
// wrappers which may be replaced with dead wrappers during unrelated
|
||||
// wrapper recomputation *before* we set that bit.
|
||||
js::NukeCrossCompartmentWrappers(cx, js::AllCompartments(),
|
||||
js::SingleCompartment(compartment),
|
||||
js::NukeCrossCompartmentWrappers(cx, js::AllCompartments(), compartment,
|
||||
nukeReferencesToWindow,
|
||||
js::NukeAllReferences);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user