diff options
author | Moonchild <moonchild@palemoon.org> | 2020-07-08 14:53:31 +0000 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2020-08-30 09:33:33 +0000 |
commit | c8a38346c88995b4ba7e07a225c3a8ba860567c6 (patch) | |
tree | ff124233adf72bc53e16cd2d26275834e6a503d8 | |
parent | 70bafe4df514219dfc02185804286d1619290a16 (diff) | |
download | UXP-c8a38346c88995b4ba7e07a225c3a8ba860567c6.tar UXP-c8a38346c88995b4ba7e07a225c3a8ba860567c6.tar.gz UXP-c8a38346c88995b4ba7e07a225c3a8ba860567c6.tar.lz UXP-c8a38346c88995b4ba7e07a225c3a8ba860567c6.tar.xz UXP-c8a38346c88995b4ba7e07a225c3a8ba860567c6.zip |
Issue #618 - Lazily initialise module binding maps
Make it so they are not allocated on a background thread in a different zone to
the final module.
Ref: BZ 1372258
-rw-r--r-- | js/src/builtin/ModuleObject.cpp | 46 | ||||
-rw-r--r-- | js/src/builtin/ModuleObject.h | 16 |
2 files changed, 35 insertions, 27 deletions
diff --git a/js/src/builtin/ModuleObject.cpp b/js/src/builtin/ModuleObject.cpp index 14d27845c..44e5a2c88 100644 --- a/js/src/builtin/ModuleObject.cpp +++ b/js/src/builtin/ModuleObject.cpp @@ -248,21 +248,13 @@ IndirectBindingMap::Binding::Binding(ModuleEnvironmentObject* environment, Shape : environment(environment), shape(shape) {} -IndirectBindingMap::IndirectBindingMap(Zone* zone) - : map_(ZoneAllocPolicy(zone)) -{ -} - -bool -IndirectBindingMap::init() -{ - return map_.init(); -} - void IndirectBindingMap::trace(JSTracer* trc) { - for (Map::Enum e(map_); !e.empty(); e.popFront()) { + if (!map_) + return; + + for (Map::Enum e(*map_); !e.empty(); e.popFront()) { Binding& b = e.front().value(); TraceEdge(trc, &b.environment, "module bindings environment"); TraceEdge(trc, &b.shape, "module bindings shape"); @@ -276,9 +268,22 @@ bool IndirectBindingMap::put(JSContext* cx, HandleId name, HandleModuleEnvironmentObject environment, HandleId localName) { + // This object might have been allocated on the background parsing thread in + // different zone to the final module. Lazily allocate the map so we don't + // have to switch its zone when merging compartments. + if (!map_) { + MOZ_ASSERT(!cx->zone()->group()->createdForHelperThread()); + map_.emplace(cx->zone()); + if (!map_->init()) { + map_.reset(); + ReportOutOfMemory(cx); + return false; + } + } + RootedShape shape(cx, environment->lookup(cx, localName)); MOZ_ASSERT(shape); - if (!map_.put(name, Binding(environment, shape))) { + if (!map_->put(name, Binding(environment, shape))) { ReportOutOfMemory(cx); return false; } @@ -289,7 +294,10 @@ IndirectBindingMap::put(JSContext* cx, HandleId name, bool IndirectBindingMap::lookup(jsid name, ModuleEnvironmentObject** envOut, Shape** shapeOut) const { - auto ptr = map_.lookup(name); + if (!map_) + return false; + + auto ptr = map_->lookup(name); if (!ptr) return false; @@ -625,10 +633,9 @@ ModuleObject::create(ExclusiveContext* cx) RootedModuleObject self(cx, &obj->as<ModuleObject>()); Zone* zone = cx->zone(); - IndirectBindingMap* bindings = zone->new_<IndirectBindingMap>(zone); - if (!bindings || !bindings->init()) { + IndirectBindingMap* bindings = zone->new_<IndirectBindingMap>(); + if (!bindings) { ReportOutOfMemory(cx); - js_delete<IndirectBindingMap>(bindings); return nullptr; } @@ -974,10 +981,9 @@ ModuleObject::createNamespace(JSContext* cx, HandleModuleObject self, HandleObje return nullptr; Zone* zone = cx->zone(); - IndirectBindingMap* bindings = zone->new_<IndirectBindingMap>(zone); - if (!bindings || !bindings->init()) { + IndirectBindingMap* bindings = zone->new_<IndirectBindingMap>(); + if (!bindings) { ReportOutOfMemory(cx); - js_delete<IndirectBindingMap>(bindings); return nullptr; } diff --git a/js/src/builtin/ModuleObject.h b/js/src/builtin/ModuleObject.h index bd3e7044e..5e4e7f342 100644 --- a/js/src/builtin/ModuleObject.h +++ b/js/src/builtin/ModuleObject.h @@ -7,6 +7,8 @@ #ifndef builtin_ModuleObject_h #define builtin_ModuleObject_h +#include "mozilla/Maybe.h" + #include "jsapi.h" #include "jsatom.h" @@ -102,27 +104,27 @@ typedef Handle<ExportEntryObject*> HandleExportEntryObject; class IndirectBindingMap { public: - explicit IndirectBindingMap(Zone* zone); - bool init(); - void trace(JSTracer* trc); bool put(JSContext* cx, HandleId name, HandleModuleEnvironmentObject environment, HandleId localName); size_t count() const { - return map_.count(); + return map_ ? map_->count() : 0; } bool has(jsid name) const { - return map_.has(name); + return map_ ? map_->has(name) : false; } bool lookup(jsid name, ModuleEnvironmentObject** envOut, Shape** shapeOut) const; template <typename Func> void forEachExportedName(Func func) const { - for (auto r = map_.all(); !r.empty(); r.popFront()) + if (!map_) + return; + + for (auto r = map_->all(); !r.empty(); r.popFront()) func(r.front().key()); } @@ -136,7 +138,7 @@ class IndirectBindingMap typedef HashMap<jsid, Binding, DefaultHasher<jsid>, ZoneAllocPolicy> Map; - Map map_; + mozilla::Maybe<Map> map_; }; class ModuleNamespaceObject : public ProxyObject |