summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2020-07-08 14:53:31 +0000
committerMoonchild <moonchild@palemoon.org>2020-08-30 09:33:33 +0000
commitc8a38346c88995b4ba7e07a225c3a8ba860567c6 (patch)
treeff124233adf72bc53e16cd2d26275834e6a503d8
parent70bafe4df514219dfc02185804286d1619290a16 (diff)
downloadUXP-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.cpp46
-rw-r--r--js/src/builtin/ModuleObject.h16
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