Loading dom/base/nsGlobalWindow.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -9651,7 +9651,8 @@ public: : js::NukeWindowReferences); } else { // We only want to nuke wrappers for the chrome->content case js::NukeCrossCompartmentWrappers(cx, BrowserCompartmentMatcher(), cpt, js::NukeCrossCompartmentWrappers(cx, BrowserCompartmentMatcher(), js::SingleCompartment(cpt), win->IsInnerWindow() ? js::DontNukeWindowReferences : js::NukeWindowReferences, js::NukeIncomingReferences); Loading js/src/devtools/rootAnalysis/annotations.js +0 −2 Original line number Diff line number Diff line Loading @@ -231,8 +231,6 @@ var ignoreFunctions = { // The big hammers. "PR_GetCurrentThread" : true, "calloc" : true, "uint8 nsContentUtils::IsExpandedPrincipal(nsIPrincipal*)" : true, }; function extraGCFunctions() { Loading js/src/gc/NurseryAwareHashMap.h +0 −1 Original line number Diff line number Diff line Loading @@ -87,7 +87,6 @@ class NurseryAwareHashMap using Lookup = typename MapType::Lookup; using Ptr = typename MapType::Ptr; using Range = typename MapType::Range; using Entry = typename MapType::Entry; explicit NurseryAwareHashMap(AllocPolicy a = AllocPolicy()) : map(a) {} Loading js/src/jscompartment.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -681,9 +681,9 @@ JSCompartment::traceOutgoingCrossCompartmentWrappers(JSTracer* trc) MOZ_ASSERT(JS::CurrentThreadIsHeapMajorCollecting()); MOZ_ASSERT(!zone()->isCollectingFromAnyThread() || trc->runtime()->gc.isHeapCompacting()); for (NonStringWrapperEnum e(this); !e.empty(); e.popFront()) { if (e.front().key().is<JSObject*>()) { for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) { Value v = e.front().value().unbarrieredGet(); if (e.front().key().is<JSObject*>()) { ProxyObject* wrapper = &v.toObject().as<ProxyObject>(); /* Loading js/src/jscompartment.h +7 −195 Original line number Diff line number Diff line Loading @@ -184,11 +184,15 @@ class CrossCompartmentKey return wrapped.match(matcher); } // Valid for JSObject* and Debugger keys. Crashes immediately if used on a // JSString* key. JSCompartment* compartment() { struct GetCompartmentFunctor { JSCompartment* operator()(JSObject** tp) const { return (*tp)->compartment(); } JSCompartment* operator()(JSScript** tp) const { return (*tp)->compartment(); } JSCompartment* operator()(JSString** tp) const { return nullptr; } JSCompartment* operator()(JSString** tp) const { MOZ_CRASH("invalid ccw key"); return nullptr; } }; return applyToWrapped(GetCompartmentFunctor()); } Loading Loading @@ -235,191 +239,9 @@ class CrossCompartmentKey WrappedType wrapped; }; // The data structure for storing CCWs, which has a map per target compartment // so we can access them easily. Note string CCWs are stored separately from the // others because they have target compartment nullptr. class WrapperMap { static const size_t InitialInnerMapSize = 4; using InnerMap = NurseryAwareHashMap<CrossCompartmentKey, JS::Value, CrossCompartmentKey::Hasher, SystemAllocPolicy>; using OuterMap = GCHashMap<JSCompartment*, InnerMap, DefaultHasher<JSCompartment*>, SystemAllocPolicy>; OuterMap map; public: class Enum { public: enum SkipStrings : bool { WithStrings = false, WithoutStrings = true }; private: Enum(const Enum&) = delete; void operator=(const Enum&) = delete; void goToNext() { if (outer.isNothing()) return; for (; !outer->empty(); outer->popFront()) { JSCompartment* c = outer->front().key(); // Need to skip string at first, because the filter may not be // happy with a nullptr. if (!c && skipStrings) continue; if (filter && !filter->match(c)) continue; InnerMap& m = outer->front().value(); if (!m.empty()) { if (inner.isSome()) inner.reset(); inner.emplace(m); outer->popFront(); return; } } } mozilla::Maybe<OuterMap::Enum> outer; mozilla::Maybe<InnerMap::Enum> inner; const CompartmentFilter* filter; SkipStrings skipStrings; public: explicit Enum(WrapperMap& m, SkipStrings s = WithStrings) : filter(nullptr), skipStrings(s) { outer.emplace(m.map); goToNext(); } Enum(WrapperMap& m, const CompartmentFilter& f, SkipStrings s = WithStrings) : filter(&f), skipStrings(s) { outer.emplace(m.map); goToNext(); } Enum(WrapperMap& m, JSCompartment* target) { // Leave the outer map as nothing and only iterate the inner map we // find here. auto p = m.map.lookup(target); if (p) inner.emplace(p->value()); } bool empty() const { return (outer.isNothing() || outer->empty()) && (inner.isNothing() || inner->empty()); } InnerMap::Entry& front() const { MOZ_ASSERT(inner.isSome() && !inner->empty()); return inner->front(); } void popFront() { MOZ_ASSERT(!empty()); if (!inner->empty()) { inner->popFront(); if (!inner->empty()) return; } goToNext(); } void removeFront() { MOZ_ASSERT(inner.isSome()); inner->removeFront(); } }; class Ptr : public InnerMap::Ptr { friend class WrapperMap; InnerMap* map; Ptr() : InnerMap::Ptr(), map(nullptr) {} Ptr(const InnerMap::Ptr& p, InnerMap& m) : InnerMap::Ptr(p), map(&m) {} }; MOZ_MUST_USE bool init(uint32_t len) { return map.init(len); } bool empty() { if (map.empty()) return true; for (OuterMap::Enum e(map); !e.empty(); e.popFront()) { if (!e.front().value().empty()) return false; } return true; } Ptr lookup(const CrossCompartmentKey& k) const { auto op = map.lookup(const_cast<CrossCompartmentKey&>(k).compartment()); if (op) { auto ip = op->value().lookup(k); if (ip) return Ptr(ip, op->value()); } return Ptr(); } void remove(Ptr p) { if (p) p.map->remove(p); } MOZ_MUST_USE bool put(const CrossCompartmentKey& k, const JS::Value& v) { JSCompartment* c = const_cast<CrossCompartmentKey&>(k).compartment(); MOZ_ASSERT(k.is<JSString*>() == !c); auto p = map.lookupForAdd(c); if (!p) { InnerMap m; if (!m.init(InitialInnerMapSize) || !map.add(p, c, mozilla::Move(m))) return false; } return p->value().put(k, v); } size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) { size_t size = map.sizeOfExcludingThis(mallocSizeOf); for (OuterMap::Enum e(map); !e.empty(); e.popFront()) size += e.front().value().sizeOfExcludingThis(mallocSizeOf); return size; } size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) { size_t size = map.sizeOfIncludingThis(mallocSizeOf); for (OuterMap::Enum e(map); !e.empty(); e.popFront()) size += e.front().value().sizeOfIncludingThis(mallocSizeOf); return size; } void sweepAfterMinorGC(JSTracer* trc) { for (OuterMap::Enum e(map); !e.empty(); e.popFront()) { InnerMap& m = e.front().value(); m.sweepAfterMinorGC(trc); if (m.empty()) e.removeFront(); } } void sweep() { for (OuterMap::Enum e(map); !e.empty(); e.popFront()) { InnerMap& m = e.front().value(); m.sweep(); if (m.empty()) e.removeFront(); } } }; using WrapperMap = NurseryAwareHashMap<CrossCompartmentKey, JS::Value, CrossCompartmentKey::Hasher, SystemAllocPolicy>; // We must ensure that all newly allocated JSObjects get their metadata // set. However, metadata builders may require the new object be in a sane Loading Loading @@ -856,16 +678,6 @@ struct JSCompartment explicit WrapperEnum(JSCompartment* c) : js::WrapperMap::Enum(c->crossCompartmentWrappers) {} }; struct NonStringWrapperEnum : public js::WrapperMap::Enum { explicit NonStringWrapperEnum(JSCompartment* c) : js::WrapperMap::Enum(c->crossCompartmentWrappers, WithoutStrings) {} explicit NonStringWrapperEnum(JSCompartment* c, const js::CompartmentFilter& f) : js::WrapperMap::Enum(c->crossCompartmentWrappers, f, WithoutStrings) {} explicit NonStringWrapperEnum(JSCompartment* c, JSCompartment* target) : js::WrapperMap::Enum(c->crossCompartmentWrappers, target) { MOZ_ASSERT(target); } }; struct StringWrapperEnum : public js::WrapperMap::Enum { explicit StringWrapperEnum(JSCompartment* c) : js::WrapperMap::Enum(c->crossCompartmentWrappers, nullptr) {} }; js::LexicalEnvironmentObject* getOrCreateNonSyntacticLexicalEnvironment(JSContext* cx, js::HandleObject enclosing); js::LexicalEnvironmentObject* getNonSyntacticLexicalEnvironment(JSObject* enclosing) const; Loading Loading
dom/base/nsGlobalWindow.cpp +2 −1 Original line number Diff line number Diff line Loading @@ -9651,7 +9651,8 @@ public: : js::NukeWindowReferences); } else { // We only want to nuke wrappers for the chrome->content case js::NukeCrossCompartmentWrappers(cx, BrowserCompartmentMatcher(), cpt, js::NukeCrossCompartmentWrappers(cx, BrowserCompartmentMatcher(), js::SingleCompartment(cpt), win->IsInnerWindow() ? js::DontNukeWindowReferences : js::NukeWindowReferences, js::NukeIncomingReferences); Loading
js/src/devtools/rootAnalysis/annotations.js +0 −2 Original line number Diff line number Diff line Loading @@ -231,8 +231,6 @@ var ignoreFunctions = { // The big hammers. "PR_GetCurrentThread" : true, "calloc" : true, "uint8 nsContentUtils::IsExpandedPrincipal(nsIPrincipal*)" : true, }; function extraGCFunctions() { Loading
js/src/gc/NurseryAwareHashMap.h +0 −1 Original line number Diff line number Diff line Loading @@ -87,7 +87,6 @@ class NurseryAwareHashMap using Lookup = typename MapType::Lookup; using Ptr = typename MapType::Ptr; using Range = typename MapType::Range; using Entry = typename MapType::Entry; explicit NurseryAwareHashMap(AllocPolicy a = AllocPolicy()) : map(a) {} Loading
js/src/jscompartment.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -681,9 +681,9 @@ JSCompartment::traceOutgoingCrossCompartmentWrappers(JSTracer* trc) MOZ_ASSERT(JS::CurrentThreadIsHeapMajorCollecting()); MOZ_ASSERT(!zone()->isCollectingFromAnyThread() || trc->runtime()->gc.isHeapCompacting()); for (NonStringWrapperEnum e(this); !e.empty(); e.popFront()) { if (e.front().key().is<JSObject*>()) { for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) { Value v = e.front().value().unbarrieredGet(); if (e.front().key().is<JSObject*>()) { ProxyObject* wrapper = &v.toObject().as<ProxyObject>(); /* Loading
js/src/jscompartment.h +7 −195 Original line number Diff line number Diff line Loading @@ -184,11 +184,15 @@ class CrossCompartmentKey return wrapped.match(matcher); } // Valid for JSObject* and Debugger keys. Crashes immediately if used on a // JSString* key. JSCompartment* compartment() { struct GetCompartmentFunctor { JSCompartment* operator()(JSObject** tp) const { return (*tp)->compartment(); } JSCompartment* operator()(JSScript** tp) const { return (*tp)->compartment(); } JSCompartment* operator()(JSString** tp) const { return nullptr; } JSCompartment* operator()(JSString** tp) const { MOZ_CRASH("invalid ccw key"); return nullptr; } }; return applyToWrapped(GetCompartmentFunctor()); } Loading Loading @@ -235,191 +239,9 @@ class CrossCompartmentKey WrappedType wrapped; }; // The data structure for storing CCWs, which has a map per target compartment // so we can access them easily. Note string CCWs are stored separately from the // others because they have target compartment nullptr. class WrapperMap { static const size_t InitialInnerMapSize = 4; using InnerMap = NurseryAwareHashMap<CrossCompartmentKey, JS::Value, CrossCompartmentKey::Hasher, SystemAllocPolicy>; using OuterMap = GCHashMap<JSCompartment*, InnerMap, DefaultHasher<JSCompartment*>, SystemAllocPolicy>; OuterMap map; public: class Enum { public: enum SkipStrings : bool { WithStrings = false, WithoutStrings = true }; private: Enum(const Enum&) = delete; void operator=(const Enum&) = delete; void goToNext() { if (outer.isNothing()) return; for (; !outer->empty(); outer->popFront()) { JSCompartment* c = outer->front().key(); // Need to skip string at first, because the filter may not be // happy with a nullptr. if (!c && skipStrings) continue; if (filter && !filter->match(c)) continue; InnerMap& m = outer->front().value(); if (!m.empty()) { if (inner.isSome()) inner.reset(); inner.emplace(m); outer->popFront(); return; } } } mozilla::Maybe<OuterMap::Enum> outer; mozilla::Maybe<InnerMap::Enum> inner; const CompartmentFilter* filter; SkipStrings skipStrings; public: explicit Enum(WrapperMap& m, SkipStrings s = WithStrings) : filter(nullptr), skipStrings(s) { outer.emplace(m.map); goToNext(); } Enum(WrapperMap& m, const CompartmentFilter& f, SkipStrings s = WithStrings) : filter(&f), skipStrings(s) { outer.emplace(m.map); goToNext(); } Enum(WrapperMap& m, JSCompartment* target) { // Leave the outer map as nothing and only iterate the inner map we // find here. auto p = m.map.lookup(target); if (p) inner.emplace(p->value()); } bool empty() const { return (outer.isNothing() || outer->empty()) && (inner.isNothing() || inner->empty()); } InnerMap::Entry& front() const { MOZ_ASSERT(inner.isSome() && !inner->empty()); return inner->front(); } void popFront() { MOZ_ASSERT(!empty()); if (!inner->empty()) { inner->popFront(); if (!inner->empty()) return; } goToNext(); } void removeFront() { MOZ_ASSERT(inner.isSome()); inner->removeFront(); } }; class Ptr : public InnerMap::Ptr { friend class WrapperMap; InnerMap* map; Ptr() : InnerMap::Ptr(), map(nullptr) {} Ptr(const InnerMap::Ptr& p, InnerMap& m) : InnerMap::Ptr(p), map(&m) {} }; MOZ_MUST_USE bool init(uint32_t len) { return map.init(len); } bool empty() { if (map.empty()) return true; for (OuterMap::Enum e(map); !e.empty(); e.popFront()) { if (!e.front().value().empty()) return false; } return true; } Ptr lookup(const CrossCompartmentKey& k) const { auto op = map.lookup(const_cast<CrossCompartmentKey&>(k).compartment()); if (op) { auto ip = op->value().lookup(k); if (ip) return Ptr(ip, op->value()); } return Ptr(); } void remove(Ptr p) { if (p) p.map->remove(p); } MOZ_MUST_USE bool put(const CrossCompartmentKey& k, const JS::Value& v) { JSCompartment* c = const_cast<CrossCompartmentKey&>(k).compartment(); MOZ_ASSERT(k.is<JSString*>() == !c); auto p = map.lookupForAdd(c); if (!p) { InnerMap m; if (!m.init(InitialInnerMapSize) || !map.add(p, c, mozilla::Move(m))) return false; } return p->value().put(k, v); } size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) { size_t size = map.sizeOfExcludingThis(mallocSizeOf); for (OuterMap::Enum e(map); !e.empty(); e.popFront()) size += e.front().value().sizeOfExcludingThis(mallocSizeOf); return size; } size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) { size_t size = map.sizeOfIncludingThis(mallocSizeOf); for (OuterMap::Enum e(map); !e.empty(); e.popFront()) size += e.front().value().sizeOfIncludingThis(mallocSizeOf); return size; } void sweepAfterMinorGC(JSTracer* trc) { for (OuterMap::Enum e(map); !e.empty(); e.popFront()) { InnerMap& m = e.front().value(); m.sweepAfterMinorGC(trc); if (m.empty()) e.removeFront(); } } void sweep() { for (OuterMap::Enum e(map); !e.empty(); e.popFront()) { InnerMap& m = e.front().value(); m.sweep(); if (m.empty()) e.removeFront(); } } }; using WrapperMap = NurseryAwareHashMap<CrossCompartmentKey, JS::Value, CrossCompartmentKey::Hasher, SystemAllocPolicy>; // We must ensure that all newly allocated JSObjects get their metadata // set. However, metadata builders may require the new object be in a sane Loading Loading @@ -856,16 +678,6 @@ struct JSCompartment explicit WrapperEnum(JSCompartment* c) : js::WrapperMap::Enum(c->crossCompartmentWrappers) {} }; struct NonStringWrapperEnum : public js::WrapperMap::Enum { explicit NonStringWrapperEnum(JSCompartment* c) : js::WrapperMap::Enum(c->crossCompartmentWrappers, WithoutStrings) {} explicit NonStringWrapperEnum(JSCompartment* c, const js::CompartmentFilter& f) : js::WrapperMap::Enum(c->crossCompartmentWrappers, f, WithoutStrings) {} explicit NonStringWrapperEnum(JSCompartment* c, JSCompartment* target) : js::WrapperMap::Enum(c->crossCompartmentWrappers, target) { MOZ_ASSERT(target); } }; struct StringWrapperEnum : public js::WrapperMap::Enum { explicit StringWrapperEnum(JSCompartment* c) : js::WrapperMap::Enum(c->crossCompartmentWrappers, nullptr) {} }; js::LexicalEnvironmentObject* getOrCreateNonSyntacticLexicalEnvironment(JSContext* cx, js::HandleObject enclosing); js::LexicalEnvironmentObject* getNonSyntacticLexicalEnvironment(JSObject* enclosing) const; Loading