Bug 1461938 part 7 - Move varNames from JSCompartment to JS::Realm. r=jwalden

This commit is contained in:
Jan de Mooij 2018-05-18 15:18:24 +02:00
parent b95abd503e
commit d576950ebd
7 changed files with 131 additions and 100 deletions

View File

@ -5402,8 +5402,8 @@ UpdateAtomsBitmap(GCParallelTask* task)
// For convenience sweep these tables non-incrementally as part of bitmap
// sweeping; they are likely to be much smaller than the main atoms table.
runtime->unsafeSymbolRegistry().sweep();
for (CompartmentsIter comp(runtime, SkipAtoms); !comp.done(); comp.next())
comp->sweepVarNames();
for (RealmsIter realm(runtime, SkipAtoms); !realm.done(); realm.next())
realm->sweepVarNames();
}
static void

View File

@ -3316,7 +3316,7 @@ js::CheckLexicalNameConflict(JSContext* cx, Handle<LexicalEnvironmentObject*> le
const char* redeclKind = nullptr;
RootedId id(cx, NameToId(name));
RootedShape shape(cx);
if (varObj->is<GlobalObject>() && varObj->compartment()->isInVarNames(name)) {
if (varObj->is<GlobalObject>() && varObj->realm()->isInVarNames(name)) {
// ES 15.1.11 step 5.a
redeclKind = "var";
} else if ((shape = lexicalEnv->lookup(cx, name))) {

View File

@ -439,7 +439,7 @@ DefVarOperation(JSContext* cx, HandleObject varobj, HandlePropertyName dn, unsig
}
if (varobj->is<GlobalObject>()) {
if (!varobj->compartment()->addToVarNames(cx, dn))
if (!varobj->realm()->addToVarNames(cx, dn))
return false;
}

View File

@ -4468,7 +4468,7 @@ js::DefFunOperation(JSContext* cx, HandleScript script, HandleObject envChain,
if (!DefineDataProperty(cx, parent, name, rval, attrs))
return false;
return parent->is<GlobalObject>() ? parent->compartment()->addToVarNames(cx, name) : true;
return parent->is<GlobalObject>() ? parent->realm()->addToVarNames(cx, name) : true;
}
/*
@ -4494,7 +4494,7 @@ js::DefFunOperation(JSContext* cx, HandleScript script, HandleObject envChain,
// Careful: the presence of a shape, even one appearing to derive from
// a variable declaration, doesn't mean it's in [[VarNames]].
if (!parent->compartment()->addToVarNames(cx, name))
if (!parent->realm()->addToVarNames(cx, name))
return false;
}
@ -4718,7 +4718,7 @@ js::DeleteNameOperation(JSContext* cx, HandlePropertyName name, HandleObject sco
if (status) {
// Deleting a name from the global object removes it from [[VarNames]].
if (pobj == scope && scope->is<GlobalObject>())
scope->compartment()->removeFromVarNames(name);
scope->realm()->removeFromVarNames(name);
}
return true;

View File

@ -130,23 +130,34 @@ JSCompartment::~JSCompartment()
bool
JSCompartment::init(JSContext* maybecx)
{
/*
* maybecx is null when called to create the atoms compartment from
* JSRuntime::init().
*
* As a hack, we clear our timezone cache every time we create a new
* compartment. This ensures that the cache is always relatively fresh, but
* shouldn't interfere with benchmarks that create tons of date objects
* (unless they also create tons of iframes, which seems unlikely).
*/
JS::ResetTimeZone();
if (!crossCompartmentWrappers.init(0)) {
if (maybecx)
ReportOutOfMemory(maybecx);
return false;
}
return true;
}
bool
Realm::init(JSContext* maybecx)
{
// Initialize JSCompartment. This is temporary until Realm and
// JSCompartment are completely separated.
if (!JSCompartment::init(maybecx))
return false;
/*
* maybecx is null when called to create the atoms realm from
* JSRuntime::init().
*
* As a hack, we clear our timezone cache every time we create a new realm.
* This ensures that the cache is always relatively fresh, but shouldn't
* interfere with benchmarks that create tons of date objects (unless they
* also create tons of iframes, which seems unlikely).
*/
JS::ResetTimeZone();
enumerators = NativeIterator::allocateSentinel(maybecx);
if (!enumerators)
return false;
@ -602,10 +613,10 @@ JSCompartment::getNonSyntacticLexicalEnvironment(JSObject* enclosing) const
}
bool
JSCompartment::addToVarNames(JSContext* cx, JS::Handle<JSAtom*> name)
Realm::addToVarNames(JSContext* cx, JS::Handle<JSAtom*> name)
{
MOZ_ASSERT(name);
MOZ_ASSERT(!JS::GetRealmForCompartment(this)->isAtomsRealm());
MOZ_ASSERT(!isAtomsRealm());
if (varNames_.put(name))
return true;
@ -829,7 +840,7 @@ JSCompartment::sweepCrossCompartmentWrappers()
}
void
JSCompartment::sweepVarNames()
Realm::sweepVarNames()
{
varNames_.sweep();
}
@ -1301,35 +1312,47 @@ JSCompartment::clearBreakpointsIn(FreeOp* fop, js::Debugger* dbg, HandleObject h
}
void
JSCompartment::addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
size_t* tiAllocationSiteTables,
size_t* tiArrayTypeTables,
size_t* tiObjectTypeTables,
size_t* compartmentObject,
size_t* compartmentTables,
size_t* innerViewsArg,
size_t* lazyArrayBuffersArg,
size_t* objectMetadataTablesArg,
size_t* crossCompartmentWrappersArg,
size_t* savedStacksSet,
size_t* varNamesSet,
size_t* nonSyntacticLexicalEnvironmentsArg,
size_t* jitCompartment,
size_t* privateData,
size_t* scriptCountsMapArg)
JSCompartment::addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf,
size_t* crossCompartmentWrappersArg)
{
*compartmentObject += mallocSizeOf(this);
// Note that Realm inherits from JSCompartment (for now) so sizeof(*this) is
// included in that.
*crossCompartmentWrappersArg += crossCompartmentWrappers.sizeOfExcludingThis(mallocSizeOf);
}
void
Realm::addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
size_t* tiAllocationSiteTables,
size_t* tiArrayTypeTables,
size_t* tiObjectTypeTables,
size_t* realmObject,
size_t* realmTables,
size_t* innerViewsArg,
size_t* lazyArrayBuffersArg,
size_t* objectMetadataTablesArg,
size_t* crossCompartmentWrappersArg,
size_t* savedStacksSet,
size_t* varNamesSet,
size_t* nonSyntacticLexicalEnvironmentsArg,
size_t* jitCompartment,
size_t* privateData,
size_t* scriptCountsMapArg)
{
// This is temporary until Realm and JSCompartment are completely separated.
JSCompartment::addSizeOfExcludingThis(mallocSizeOf, crossCompartmentWrappersArg);
*realmObject += mallocSizeOf(this);
objectGroups.addSizeOfExcludingThis(mallocSizeOf, tiAllocationSiteTables,
tiArrayTypeTables, tiObjectTypeTables,
compartmentTables);
wasm.addSizeOfExcludingThis(mallocSizeOf, compartmentTables);
realmTables);
wasm.addSizeOfExcludingThis(mallocSizeOf, realmTables);
*innerViewsArg += innerViews.sizeOfExcludingThis(mallocSizeOf);
if (lazyArrayBuffers)
*lazyArrayBuffersArg += lazyArrayBuffers->sizeOfIncludingThis(mallocSizeOf);
if (objectMetadataTable)
*objectMetadataTablesArg += objectMetadataTable->sizeOfIncludingThis(mallocSizeOf);
*crossCompartmentWrappersArg += crossCompartmentWrappers.sizeOfExcludingThis(mallocSizeOf);
*savedStacksSet += savedStacks_.sizeOfExcludingThis(mallocSizeOf);
*varNamesSet += varNames_.sizeOfExcludingThis(mallocSizeOf);
if (nonSyntacticLexicalEnvironments_)

