зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1132706 - Lazify hashing for insertions into the NewObjectCache; r=jonco
--HG-- extra : rebase_source : 9435fdbada6cc43d6e59cddef93d17572f423cba
This commit is contained in:
Родитель
847508c681
Коммит
d2a24551f7
|
@ -3329,6 +3329,14 @@ EnsureNewArrayElements(ExclusiveContext *cx, ArrayObject *obj, uint32_t length)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
NewArrayIsCachable(ExclusiveContext *cxArg, NewObjectKind newKind)
|
||||||
|
{
|
||||||
|
return cxArg->isJSContext() &&
|
||||||
|
newKind == GenericObject &&
|
||||||
|
!cxArg->asJSContext()->compartment()->hasObjectMetadataCallback();
|
||||||
|
}
|
||||||
|
|
||||||
template <uint32_t maxLength>
|
template <uint32_t maxLength>
|
||||||
static MOZ_ALWAYS_INLINE ArrayObject *
|
static MOZ_ALWAYS_INLINE ArrayObject *
|
||||||
NewArray(ExclusiveContext *cxArg, uint32_t length,
|
NewArray(ExclusiveContext *cxArg, uint32_t length,
|
||||||
|
@ -3338,15 +3346,13 @@ NewArray(ExclusiveContext *cxArg, uint32_t length,
|
||||||
MOZ_ASSERT(CanBeFinalizedInBackground(allocKind, &ArrayObject::class_));
|
MOZ_ASSERT(CanBeFinalizedInBackground(allocKind, &ArrayObject::class_));
|
||||||
allocKind = GetBackgroundAllocKind(allocKind);
|
allocKind = GetBackgroundAllocKind(allocKind);
|
||||||
|
|
||||||
NewObjectCache::EntryIndex entry = -1;
|
bool isCachable = NewArrayIsCachable(cxArg, newKind);
|
||||||
uint64_t gcNumber = 0;
|
if (isCachable) {
|
||||||
if (JSContext *cx = cxArg->maybeJSContext()) {
|
JSContext *cx = cxArg->asJSContext();
|
||||||
JSRuntime *rt = cx->runtime();
|
JSRuntime *rt = cx->runtime();
|
||||||
NewObjectCache &cache = rt->newObjectCache;
|
NewObjectCache &cache = rt->newObjectCache;
|
||||||
if (newKind == GenericObject &&
|
NewObjectCache::EntryIndex entry = -1;
|
||||||
!cx->compartment()->hasObjectMetadataCallback() &&
|
if (cache.lookupGlobal(&ArrayObject::class_, cx->global(), allocKind, &entry)) {
|
||||||
cache.lookupGlobal(&ArrayObject::class_, cx->global(), allocKind, &entry))
|
|
||||||
{
|
|
||||||
gc::InitialHeap heap = GetInitialHeap(newKind, &ArrayObject::class_);
|
gc::InitialHeap heap = GetInitialHeap(newKind, &ArrayObject::class_);
|
||||||
JSObject *obj = cache.newObjectFromHit(cx, entry, heap);
|
JSObject *obj = cache.newObjectFromHit(cx, entry, heap);
|
||||||
if (obj) {
|
if (obj) {
|
||||||
|
@ -3361,8 +3367,6 @@ NewArray(ExclusiveContext *cxArg, uint32_t length,
|
||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
gcNumber = rt->gc.gcNumber();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3405,11 +3409,11 @@ NewArray(ExclusiveContext *cxArg, uint32_t length,
|
||||||
if (newKind == SingletonObject && !JSObject::setSingleton(cxArg, arr))
|
if (newKind == SingletonObject && !JSObject::setSingleton(cxArg, arr))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (entry != -1 &&
|
if (isCachable) {
|
||||||
cxArg->asJSContext()->runtime()->gc.gcNumber() == gcNumber)
|
NewObjectCache &cache = cxArg->asJSContext()->runtime()->newObjectCache;
|
||||||
{
|
NewObjectCache::EntryIndex entry = -1;
|
||||||
cxArg->asJSContext()->runtime()->newObjectCache.fillGlobal(entry, &ArrayObject::class_,
|
cache.lookupGlobal(&ArrayObject::class_, cxArg->global(), allocKind, &entry);
|
||||||
cxArg->global(), allocKind, arr);
|
cache.fillGlobal(entry, &ArrayObject::class_, cxArg->global(), allocKind, arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxLength > 0 && !EnsureNewArrayElements(cxArg, arr, std::min(maxLength, length)))
|
if (maxLength > 0 && !EnsureNewArrayElements(cxArg, arr, std::min(maxLength, length)))
|
||||||
|
|
133
js/src/jsobj.cpp
133
js/src/jsobj.cpp
|
@ -1218,6 +1218,20 @@ NewObjectCache::fillProto(EntryIndex entry, const Class *clasp, js::TaggedProto
|
||||||
return fill(entry, clasp, proto.raw(), kind, obj);
|
return fill(entry, clasp, proto.raw(), kind, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
NewObjectWithTaggedProtoIsCachable(ExclusiveContext *cxArg, Handle<TaggedProto> proto,
|
||||||
|
NewObjectKind newKind, const Class *clasp,
|
||||||
|
HandleObject parentArg)
|
||||||
|
{
|
||||||
|
return cxArg->isJSContext() &&
|
||||||
|
proto.isObject() &&
|
||||||
|
newKind == GenericObject &&
|
||||||
|
clasp->isNative() &&
|
||||||
|
!cxArg->asJSContext()->compartment()->hasObjectMetadataCallback() &&
|
||||||
|
(!parentArg || parentArg == proto.toObject()->getParent()) &&
|
||||||
|
!proto.toObject()->is<GlobalObject>();
|
||||||
|
}
|
||||||
|
|
||||||
JSObject *
|
JSObject *
|
||||||
js::NewObjectWithGivenTaggedProto(ExclusiveContext *cxArg, const Class *clasp,
|
js::NewObjectWithGivenTaggedProto(ExclusiveContext *cxArg, const Class *clasp,
|
||||||
Handle<TaggedProto> proto, HandleObject parentArg,
|
Handle<TaggedProto> proto, HandleObject parentArg,
|
||||||
|
@ -1226,25 +1240,16 @@ js::NewObjectWithGivenTaggedProto(ExclusiveContext *cxArg, const Class *clasp,
|
||||||
if (CanBeFinalizedInBackground(allocKind, clasp))
|
if (CanBeFinalizedInBackground(allocKind, clasp))
|
||||||
allocKind = GetBackgroundAllocKind(allocKind);
|
allocKind = GetBackgroundAllocKind(allocKind);
|
||||||
|
|
||||||
NewObjectCache::EntryIndex entry = -1;
|
bool isCachable = NewObjectWithTaggedProtoIsCachable(cxArg, proto, newKind, clasp, parentArg);
|
||||||
uint64_t gcNumber = 0;
|
if (isCachable) {
|
||||||
if (JSContext *cx = cxArg->maybeJSContext()) {
|
JSContext *cx = cxArg->asJSContext();
|
||||||
JSRuntime *rt = cx->runtime();
|
JSRuntime *rt = cx->runtime();
|
||||||
NewObjectCache &cache = rt->newObjectCache;
|
NewObjectCache &cache = rt->newObjectCache;
|
||||||
if (proto.isObject() &&
|
NewObjectCache::EntryIndex entry = -1;
|
||||||
newKind == GenericObject &&
|
if (cache.lookupProto(clasp, proto.toObject(), allocKind, &entry)) {
|
||||||
clasp->isNative() &&
|
JSObject *obj = cache.newObjectFromHit(cx, entry, GetInitialHeap(newKind, clasp));
|
||||||
!cx->compartment()->hasObjectMetadataCallback() &&
|
if (obj)
|
||||||
(!parentArg || parentArg == proto.toObject()->getParent()) &&
|
return obj;
|
||||||
!proto.toObject()->is<GlobalObject>())
|
|
||||||
{
|
|
||||||
if (cache.lookupProto(clasp, proto.toObject(), allocKind, &entry)) {
|
|
||||||
JSObject *obj = cache.newObjectFromHit(cx, entry, GetInitialHeap(newKind, clasp));
|
|
||||||
if (obj)
|
|
||||||
return obj;
|
|
||||||
} else {
|
|
||||||
gcNumber = rt->gc.gcNumber();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1264,12 +1269,11 @@ js::NewObjectWithGivenTaggedProto(ExclusiveContext *cxArg, const Class *clasp,
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (entry != -1 && !obj->as<NativeObject>().hasDynamicSlots() &&
|
if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) {
|
||||||
cxArg->asJSContext()->runtime()->gc.gcNumber() == gcNumber)
|
NewObjectCache &cache = cxArg->asJSContext()->runtime()->newObjectCache;
|
||||||
{
|
NewObjectCache::EntryIndex entry = -1;
|
||||||
cxArg->asJSContext()->runtime()->newObjectCache.fillProto(entry, clasp,
|
cache.lookupProto(clasp, proto.toObject(), allocKind, &entry);
|
||||||
proto, allocKind,
|
cache.fillProto(entry, clasp, proto, allocKind, &obj->as<NativeObject>());
|
||||||
&obj->as<NativeObject>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
|
@ -1369,6 +1373,17 @@ FindProto(ExclusiveContext *cx, const js::Class *clasp, MutableHandleObject prot
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
NewObjectWithClassProtoIsCachable(ExclusiveContext *cxArg, HandleObject parent,
|
||||||
|
JSProtoKey protoKey, NewObjectKind newKind, const Class *clasp)
|
||||||
|
{
|
||||||
|
return cxArg->isJSContext() &&
|
||||||
|
parent->is<GlobalObject>() &&
|
||||||
|
protoKey != JSProto_Null &&
|
||||||
|
newKind == GenericObject &&
|
||||||
|
clasp->isNative() &&
|
||||||
|
!cxArg->asJSContext()->compartment()->hasObjectMetadataCallback();
|
||||||
|
}
|
||||||
|
|
||||||
JSObject *
|
JSObject *
|
||||||
js::NewObjectWithClassProtoCommon(ExclusiveContext *cxArg, const Class *clasp,
|
js::NewObjectWithClassProtoCommon(ExclusiveContext *cxArg, const Class *clasp,
|
||||||
|
@ -1396,24 +1411,16 @@ js::NewObjectWithClassProtoCommon(ExclusiveContext *cxArg, const Class *clasp,
|
||||||
*/
|
*/
|
||||||
JSProtoKey protoKey = ClassProtoKeyOrAnonymousOrNull(clasp);
|
JSProtoKey protoKey = ClassProtoKeyOrAnonymousOrNull(clasp);
|
||||||
|
|
||||||
NewObjectCache::EntryIndex entry = -1;
|
bool isCachable = NewObjectWithClassProtoIsCachable(cxArg, parent, protoKey, newKind, clasp);
|
||||||
uint64_t gcNumber = 0;
|
if (isCachable) {
|
||||||
if (JSContext *cx = cxArg->maybeJSContext()) {
|
JSContext *cx = cxArg->asJSContext();
|
||||||
JSRuntime *rt = cx->runtime();
|
JSRuntime *rt = cx->runtime();
|
||||||
NewObjectCache &cache = rt->newObjectCache;
|
NewObjectCache &cache = rt->newObjectCache;
|
||||||
if (parent->is<GlobalObject>() &&
|
NewObjectCache::EntryIndex entry = -1;
|
||||||
protoKey != JSProto_Null &&
|
if (cache.lookupGlobal(clasp, &parent->as<GlobalObject>(), allocKind, &entry)) {
|
||||||
newKind == GenericObject &&
|
JSObject *obj = cache.newObjectFromHit(cx, entry, GetInitialHeap(newKind, clasp));
|
||||||
clasp->isNative() &&
|
if (obj)
|
||||||
!cx->compartment()->hasObjectMetadataCallback())
|
return obj;
|
||||||
{
|
|
||||||
if (cache.lookupGlobal(clasp, &parent->as<GlobalObject>(), allocKind, &entry)) {
|
|
||||||
JSObject *obj = cache.newObjectFromHit(cx, entry, GetInitialHeap(newKind, clasp));
|
|
||||||
if (obj)
|
|
||||||
return obj;
|
|
||||||
} else {
|
|
||||||
gcNumber = rt->gc.gcNumber();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1430,17 +1437,29 @@ js::NewObjectWithClassProtoCommon(ExclusiveContext *cxArg, const Class *clasp,
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (entry != -1 && !obj->as<NativeObject>().hasDynamicSlots() &&
|
if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) {
|
||||||
cxArg->asJSContext()->runtime()->gc.gcNumber() == gcNumber)
|
NewObjectCache &cache = cxArg->asJSContext()->runtime()->newObjectCache;
|
||||||
{
|
NewObjectCache::EntryIndex entry = -1;
|
||||||
cxArg->asJSContext()->runtime()->newObjectCache.fillGlobal(entry, clasp,
|
cache.lookupGlobal(clasp, &parent->as<GlobalObject>(), allocKind, &entry);
|
||||||
&parent->as<GlobalObject>(),
|
cache.fillGlobal(entry, clasp, &parent->as<GlobalObject>(), allocKind,
|
||||||
allocKind, &obj->as<NativeObject>());
|
&obj->as<NativeObject>());
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
NewObjectWithGroupIsCachable(JSContext *cx, HandleObjectGroup group, HandleObject parent,
|
||||||
|
NewObjectKind newKind)
|
||||||
|
{
|
||||||
|
return group->proto().isObject() &&
|
||||||
|
parent == group->proto().toObject()->getParent() &&
|
||||||
|
newKind == GenericObject &&
|
||||||
|
group->clasp()->isNative() &&
|
||||||
|
(!group->newScript() || group->newScript()->analyzed()) &&
|
||||||
|
!cx->compartment()->hasObjectMetadataCallback();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a plain object with the specified group. This bypasses getNewGroup to
|
* Create a plain object with the specified group. This bypasses getNewGroup to
|
||||||
* avoid losing creation site information for objects made by scripted 'new'.
|
* avoid losing creation site information for objects made by scripted 'new'.
|
||||||
|
@ -1455,24 +1474,15 @@ js::NewObjectWithGroupCommon(JSContext *cx, HandleObjectGroup group, HandleObjec
|
||||||
if (CanBeFinalizedInBackground(allocKind, group->clasp()))
|
if (CanBeFinalizedInBackground(allocKind, group->clasp()))
|
||||||
allocKind = GetBackgroundAllocKind(allocKind);
|
allocKind = GetBackgroundAllocKind(allocKind);
|
||||||
|
|
||||||
NewObjectCache &cache = cx->runtime()->newObjectCache;
|
bool isCachable = NewObjectWithGroupIsCachable(cx, group, parent, newKind);
|
||||||
|
if (isCachable) {
|
||||||
NewObjectCache::EntryIndex entry = -1;
|
NewObjectCache &cache = cx->runtime()->newObjectCache;
|
||||||
uint64_t gcNumber = 0;
|
NewObjectCache::EntryIndex entry = -1;
|
||||||
if (group->proto().isObject() &&
|
|
||||||
parent == group->proto().toObject()->getParent() &&
|
|
||||||
newKind == GenericObject &&
|
|
||||||
group->clasp()->isNative() &&
|
|
||||||
(!group->newScript() || group->newScript()->analyzed()) &&
|
|
||||||
!cx->compartment()->hasObjectMetadataCallback())
|
|
||||||
{
|
|
||||||
if (cache.lookupGroup(group, allocKind, &entry)) {
|
if (cache.lookupGroup(group, allocKind, &entry)) {
|
||||||
JSObject *obj = cache.newObjectFromHit(cx, entry,
|
JSObject *obj = cache.newObjectFromHit(cx, entry,
|
||||||
GetInitialHeap(newKind, group->clasp()));
|
GetInitialHeap(newKind, group->clasp()));
|
||||||
if (obj)
|
if (obj)
|
||||||
return obj;
|
return obj;
|
||||||
} else {
|
|
||||||
gcNumber = cx->runtime()->gc.gcNumber();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1480,9 +1490,10 @@ js::NewObjectWithGroupCommon(JSContext *cx, HandleObjectGroup group, HandleObjec
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (entry != -1 && !obj->as<NativeObject>().hasDynamicSlots() &&
|
if (isCachable && !obj->as<NativeObject>().hasDynamicSlots()) {
|
||||||
cx->runtime()->gc.gcNumber() == gcNumber)
|
NewObjectCache &cache = cx->runtime()->newObjectCache;
|
||||||
{
|
NewObjectCache::EntryIndex entry = -1;
|
||||||
|
cache.lookupGroup(group, allocKind, &entry);
|
||||||
cache.fillGroup(entry, group, allocKind, &obj->as<NativeObject>());
|
cache.fillGroup(entry, group, allocKind, &obj->as<NativeObject>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче