summaryrefslogtreecommitdiffstats
path: root/js/src/vm/ObjectGroup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/vm/ObjectGroup.cpp')
-rw-r--r--js/src/vm/ObjectGroup.cpp197
1 files changed, 27 insertions, 170 deletions
diff --git a/js/src/vm/ObjectGroup.cpp b/js/src/vm/ObjectGroup.cpp
index d6a8fcaa4..ec0a7aec1 100644
--- a/js/src/vm/ObjectGroup.cpp
+++ b/js/src/vm/ObjectGroup.cpp
@@ -18,11 +18,10 @@
#include "vm/ArrayObject.h"
#include "vm/Shape.h"
#include "vm/TaggedProto.h"
-#include "vm/UnboxedObject.h"
#include "jsobjinlines.h"
-#include "vm/UnboxedObject-inl.h"
+#include "vm/NativeObject-inl.h"
using namespace js;
@@ -56,7 +55,6 @@ ObjectGroup::finalize(FreeOp* fop)
if (newScriptDontCheckGeneration())
newScriptDontCheckGeneration()->clear();
fop->delete_(newScriptDontCheckGeneration());
- fop->delete_(maybeUnboxedLayoutDontCheckGeneration());
if (maybePreliminaryObjectsDontCheckGeneration())
maybePreliminaryObjectsDontCheckGeneration()->clear();
fop->delete_(maybePreliminaryObjectsDontCheckGeneration());
@@ -83,8 +81,6 @@ ObjectGroup::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const
size_t n = 0;
if (TypeNewScript* newScript = newScriptDontCheckGeneration())
n += newScript->sizeOfIncludingThis(mallocSizeOf);
- if (UnboxedLayout* layout = maybeUnboxedLayoutDontCheckGeneration())
- n += layout->sizeOfIncludingThis(mallocSizeOf);
return n;
}
@@ -253,7 +249,7 @@ ObjectGroup::useSingletonForAllocationSite(JSScript* script, jsbytecode* pc, con
/////////////////////////////////////////////////////////////////////
bool
-JSObject::shouldSplicePrototype(JSContext* cx)
+JSObject::shouldSplicePrototype()
{
/*
* During bootstrapping, if inference is enabled we need to make sure not
@@ -266,33 +262,36 @@ JSObject::shouldSplicePrototype(JSContext* cx)
return isSingleton();
}
-bool
-JSObject::splicePrototype(JSContext* cx, const Class* clasp, Handle<TaggedProto> proto)
+/* static */ bool
+JSObject::splicePrototype(JSContext* cx, HandleObject obj, const Class* clasp,
+ Handle<TaggedProto> proto)
{
- MOZ_ASSERT(cx->compartment() == compartment());
-
- RootedObject self(cx, this);
+ MOZ_ASSERT(cx->compartment() == obj->compartment());
/*
* For singleton groups representing only a single JSObject, the proto
* can be rearranged as needed without destroying type information for
* the old or new types.
*/
- MOZ_ASSERT(self->isSingleton());
+ MOZ_ASSERT(obj->isSingleton());
// Windows may not appear on prototype chains.
MOZ_ASSERT_IF(proto.isObject(), !IsWindow(proto.toObject()));
- if (proto.isObject() && !proto.toObject()->setDelegate(cx))
- return false;
+ if (proto.isObject()) {
+ RootedObject protoObj(cx, proto.toObject());
+ if (!JSObject::setDelegate(cx, protoObj))
+ return false;
+ }
// Force type instantiation when splicing lazy group.
- RootedObjectGroup group(cx, self->getGroup(cx));
+ RootedObjectGroup group(cx, JSObject::getGroup(cx, obj));
if (!group)
return false;
RootedObjectGroup protoGroup(cx, nullptr);
if (proto.isObject()) {
- protoGroup = proto.toObject()->getGroup(cx);
+ RootedObject protoObj(cx, proto.toObject());
+ protoGroup = JSObject::getGroup(cx, protoObj);
if (!protoGroup)
return false;
}
@@ -311,7 +310,7 @@ JSObject::makeLazyGroup(JSContext* cx, HandleObject obj)
/* De-lazification of functions can GC, so we need to do it up here. */
if (obj->is<JSFunction>() && obj->as<JSFunction>().isInterpretedLazy()) {
RootedFunction fun(cx, &obj->as<JSFunction>());
- if (!fun->getOrCreateScript(cx))
+ if (!JSFunction::getOrCreateScript(cx, fun))
return nullptr;
}
@@ -350,7 +349,7 @@ JSObject::makeLazyGroup(JSContext* cx, HandleObject obj)
JSObject::setNewGroupUnknown(JSContext* cx, const js::Class* clasp, JS::HandleObject obj)
{
ObjectGroup::setDefaultNewGroupUnknown(cx, clasp, obj);
- return obj->setFlags(cx, BaseShape::NEW_GROUP_UNKNOWN);
+ return JSObject::setFlags(cx, obj, BaseShape::NEW_GROUP_UNKNOWN);
}
/////////////////////////////////////////////////////////////////////
@@ -495,13 +494,7 @@ ObjectGroup::defaultNewGroup(ExclusiveContext* cx, const Class* clasp,
if (associated->is<JSFunction>()) {
// Canonicalize new functions to use the original one associated with its script.
- JSFunction* fun = &associated->as<JSFunction>();
- if (fun->hasScript())
- associated = fun->nonLazyScript()->functionNonDelazifying();
- else if (fun->isInterpretedLazy() && !fun->isSelfHostedBuiltin())
- associated = fun->lazyScript()->functionNonDelazifying();
- else
- associated = nullptr;
+ associated = associated->as<JSFunction>().maybeCanonicalFunction();
// If we have previously cleared the 'new' script information for this
// function, don't try to construct another one.
@@ -518,7 +511,7 @@ ObjectGroup::defaultNewGroup(ExclusiveContext* cx, const Class* clasp,
if (proto.isObject() && !proto.toObject()->isDelegate()) {
RootedObject protoObj(cx, proto.toObject());
- if (!protoObj->setDelegate(cx))
+ if (!JSObject::setDelegate(cx, protoObj))
return nullptr;
// Objects which are prototypes of one another should be singletons, so
@@ -536,8 +529,7 @@ ObjectGroup::defaultNewGroup(ExclusiveContext* cx, const Class* clasp,
if (p) {
ObjectGroup* group = p->group;
MOZ_ASSERT_IF(clasp, group->clasp() == clasp);
- MOZ_ASSERT_IF(!clasp, group->clasp() == &PlainObject::class_ ||
- group->clasp() == &UnboxedPlainObject::class_);
+ MOZ_ASSERT_IF(!clasp, group->clasp() == &PlainObject::class_);
MOZ_ASSERT(group->proto() == proto);
return group;
}
@@ -780,7 +772,7 @@ GetValueTypeForTable(const Value& v)
return type;
}
-/* static */ JSObject*
+/* static */ ArrayObject*
ObjectGroup::newArrayObject(ExclusiveContext* cx,
const Value* vp, size_t length,
NewObjectKind newKind, NewArrayKind arrayKind)
@@ -844,56 +836,13 @@ ObjectGroup::newArrayObject(ExclusiveContext* cx,
AddTypePropertyId(cx, group, nullptr, JSID_VOID, elementType);
- if (elementType != TypeSet::UnknownType()) {
- // Keep track of the initial objects we create with this type.
- // If the initial ones have a consistent shape and property types, we
- // will try to use an unboxed layout for the group.
- PreliminaryObjectArrayWithTemplate* preliminaryObjects =
- cx->new_<PreliminaryObjectArrayWithTemplate>(nullptr);
- if (!preliminaryObjects)
- return nullptr;
- group->setPreliminaryObjects(preliminaryObjects);
- }
-
if (!p.add(cx, *table, ObjectGroupCompartment::ArrayObjectKey(elementType), group))
return nullptr;
}
// The type of the elements being added will already be reflected in type
- // information, but make sure when creating an unboxed array that the
- // common element type is suitable for the unboxed representation.
+ // information.
ShouldUpdateTypes updateTypes = ShouldUpdateTypes::DontUpdate;
- if (!MaybeAnalyzeBeforeCreatingLargeArray(cx, group, vp, length))
- return nullptr;
- if (group->maybePreliminaryObjects())
- group->maybePreliminaryObjects()->maybeAnalyze(cx, group);
- if (group->maybeUnboxedLayout()) {
- switch (group->unboxedLayout().elementType()) {
- case JSVAL_TYPE_BOOLEAN:
- if (elementType != TypeSet::BooleanType())
- updateTypes = ShouldUpdateTypes::Update;
- break;
- case JSVAL_TYPE_INT32:
- if (elementType != TypeSet::Int32Type())
- updateTypes = ShouldUpdateTypes::Update;
- break;
- case JSVAL_TYPE_DOUBLE:
- if (elementType != TypeSet::Int32Type() && elementType != TypeSet::DoubleType())
- updateTypes = ShouldUpdateTypes::Update;
- break;
- case JSVAL_TYPE_STRING:
- if (elementType != TypeSet::StringType())
- updateTypes = ShouldUpdateTypes::Update;
- break;
- case JSVAL_TYPE_OBJECT:
- if (elementType != TypeSet::NullType() && !elementType.get().isObjectUnchecked())
- updateTypes = ShouldUpdateTypes::Update;
- break;
- default:
- MOZ_CRASH();
- }
- }
-
return NewCopiedArrayTryUseGroup(cx, group, vp, length, newKind, updateTypes);
}
@@ -903,49 +852,15 @@ GiveObjectGroup(ExclusiveContext* cx, JSObject* source, JSObject* target)
{
MOZ_ASSERT(source->group() != target->group());
- if (!target->is<ArrayObject>() && !target->is<UnboxedArrayObject>())
- return true;
-
- if (target->group()->maybePreliminaryObjects()) {
- bool force = IsInsideNursery(source);
- target->group()->maybePreliminaryObjects()->maybeAnalyze(cx, target->group(), force);
- }
-
- if (target->is<ArrayObject>()) {
- ObjectGroup* sourceGroup = source->group();
-
- if (source->is<UnboxedArrayObject>()) {
- Shape* shape = target->as<ArrayObject>().lastProperty();
- if (!UnboxedArrayObject::convertToNativeWithGroup(cx, source, target->group(), shape))
- return false;
- } else if (source->is<ArrayObject>()) {
- source->setGroup(target->group());
- } else {
- return true;
- }
-
- if (sourceGroup->maybePreliminaryObjects())
- sourceGroup->maybePreliminaryObjects()->unregisterObject(source);
- if (target->group()->maybePreliminaryObjects())
- target->group()->maybePreliminaryObjects()->registerNewObject(source);
-
- for (size_t i = 0; i < source->as<ArrayObject>().getDenseInitializedLength(); i++) {
- Value v = source->as<ArrayObject>().getDenseElement(i);
- AddTypePropertyId(cx, source->group(), source, JSID_VOID, v);
- }
-
+ if (!target->is<ArrayObject>() || !source->is<ArrayObject>()) {
return true;
}
- if (target->is<UnboxedArrayObject>()) {
- if (!source->is<UnboxedArrayObject>())
- return true;
- if (source->as<UnboxedArrayObject>().elementType() != JSVAL_TYPE_INT32)
- return true;
- if (target->as<UnboxedArrayObject>().elementType() != JSVAL_TYPE_DOUBLE)
- return true;
+ source->setGroup(target->group());
- return source->as<UnboxedArrayObject>().convertInt32ToDouble(cx, target->group());
+ for (size_t i = 0; i < source->as<ArrayObject>().getDenseInitializedLength(); i++) {
+ Value v = source->as<ArrayObject>().getDenseElement(i);
+ AddTypePropertyId(cx, source->group(), source, JSID_VOID, v);
}
return true;
@@ -1054,46 +969,6 @@ js::CombinePlainObjectPropertyTypes(ExclusiveContext* cx, JSObject* newObj,
}
}
}
- } else if (newObj->is<UnboxedPlainObject>()) {
- const UnboxedLayout& layout = newObj->as<UnboxedPlainObject>().layout();
- const int32_t* traceList = layout.traceList();
- if (!traceList)
- return true;
-
- uint8_t* newData = newObj->as<UnboxedPlainObject>().data();
- uint8_t* oldData = oldObj->as<UnboxedPlainObject>().data();
-
- for (; *traceList != -1; traceList++) {}
- traceList++;
- for (; *traceList != -1; traceList++) {
- JSObject* newInnerObj = *reinterpret_cast<JSObject**>(newData + *traceList);
- JSObject* oldInnerObj = *reinterpret_cast<JSObject**>(oldData + *traceList);
-
- if (!newInnerObj || !oldInnerObj || SameGroup(oldInnerObj, newInnerObj))
- continue;
-
- if (!GiveObjectGroup(cx, newInnerObj, oldInnerObj))
- return false;
-
- if (SameGroup(oldInnerObj, newInnerObj))
- continue;
-
- if (!GiveObjectGroup(cx, oldInnerObj, newInnerObj))
- return false;
-
- if (SameGroup(oldInnerObj, newInnerObj)) {
- for (size_t i = 1; i < ncompare; i++) {
- if (compare[i].isObject() && SameGroup(&compare[i].toObject(), newObj)) {
- uint8_t* otherData = compare[i].toObject().as<UnboxedPlainObject>().data();
- JSObject* otherInnerObj = *reinterpret_cast<JSObject**>(otherData + *traceList);
- if (otherInnerObj && !SameGroup(otherInnerObj, newInnerObj)) {
- if (!GiveObjectGroup(cx, otherInnerObj, newInnerObj))
- return false;
- }
- }
- }
- }
- }
}
return true;
@@ -1317,12 +1192,6 @@ ObjectGroup::newPlainObject(ExclusiveContext* cx, IdValuePair* properties, size_
RootedObjectGroup group(cx, p->value().group);
- // Watch for existing groups which now use an unboxed layout.
- if (group->maybeUnboxedLayout()) {
- MOZ_ASSERT(group->unboxedLayout().properties().length() == nproperties);
- return UnboxedPlainObject::createWithProperties(cx, group, newKind, properties);
- }
-
// Update property types according to the properties we are about to add.
// Do this before we do anything which can GC, which might move or remove
// this table entry.
@@ -1509,18 +1378,6 @@ ObjectGroup::allocationSiteGroup(JSContext* cx, JSScript* scriptArg, jsbytecode*
}
}
- if (kind == JSProto_Array &&
- (JSOp(*pc) == JSOP_NEWARRAY || IsCallPC(pc)) &&
- cx->options().unboxedArrays())
- {
- PreliminaryObjectArrayWithTemplate* preliminaryObjects =
- cx->new_<PreliminaryObjectArrayWithTemplate>(nullptr);
- if (preliminaryObjects)
- res->setPreliminaryObjects(preliminaryObjects);
- else
- cx->recoverFromOutOfMemory();
- }
-
if (!table->add(p, key, res)) {
ReportOutOfMemory(cx);
return nullptr;