summaryrefslogtreecommitdiffstats
path: root/js/src/jit
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit')
-rw-r--r--js/src/jit/AliasAnalysisShared.cpp2
-rw-r--r--js/src/jit/BaselineInspector.cpp31
-rw-r--r--js/src/jit/BaselineInspector.h9
-rw-r--r--js/src/jit/CodeGenerator.cpp61
-rw-r--r--js/src/jit/CodeGenerator.h3
-rw-r--r--js/src/jit/IonAnalysis.cpp2
-rw-r--r--js/src/jit/IonBuilder.cpp272
-rw-r--r--js/src/jit/IonBuilder.h10
-rw-r--r--js/src/jit/IonCaches.cpp1
-rw-r--r--js/src/jit/Lowering.cpp26
-rw-r--r--js/src/jit/Lowering.h3
-rw-r--r--js/src/jit/MCallOptimize.cpp8
-rw-r--r--js/src/jit/MIR.cpp161
-rw-r--r--js/src/jit/MIR.h131
-rw-r--r--js/src/jit/MOpcodes.h3
-rw-r--r--js/src/jit/OptimizationTracking.cpp2
-rw-r--r--js/src/jit/Recover.cpp1
-rw-r--r--js/src/jit/ScalarReplacement.cpp112
-rw-r--r--js/src/jit/SharedIC.cpp1
-rw-r--r--js/src/jit/arm/Assembler-arm.cpp7
-rw-r--r--js/src/jit/arm/MacroAssembler-arm.cpp5
-rw-r--r--js/src/jit/shared/LIR-shared.h48
-rw-r--r--js/src/jit/shared/LOpcodes-shared.h3
23 files changed, 66 insertions, 836 deletions
diff --git a/js/src/jit/AliasAnalysisShared.cpp b/js/src/jit/AliasAnalysisShared.cpp
index 81c0fd067..3b83df74e 100644
--- a/js/src/jit/AliasAnalysisShared.cpp
+++ b/js/src/jit/AliasAnalysisShared.cpp
@@ -114,8 +114,6 @@ GetObject(const MDefinition* ins)
case MDefinition::Op_GuardObjectGroup:
case MDefinition::Op_GuardObjectIdentity:
case MDefinition::Op_GuardClass:
- case MDefinition::Op_GuardUnboxedExpando:
- case MDefinition::Op_LoadUnboxedExpando:
case MDefinition::Op_LoadSlot:
case MDefinition::Op_StoreSlot:
case MDefinition::Op_InArray:
diff --git a/js/src/jit/BaselineInspector.cpp b/js/src/jit/BaselineInspector.cpp
index c9e09bed7..9c7b88fb2 100644
--- a/js/src/jit/BaselineInspector.cpp
+++ b/js/src/jit/BaselineInspector.cpp
@@ -96,13 +96,8 @@ VectorAppendNoDuplicate(S& list, T value)
static bool
AddReceiver(const ReceiverGuard& receiver,
- BaselineInspector::ReceiverVector& receivers,
- BaselineInspector::ObjectGroupVector& convertUnboxedGroups)
+ BaselineInspector::ReceiverVector& receivers)
{
- if (receiver.group && receiver.group->maybeUnboxedLayout()) {
- if (receiver.group->unboxedLayout().nativeGroup())
- return VectorAppendNoDuplicate(convertUnboxedGroups, receiver.group);
- }
return VectorAppendNoDuplicate(receivers, receiver);
}
@@ -170,16 +165,12 @@ GetCacheIRReceiverForUnboxedProperty(ICCacheIR_Monitored* stub, ReceiverGuard* r
}
bool
-BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receivers,
- ObjectGroupVector& convertUnboxedGroups)
+BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receivers)
{
// Return a list of the receivers seen by the baseline IC for the current
// op. Empty lists indicate no receivers are known, or there was an
- // uncacheable access. convertUnboxedGroups is used for unboxed object
- // groups which have been seen, but have had instances converted to native
- // objects and should be eagerly converted by Ion.
+ // uncacheable access.
MOZ_ASSERT(receivers.empty());
- MOZ_ASSERT(convertUnboxedGroups.empty());
if (!hasBaselineScript())
return true;
@@ -207,7 +198,7 @@ BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receiv
return true;
}
- if (!AddReceiver(receiver, receivers, convertUnboxedGroups))
+ if (!AddReceiver(receiver, receivers))
return false;
stub = stub->next();
@@ -700,14 +691,12 @@ bool
BaselineInspector::commonGetPropFunction(jsbytecode* pc, JSObject** holder, Shape** holderShape,
JSFunction** commonGetter, Shape** globalShape,
bool* isOwnProperty,
- ReceiverVector& receivers,
- ObjectGroupVector& convertUnboxedGroups)
+ ReceiverVector& receivers)
{
if (!hasBaselineScript())
return false;
MOZ_ASSERT(receivers.empty());
- MOZ_ASSERT(convertUnboxedGroups.empty());
*holder = nullptr;
const ICEntry& entry = icEntryFromPC(pc);
@@ -719,7 +708,7 @@ BaselineInspector::commonGetPropFunction(jsbytecode* pc, JSObject** holder, Shap
{
ICGetPropCallGetter* nstub = static_cast<ICGetPropCallGetter*>(stub);
bool isOwn = nstub->isOwnGetter();
- if (!isOwn && !AddReceiver(nstub->receiverGuard(), receivers, convertUnboxedGroups))
+ if (!isOwn && !AddReceiver(nstub->receiverGuard(), receivers))
return false;
if (!*holder) {
@@ -751,21 +740,19 @@ BaselineInspector::commonGetPropFunction(jsbytecode* pc, JSObject** holder, Shap
if (!*holder)
return false;
- MOZ_ASSERT(*isOwnProperty == (receivers.empty() && convertUnboxedGroups.empty()));
+ MOZ_ASSERT(*isOwnProperty == (receivers.empty()));
return true;
}
bool
BaselineInspector::commonSetPropFunction(jsbytecode* pc, JSObject** holder, Shape** holderShape,
JSFunction** commonSetter, bool* isOwnProperty,
- ReceiverVector& receivers,
- ObjectGroupVector& convertUnboxedGroups)
+ ReceiverVector& receivers)
{
if (!hasBaselineScript())
return false;
MOZ_ASSERT(receivers.empty());
- MOZ_ASSERT(convertUnboxedGroups.empty());
*holder = nullptr;
const ICEntry& entry = icEntryFromPC(pc);
@@ -774,7 +761,7 @@ BaselineInspector::commonSetPropFunction(jsbytecode* pc, JSObject** holder, Shap
if (stub->isSetProp_CallScripted() || stub->isSetProp_CallNative()) {
ICSetPropCallSetter* nstub = static_cast<ICSetPropCallSetter*>(stub);
bool isOwn = nstub->isOwnSetter();
- if (!isOwn && !AddReceiver(nstub->receiverGuard(), receivers, convertUnboxedGroups))
+ if (!isOwn && !AddReceiver(nstub->receiverGuard(), receivers))
return false;
if (!*holder) {
diff --git a/js/src/jit/BaselineInspector.h b/js/src/jit/BaselineInspector.h
index 961df18aa..4a1791798 100644
--- a/js/src/jit/BaselineInspector.h
+++ b/js/src/jit/BaselineInspector.h
@@ -95,8 +95,7 @@ class BaselineInspector
public:
typedef Vector<ReceiverGuard, 4, JitAllocPolicy> ReceiverVector;
typedef Vector<ObjectGroup*, 4, JitAllocPolicy> ObjectGroupVector;
- MOZ_MUST_USE bool maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receivers,
- ObjectGroupVector& convertUnboxedGroups);
+ MOZ_MUST_USE bool maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receivers);
SetElemICInspector setElemICInspector(jsbytecode* pc) {
return makeICInspector<SetElemICInspector>(pc, ICStub::SetElem_Fallback);
@@ -131,12 +130,10 @@ class BaselineInspector
MOZ_MUST_USE bool commonGetPropFunction(jsbytecode* pc, JSObject** holder, Shape** holderShape,
JSFunction** commonGetter, Shape** globalShape,
- bool* isOwnProperty, ReceiverVector& receivers,
- ObjectGroupVector& convertUnboxedGroups);
+ bool* isOwnProperty, ReceiverVector& receivers);
MOZ_MUST_USE bool commonSetPropFunction(jsbytecode* pc, JSObject** holder, Shape** holderShape,
JSFunction** commonSetter, bool* isOwnProperty,
- ReceiverVector& receivers,
- ObjectGroupVector& convertUnboxedGroups);
+ ReceiverVector& receivers);
MOZ_MUST_USE bool instanceOfData(jsbytecode* pc, Shape** shape, uint32_t* slot,
JSObject** prototypeObject);
diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp
index 16d026092..6d1fb6b9b 100644
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -3031,15 +3031,6 @@ GuardReceiver(MacroAssembler& masm, const ReceiverGuard& guard,
{
if (guard.group) {
masm.branchTestObjGroup(Assembler::NotEqual, obj, guard.group, miss);
-
- Address expandoAddress(obj, UnboxedPlainObject::offsetOfExpando());
- if (guard.shape) {
- masm.loadPtr(expandoAddress, scratch);
- masm.branchPtr(Assembler::Equal, scratch, ImmWord(0), miss);
- masm.branchTestObjShape(Assembler::NotEqual, scratch, guard.shape, miss);
- } else if (checkNullExpando) {
- masm.branchPtr(Assembler::NotEqual, expandoAddress, ImmWord(0), miss);
- }
} else {
masm.branchTestObjShape(Assembler::NotEqual, obj, guard.shape, miss);
}
@@ -3077,13 +3068,6 @@ CodeGenerator::emitGetPropertyPolymorphic(LInstruction* ins, Register obj, Regis
masm.loadPtr(Address(target, NativeObject::offsetOfSlots()), scratch);
masm.loadTypedOrValue(Address(scratch, offset), output);
}
- } else {
- masm.comment("loadUnboxedProperty");
- const UnboxedLayout::Property* property =
- receiver.group->unboxedLayout().lookup(mir->name());
- Address propertyAddr(obj, UnboxedPlainObject::offsetOfData() + property->offset);
-
- masm.loadUnboxedProperty(propertyAddr, property->type, output);
}
if (i == mir->numReceivers() - 1) {
@@ -3124,8 +3108,6 @@ EmitUnboxedPreBarrier(MacroAssembler &masm, T address, JSValueType type)
masm.patchableCallPreBarrier(address, MIRType::Object);
else if (type == JSVAL_TYPE_STRING)
masm.patchableCallPreBarrier(address, MIRType::String);
- else
- MOZ_ASSERT(!UnboxedTypeNeedsPreBarrier(type));
}
void
@@ -3161,13 +3143,6 @@ CodeGenerator::emitSetPropertyPolymorphic(LInstruction* ins, Register obj, Regis
emitPreBarrier(addr);
masm.storeConstantOrRegister(value, addr);
}
- } else {
- const UnboxedLayout::Property* property =
- receiver.group->unboxedLayout().lookup(mir->name());
- Address propertyAddr(obj, UnboxedPlainObject::offsetOfData() + property->offset);
-
- EmitUnboxedPreBarrier(masm, propertyAddr, property->type);
- masm.storeUnboxedProperty(propertyAddr, property->type, value, nullptr);
}
if (i == mir->numReceivers() - 1) {
@@ -3333,27 +3308,6 @@ CodeGenerator::visitGuardReceiverPolymorphic(LGuardReceiverPolymorphic* lir)
}
void
-CodeGenerator::visitGuardUnboxedExpando(LGuardUnboxedExpando* lir)
-{
- Label miss;
-
- Register obj = ToRegister(lir->object());
- masm.branchPtr(lir->mir()->requireExpando() ? Assembler::Equal : Assembler::NotEqual,
- Address(obj, UnboxedPlainObject::offsetOfExpando()), ImmWord(0), &miss);
-
- bailoutFrom(&miss, lir->snapshot());
-}
-
-void
-CodeGenerator::visitLoadUnboxedExpando(LLoadUnboxedExpando* lir)
-{
- Register obj = ToRegister(lir->object());
- Register result = ToRegister(lir->getDef(0));
-
- masm.loadPtr(Address(obj, UnboxedPlainObject::offsetOfExpando()), result);
-}
-
-void
CodeGenerator::visitTypeBarrierV(LTypeBarrierV* lir)
{
ValueOperand operand = ToValue(lir, LTypeBarrierV::Input);
@@ -8576,21 +8530,6 @@ static const VMFunction ConvertUnboxedArrayObjectToNativeInfo =
FunctionInfo<ConvertUnboxedObjectToNativeFn>(UnboxedArrayObject::convertToNative,
"UnboxedArrayObject::convertToNative");
-void
-CodeGenerator::visitConvertUnboxedObjectToNative(LConvertUnboxedObjectToNative* lir)
-{
- Register object = ToRegister(lir->getOperand(0));
-
- OutOfLineCode* ool = oolCallVM(lir->mir()->group()->unboxedLayoutDontCheckGeneration().isArray()
- ? ConvertUnboxedArrayObjectToNativeInfo
- : ConvertUnboxedPlainObjectToNativeInfo,
- lir, ArgList(object), StoreNothing());
-
- masm.branchPtr(Assembler::Equal, Address(object, JSObject::offsetOfGroup()),
- ImmGCPtr(lir->mir()->group()), ool->entry());
- masm.bind(ool->rejoin());
-}
-
typedef bool (*ArrayPopShiftFn)(JSContext*, HandleObject, MutableHandleValue);
static const VMFunction ArrayPopDenseInfo =
FunctionInfo<ArrayPopShiftFn>(jit::ArrayPopDense, "ArrayPopDense");
diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h
index b226f6cc9..292f163b5 100644
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -148,8 +148,6 @@ class CodeGenerator final : public CodeGeneratorSpecific
void visitMaybeCopyElementsForWrite(LMaybeCopyElementsForWrite* lir);
void visitGuardObjectIdentity(LGuardObjectIdentity* guard);
void visitGuardReceiverPolymorphic(LGuardReceiverPolymorphic* lir);
- void visitGuardUnboxedExpando(LGuardUnboxedExpando* lir);
- void visitLoadUnboxedExpando(LLoadUnboxedExpando* lir);
void visitTypeBarrierV(LTypeBarrierV* lir);
void visitTypeBarrierO(LTypeBarrierO* lir);
void visitMonitorTypes(LMonitorTypes* lir);
@@ -310,7 +308,6 @@ class CodeGenerator final : public CodeGeneratorSpecific
void visitFallibleStoreElementV(LFallibleStoreElementV* lir);
void visitFallibleStoreElementT(LFallibleStoreElementT* lir);
void visitStoreUnboxedPointer(LStoreUnboxedPointer* lir);
- void visitConvertUnboxedObjectToNative(LConvertUnboxedObjectToNative* lir);
void emitArrayPopShift(LInstruction* lir, const MArrayPopShift* mir, Register obj,
Register elementsTemp, Register lengthTemp, TypedOrValueRegister out);
void visitArrayPopShiftV(LArrayPopShiftV* lir);
diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp
index d255c32a8..41c71c9c3 100644
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -3515,8 +3515,6 @@ PassthroughOperand(MDefinition* def)
return def->toConvertElementsToDoubles()->elements();
if (def->isMaybeCopyElementsForWrite())
return def->toMaybeCopyElementsForWrite()->object();
- if (def->isConvertUnboxedObjectToNative())
- return def->toConvertUnboxedObjectToNative()->object();
return nullptr;
}
diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp
index 54d05cac4..af85011be 100644
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -32,7 +32,6 @@
#include "vm/EnvironmentObject-inl.h"
#include "vm/NativeObject-inl.h"
#include "vm/ObjectGroup-inl.h"
-#include "vm/UnboxedObject-inl.h"
using namespace js;
using namespace js::jit;
@@ -6392,7 +6391,7 @@ IonBuilder::createThisScriptedSingleton(JSFunction* target, MDefinition* callee)
JSObject* templateObject = inspector->getTemplateObject(pc);
if (!templateObject)
return nullptr;
- if (!templateObject->is<PlainObject>() && !templateObject->is<UnboxedPlainObject>())
+ if (!templateObject->is<PlainObject>())
return nullptr;
if (templateObject->staticPrototype() != proto)
return nullptr;
@@ -6429,7 +6428,7 @@ IonBuilder::createThisScriptedBaseline(MDefinition* callee)
JSObject* templateObject = inspector->getTemplateObject(pc);
if (!templateObject)
return nullptr;
- if (!templateObject->is<PlainObject>() && !templateObject->is<UnboxedPlainObject>())
+ if (!templateObject->is<PlainObject>())
return nullptr;
Shape* shape = target->lookupPure(compartment->runtime()->names().prototype);
@@ -7718,8 +7717,6 @@ IonBuilder::jsop_initprop(PropertyName* name)
if (templateObject->is<PlainObject>()) {
if (!templateObject->as<PlainObject>().containsPure(name))
useSlowPath = true;
- } else {
- MOZ_ASSERT(templateObject->as<UnboxedPlainObject>().layout().lookup(name));
}
} else {
useSlowPath = true;
@@ -8178,8 +8175,7 @@ IonBuilder::maybeMarkEmpty(MDefinition* ins)
static bool
ClassHasEffectlessLookup(const Class* clasp)
{
- return (clasp == &UnboxedPlainObject::class_) ||
- (clasp == &UnboxedArrayObject::class_) ||
+ return (clasp == &UnboxedArrayObject::class_) ||
IsTypedObjectClass(clasp) ||
(clasp->isNative() && !clasp->getOpsLookupProperty());
}
@@ -9012,8 +9008,6 @@ IonBuilder::jsop_getelem()
}
obj = maybeUnboxForPropertyAccess(obj);
- if (obj->type() == MIRType::Object)
- obj = convertUnboxedObjects(obj);
bool emitted = false;
@@ -10137,7 +10131,7 @@ IonBuilder::jsop_setelem()
MDefinition* value = current->pop();
MDefinition* index = current->pop();
- MDefinition* object = convertUnboxedObjects(current->pop());
+ MDefinition* object = current->pop();
trackTypeInfo(TrackedTypeSite::Receiver, object->type(), object->resultTypeSet());
trackTypeInfo(TrackedTypeSite::Index, index->type(), index->resultTypeSet());
@@ -10972,11 +10966,8 @@ IonBuilder::getDefiniteSlot(TemporaryTypeSet* types, PropertyName* name, uint32_
}
// Definite slots will always be fixed slots when they are in the
- // allowable range for fixed slots, except for objects which were
- // converted from unboxed objects and have a smaller allocation size.
+ // allowable range for fixed slots.
size_t nfixed = NativeObject::MAX_FIXED_SLOTS;
- if (ObjectGroup* group = key->group()->maybeOriginalUnboxedGroup())
- nfixed = gc::GetGCKindSlots(group->unboxedLayout().getAllocKind());
uint32_t propertySlot = property.maybeTypes()->definiteSlot();
if (slot == UINT32_MAX) {
@@ -11033,8 +11024,6 @@ IonBuilder::getUnboxedOffset(TemporaryTypeSet* types, PropertyName* name, JSValu
return UINT32_MAX;
}
- key->watchStateChangeForUnboxedConvertedToNative(constraints());
-
if (offset == UINT32_MAX) {
offset = property->offset;
*punboxedType = property->type;
@@ -11496,8 +11485,6 @@ IonBuilder::jsop_getprop(PropertyName* name)
}
obj = maybeUnboxForPropertyAccess(obj);
- if (obj->type() == MIRType::Object)
- obj = convertUnboxedObjects(obj);
BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(),
obj, name, types);
@@ -11569,11 +11556,6 @@ IonBuilder::jsop_getprop(PropertyName* name)
if (!getPropTryDefiniteSlot(&emitted, obj, name, barrier, types) || emitted)
return emitted;
- // Try to emit loads from unboxed objects.
- trackOptimizationAttempt(TrackedStrategy::GetProp_Unboxed);
- if (!getPropTryUnboxed(&emitted, obj, name, barrier, types) || emitted)
- return emitted;
-
// Try to inline a common property getter, or make a call.
trackOptimizationAttempt(TrackedStrategy::GetProp_CommonGetter);
if (!getPropTryCommonGetter(&emitted, obj, name, types) || emitted)
@@ -11939,49 +11921,6 @@ IonBuilder::getPropTryComplexPropOfTypedObject(bool* emitted,
fieldPrediction, fieldTypeObj);
}
-MDefinition*
-IonBuilder::convertUnboxedObjects(MDefinition* obj)
-{
- // If obj might be in any particular unboxed group which should be
- // converted to a native representation, perform that conversion. This does
- // not guarantee the object will not have such a group afterwards, if the
- // object's possible groups are not precisely known.
- TemporaryTypeSet* types = obj->resultTypeSet();
- if (!types || types->unknownObject() || !types->objectOrSentinel())
- return obj;
-
- BaselineInspector::ObjectGroupVector list(alloc());
- for (size_t i = 0; i < types->getObjectCount(); i++) {
- TypeSet::ObjectKey* key = obj->resultTypeSet()->getObject(i);
- if (!key || !key->isGroup())
- continue;
-
- if (UnboxedLayout* layout = key->group()->maybeUnboxedLayout()) {
- AutoEnterOOMUnsafeRegion oomUnsafe;
- if (layout->nativeGroup() && !list.append(key->group()))
- oomUnsafe.crash("IonBuilder::convertUnboxedObjects");
- }
- }
-
- return convertUnboxedObjects(obj, list);
-}
-
-MDefinition*
-IonBuilder::convertUnboxedObjects(MDefinition* obj,
- const BaselineInspector::ObjectGroupVector& list)
-{
- for (size_t i = 0; i < list.length(); i++) {
- ObjectGroup* group = list[i];
- if (TemporaryTypeSet* types = obj->resultTypeSet()) {
- if (!types->hasType(TypeSet::ObjectType(group)))
- continue;
- }
- obj = MConvertUnboxedObjectToNative::New(alloc(), obj, group);
- current->add(obj->toInstruction());
- }
- return obj;
-}
-
bool
IonBuilder::getPropTryDefiniteSlot(bool* emitted, MDefinition* obj, PropertyName* name,
BarrierKind barrier, TemporaryTypeSet* types)
@@ -12132,45 +12071,14 @@ IonBuilder::loadUnboxedValue(MDefinition* elements, size_t elementsOffset,
return load;
}
-bool
-IonBuilder::getPropTryUnboxed(bool* emitted, MDefinition* obj, PropertyName* name,
- BarrierKind barrier, TemporaryTypeSet* types)
-{
- MOZ_ASSERT(*emitted == false);
-
- JSValueType unboxedType;
- uint32_t offset = getUnboxedOffset(obj->resultTypeSet(), name, &unboxedType);
- if (offset == UINT32_MAX)
- return true;
-
- if (obj->type() != MIRType::Object) {
- MGuardObject* guard = MGuardObject::New(alloc(), obj);
- current->add(guard);
- obj = guard;
- }
-
- MInstruction* load = loadUnboxedProperty(obj, offset, unboxedType, barrier, types);
- current->push(load);
-
- if (!pushTypeBarrier(load, types, barrier))
- return false;
-
- trackOptimizationSuccess();
- *emitted = true;
- return true;
-}
-
MDefinition*
IonBuilder::addShapeGuardsForGetterSetter(MDefinition* obj, JSObject* holder, Shape* holderShape,
const BaselineInspector::ReceiverVector& receivers,
- const BaselineInspector::ObjectGroupVector& convertUnboxedGroups,
bool isOwnProperty)
{
MOZ_ASSERT(holder);
MOZ_ASSERT(holderShape);
- obj = convertUnboxedObjects(obj, convertUnboxedGroups);
-
if (isOwnProperty) {
MOZ_ASSERT(receivers.empty());
return addShapeGuard(obj, holderShape, Bailout_ShapeGuard);
@@ -12194,10 +12102,8 @@ IonBuilder::getPropTryCommonGetter(bool* emitted, MDefinition* obj, PropertyName
JSObject* foundProto = nullptr;
bool isOwnProperty = false;
BaselineInspector::ReceiverVector receivers(alloc());
- BaselineInspector::ObjectGroupVector convertUnboxedGroups(alloc());
if (!inspector->commonGetPropFunction(pc, &foundProto, &lastProperty, &commonGetter,
- &globalShape, &isOwnProperty,
- receivers, convertUnboxedGroups))
+ &globalShape, &isOwnProperty, receivers))
{
return true;
}
@@ -12213,8 +12119,7 @@ IonBuilder::getPropTryCommonGetter(bool* emitted, MDefinition* obj, PropertyName
// If type information is bad, we can still optimize the getter if we
// shape guard.
obj = addShapeGuardsForGetterSetter(obj, foundProto, lastProperty,
- receivers, convertUnboxedGroups,
- isOwnProperty);
+ receivers, isOwnProperty);
if (!obj)
return false;
}
@@ -12381,15 +12286,12 @@ IonBuilder::getPropTryInlineAccess(bool* emitted, MDefinition* obj, PropertyName
MOZ_ASSERT(*emitted == false);
BaselineInspector::ReceiverVector receivers(alloc());
- BaselineInspector::ObjectGroupVector convertUnboxedGroups(alloc());
- if (!inspector->maybeInfoForPropertyOp(pc, receivers, convertUnboxedGroups))
+ if (!inspector->maybeInfoForPropertyOp(pc, receivers))
return false;
if (!canInlinePropertyOpShapes(receivers))
return true;
- obj = convertUnboxedObjects(obj, convertUnboxedGroups);
-
MIRType rvalType = types->getKnownMIRType();
if (barrier != BarrierKind::NoBarrier || IsNullOrUndefined(rvalType))
rvalType = MIRType::Value;
@@ -12412,45 +12314,6 @@ IonBuilder::getPropTryInlineAccess(bool* emitted, MDefinition* obj, PropertyName
return true;
}
- if (receivers[0].shape) {
- // Monomorphic load from an unboxed object expando.
- spew("Inlining monomorphic unboxed expando GETPROP");
-
- obj = addGroupGuard(obj, receivers[0].group, Bailout_ShapeGuard);
- obj = addUnboxedExpandoGuard(obj, /* hasExpando = */ true, Bailout_ShapeGuard);
-
- MInstruction* expando = MLoadUnboxedExpando::New(alloc(), obj);
- current->add(expando);
-
- expando = addShapeGuard(expando, receivers[0].shape, Bailout_ShapeGuard);
-
- Shape* shape = receivers[0].shape->searchLinear(NameToId(name));
- MOZ_ASSERT(shape);
-
- if (!loadSlot(expando, shape, rvalType, barrier, types))
- return false;
-
- trackOptimizationOutcome(TrackedOutcome::Monomorphic);
- *emitted = true;
- return true;
- }
-
- // Monomorphic load from an unboxed object.
- ObjectGroup* group = receivers[0].group;
- if (obj->resultTypeSet() && !obj->resultTypeSet()->hasType(TypeSet::ObjectType(group)))
- return true;
-
- obj = addGroupGuard(obj, group, Bailout_ShapeGuard);
-
- const UnboxedLayout::Property* property = group->unboxedLayout().lookup(name);
- MInstruction* load = loadUnboxedProperty(obj, property->offset, property->type, barrier, types);
- current->push(load);
-
- if (!pushTypeBarrier(load, types, barrier))
- return false;
-
- trackOptimizationOutcome(TrackedOutcome::Monomorphic);
- *emitted = true;
return true;
}
@@ -12692,7 +12555,7 @@ bool
IonBuilder::jsop_setprop(PropertyName* name)
{
MDefinition* value = current->pop();
- MDefinition* obj = convertUnboxedObjects(current->pop());
+ MDefinition* obj = current->pop();
bool emitted = false;
startTrackingOptimizations();
@@ -12725,13 +12588,6 @@ IonBuilder::jsop_setprop(PropertyName* name)
bool barrier = PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current, &obj, name, &value,
/* canModify = */ true);
- if (!forceInlineCaches()) {
- // Try to emit stores to unboxed objects.
- trackOptimizationAttempt(TrackedStrategy::SetProp_Unboxed);
- if (!setPropTryUnboxed(&emitted, obj, name, value, barrier, objTypes) || emitted)
- return emitted;
- }
-
// Add post barrier if needed. The instructions above manage any post
// barriers they need directly.
if (NeedsPostBarrier(value))
@@ -12765,10 +12621,8 @@ IonBuilder::setPropTryCommonSetter(bool* emitted, MDefinition* obj,
JSObject* foundProto = nullptr;
bool isOwnProperty;
BaselineInspector::ReceiverVector receivers(alloc());
- BaselineInspector::ObjectGroupVector convertUnboxedGroups(alloc());
if (!inspector->commonSetPropFunction(pc, &foundProto, &lastProperty, &commonSetter,
- &isOwnProperty,
- receivers, convertUnboxedGroups))
+ &isOwnProperty, receivers))
{
trackOptimizationOutcome(TrackedOutcome::NoProtoFound);
return true;
@@ -12783,8 +12637,7 @@ IonBuilder::setPropTryCommonSetter(bool* emitted, MDefinition* obj,
// If type information is bad, we can still optimize the setter if we
// shape guard.
obj = addShapeGuardsForGetterSetter(obj, foundProto, lastProperty,
- receivers, convertUnboxedGroups,
- isOwnProperty);
+ receivers, isOwnProperty);
if (!obj)
return false;
}
@@ -13100,40 +12953,6 @@ IonBuilder::storeUnboxedValue(MDefinition* obj, MDefinition* elements, int32_t e
}
bool
-IonBuilder::setPropTryUnboxed(bool* emitted, MDefinition* obj,
- PropertyName* name, MDefinition* value,
- bool barrier, TemporaryTypeSet* objTypes)
-{
- MOZ_ASSERT(*emitted == false);
-
- if (barrier) {
- trackOptimizationOutcome(TrackedOutcome::NeedsTypeBarrier);
- return true;
- }
-
- JSValueType unboxedType;
- uint32_t offset = getUnboxedOffset(obj->resultTypeSet(), name, &unboxedType);
- if (offset == UINT32_MAX)
- return true;
-
- if (obj->type() != MIRType::Object) {
- MGuardObject* guard = MGuardObject::New(alloc(), obj);
- current->add(guard);
- obj = guard;
- }
-
- MInstruction* store = storeUnboxedProperty(obj, offset, unboxedType, value);
-
- current->push(value);
-
- if (!resumeAfter(store))
- return false;
-
- *emitted = true;
- return true;
-}
-
-bool
IonBuilder::setPropTryInlineAccess(bool* emitted, MDefinition* obj,
PropertyName* name, MDefinition* value,
bool barrier, TemporaryTypeSet* objTypes)
@@ -13146,15 +12965,12 @@ IonBuilder::setPropTryInlineAccess(bool* emitted, MDefinition* obj,
}
BaselineInspector::ReceiverVector receivers(alloc());
- BaselineInspector::ObjectGroupVector convertUnboxedGroups(alloc());
- if (!inspector->maybeInfoForPropertyOp(pc, receivers, convertUnboxedGroups))
+ if (!inspector->maybeInfoForPropertyOp(pc, receivers))
return false;
if (!canInlinePropertyOpShapes(receivers))
return true;
- obj = convertUnboxedObjects(obj, convertUnboxedGroups);
-
if (receivers.length() == 1) {
if (!receivers[0].group) {
// Monomorphic store to a native object.
@@ -13174,46 +12990,6 @@ IonBuilder::setPropTryInlineAccess(bool* emitted, MDefinition* obj,
return true;
}
- if (receivers[0].shape) {
- // Monomorphic store to an unboxed object expando.
- spew("Inlining monomorphic unboxed expando SETPROP");
-
- obj = addGroupGuard(obj, receivers[0].group, Bailout_ShapeGuard);
- obj = addUnboxedExpandoGuard(obj, /* hasExpando = */ true, Bailout_ShapeGuard);
-
- MInstruction* expando = MLoadUnboxedExpando::New(alloc(), obj);
- current->add(expando);
-
- expando = addShapeGuard(expando, receivers[0].shape, Bailout_ShapeGuard);
-
- Shape* shape = receivers[0].shape->searchLinear(NameToId(name));
- MOZ_ASSERT(shape);
-
- bool needsBarrier = objTypes->propertyNeedsBarrier(constraints(), NameToId(name));
- if (!storeSlot(expando, shape, value, needsBarrier))
- return false;
-
- trackOptimizationOutcome(TrackedOutcome::Monomorphic);
- *emitted = true;
- return true;
- }
-
- // Monomorphic store to an unboxed object.
- spew("Inlining monomorphic unboxed SETPROP");
-
- ObjectGroup* group = receivers[0].group;
- if (!objTypes->hasType(TypeSet::ObjectType(group)))
- return true;
-
- obj = addGroupGuard(obj, group, Bailout_ShapeGuard);
-
- const UnboxedLayout::Property* property = group->unboxedLayout().lookup(name);
- storeUnboxedProperty(obj, property->offset, property->type, value);
-
- current->push(value);
-
- trackOptimizationOutcome(TrackedOutcome::Monomorphic);
- *emitted = true;
return true;
}
@@ -13884,7 +13660,7 @@ IonBuilder::jsop_setaliasedvar(EnvironmentCoordinate ec)
bool
IonBuilder::jsop_in()
{
- MDefinition* obj = convertUnboxedObjects(current->pop());
+ MDefinition* obj = current->pop();
MDefinition* id = current->pop();
bool emitted = false;
@@ -14241,19 +14017,6 @@ IonBuilder::addGroupGuard(MDefinition* obj, ObjectGroup* group, BailoutKind bail
}
MInstruction*
-IonBuilder::addUnboxedExpandoGuard(MDefinition* obj, bool hasExpando, BailoutKind bailoutKind)
-{
- MGuardUnboxedExpando* guard = MGuardUnboxedExpando::New(alloc(), obj, hasExpando, bailoutKind);
- current->add(guard);
-
- // If a shape guard failed in the past, don't optimize group guards.
- if (failedShapeGuard_)
- guard->setNotMovable();
-
- return guard;
-}
-
-MInstruction*
IonBuilder::addGuardReceiverPolymorphic(MDefinition* obj,
const BaselineInspector::ReceiverVector& receivers)
{
@@ -14262,15 +14025,6 @@ IonBuilder::addGuardReceiverPolymorphic(MDefinition* obj,
// Monomorphic guard on a native object.
return addShapeGuard(obj, receivers[0].shape, Bailout_ShapeGuard);
}
-
- if (!receivers[0].shape) {
- // Guard on an unboxed object that does not have an expando.
- obj = addGroupGuard(obj, receivers[0].group, Bailout_ShapeGuard);
- return addUnboxedExpandoGuard(obj, /* hasExpando = */ false, Bailout_ShapeGuard);
- }
-
- // Monomorphic receiver guards are not yet supported when the receiver
- // is an unboxed object with an expando.
}
MGuardReceiverPolymorphic* guard = MGuardReceiverPolymorphic::New(alloc(), obj);
diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h
index f24ef30c8..77528ad37 100644
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -401,7 +401,6 @@ class IonBuilder
MInstruction* addBoundsCheck(MDefinition* index, MDefinition* length);
MInstruction* addShapeGuard(MDefinition* obj, Shape* const shape, BailoutKind bailoutKind);
MInstruction* addGroupGuard(MDefinition* obj, ObjectGroup* group, BailoutKind bailoutKind);
- MInstruction* addUnboxedExpandoGuard(MDefinition* obj, bool hasExpando, BailoutKind bailoutKind);
MInstruction* addSharedTypedArrayGuard(MDefinition* obj);
MInstruction*
@@ -441,8 +440,6 @@ class IonBuilder
BarrierKind barrier, TemporaryTypeSet* types);
MOZ_MUST_USE bool getPropTryModuleNamespace(bool* emitted, MDefinition* obj, PropertyName* name,
BarrierKind barrier, TemporaryTypeSet* types);
- MOZ_MUST_USE bool getPropTryUnboxed(bool* emitted, MDefinition* obj, PropertyName* name,
- BarrierKind barrier, TemporaryTypeSet* types);
MOZ_MUST_USE bool getPropTryCommonGetter(bool* emitted, MDefinition* obj, PropertyName* name,
TemporaryTypeSet* types);
MOZ_MUST_USE bool getPropTryInlineAccess(bool* emitted, MDefinition* obj, PropertyName* name,
@@ -475,9 +472,6 @@ class IonBuilder
MOZ_MUST_USE bool setPropTryDefiniteSlot(bool* emitted, MDefinition* obj,
PropertyName* name, MDefinition* value,
bool barrier, TemporaryTypeSet* objTypes);
- MOZ_MUST_USE bool setPropTryUnboxed(bool* emitted, MDefinition* obj,
- PropertyName* name, MDefinition* value,
- bool barrier, TemporaryTypeSet* objTypes);
MOZ_MUST_USE bool setPropTryInlineAccess(bool* emitted, MDefinition* obj,
PropertyName* name, MDefinition* value,
bool barrier, TemporaryTypeSet* objTypes);
@@ -1041,7 +1035,6 @@ class IonBuilder
MDefinition*
addShapeGuardsForGetterSetter(MDefinition* obj, JSObject* holder, Shape* holderShape,
const BaselineInspector::ReceiverVector& receivers,
- const BaselineInspector::ObjectGroupVector& convertUnboxedGroups,
bool isOwnProperty);
MOZ_MUST_USE bool annotateGetPropertyCache(MDefinition* obj, PropertyName* name,
@@ -1059,9 +1052,6 @@ class IonBuilder
ResultWithOOM<bool> testNotDefinedProperty(MDefinition* obj, jsid id);
uint32_t getDefiniteSlot(TemporaryTypeSet* types, PropertyName* name, uint32_t* pnfixed);
- MDefinition* convertUnboxedObjects(MDefinition* obj);
- MDefinition* convertUnboxedObjects(MDefinition* obj,
- const BaselineInspector::ObjectGroupVector& list);
uint32_t getUnboxedOffset(TemporaryTypeSet* types, PropertyName* name,
JSValueType* punboxedType);
MInstruction* loadUnboxedProperty(MDefinition* obj, size_t offset, JSValueType unboxedType,
diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp
index 96e488ea8..0208db6ae 100644
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -31,6 +31,7 @@
#include "jit/shared/Lowering-shared-inl.h"
#include "vm/Interpreter-inl.h"
#include "vm/Shape-inl.h"
+#include "vm/UnboxedObject-inl.h"
using namespace js;
using namespace js::jit;
diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp
index 709de9987..aafa57c09 100644
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -3252,14 +3252,6 @@ LIRGenerator::visitStoreUnboxedString(MStoreUnboxedString* ins)
}
void
-LIRGenerator::visitConvertUnboxedObjectToNative(MConvertUnboxedObjectToNative* ins)
-{
- LInstruction* check = new(alloc()) LConvertUnboxedObjectToNative(useRegister(ins->object()));
- add(check, ins);
- assignSafepoint(check, ins);
-}
-
-void
LIRGenerator::visitEffectiveAddress(MEffectiveAddress* ins)
{
define(new(alloc()) LEffectiveAddress(useRegister(ins->base()), useRegister(ins->index())), ins);
@@ -3777,24 +3769,6 @@ LIRGenerator::visitGuardReceiverPolymorphic(MGuardReceiverPolymorphic* ins)
}
void
-LIRGenerator::visitGuardUnboxedExpando(MGuardUnboxedExpando* ins)
-{
- LGuardUnboxedExpando* guard =
- new(alloc()) LGuardUnboxedExpando(useRegister(ins->object()));
- assignSnapshot(guard, ins->bailoutKind());
- add(guard, ins);
- redefine(ins, ins->object());
-}
-
-void
-LIRGenerator::visitLoadUnboxedExpando(MLoadUnboxedExpando* ins)
-{
- LLoadUnboxedExpando* lir =
- new(alloc()) LLoadUnboxedExpando(useRegisterAtStart(ins->object()));
- define(lir, ins);
-}
-
-void
LIRGenerator::visitAssertRange(MAssertRange* ins)
{
MDefinition* input = ins->input();
diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h
index 9b4095aec..e36620bce 100644
--- a/js/src/jit/Lowering.h
+++ b/js/src/jit/Lowering.h
@@ -232,7 +232,6 @@ class LIRGenerator : public LIRGeneratorSpecific
void visitFallibleStoreElement(MFallibleStoreElement* ins);
void visitStoreUnboxedObjectOrNull(MStoreUnboxedObjectOrNull* ins);
void visitStoreUnboxedString(MStoreUnboxedString* ins);
- void visitConvertUnboxedObjectToNative(MConvertUnboxedObjectToNative* ins);
void visitEffectiveAddress(MEffectiveAddress* ins);
void visitArrayPopShift(MArrayPopShift* ins);
void visitArrayPush(MArrayPush* ins);
@@ -256,8 +255,6 @@ class LIRGenerator : public LIRGeneratorSpecific
void visitGuardObject(MGuardObject* ins);
void visitGuardString(MGuardString* ins);
void visitGuardReceiverPolymorphic(MGuardReceiverPolymorphic* ins);
- void visitGuardUnboxedExpando(MGuardUnboxedExpando* ins);
- void visitLoadUnboxedExpando(MLoadUnboxedExpando* ins);
void visitPolyInlineGuard(MPolyInlineGuard* ins);
void visitAssertRange(MAssertRange* ins);
void visitCallGetProperty(MCallGetProperty* ins);
diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp
index 01755094a..41ccd0ca7 100644
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -615,7 +615,7 @@ IonBuilder::inlineArrayPopShift(CallInfo& callInfo, MArrayPopShift::Mode mode)
OBJECT_FLAG_LENGTH_OVERFLOW |
OBJECT_FLAG_ITERATED;
- MDefinition* obj = convertUnboxedObjects(callInfo.thisArg());
+ MDefinition* obj = callInfo.thisArg();
TemporaryTypeSet* thisTypes = obj->resultTypeSet();
if (!thisTypes)
return InliningStatus_NotInlined;
@@ -743,7 +743,7 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo)
return InliningStatus_NotInlined;
}
- MDefinition* obj = convertUnboxedObjects(callInfo.thisArg());
+ MDefinition* obj = callInfo.thisArg();
MDefinition* value = callInfo.getArg(0);
if (PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current,
&obj, nullptr, &value, /* canModify = */ false))
@@ -822,7 +822,7 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo)
return InliningStatus_NotInlined;
}
- MDefinition* obj = convertUnboxedObjects(callInfo.thisArg());
+ MDefinition* obj = callInfo.thisArg();
// Ensure |this| and result are objects.
if (getInlineReturnType() != MIRType::Object)
@@ -2152,7 +2152,7 @@ IonBuilder::inlineDefineDataProperty(CallInfo& callInfo)
if (callInfo.argc() != 3)
return InliningStatus_NotInlined;
- MDefinition* obj = convertUnboxedObjects(callInfo.getArg(0));
+ MDefinition* obj = callInfo.getArg(0);
MDefinition* id = callInfo.getArg(1);
MDefinition* value = callInfo.getArg(2);
diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp
index 287b87582..1f33b2174 100644
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -4810,35 +4810,8 @@ MBeta::printOpcode(GenericPrinter& out) const
bool
MCreateThisWithTemplate::canRecoverOnBailout() const
{
- MOZ_ASSERT(templateObject()->is<PlainObject>() || templateObject()->is<UnboxedPlainObject>());
- MOZ_ASSERT_IF(templateObject()->is<PlainObject>(),
- !templateObject()->as<PlainObject>().denseElementsAreCopyOnWrite());
- return true;
-}
-
-bool
-OperandIndexMap::init(TempAllocator& alloc, JSObject* templateObject)
-{
- const UnboxedLayout& layout =
- templateObject->as<UnboxedPlainObject>().layoutDontCheckGeneration();
-
- const UnboxedLayout::PropertyVector& properties = layout.properties();
- MOZ_ASSERT(properties.length() < 255);
-
- // Allocate an array of indexes, where the top of each field correspond to
- // the index of the operand in the MObjectState instance.
- if (!map.init(alloc, layout.size()))
- return false;
-
- // Reset all indexes to 0, which is an error code.
- for (size_t i = 0; i < map.length(); i++)
- map[i] = 0;
-
- // Map the property offsets to the indexes of MObjectState operands.
- uint8_t index = 1;
- for (size_t i = 0; i < properties.length(); i++, index++)
- map[properties[i].offset] = index;
-
+ MOZ_ASSERT(templateObject()->is<PlainObject>());
+ MOZ_ASSERT(!templateObject()->as<PlainObject>().denseElementsAreCopyOnWrite());
return true;
}
@@ -4858,17 +4831,11 @@ MObjectState::MObjectState(JSObject *templateObject, OperandIndexMap* operandInd
setResultType(MIRType::Object);
setRecoveredOnBailout();
- if (templateObject->is<NativeObject>()) {
- NativeObject* nativeObject = &templateObject->as<NativeObject>();
- numSlots_ = nativeObject->slotSpan();
- numFixedSlots_ = nativeObject->numFixedSlots();
- } else {
- const UnboxedLayout& layout =
- templateObject->as<UnboxedPlainObject>().layoutDontCheckGeneration();
- // Same as UnboxedLayout::makeNativeGroup
- numSlots_ = layout.properties().length();
- numFixedSlots_ = gc::GetGCKindSlots(layout.getAllocKind());
- }
+ MOZ_ASSERT(templateObject->is<NativeObject>());
+
+ NativeObject* nativeObject = &templateObject->as<NativeObject>();
+ numSlots_ = nativeObject->slotSpan();
+ numFixedSlots_ = nativeObject->numFixedSlots();
operandIndex_ = operandIndex;
}
@@ -4905,39 +4872,21 @@ MObjectState::initFromTemplateObject(TempAllocator& alloc, MDefinition* undefine
// the template object. This is needed to account values which are baked in
// the template objects and not visible in IonMonkey, such as the
// uninitialized-lexical magic value of call objects.
- if (templateObject->is<UnboxedPlainObject>()) {
- UnboxedPlainObject& unboxedObject = templateObject->as<UnboxedPlainObject>();
- const UnboxedLayout& layout = unboxedObject.layoutDontCheckGeneration();
- const UnboxedLayout::PropertyVector& properties = layout.properties();
-
- for (size_t i = 0; i < properties.length(); i++) {
- Value val = unboxedObject.getValue(properties[i], /* maybeUninitialized = */ true);
- MDefinition *def = undefinedVal;
- if (!val.isUndefined()) {
- MConstant* ins = val.isObject() ?
- MConstant::NewConstraintlessObject(alloc, &val.toObject()) :
- MConstant::New(alloc, val);
- block()->insertBefore(this, ins);
- def = ins;
- }
- initSlot(i, def);
- }
- } else {
- NativeObject& nativeObject = templateObject->as<NativeObject>();
- MOZ_ASSERT(nativeObject.slotSpan() == numSlots());
-
- for (size_t i = 0; i < numSlots(); i++) {
- Value val = nativeObject.getSlot(i);
- MDefinition *def = undefinedVal;
- if (!val.isUndefined()) {
- MConstant* ins = val.isObject() ?
- MConstant::NewConstraintlessObject(alloc, &val.toObject()) :
- MConstant::New(alloc, val);
- block()->insertBefore(this, ins);
- def = ins;
- }
- initSlot(i, def);
+ NativeObject& nativeObject = templateObject->as<NativeObject>();
+ MOZ_ASSERT(nativeObject.slotSpan() == numSlots());
+
+ MOZ_ASSERT(templateObject->is<NativeObject>());
+ for (size_t i = 0; i < numSlots(); i++) {
+ Value val = nativeObject.getSlot(i);
+ MDefinition *def = undefinedVal;
+ if (!val.isUndefined()) {
+ MConstant* ins = val.isObject() ?
+ MConstant::NewConstraintlessObject(alloc, &val.toObject()) :
+ MConstant::New(alloc, val);
+ block()->insertBefore(this, ins);
+ def = ins;
}
+ initSlot(i, def);
}
return true;
}
@@ -4948,14 +4897,7 @@ MObjectState::New(TempAllocator& alloc, MDefinition* obj)
JSObject* templateObject = templateObjectOf(obj);
MOZ_ASSERT(templateObject, "Unexpected object creation.");
- OperandIndexMap* operandIndex = nullptr;
- if (templateObject->is<UnboxedPlainObject>()) {
- operandIndex = new(alloc) OperandIndexMap;
- if (!operandIndex || !operandIndex->init(alloc, templateObject))
- return nullptr;
- }
-
- MObjectState* res = new(alloc) MObjectState(templateObject, operandIndex);
+ MObjectState* res = new(alloc) MObjectState(templateObject, nullptr);
if (!res || !res->init(alloc, obj))
return nullptr;
return res;
@@ -5862,35 +5804,6 @@ MGetFirstDollarIndex::foldsTo(TempAllocator& alloc)
return MConstant::New(alloc, Int32Value(index));
}
-MConvertUnboxedObjectToNative*
-MConvertUnboxedObjectToNative::New(TempAllocator& alloc, MDefinition* obj, ObjectGroup* group)
-{
- MConvertUnboxedObjectToNative* res = new(alloc) MConvertUnboxedObjectToNative(obj, group);
-
- ObjectGroup* nativeGroup = group->unboxedLayout().nativeGroup();
-
- // Make a new type set for the result of this instruction which replaces
- // the input group with the native group we will convert it to.
- TemporaryTypeSet* types = obj->resultTypeSet();
- if (types && !types->unknownObject()) {
- TemporaryTypeSet* newTypes = types->cloneWithoutObjects(alloc.lifoAlloc());
- if (newTypes) {
- for (size_t i = 0; i < types->getObjectCount(); i++) {
- TypeSet::ObjectKey* key = types->getObject(i);
- if (!key)
- continue;
- if (key->unknownProperties() || !key->isGroup() || key->group() != group)
- newTypes->addType(TypeSet::ObjectType(key), alloc.lifoAlloc());
- else
- newTypes->addType(TypeSet::ObjectType(nativeGroup), alloc.lifoAlloc());
- }
- res->setResultTypeSet(newTypes);
- }
- }
-
- return res;
-}
-
bool
jit::ElementAccessIsDenseNative(CompilerConstraintList* constraints,
MDefinition* obj, MDefinition* id)
@@ -5945,8 +5858,6 @@ jit::UnboxedArrayElementType(CompilerConstraintList* constraints, MDefinition* o
elementType = layout.elementType();
else
return JSVAL_TYPE_MAGIC;
-
- key->watchStateChangeForUnboxedConvertedToNative(constraints);
}
return elementType;
@@ -6579,23 +6490,6 @@ jit::PropertyWriteNeedsTypeBarrier(TempAllocator& alloc, CompilerConstraintList*
}
}
- // Perform additional filtering to make sure that any unboxed property
- // being written can accommodate the value.
- for (size_t i = 0; i < types->getObjectCount(); i++) {
- TypeSet::ObjectKey* key = types->getObject(i);
- if (key && key->isGroup() && key->group()->maybeUnboxedLayout()) {
- const UnboxedLayout& layout = key->group()->unboxedLayout();
- if (name) {
- const UnboxedLayout::Property* property = layout.lookup(name);
- if (property && !CanStoreUnboxedType(alloc, property->type, *pvalue))
- return true;
- } else {
- if (layout.isArray() && !CanStoreUnboxedType(alloc, layout.elementType(), *pvalue))
- return true;
- }
- }
- }
-
if (success)
return false;
@@ -6626,17 +6520,6 @@ jit::PropertyWriteNeedsTypeBarrier(TempAllocator& alloc, CompilerConstraintList*
MOZ_ASSERT(excluded);
- // If the excluded object is a group with an unboxed layout, make sure it
- // does not have a corresponding native group. Objects with the native
- // group might appear even though they are not in the type set.
- if (excluded->isGroup()) {
- if (UnboxedLayout* layout = excluded->group()->maybeUnboxedLayout()) {
- if (layout->nativeGroup())
- return true;
- excluded->watchStateChangeForUnboxedConvertedToNative(constraints);
- }
- }
-
*pobj = AddGroupGuard(alloc, current, *pobj, excluded, /* bailOnEquality = */ true);
return false;
}
diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h
index fb0f22fc3..3e0421789 100644
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -30,7 +30,6 @@
#include "vm/EnvironmentObject.h"
#include "vm/SharedMem.h"
#include "vm/TypedArrayCommon.h"
-#include "vm/UnboxedObject.h"
// Undo windows.h damage on Win64
#undef MemoryBarrier
@@ -9742,59 +9741,6 @@ class MStoreUnboxedString
ALLOW_CLONE(MStoreUnboxedString)
};
-// Passes through an object, after ensuring it is converted from an unboxed
-// object to a native representation.
-class MConvertUnboxedObjectToNative
- : public MUnaryInstruction,
- public SingleObjectPolicy::Data
-{
- CompilerObjectGroup group_;
-
- explicit MConvertUnboxedObjectToNative(MDefinition* obj, ObjectGroup* group)
- : MUnaryInstruction(obj),
- group_(group)
- {
- setGuard();
- setMovable();
- setResultType(MIRType::Object);
- }
-
- public:
- INSTRUCTION_HEADER(ConvertUnboxedObjectToNative)
- NAMED_OPERANDS((0, object))
-
- static MConvertUnboxedObjectToNative* New(TempAllocator& alloc, MDefinition* obj,
- ObjectGroup* group);
-
- ObjectGroup* group() const {
- return group_;
- }
- bool congruentTo(const MDefinition* ins) const override {
- if (!congruentIfOperandsEqual(ins))
- return false;
- return ins->toConvertUnboxedObjectToNative()->group() == group();
- }
- AliasSet getAliasSet() const override {
- // This instruction can read and write to all parts of the object, but
- // is marked as non-effectful so it can be consolidated by LICM and GVN
- // and avoid inhibiting other optimizations.
- //
- // This is valid to do because when unboxed objects might have a native
- // group they can be converted to, we do not optimize accesses to the
- // unboxed objects and do not guard on their group or shape (other than
- // in this opcode).
- //
- // Later accesses can assume the object has a native representation
- // and optimize accordingly. Those accesses cannot be reordered before
- // this instruction, however. This is prevented by chaining this
- // instruction with the object itself, in the same way as MBoundsCheck.
- return AliasSet::None();
- }
- bool appendRoots(MRootList& roots) const override {
- return roots.append(group_);
- }
-};
-
// Array.prototype.pop or Array.prototype.shift on a dense array.
class MArrayPopShift
: public MUnaryInstruction,
@@ -11174,11 +11120,6 @@ class MGuardShape
setMovable();
setResultType(MIRType::Object);
setResultTypeSet(obj->resultTypeSet());
-
- // Disallow guarding on unboxed object shapes. The group is better to
- // guard on, and guarding on the shape can interact badly with
- // MConvertUnboxedObjectToNative.
- MOZ_ASSERT(shape->getObjectClass() != &UnboxedPlainObject::class_);
}
public:
@@ -11273,11 +11214,6 @@ class MGuardObjectGroup
setGuard();
setMovable();
setResultType(MIRType::Object);
-
- // Unboxed groups which might be converted to natives can't be guarded
- // on, due to MConvertUnboxedObjectToNative.
- MOZ_ASSERT_IF(group->maybeUnboxedLayoutDontCheckGeneration(),
- !group->unboxedLayoutDontCheckGeneration().nativeGroup());
}
public:
@@ -11386,73 +11322,6 @@ class MGuardClass
ALLOW_CLONE(MGuardClass)
};
-// Guard on the presence or absence of an unboxed object's expando.
-class MGuardUnboxedExpando
- : public MUnaryInstruction,
- public SingleObjectPolicy::Data
-{
- bool requireExpando_;
- BailoutKind bailoutKind_;
-
- MGuardUnboxedExpando(MDefinition* obj, bool requireExpando, BailoutKind bailoutKind)
- : MUnaryInstruction(obj),
- requireExpando_(requireExpando),
- bailoutKind_(bailoutKind)
- {
- setGuard();
- setMovable();
- setResultType(MIRType::Object);
- }
-
- public:
- INSTRUCTION_HEADER(GuardUnboxedExpando)
- TRIVIAL_NEW_WRAPPERS
- NAMED_OPERANDS((0, object))
-
- bool requireExpando() const {
- return requireExpando_;
- }
- BailoutKind bailoutKind() const {
- return bailoutKind_;
- }
- bool congruentTo(const MDefinition* ins) const override {
- if (!congruentIfOperandsEqual(ins))
- return false;
- if (requireExpando() != ins->toGuardUnboxedExpando()->requireExpando())
- return false;
- return true;
- }
- AliasSet getAliasSet() const override {
- return AliasSet::Load(AliasSet::ObjectFields);
- }
-};
-
-// Load an unboxed plain object's expando.
-class MLoadUnboxedExpando
- : public MUnaryInstruction,
- public SingleObjectPolicy::Data
-{
- private:
- explicit MLoadUnboxedExpando(MDefinition* object)
- : MUnaryInstruction(object)
- {
- setResultType(MIRType::Object);
- setMovable();
- }
-
- public:
- INSTRUCTION_HEADER(LoadUnboxedExpando)
- TRIVIAL_NEW_WRAPPERS
- NAMED_OPERANDS((0, object))
-
- bool congruentTo(const MDefinition* ins) const override {
- return congruentIfOperandsEqual(ins);
- }
- AliasSet getAliasSet() const override {
- return AliasSet::Load(AliasSet::ObjectFields);
- }
-};
-
// Load from vp[slot] (slots that are not inline in an object).
class MLoadSlot
: public MUnaryInstruction,
diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h
index fddc1e637..b80d1baf9 100644
--- a/js/src/jit/MOpcodes.h
+++ b/js/src/jit/MOpcodes.h
@@ -187,8 +187,6 @@ namespace jit {
_(GuardObjectGroup) \
_(GuardObjectIdentity) \
_(GuardClass) \
- _(GuardUnboxedExpando) \
- _(LoadUnboxedExpando) \
_(ArrayLength) \
_(SetArrayLength) \
_(GetNextEntryForIterator) \
@@ -219,7 +217,6 @@ namespace jit {
_(StoreUnboxedScalar) \
_(StoreUnboxedObjectOrNull) \
_(StoreUnboxedString) \
- _(ConvertUnboxedObjectToNative) \
_(ArrayPopShift) \
_(ArrayPush) \
_(ArraySlice) \
diff --git a/js/src/jit/OptimizationTracking.cpp b/js/src/jit/OptimizationTracking.cpp
index 308def041..b42634d43 100644
--- a/js/src/jit/OptimizationTracking.cpp
+++ b/js/src/jit/OptimizationTracking.cpp
@@ -15,9 +15,11 @@
#include "jit/JitcodeMap.h"
#include "jit/JitSpewer.h"
#include "js/TrackedOptimizationInfo.h"
+#include "vm/UnboxedObject.h"
#include "vm/ObjectGroup-inl.h"
#include "vm/TypeInference-inl.h"
+#include "vm/UnboxedObject-inl.h"
using namespace js;
using namespace js::jit;
diff --git a/js/src/jit/Recover.cpp b/js/src/jit/Recover.cpp
index 13bf9224b..6fd71f377 100644
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -30,6 +30,7 @@
#include "vm/Interpreter-inl.h"
#include "vm/NativeObject-inl.h"
+#include "vm/UnboxedObject-inl.h"
using namespace js;
using namespace js::jit;
diff --git a/js/src/jit/ScalarReplacement.cpp b/js/src/jit/ScalarReplacement.cpp
index 4614b2162..2065c0371 100644
--- a/js/src/jit/ScalarReplacement.cpp
+++ b/js/src/jit/ScalarReplacement.cpp
@@ -13,7 +13,6 @@
#include "jit/MIR.h"
#include "jit/MIRGenerator.h"
#include "jit/MIRGraph.h"
-#include "vm/UnboxedObject.h"
#include "jsobjinlines.h"
@@ -183,25 +182,6 @@ IsObjectEscaped(MInstruction* ins, JSObject* objDefault)
JitSpewDef(JitSpew_Escape, "is escaped by\n", def);
return true;
- case MDefinition::Op_LoadUnboxedScalar:
- case MDefinition::Op_StoreUnboxedScalar:
- case MDefinition::Op_LoadUnboxedObjectOrNull:
- case MDefinition::Op_StoreUnboxedObjectOrNull:
- case MDefinition::Op_LoadUnboxedString:
- case MDefinition::Op_StoreUnboxedString:
- // Not escaped if it is the first argument.
- if (def->indexOf(*i) != 0) {
- JitSpewDef(JitSpew_Escape, "is escaped by\n", def);
- return true;
- }
-
- if (!def->getOperand(1)->isConstant()) {
- JitSpewDef(JitSpew_Escape, "is addressed with unknown index\n", def);
- return true;
- }
-
- break;
-
case MDefinition::Op_PostWriteBarrier:
break;
@@ -305,12 +285,6 @@ class ObjectMemoryView : public MDefinitionVisitorDefaultNoop
void visitGuardShape(MGuardShape* ins);
void visitFunctionEnvironment(MFunctionEnvironment* ins);
void visitLambda(MLambda* ins);
- void visitStoreUnboxedScalar(MStoreUnboxedScalar* ins);
- void visitLoadUnboxedScalar(MLoadUnboxedScalar* ins);
- void visitStoreUnboxedObjectOrNull(MStoreUnboxedObjectOrNull* ins);
- void visitLoadUnboxedObjectOrNull(MLoadUnboxedObjectOrNull* ins);
- void visitStoreUnboxedString(MStoreUnboxedString* ins);
- void visitLoadUnboxedString(MLoadUnboxedString* ins);
private:
void storeOffset(MInstruction* ins, size_t offset, MDefinition* value);
@@ -656,21 +630,6 @@ ObjectMemoryView::visitLambda(MLambda* ins)
ins->setIncompleteObject();
}
-static size_t
-GetOffsetOf(MDefinition* index, size_t width, int32_t baseOffset)
-{
- int32_t idx = index->toConstant()->toInt32();
- MOZ_ASSERT(idx >= 0);
- MOZ_ASSERT(baseOffset >= 0 && size_t(baseOffset) >= UnboxedPlainObject::offsetOfData());
- return idx * width + baseOffset - UnboxedPlainObject::offsetOfData();
-}
-
-static size_t
-GetOffsetOf(MDefinition* index, Scalar::Type type, int32_t baseOffset)
-{
- return GetOffsetOf(index, Scalar::byteSize(type), baseOffset);
-}
-
void
ObjectMemoryView::storeOffset(MInstruction* ins, size_t offset, MDefinition* value)
{
@@ -700,77 +659,6 @@ ObjectMemoryView::loadOffset(MInstruction* ins, size_t offset)
ins->block()->discard(ins);
}
-void
-ObjectMemoryView::visitStoreUnboxedScalar(MStoreUnboxedScalar* ins)
-{
- // Skip stores made on other objects.
- if (ins->elements() != obj_)
- return;
-
- size_t offset = GetOffsetOf(ins->index(), ins->storageType(), ins->offsetAdjustment());
- storeOffset(ins, offset, ins->value());
-}
-
-void
-ObjectMemoryView::visitLoadUnboxedScalar(MLoadUnboxedScalar* ins)
-{
- // Skip loads made on other objects.
- if (ins->elements() != obj_)
- return;
-
- // Replace load by the slot value.
- size_t offset = GetOffsetOf(ins->index(), ins->storageType(), ins->offsetAdjustment());
- loadOffset(ins, offset);
-}
-
-void
-ObjectMemoryView::visitStoreUnboxedObjectOrNull(MStoreUnboxedObjectOrNull* ins)
-{
- // Skip stores made on other objects.
- if (ins->elements() != obj_)
- return;
-
- // Clone the state and update the slot value.
- size_t offset = GetOffsetOf(ins->index(), sizeof(uintptr_t), ins->offsetAdjustment());
- storeOffset(ins, offset, ins->value());
-}
-
-void
-ObjectMemoryView::visitLoadUnboxedObjectOrNull(MLoadUnboxedObjectOrNull* ins)
-{
- // Skip loads made on other objects.
- if (ins->elements() != obj_)
- return;
-
- // Replace load by the slot value.
- size_t offset = GetOffsetOf(ins->index(), sizeof(uintptr_t), ins->offsetAdjustment());
- loadOffset(ins, offset);
-}
-
-void
-ObjectMemoryView::visitStoreUnboxedString(MStoreUnboxedString* ins)
-{
- // Skip stores made on other objects.
- if (ins->elements() != obj_)
- return;
-
- // Clone the state and update the slot value.
- size_t offset = GetOffsetOf(ins->index(), sizeof(uintptr_t), ins->offsetAdjustment());
- storeOffset(ins, offset, ins->value());
-}
-
-void
-ObjectMemoryView::visitLoadUnboxedString(MLoadUnboxedString* ins)
-{
- // Skip loads made on other objects.
- if (ins->elements() != obj_)
- return;
-
- // Replace load by the slot value.
- size_t offset = GetOffsetOf(ins->index(), sizeof(uintptr_t), ins->offsetAdjustment());
- loadOffset(ins, offset);
-}
-
static bool
IndexOf(MDefinition* ins, int32_t* res)
{
diff --git a/js/src/jit/SharedIC.cpp b/js/src/jit/SharedIC.cpp
index 767cff661..2475dfb22 100644
--- a/js/src/jit/SharedIC.cpp
+++ b/js/src/jit/SharedIC.cpp
@@ -27,6 +27,7 @@
#endif
#include "jit/VMFunctions.h"
#include "vm/Interpreter.h"
+#include "vm/NativeObject-inl.h"
#include "jit/MacroAssembler-inl.h"
#include "vm/Interpreter-inl.h"
diff --git a/js/src/jit/arm/Assembler-arm.cpp b/js/src/jit/arm/Assembler-arm.cpp
index 2830f0695..1e20da1c8 100644
--- a/js/src/jit/arm/Assembler-arm.cpp
+++ b/js/src/jit/arm/Assembler-arm.cpp
@@ -2401,7 +2401,12 @@ Assembler::as_b(Label* l, Condition c)
if (oom())
return BufferOffset();
- as_b(BufferOffset(l).diffB<BOffImm>(ret), c, ret);
+ BOffImm off = BufferOffset(l).diffB<BOffImm>(ret);
+ if (off.isInvalid()) {
+ m_buffer.fail_bail();
+ return BufferOffset();
+ }
+ as_b(off, c, ret);
#ifdef JS_DISASM_ARM
spewBranch(m_buffer.getInstOrNull(ret), l);
#endif
diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp
index d40578514..a4161ab00 100644
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -5012,7 +5012,10 @@ void
MacroAssembler::patchCall(uint32_t callerOffset, uint32_t calleeOffset)
{
BufferOffset inst(callerOffset - 4);
- as_bl(BufferOffset(calleeOffset).diffB<BOffImm>(inst), Always, inst);
+ BOffImm off = BufferOffset(calleeOffset).diffB<BOffImm>(inst);
+ MOZ_RELEASE_ASSERT(!off.isInvalid(),
+ "Failed to insert necessary far jump islands");
+ as_bl(off, Always, inst);
}
CodeOffset
diff --git a/js/src/jit/shared/LIR-shared.h b/js/src/jit/shared/LIR-shared.h
index f4adcc63c..f386d5256 100644
--- a/js/src/jit/shared/LIR-shared.h
+++ b/js/src/jit/shared/LIR-shared.h
@@ -5891,22 +5891,6 @@ class LStoreUnboxedPointer : public LInstructionHelper<0, 3, 0>
}
};
-// If necessary, convert an unboxed object in a particular group to its native
-// representation.
-class LConvertUnboxedObjectToNative : public LInstructionHelper<0, 1, 0>
-{
- public:
- LIR_HEADER(ConvertUnboxedObjectToNative)
-
- explicit LConvertUnboxedObjectToNative(const LAllocation& object) {
- setOperand(0, object);
- }
-
- MConvertUnboxedObjectToNative* mir() {
- return mir_->toConvertUnboxedObjectToNative();
- }
-};
-
class LArrayPopShiftV : public LInstructionHelper<BOX_PIECES, 1, 2>
{
public:
@@ -7429,38 +7413,6 @@ class LGuardReceiverPolymorphic : public LInstructionHelper<0, 1, 1>
}
};
-class LGuardUnboxedExpando : public LInstructionHelper<0, 1, 0>
-{
- public:
- LIR_HEADER(GuardUnboxedExpando)
-
- explicit LGuardUnboxedExpando(const LAllocation& in) {
- setOperand(0, in);
- }
- const LAllocation* object() {
- return getOperand(0);
- }
- const MGuardUnboxedExpando* mir() const {
- return mir_->toGuardUnboxedExpando();
- }
-};
-
-class LLoadUnboxedExpando : public LInstructionHelper<1, 1, 0>
-{
- public:
- LIR_HEADER(LoadUnboxedExpando)
-
- explicit LLoadUnboxedExpando(const LAllocation& in) {
- setOperand(0, in);
- }
- const LAllocation* object() {
- return getOperand(0);
- }
- const MLoadUnboxedExpando* mir() const {
- return mir_->toLoadUnboxedExpando();
- }
-};
-
// Guard that a value is in a TypeSet.
class LTypeBarrierV : public LInstructionHelper<0, BOX_PIECES, 1>
{
diff --git a/js/src/jit/shared/LOpcodes-shared.h b/js/src/jit/shared/LOpcodes-shared.h
index fe2ab5ea3..6912e8904 100644
--- a/js/src/jit/shared/LOpcodes-shared.h
+++ b/js/src/jit/shared/LOpcodes-shared.h
@@ -258,8 +258,6 @@
_(GuardObjectGroup) \
_(GuardObjectIdentity) \
_(GuardClass) \
- _(GuardUnboxedExpando) \
- _(LoadUnboxedExpando) \
_(TypeBarrierV) \
_(TypeBarrierO) \
_(MonitorTypes) \
@@ -287,7 +285,6 @@
_(StoreElementT) \
_(StoreUnboxedScalar) \
_(StoreUnboxedPointer) \
- _(ConvertUnboxedObjectToNative) \
_(ArrayPopShiftV) \
_(ArrayPopShiftT) \
_(ArrayPushV) \