View File

@ -665,16 +665,6 @@ struct JSCompartment
MOZ_ASSERT(crossCompartmentWrappers.empty());
}
protected:
// The global environment record's [[VarNames]] list that contains all
// names declared using FunctionDeclaration, GeneratorDeclaration, and
// VariableDeclaration declarations in global code in this compartment.
// Names are only removed from this list by a |delete IdentifierReference|
// that successfully removes that global property.
JS::GCHashSet<JSAtom*,
js::DefaultHasher<JSAtom*>,
js::SystemAllocPolicy> varNames_;
public:
/* Last time at which an animation was played for a global in this compartment. */
int64_t lastAnimationTime;
@ -721,24 +711,11 @@ struct JSCompartment
}
}
public:
void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
size_t* tiAllocationSiteTables,
size_t* tiArrayTypeTables,
size_t* tiObjectTypeTables,
size_t* compartmentObject,
size_t* compartmentTables,
size_t* innerViews,
size_t* lazyArrayBuffers,
size_t* objectMetadataTables,
size_t* crossCompartmentWrappers,
size_t* savedStacksSet,
size_t* varNamesSet,
size_t* nonSyntacticLexicalScopes,
size_t* jitCompartment,
size_t* privateData,
size_t* scriptCountsMapArg);
protected:
void addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf,
size_t* crossCompartmentWrappersArg);
public:
// Object group tables and other state in the compartment.
js::ObjectGroupCompartment objectGroups;
@ -825,9 +802,9 @@ struct JSCompartment
explicit JSCompartment(JS::Zone* zone);
~JSCompartment();
public:
MOZ_MUST_USE bool init(JSContext* maybecx);
public:
MOZ_MUST_USE inline bool wrap(JSContext* cx, JS::MutableHandleValue vp);
MOZ_MUST_USE bool wrap(JSContext* cx, js::MutableHandleString strp);
@ -893,7 +870,6 @@ struct JSCompartment
void sweepDebugEnvironments();
void sweepNativeIterators();
void sweepTemplateObjects();
void sweepVarNames();
void purge();
@ -915,18 +891,6 @@ struct JSCompartment
js::SavedStacks& savedStacks() { return savedStacks_; }
// Add a name to [[VarNames]]. Reports OOM on failure.
MOZ_MUST_USE bool addToVarNames(JSContext* cx, JS::Handle<JSAtom*> name);
void removeFromVarNames(JS::Handle<JSAtom*> name) {
varNames_.remove(name);
}
// Whether the given name is in [[VarNames]].
bool isInVarNames(JS::Handle<JSAtom*> name) {
return varNames_.has(name);
}
void findOutgoingEdges(js::gc::ZoneComponentFinder& finder);
js::DtoaCache dtoaCache;
@ -1166,9 +1130,27 @@ class JS::Realm : public JSCompartment
public:
Realm(JS::Zone* zone, const JS::RealmOptions& options);
MOZ_MUST_USE bool init(JSContext* maybecx);
void destroy(js::FreeOp* fop);
void clearTables();
void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
size_t* tiAllocationSiteTables,
size_t* tiArrayTypeTables,
size_t* tiObjectTypeTables,
size_t* realmObject,
size_t* realmTables,
size_t* innerViews,
size_t* lazyArrayBuffers,
size_t* objectMetadataTables,
size_t* crossCompartmentWrappers,
size_t* savedStacksSet,
size_t* varNamesSet,
size_t* nonSyntacticLexicalScopes,
size_t* jitCompartment,
size_t* privateData,
size_t* scriptCountsMapArg);
const JS::RealmCreationOptions& creationOptions() const { return creationOptions_; }
JS::RealmBehaviors& behaviors() { return behaviors_; }
const JS::RealmBehaviors& behaviors() const { return behaviors_; }
@ -1227,6 +1209,30 @@ class JS::Realm : public JSCompartment
* This method clears out tables of roots in preparation for the final GC.
*/
void finishRoots();
private:
// The global environment record's [[VarNames]] list that contains all
// names declared using FunctionDeclaration, GeneratorDeclaration, and
// VariableDeclaration declarations in global code in this realm.
// Names are only removed from this list by a |delete IdentifierReference|
// that successfully removes that global property.
using VarNamesSet = JS::GCHashSet<JSAtom*,
js::DefaultHasher<JSAtom*>,
js::SystemAllocPolicy>;
VarNamesSet varNames_;
public:
// Add a name to [[VarNames]]. Reports OOM on failure.
MOZ_MUST_USE bool addToVarNames(JSContext* cx, JS::Handle<JSAtom*> name);
void sweepVarNames();
void removeFromVarNames(JS::Handle<JSAtom*> name) {
varNames_.remove(name);
}
// Whether the given name is in [[VarNames]].
bool isInVarNames(JS::Handle<JSAtom*> name) {
return varNames_.has(name);
}
};
namespace js {

View File

@ -332,6 +332,8 @@ StatsZoneCallback(JSRuntime* rt, void* data, Zone* zone)
static void
StatsRealmCallback(JSContext* cx, void* data, JSCompartment* compartment)
{
Realm* realm = JS::GetRealmForCompartment(compartment);
// Append a new RealmStats to the vector.
RuntimeStats* rtStats = static_cast<StatsClosure*>(data)->rtStats;
@ -342,25 +344,25 @@ StatsRealmCallback(JSContext* cx, void* data, JSCompartment* compartment)
MOZ_CRASH("oom");
rtStats->initExtraRealmStats(compartment, &realmStats);
compartment->setRealmStats(&realmStats);
realm->setRealmStats(&realmStats);
// Measure the compartment object itself, and things hanging off it.
compartment->addSizeOfIncludingThis(rtStats->mallocSizeOf_,
&realmStats.typeInferenceAllocationSiteTables,
&realmStats.typeInferenceArrayTypeTables,
&realmStats.typeInferenceObjectTypeTables,
&realmStats.realmObject,
&realmStats.realmTables,
&realmStats.innerViewsTable,
&realmStats.lazyArrayBuffersTable,
&realmStats.objectMetadataTable,
&realmStats.crossCompartmentWrappersTable,
&realmStats.savedStacksSet,
&realmStats.varNamesSet,
&realmStats.nonSyntacticLexicalScopesTable,
&realmStats.jitRealm,
&realmStats.privateData,
&realmStats.scriptCountsMap);
// Measure the realm object itself, and things hanging off it.
realm->addSizeOfIncludingThis(rtStats->mallocSizeOf_,
&realmStats.typeInferenceAllocationSiteTables,
&realmStats.typeInferenceArrayTypeTables,
&realmStats.typeInferenceObjectTypeTables,
&realmStats.realmObject,
&realmStats.realmTables,
&realmStats.innerViewsTable,
&realmStats.lazyArrayBuffersTable,
&realmStats.objectMetadataTable,
&realmStats.crossCompartmentWrappersTable,
&realmStats.savedStacksSet,
&realmStats.varNamesSet,
&realmStats.nonSyntacticLexicalScopesTable,
&realmStats.jitRealm,
&realmStats.privateData,
&realmStats.scriptCountsMap);
}
static void