зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1358504 - Add a 1-entry cache to ObjectGroup::defaultNewGroup. r=bhackett
This commit is contained in:
Родитель
012fd2ffcb
Коммит
7e95b8fabe
|
@ -1047,6 +1047,7 @@ JSCompartment::purge()
|
|||
dtoaCache.purge();
|
||||
newProxyCache.purge();
|
||||
lastCachedNativeIterator = nullptr;
|
||||
objectGroups.purge();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -461,6 +461,20 @@ class ObjectGroupCompartment::NewTable : public JS::WeakCache<js::GCHashSet<NewE
|
|||
explicit NewTable(Zone* zone) : Base(zone, Table()) {}
|
||||
};
|
||||
|
||||
MOZ_ALWAYS_INLINE ObjectGroup*
|
||||
ObjectGroupCompartment::DefaultNewGroupCache::lookup(const Class* clasp, TaggedProto proto,
|
||||
JSObject* associated)
|
||||
{
|
||||
if (group_ &&
|
||||
associated_ == associated &&
|
||||
group_->proto() == proto &&
|
||||
(!clasp || group_->clasp() == clasp))
|
||||
{
|
||||
return group_;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* static */ ObjectGroup*
|
||||
ObjectGroup::defaultNewGroup(JSContext* cx, const Class* clasp,
|
||||
TaggedProto proto, JSObject* associated)
|
||||
|
@ -473,20 +487,6 @@ ObjectGroup::defaultNewGroup(JSContext* cx, const Class* clasp,
|
|||
// unboxed plain object.
|
||||
MOZ_ASSERT_IF(!clasp, !!associated);
|
||||
|
||||
AutoEnterAnalysis enter(cx);
|
||||
|
||||
ObjectGroupCompartment::NewTable*& table = cx->compartment()->objectGroups.defaultNewTable;
|
||||
|
||||
if (!table) {
|
||||
table = cx->new_<ObjectGroupCompartment::NewTable>(cx->zone());
|
||||
if (!table || !table->init()) {
|
||||
js_delete(table);
|
||||
table = nullptr;
|
||||
ReportOutOfMemory(cx);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (associated && !associated->is<TypeDescr>()) {
|
||||
MOZ_ASSERT(!clasp);
|
||||
if (associated->is<JSFunction>()) {
|
||||
|
@ -513,6 +513,25 @@ ObjectGroup::defaultNewGroup(JSContext* cx, const Class* clasp,
|
|||
clasp = &PlainObject::class_;
|
||||
}
|
||||
|
||||
ObjectGroupCompartment& groups = cx->compartment()->objectGroups;
|
||||
|
||||
if (ObjectGroup* group = groups.defaultNewGroupCache.lookup(clasp, proto, associated))
|
||||
return group;
|
||||
|
||||
AutoEnterAnalysis enter(cx);
|
||||
|
||||
ObjectGroupCompartment::NewTable*& table = groups.defaultNewTable;
|
||||
|
||||
if (!table) {
|
||||
table = cx->new_<ObjectGroupCompartment::NewTable>(cx->zone());
|
||||
if (!table || !table->init()) {
|
||||
js_delete(table);
|
||||
table = nullptr;
|
||||
ReportOutOfMemory(cx);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (proto.isObject() && !proto.toObject()->isDelegate()) {
|
||||
RootedObject protoObj(cx, proto.toObject());
|
||||
if (!JSObject::setDelegate(cx, protoObj))
|
||||
|
@ -536,6 +555,7 @@ ObjectGroup::defaultNewGroup(JSContext* cx, const Class* clasp,
|
|||
MOZ_ASSERT_IF(!clasp, group->clasp() == &PlainObject::class_ ||
|
||||
group->clasp() == &UnboxedPlainObject::class_);
|
||||
MOZ_ASSERT(group->proto() == proto);
|
||||
groups.defaultNewGroupCache.put(group, associated);
|
||||
return group;
|
||||
}
|
||||
|
||||
|
@ -582,6 +602,7 @@ ObjectGroup::defaultNewGroup(JSContext* cx, const Class* clasp,
|
|||
AddTypePropertyId(cx, group, nullptr, NameToId(names.columnNumber), TypeSet::Int32Type());
|
||||
}
|
||||
|
||||
groups.defaultNewGroupCache.put(group, associated);
|
||||
return group;
|
||||
}
|
||||
|
||||
|
@ -1681,6 +1702,7 @@ ObjectGroupCompartment::removeDefaultNewGroup(const Class* clasp, TaggedProto pr
|
|||
MOZ_RELEASE_ASSERT(p);
|
||||
|
||||
defaultNewTable->get().remove(p);
|
||||
defaultNewGroupCache.purge();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1692,6 +1714,7 @@ ObjectGroupCompartment::replaceDefaultNewGroup(const Class* clasp, TaggedProto p
|
|||
auto p = defaultNewTable->lookup(lookup);
|
||||
MOZ_RELEASE_ASSERT(p);
|
||||
defaultNewTable->get().remove(p);
|
||||
defaultNewGroupCache.purge();
|
||||
{
|
||||
AutoEnterOOMUnsafeRegion oomUnsafe;
|
||||
if (!defaultNewTable->putNew(lookup, NewEntry(group, associated)))
|
||||
|
@ -1770,6 +1793,7 @@ ObjectGroupCompartment::clearTables()
|
|||
defaultNewTable->clear();
|
||||
if (lazyTable && lazyTable->initialized())
|
||||
lazyTable->clear();
|
||||
defaultNewGroupCache.purge();
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
|
|
|
@ -566,6 +566,28 @@ class ObjectGroupCompartment
|
|||
NewTable* defaultNewTable;
|
||||
NewTable* lazyTable;
|
||||
|
||||
// Cache for defaultNewGroup. Purged on GC.
|
||||
class DefaultNewGroupCache
|
||||
{
|
||||
ObjectGroup* group_;
|
||||
JSObject* associated_;
|
||||
|
||||
public:
|
||||
DefaultNewGroupCache() { purge(); }
|
||||
|
||||
void purge() {
|
||||
group_ = nullptr;
|
||||
}
|
||||
void put(ObjectGroup* group, JSObject* associated) {
|
||||
group_ = group;
|
||||
associated_ = associated;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE ObjectGroup* lookup(const Class* clasp, TaggedProto proto,
|
||||
JSObject* associated);
|
||||
};
|
||||
DefaultNewGroupCache defaultNewGroupCache;
|
||||
|
||||
struct ArrayObjectKey;
|
||||
using ArrayObjectTable = js::GCRekeyableHashMap<ArrayObjectKey,
|
||||
ReadBarrieredObjectGroup,
|
||||
|
@ -628,6 +650,10 @@ class ObjectGroupCompartment
|
|||
|
||||
void sweep(FreeOp* fop);
|
||||
|
||||
void purge() {
|
||||
defaultNewGroupCache.purge();
|
||||
}
|
||||
|
||||
#ifdef JSGC_HASH_TABLE_CHECKS
|
||||
void checkTablesAfterMovingGC() {
|
||||
checkNewTableAfterMovingGC(defaultNewTable);
|
||||
|
|
Загрузка…
Ссылка в новой задаче