mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-24 08:07:30 +09:00
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
This commit is contained in:
parent
1cfaf06d8f
commit
39050b430e
2 changed files with 35 additions and 27 deletions
|
|
@ -248,21 +248,13 @@ IndirectBindingMap::Binding::Binding(ModuleEnvironmentObject* environment, Shape
|
||||||
: environment(environment), shape(shape)
|
: environment(environment), shape(shape)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
IndirectBindingMap::IndirectBindingMap(Zone* zone)
|
|
||||||
: map_(ZoneAllocPolicy(zone))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
IndirectBindingMap::init()
|
|
||||||
{
|
|
||||||
return map_.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
IndirectBindingMap::trace(JSTracer* trc)
|
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();
|
Binding& b = e.front().value();
|
||||||
TraceEdge(trc, &b.environment, "module bindings environment");
|
TraceEdge(trc, &b.environment, "module bindings environment");
|
||||||
TraceEdge(trc, &b.shape, "module bindings shape");
|
TraceEdge(trc, &b.shape, "module bindings shape");
|
||||||
|
|
@ -276,9 +268,22 @@ bool
|
||||||
IndirectBindingMap::put(JSContext* cx, HandleId name,
|
IndirectBindingMap::put(JSContext* cx, HandleId name,
|
||||||
HandleModuleEnvironmentObject environment, HandleId localName)
|
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));
|
RootedShape shape(cx, environment->lookup(cx, localName));
|
||||||
MOZ_ASSERT(shape);
|
MOZ_ASSERT(shape);
|
||||||
if (!map_.put(name, Binding(environment, shape))) {
|
if (!map_->put(name, Binding(environment, shape))) {
|
||||||
ReportOutOfMemory(cx);
|
ReportOutOfMemory(cx);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -289,7 +294,10 @@ IndirectBindingMap::put(JSContext* cx, HandleId name,
|
||||||
bool
|
bool
|
||||||
IndirectBindingMap::lookup(jsid name, ModuleEnvironmentObject** envOut, Shape** shapeOut) const
|
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)
|
if (!ptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -625,10 +633,9 @@ ModuleObject::create(ExclusiveContext* cx)
|
||||||
RootedModuleObject self(cx, &obj->as<ModuleObject>());
|
RootedModuleObject self(cx, &obj->as<ModuleObject>());
|
||||||
|
|
||||||
Zone* zone = cx->zone();
|
Zone* zone = cx->zone();
|
||||||
IndirectBindingMap* bindings = zone->new_<IndirectBindingMap>(zone);
|
IndirectBindingMap* bindings = zone->new_<IndirectBindingMap>();
|
||||||
if (!bindings || !bindings->init()) {
|
if (!bindings) {
|
||||||
ReportOutOfMemory(cx);
|
ReportOutOfMemory(cx);
|
||||||
js_delete<IndirectBindingMap>(bindings);
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -974,10 +981,9 @@ ModuleObject::createNamespace(JSContext* cx, HandleModuleObject self, HandleObje
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
Zone* zone = cx->zone();
|
Zone* zone = cx->zone();
|
||||||
IndirectBindingMap* bindings = zone->new_<IndirectBindingMap>(zone);
|
IndirectBindingMap* bindings = zone->new_<IndirectBindingMap>();
|
||||||
if (!bindings || !bindings->init()) {
|
if (!bindings) {
|
||||||
ReportOutOfMemory(cx);
|
ReportOutOfMemory(cx);
|
||||||
js_delete<IndirectBindingMap>(bindings);
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
#ifndef builtin_ModuleObject_h
|
#ifndef builtin_ModuleObject_h
|
||||||
#define builtin_ModuleObject_h
|
#define builtin_ModuleObject_h
|
||||||
|
|
||||||
|
#include "mozilla/Maybe.h"
|
||||||
|
|
||||||
#include "jsapi.h"
|
#include "jsapi.h"
|
||||||
#include "jsatom.h"
|
#include "jsatom.h"
|
||||||
|
|
||||||
|
|
@ -102,27 +104,27 @@ typedef Handle<ExportEntryObject*> HandleExportEntryObject;
|
||||||
class IndirectBindingMap
|
class IndirectBindingMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit IndirectBindingMap(Zone* zone);
|
|
||||||
bool init();
|
|
||||||
|
|
||||||
void trace(JSTracer* trc);
|
void trace(JSTracer* trc);
|
||||||
|
|
||||||
bool put(JSContext* cx, HandleId name,
|
bool put(JSContext* cx, HandleId name,
|
||||||
HandleModuleEnvironmentObject environment, HandleId localName);
|
HandleModuleEnvironmentObject environment, HandleId localName);
|
||||||
|
|
||||||
size_t count() const {
|
size_t count() const {
|
||||||
return map_.count();
|
return map_ ? map_->count() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has(jsid name) const {
|
bool has(jsid name) const {
|
||||||
return map_.has(name);
|
return map_ ? map_->has(name) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lookup(jsid name, ModuleEnvironmentObject** envOut, Shape** shapeOut) const;
|
bool lookup(jsid name, ModuleEnvironmentObject** envOut, Shape** shapeOut) const;
|
||||||
|
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
void forEachExportedName(Func func) const {
|
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());
|
func(r.front().key());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,7 +138,7 @@ class IndirectBindingMap
|
||||||
|
|
||||||
typedef HashMap<jsid, Binding, DefaultHasher<jsid>, ZoneAllocPolicy> Map;
|
typedef HashMap<jsid, Binding, DefaultHasher<jsid>, ZoneAllocPolicy> Map;
|
||||||
|
|
||||||
Map map_;
|
mozilla::Maybe<Map> map_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModuleNamespaceObject : public ProxyObject
|
class ModuleNamespaceObject : public ProxyObject
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue