summaryrefslogtreecommitdiffstats
path: root/js/src/jit
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit')
-rw-r--r--js/src/jit/BaselineCacheIR.cpp52
-rw-r--r--js/src/jit/BaselineIC.cpp269
-rw-r--r--js/src/jit/BaselineIC.h10
-rw-r--r--js/src/jit/BaselineInspector.cpp46
-rw-r--r--js/src/jit/CacheIR.cpp72
-rw-r--r--js/src/jit/CacheIR.h20
-rw-r--r--js/src/jit/CodeGenerator.cpp32
-rw-r--r--js/src/jit/IonBuilder.cpp183
-rw-r--r--js/src/jit/IonBuilder.h13
-rw-r--r--js/src/jit/IonCaches.cpp336
-rw-r--r--js/src/jit/IonCaches.h12
-rw-r--r--js/src/jit/JitOptions.cpp3
-rw-r--r--js/src/jit/JitOptions.h3
-rw-r--r--js/src/jit/MCallOptimize.cpp1
-rw-r--r--js/src/jit/MIR.cpp9
-rw-r--r--js/src/jit/MIR.h23
-rw-r--r--js/src/jit/MacroAssembler.cpp274
-rw-r--r--js/src/jit/MacroAssembler.h14
-rw-r--r--js/src/jit/OptimizationTracking.cpp4
-rw-r--r--js/src/jit/Recover.cpp36
-rw-r--r--js/src/jit/ScalarReplacement.cpp33
-rw-r--r--js/src/jit/SharedIC.cpp30
-rw-r--r--js/src/jit/VMFunctions.cpp2
23 files changed, 53 insertions, 1424 deletions
diff --git a/js/src/jit/BaselineCacheIR.cpp b/js/src/jit/BaselineCacheIR.cpp
index 7fb586811..67c80473b 100644
--- a/js/src/jit/BaselineCacheIR.cpp
+++ b/js/src/jit/BaselineCacheIR.cpp
@@ -16,7 +16,7 @@ using namespace js;
using namespace js::jit;
// OperandLocation represents the location of an OperandId. The operand is
-// either in a register or on the stack, and is either boxed or unboxed.
+// either in a register or on the stack.
class OperandLocation
{
public:
@@ -815,36 +815,6 @@ BaselineCacheIRCompiler::emitGuardSpecificObject()
}
bool
-BaselineCacheIRCompiler::emitGuardNoUnboxedExpando()
-{
- Register obj = allocator.useRegister(masm, reader.objOperandId());
-
- FailurePath* failure;
- if (!addFailurePath(&failure))
- return false;
-
- Address expandoAddr(obj, UnboxedPlainObject::offsetOfExpando());
- masm.branchPtr(Assembler::NotEqual, expandoAddr, ImmWord(0), failure->label());
- return true;
-}
-
-bool
-BaselineCacheIRCompiler::emitGuardAndLoadUnboxedExpando()
-{
- Register obj = allocator.useRegister(masm, reader.objOperandId());
- Register output = allocator.defineRegister(masm, reader.objOperandId());
-
- FailurePath* failure;
- if (!addFailurePath(&failure))
- return false;
-
- Address expandoAddr(obj, UnboxedPlainObject::offsetOfExpando());
- masm.loadPtr(expandoAddr, output);
- masm.branchTestPtr(Assembler::Zero, output, output, failure->label());
- return true;
-}
-
-bool
BaselineCacheIRCompiler::emitLoadFixedSlotResult()
{
Register obj = allocator.useRegister(masm, reader.objOperandId());
@@ -871,26 +841,6 @@ BaselineCacheIRCompiler::emitLoadDynamicSlotResult()
}
bool
-BaselineCacheIRCompiler::emitLoadUnboxedPropertyResult()
-{
- Register obj = allocator.useRegister(masm, reader.objOperandId());
- AutoScratchRegister scratch(allocator, masm);
-
- JSValueType fieldType = reader.valueType();
-
- Address fieldOffset(stubAddress(reader.stubOffset()));
- masm.load32(fieldOffset, scratch);
- masm.loadUnboxedProperty(BaseIndex(obj, scratch, TimesOne), fieldType, R0);
-
- if (fieldType == JSVAL_TYPE_OBJECT)
- emitEnterTypeMonitorIC();
- else
- emitReturnFromIC();
-
- return true;
-}
-
-bool
BaselineCacheIRCompiler::emitGuardNoDetachedTypedObjects()
{
FailurePath* failure;
diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp
index 64cdf01a6..d95d08edc 100644
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -42,8 +42,8 @@
#include "jit/shared/Lowering-shared-inl.h"
#include "vm/EnvironmentObject-inl.h"
#include "vm/Interpreter-inl.h"
+#include "vm/NativeObject-inl.h"
#include "vm/StringObject-inl.h"
-#include "vm/UnboxedObject-inl.h"
using mozilla::DebugOnly;
@@ -732,11 +732,6 @@ LastPropertyForSetProp(JSObject* obj)
if (obj->isNative())
return obj->as<NativeObject>().lastProperty();
- if (obj->is<UnboxedPlainObject>()) {
- UnboxedExpandoObject* expando = obj->as<UnboxedPlainObject>().maybeExpando();
- return expando ? expando->lastProperty() : nullptr;
- }
-
return nullptr;
}
@@ -1153,56 +1148,6 @@ TryAttachNativeOrUnboxedGetValueElemStub(JSContext* cx, HandleScript script, jsb
ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
- if (obj->is<UnboxedPlainObject>() && holder == obj) {
- const UnboxedLayout::Property* property = obj->as<UnboxedPlainObject>().layout().lookup(id);
-
- // Once unboxed objects support symbol-keys, we need to change the following accordingly
- MOZ_ASSERT_IF(!keyVal.isString(), !property);
-
- if (property) {
- if (!cx->runtime()->jitSupportsFloatingPoint)
- return true;
-
- RootedPropertyName name(cx, JSID_TO_ATOM(id)->asPropertyName());
- ICGetElemNativeCompiler<PropertyName*> compiler(cx, ICStub::GetElem_UnboxedPropertyName,
- monitorStub, obj, holder,
- name,
- ICGetElemNativeStub::UnboxedProperty,
- needsAtomize, property->offset +
- UnboxedPlainObject::offsetOfData(),
- property->type);
- ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
- if (!newStub)
- return false;
-
- stub->addNewStub(newStub);
- *attached = true;
- return true;
- }
-
- Shape* shape = obj->as<UnboxedPlainObject>().maybeExpando()->lookup(cx, id);
- if (!shape->hasDefaultGetter() || !shape->hasSlot())
- return true;
-
- bool isFixedSlot;
- uint32_t offset;
- GetFixedOrDynamicSlotOffset(shape, &isFixedSlot, &offset);
-
- ICGetElemNativeStub::AccessType acctype =
- isFixedSlot ? ICGetElemNativeStub::FixedSlot
- : ICGetElemNativeStub::DynamicSlot;
- ICGetElemNativeCompiler<T> compiler(cx, getGetElemStubKind<T>(ICStub::GetElem_NativeSlotName),
- monitorStub, obj, holder, key,
- acctype, needsAtomize, offset);
- ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
- if (!newStub)
- return false;
-
- stub->addNewStub(newStub);
- *attached = true;
- return true;
- }
-
if (!holder->isNative())
return true;
@@ -1450,7 +1395,7 @@ TryAttachGetElemStub(JSContext* cx, JSScript* script, jsbytecode* pc, ICGetElem_
}
// Check for NativeObject[id] and UnboxedPlainObject[id] shape-optimizable accesses.
- if (obj->isNative() || obj->is<UnboxedPlainObject>()) {
+ if (obj->isNative()) {
RootedScript rootedScript(cx, script);
if (rhs.isString()) {
if (!TryAttachNativeOrUnboxedGetValueElemStub<PropertyName*>(cx, rootedScript, pc, stub,
@@ -1862,14 +1807,6 @@ ICGetElemNativeCompiler<T>::generateStubCode(MacroAssembler& masm)
Register holderReg;
if (obj_ == holder_) {
holderReg = objReg;
-
- if (obj_->is<UnboxedPlainObject>() && acctype_ != ICGetElemNativeStub::UnboxedProperty) {
- // The property will be loaded off the unboxed expando.
- masm.push(R1.scratchReg());
- popR1 = true;
- holderReg = R1.scratchReg();
- masm.loadPtr(Address(objReg, UnboxedPlainObject::offsetOfExpando()), holderReg);
- }
} else {
// Shape guard holder.
if (regs.empty()) {
@@ -1920,13 +1857,6 @@ ICGetElemNativeCompiler<T>::generateStubCode(MacroAssembler& masm)
if (popR1)
masm.addToStackPtr(ImmWord(sizeof(size_t)));
- } else if (acctype_ == ICGetElemNativeStub::UnboxedProperty) {
- masm.load32(Address(ICStubReg, ICGetElemNativeSlotStub<T>::offsetOfOffset()),
- scratchReg);
- masm.loadUnboxedProperty(BaseIndex(objReg, scratchReg, TimesOne), unboxedType_,
- TypedOrValueRegister(R0));
- if (popR1)
- masm.addToStackPtr(ImmWord(sizeof(size_t)));
} else {
MOZ_ASSERT(acctype_ == ICGetElemNativeStub::NativeGetter ||
acctype_ == ICGetElemNativeStub::ScriptedGetter);
@@ -2673,18 +2603,6 @@ BaselineScript::noteArrayWriteHole(uint32_t pcOffset)
// SetElem_DenseOrUnboxedArray
//
-template <typename T>
-void
-EmitUnboxedPreBarrierForBaseline(MacroAssembler &masm, T address, JSValueType type)
-{
- if (type == JSVAL_TYPE_OBJECT)
- EmitPreBarrier(masm, address, MIRType::Object);
- else if (type == JSVAL_TYPE_STRING)
- EmitPreBarrier(masm, address, MIRType::String);
- else
- MOZ_ASSERT(!UnboxedTypeNeedsPreBarrier(type));
-}
-
bool
ICSetElem_DenseOrUnboxedArray::Compiler::generateStubCode(MacroAssembler& masm)
{
@@ -4131,18 +4049,7 @@ TryAttachSetValuePropStub(JSContext* cx, HandleScript script, jsbytecode* pc, IC
return true;
if (!obj->isNative()) {
- if (obj->is<UnboxedPlainObject>()) {
- UnboxedExpandoObject* expando = obj->as<UnboxedPlainObject>().maybeExpando();
- if (expando) {
- shape = expando->lookup(cx, name);
- if (!shape)
- return true;
- } else {
- return true;
- }
- } else {
- return true;
- }
+ return true;
}
size_t chainDepth;
@@ -4293,40 +4200,6 @@ TryAttachSetAccessorPropStub(JSContext* cx, HandleScript script, jsbytecode* pc,
}
static bool
-TryAttachUnboxedSetPropStub(JSContext* cx, HandleScript script,
- ICSetProp_Fallback* stub, HandleId id,
- HandleObject obj, HandleValue rhs, bool* attached)
-{
- MOZ_ASSERT(!*attached);
-
- if (!cx->runtime()->jitSupportsFloatingPoint)
- return true;
-
- if (!obj->is<UnboxedPlainObject>())
- return true;
-
- const UnboxedLayout::Property* property = obj->as<UnboxedPlainObject>().layout().lookup(id);
- if (!property)
- return true;
-
- ICSetProp_Unboxed::Compiler compiler(cx, obj->group(),
- property->offset + UnboxedPlainObject::offsetOfData(),
- property->type);
- ICUpdatedStub* newStub = compiler.getStub(compiler.getStubSpace(script));
- if (!newStub)
- return false;
- if (compiler.needsUpdateStubs() && !newStub->addUpdateStubForValue(cx, script, obj, id, rhs))
- return false;
-
- stub->addNewStub(newStub);
-
- StripPreliminaryObjectStubs(cx, stub);
-
- *attached = true;
- return true;
-}
-
-static bool
TryAttachTypedObjectSetPropStub(JSContext* cx, HandleScript script,
ICSetProp_Fallback* stub, HandleId id,
HandleObject obj, HandleValue rhs, bool* attached)
@@ -4409,12 +4282,6 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_
return false;
RootedReceiverGuard oldGuard(cx, ReceiverGuard(obj));
- if (obj->is<UnboxedPlainObject>()) {
- MOZ_ASSERT(!oldShape);
- if (UnboxedExpandoObject* expando = obj->as<UnboxedPlainObject>().maybeExpando())
- oldShape = expando->lastProperty();
- }
-
bool attached = false;
// There are some reasons we can fail to attach a stub that are temporary.
// We want to avoid calling noteUnoptimizableAccess() if the reason we
@@ -4487,15 +4354,6 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_
if (!attached &&
lhs.isObject() &&
- !TryAttachUnboxedSetPropStub(cx, script, stub, id, obj, rhs, &attached))
- {
- return false;
- }
- if (attached)
- return true;
-
- if (!attached &&
- lhs.isObject() &&
!TryAttachTypedObjectSetPropStub(cx, script, stub, id, obj, rhs, &attached))
{
return false;
@@ -4578,20 +4436,7 @@ GuardGroupAndShapeMaybeUnboxedExpando(MacroAssembler& masm, JSObject* obj,
// Guard against shape or expando shape.
masm.loadPtr(Address(ICStubReg, offsetOfShape), scratch);
- if (obj->is<UnboxedPlainObject>()) {
- Address expandoAddress(object, UnboxedPlainObject::offsetOfExpando());
- masm.branchPtr(Assembler::Equal, expandoAddress, ImmWord(0), failure);
- Label done;
- masm.push(object);
- masm.loadPtr(expandoAddress, object);
- masm.branchTestObjShape(Assembler::Equal, object, scratch, &done);
- masm.pop(object);
- masm.jump(failure);
- masm.bind(&done);
- masm.pop(object);
- } else {
- masm.branchTestObjShape(Assembler::NotEqual, object, scratch, failure);
- }
+ masm.branchTestObjShape(Assembler::NotEqual, object, scratch, failure);
}
bool
@@ -4630,13 +4475,7 @@ ICSetProp_Native::Compiler::generateStubCode(MacroAssembler& masm)
regs.takeUnchecked(objReg);
Register holderReg;
- if (obj_->is<UnboxedPlainObject>()) {
- // We are loading off the expando object, so use that for the holder.
- holderReg = regs.takeAny();
- masm.loadPtr(Address(objReg, UnboxedPlainObject::offsetOfExpando()), holderReg);
- if (!isFixedSlot_)
- masm.loadPtr(Address(holderReg, NativeObject::offsetOfSlots()), holderReg);
- } else if (isFixedSlot_) {
+ if (isFixedSlot_) {
holderReg = objReg;
} else {
holderReg = regs.takeAny();
@@ -4773,31 +4612,17 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler& masm)
regs.add(R0);
regs.takeUnchecked(objReg);
- if (obj_->is<UnboxedPlainObject>()) {
- holderReg = regs.takeAny();
- masm.loadPtr(Address(objReg, UnboxedPlainObject::offsetOfExpando()), holderReg);
-
- // Write the expando object's new shape.
- Address shapeAddr(holderReg, ShapedObject::offsetOfShape());
- EmitPreBarrier(masm, shapeAddr, MIRType::Shape);
- masm.loadPtr(Address(ICStubReg, ICSetProp_NativeAdd::offsetOfNewShape()), scratch);
- masm.storePtr(scratch, shapeAddr);
+ // Write the object's new shape.
+ Address shapeAddr(objReg, ShapedObject::offsetOfShape());
+ EmitPreBarrier(masm, shapeAddr, MIRType::Shape);
+ masm.loadPtr(Address(ICStubReg, ICSetProp_NativeAdd::offsetOfNewShape()), scratch);
+ masm.storePtr(scratch, shapeAddr);
- if (!isFixedSlot_)
- masm.loadPtr(Address(holderReg, NativeObject::offsetOfSlots()), holderReg);
+ if (isFixedSlot_) {
+ holderReg = objReg;
} else {
- // Write the object's new shape.
- Address shapeAddr(objReg, ShapedObject::offsetOfShape());
- EmitPreBarrier(masm, shapeAddr, MIRType::Shape);
- masm.loadPtr(Address(ICStubReg, ICSetProp_NativeAdd::offsetOfNewShape()), scratch);
- masm.storePtr(scratch, shapeAddr);
-
- if (isFixedSlot_) {
- holderReg = objReg;
- } else {
- holderReg = regs.takeAny();
- masm.loadPtr(Address(objReg, NativeObject::offsetOfSlots()), holderReg);
- }
+ holderReg = regs.takeAny();
+ masm.loadPtr(Address(objReg, NativeObject::offsetOfSlots()), holderReg);
}
// Perform the store. No write barrier required since this is a new
@@ -4829,70 +4654,6 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler& masm)
}
bool
-ICSetProp_Unboxed::Compiler::generateStubCode(MacroAssembler& masm)
-{
- MOZ_ASSERT(engine_ == Engine::Baseline);
-
- Label failure;
-
- // Guard input is an object.
- masm.branchTestObject(Assembler::NotEqual, R0, &failure);
-
- AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
- Register scratch = regs.takeAny();
-
- // Unbox and group guard.
- Register object = masm.extractObject(R0, ExtractTemp0);
- masm.loadPtr(Address(ICStubReg, ICSetProp_Unboxed::offsetOfGroup()), scratch);
- masm.branchPtr(Assembler::NotEqual, Address(object, JSObject::offsetOfGroup()), scratch,
- &failure);
-
- if (needsUpdateStubs()) {
- // Stow both R0 and R1 (object and value).
- EmitStowICValues(masm, 2);
-
- // Move RHS into R0 for TypeUpdate check.
- masm.moveValue(R1, R0);
-
- // Call the type update stub.
- if (!callTypeUpdateIC(masm, sizeof(Value)))
- return false;
-
- // Unstow R0 and R1 (object and key)
- EmitUnstowICValues(masm, 2);
-
- // The TypeUpdate IC may have smashed object. Rederive it.
- masm.unboxObject(R0, object);
-
- // Trigger post barriers here on the values being written. Fields which
- // objects can be written to also need update stubs.
- LiveGeneralRegisterSet saveRegs;
- saveRegs.add(R0);
- saveRegs.add(R1);
- saveRegs.addUnchecked(object);
- saveRegs.add(ICStubReg);
- emitPostWriteBarrierSlot(masm, object, R1, scratch, saveRegs);
- }
-
- // Compute the address being written to.
- masm.load32(Address(ICStubReg, ICSetProp_Unboxed::offsetOfFieldOffset()), scratch);
- BaseIndex address(object, scratch, TimesOne);
-
- EmitUnboxedPreBarrierForBaseline(masm, address, fieldType_);
- masm.storeUnboxedProperty(address, fieldType_,
- ConstantOrRegister(TypedOrValueRegister(R1)), &failure);
-
- // The RHS has to be in R0.
- masm.moveValue(R1, R0);
-
- EmitReturnFromIC(masm);
-
- masm.bind(&failure);
- EmitStubGuardFailure(masm);
- return true;
-}
-
-bool
ICSetProp_TypedObject::Compiler::generateStubCode(MacroAssembler& masm)
{
MOZ_ASSERT(engine_ == Engine::Baseline);
@@ -5652,7 +5413,7 @@ TryAttachCallStub(JSContext* cx, ICCall_Fallback* stub, HandleScript script, jsb
if (!thisObject)
return false;
- if (thisObject->is<PlainObject>() || thisObject->is<UnboxedPlainObject>())
+ if (thisObject->is<PlainObject>())
templateObject = thisObject;
}
diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h
index 901fca9cc..98f0e1c59 100644
--- a/js/src/jit/BaselineIC.h
+++ b/js/src/jit/BaselineIC.h
@@ -22,7 +22,6 @@
#include "jit/SharedICRegisters.h"
#include "js/GCVector.h"
#include "vm/ArrayObject.h"
-#include "vm/UnboxedObject.h"
namespace js {
namespace jit {
@@ -1823,8 +1822,7 @@ class ICSetProp_Native : public ICUpdatedStub
virtual int32_t getKey() const {
return static_cast<int32_t>(engine_) |
(static_cast<int32_t>(kind) << 1) |
- (static_cast<int32_t>(isFixedSlot_) << 17) |
- (static_cast<int32_t>(obj_->is<UnboxedPlainObject>()) << 18);
+ (static_cast<int32_t>(isFixedSlot_) << 17);
}
MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm);
@@ -1929,7 +1927,6 @@ class ICSetPropNativeAddCompiler : public ICStubCompiler
return static_cast<int32_t>(engine_) |
(static_cast<int32_t>(kind) << 1) |
(static_cast<int32_t>(isFixedSlot_) << 17) |
- (static_cast<int32_t>(obj_->is<UnboxedPlainObject>()) << 18) |
(static_cast<int32_t>(protoChainDepth_) << 19);
}
@@ -1954,10 +1951,7 @@ class ICSetPropNativeAddCompiler : public ICStubCompiler
newGroup = nullptr;
RootedShape newShape(cx);
- if (obj_->isNative())
- newShape = obj_->as<NativeObject>().lastProperty();
- else
- newShape = obj_->as<UnboxedPlainObject>().maybeExpando()->lastProperty();
+ newShape = obj_->as<NativeObject>().lastProperty();
return newStub<ICSetProp_NativeAddImpl<ProtoChainDepth>>(
space, getStubCode(), oldGroup_, shapes, newShape, newGroup, offset_);
diff --git a/js/src/jit/BaselineInspector.cpp b/js/src/jit/BaselineInspector.cpp
index bcb527516..3b852debf 100644
--- a/js/src/jit/BaselineInspector.cpp
+++ b/js/src/jit/BaselineInspector.cpp
@@ -104,19 +104,11 @@ AddReceiver(const ReceiverGuard& receiver,
static bool
GetCacheIRReceiverForNativeReadSlot(ICCacheIR_Monitored* stub, ReceiverGuard* receiver)
{
- // We match either:
+ // We match:
//
// GuardIsObject 0
// GuardShape 0
// LoadFixedSlotResult 0 or LoadDynamicSlotResult 0
- //
- // or
- //
- // GuardIsObject 0
- // GuardGroup 0
- // 1: GuardAndLoadUnboxedExpando 0
- // GuardShape 1
- // LoadFixedSlotResult 1 or LoadDynamicSlotResult 1
*receiver = ReceiverGuard();
CacheIRReader reader(stub->stubInfo());
@@ -125,14 +117,6 @@ GetCacheIRReceiverForNativeReadSlot(ICCacheIR_Monitored* stub, ReceiverGuard* re
if (!reader.matchOp(CacheOp::GuardIsObject, objId))
return false;
- if (reader.matchOp(CacheOp::GuardGroup, objId)) {
- receiver->group = stub->stubInfo()->getStubField<ObjectGroup*>(stub, reader.stubOffset());
-
- if (!reader.matchOp(CacheOp::GuardAndLoadUnboxedExpando, objId))
- return false;
- objId = reader.objOperandId();
- }
-
if (reader.matchOp(CacheOp::GuardShape, objId)) {
receiver->shape = stub->stubInfo()->getStubField<Shape*>(stub, reader.stubOffset());
return reader.matchOpEither(CacheOp::LoadFixedSlotResult, CacheOp::LoadDynamicSlotResult);
@@ -141,29 +125,6 @@ GetCacheIRReceiverForNativeReadSlot(ICCacheIR_Monitored* stub, ReceiverGuard* re
return false;
}
-static bool
-GetCacheIRReceiverForUnboxedProperty(ICCacheIR_Monitored* stub, ReceiverGuard* receiver)
-{
- // We match:
- //
- // GuardIsObject 0
- // GuardGroup 0
- // LoadUnboxedPropertyResult 0 ..
-
- *receiver = ReceiverGuard();
- CacheIRReader reader(stub->stubInfo());
-
- ObjOperandId objId = ObjOperandId(0);
- if (!reader.matchOp(CacheOp::GuardIsObject, objId))
- return false;
-
- if (!reader.matchOp(CacheOp::GuardGroup, objId))
- return false;
- receiver->group = stub->stubInfo()->getStubField<ObjectGroup*>(stub, reader.stubOffset());
-
- return reader.matchOp(CacheOp::LoadUnboxedPropertyResult, objId);
-}
-
bool
BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receivers)
{
@@ -182,8 +143,7 @@ BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receiv
while (stub->next()) {
ReceiverGuard receiver;
if (stub->isCacheIR_Monitored()) {
- if (!GetCacheIRReceiverForNativeReadSlot(stub->toCacheIR_Monitored(), &receiver) &&
- !GetCacheIRReceiverForUnboxedProperty(stub->toCacheIR_Monitored(), &receiver))
+ if (!GetCacheIRReceiverForNativeReadSlot(stub->toCacheIR_Monitored(), &receiver))
{
receivers.clear();
return true;
@@ -191,8 +151,6 @@ BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receiv
} else if (stub->isSetProp_Native()) {
receiver = ReceiverGuard(stub->toSetProp_Native()->group(),
stub->toSetProp_Native()->shape());
- } else if (stub->isSetProp_Unboxed()) {
- receiver = ReceiverGuard(stub->toSetProp_Unboxed()->group(), nullptr);
} else {
receivers.clear();
return true;
diff --git a/js/src/jit/CacheIR.cpp b/js/src/jit/CacheIR.cpp
index 6822a70af..d184ea40c 100644
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -10,8 +10,7 @@
#include "jit/IonCaches.h"
#include "jsobjinlines.h"
-
-#include "vm/UnboxedObject-inl.h"
+#include "vm/NativeObject-inl.h"
using namespace js;
using namespace js::jit;
@@ -60,10 +59,6 @@ GetPropIRGenerator::tryAttachStub(Maybe<CacheIRWriter>& writer)
return false;
if (!emitted_ && !tryAttachNative(*writer, obj, objId))
return false;
- if (!emitted_ && !tryAttachUnboxed(*writer, obj, objId))
- return false;
- if (!emitted_ && !tryAttachUnboxedExpando(*writer, obj, objId))
- return false;
if (!emitted_ && !tryAttachTypedObject(*writer, obj, objId))
return false;
if (!emitted_ && !tryAttachModuleNamespace(*writer, obj, objId))
@@ -163,19 +158,9 @@ GeneratePrototypeGuards(CacheIRWriter& writer, JSObject* obj, JSObject* holder,
}
static void
-TestMatchingReceiver(CacheIRWriter& writer, JSObject* obj, Shape* shape, ObjOperandId objId,
- Maybe<ObjOperandId>* expandoId)
+TestMatchingReceiver(CacheIRWriter& writer, JSObject* obj, Shape* shape, ObjOperandId objId)
{
- if (obj->is<UnboxedPlainObject>()) {
- writer.guardGroup(objId, obj->group());
-
- if (UnboxedExpandoObject* expando = obj->as<UnboxedPlainObject>().maybeExpando()) {
- expandoId->emplace(writer.guardAndLoadUnboxedExpando(objId));
- writer.guardShape(expandoId->ref(), expando->lastProperty());
- } else {
- writer.guardNoUnboxedExpando(objId);
- }
- } else if (obj->is<TypedObject>()) {
+ if (obj->is<TypedObject>()) {
writer.guardGroup(objId, obj->group());
} else {
Shape* shape = obj->maybeShape();
@@ -188,8 +173,7 @@ static void
EmitReadSlotResult(CacheIRWriter& writer, JSObject* obj, JSObject* holder,
Shape* shape, ObjOperandId objId)
{
- Maybe<ObjOperandId> expandoId;
- TestMatchingReceiver(writer, obj, shape, objId, &expandoId);
+ TestMatchingReceiver(writer, obj, shape, objId);
ObjOperandId holderId;
if (obj != holder) {
@@ -212,9 +196,6 @@ EmitReadSlotResult(CacheIRWriter& writer, JSObject* obj, JSObject* holder,
lastObjId = protoId;
}
}
- } else if (obj->is<UnboxedPlainObject>()) {
- holder = obj->as<UnboxedPlainObject>().maybeExpando();
- holderId = *expandoId;
} else {
holderId = objId;
}
@@ -266,51 +247,6 @@ GetPropIRGenerator::tryAttachNative(CacheIRWriter& writer, HandleObject obj, Obj
}
bool
-GetPropIRGenerator::tryAttachUnboxed(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId)
-{
- MOZ_ASSERT(!emitted_);
-
- if (!obj->is<UnboxedPlainObject>())
- return true;
-
- const UnboxedLayout::Property* property = obj->as<UnboxedPlainObject>().layout().lookup(name_);
- if (!property)
- return true;
-
- if (!cx_->runtime()->jitSupportsFloatingPoint)
- return true;
-
- writer.guardGroup(objId, obj->group());
- writer.loadUnboxedPropertyResult(objId, property->type,
- UnboxedPlainObject::offsetOfData() + property->offset);
- emitted_ = true;
- preliminaryObjectAction_ = PreliminaryObjectAction::Unlink;
- return true;
-}
-
-bool
-GetPropIRGenerator::tryAttachUnboxedExpando(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId)
-{
- MOZ_ASSERT(!emitted_);
-
- if (!obj->is<UnboxedPlainObject>())
- return true;
-
- UnboxedExpandoObject* expando = obj->as<UnboxedPlainObject>().maybeExpando();
- if (!expando)
- return true;
-
- Shape* shape = expando->lookup(cx_, NameToId(name_));
- if (!shape || !shape->hasDefaultGetter() || !shape->hasSlot())
- return true;
-
- emitted_ = true;
-
- EmitReadSlotResult(writer, obj, obj, shape, objId);
- return true;
-}
-
-bool
GetPropIRGenerator::tryAttachTypedObject(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId)
{
MOZ_ASSERT(!emitted_);
diff --git a/js/src/jit/CacheIR.h b/js/src/jit/CacheIR.h
index 4fd8575f0..ae55cfebb 100644
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -87,13 +87,10 @@ class ObjOperandId : public OperandId
_(GuardClass) \
_(GuardSpecificObject) \
_(GuardNoDetachedTypedObjects) \
- _(GuardNoUnboxedExpando) \
- _(GuardAndLoadUnboxedExpando) \
_(LoadObject) \
_(LoadProto) \
_(LoadFixedSlotResult) \
_(LoadDynamicSlotResult) \
- _(LoadUnboxedPropertyResult) \
_(LoadTypedObjectResult) \
_(LoadInt32ArrayLengthResult) \
_(LoadArgumentsObjectLengthResult) \
@@ -274,15 +271,6 @@ class MOZ_RAII CacheIRWriter
void guardNoDetachedTypedObjects() {
writeOp(CacheOp::GuardNoDetachedTypedObjects);
}
- void guardNoUnboxedExpando(ObjOperandId obj) {
- writeOpWithOperandId(CacheOp::GuardNoUnboxedExpando, obj);
- }
- ObjOperandId guardAndLoadUnboxedExpando(ObjOperandId obj) {
- ObjOperandId res(nextOperandId_++);
- writeOpWithOperandId(CacheOp::GuardAndLoadUnboxedExpando, obj);
- writeOperandId(res);
- return res;
- }
ObjOperandId loadObject(JSObject* obj) {
ObjOperandId res(nextOperandId_++);
@@ -308,11 +296,6 @@ class MOZ_RAII CacheIRWriter
writeOpWithOperandId(CacheOp::LoadDynamicSlotResult, obj);
addStubWord(offset, StubField::GCType::NoGCThing);
}
- void loadUnboxedPropertyResult(ObjOperandId obj, JSValueType type, size_t offset) {
- writeOpWithOperandId(CacheOp::LoadUnboxedPropertyResult, obj);
- buffer_.writeByte(uint32_t(type));
- addStubWord(offset, StubField::GCType::NoGCThing);
- }
void loadTypedObjectResult(ObjOperandId obj, uint32_t offset, TypedThingLayout layout,
uint32_t typeDescr) {
MOZ_ASSERT(uint32_t(layout) <= UINT8_MAX);
@@ -406,9 +389,6 @@ class MOZ_RAII GetPropIRGenerator
PreliminaryObjectAction preliminaryObjectAction_;
MOZ_MUST_USE bool tryAttachNative(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
- MOZ_MUST_USE bool tryAttachUnboxed(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
- MOZ_MUST_USE bool tryAttachUnboxedExpando(CacheIRWriter& writer, HandleObject obj,
- ObjOperandId objId);
MOZ_MUST_USE bool tryAttachTypedObject(CacheIRWriter& writer, HandleObject obj,
ObjOperandId objId);
MOZ_MUST_USE bool tryAttachObjectLength(CacheIRWriter& writer, HandleObject obj,
diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp
index e0b8a7f28..fcb711237 100644
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -25,6 +25,7 @@
#include "builtin/Eval.h"
#include "builtin/TypedObject.h"
#include "gc/Nursery.h"
+#include "gc/StoreBuffer-inl.h"
#include "irregexp/NativeRegExpMacroAssembler.h"
#include "jit/AtomicOperations.h"
#include "jit/BaselineCompiler.h"
@@ -3027,7 +3028,7 @@ CodeGenerator::visitStoreSlotV(LStoreSlotV* lir)
static void
GuardReceiver(MacroAssembler& masm, const ReceiverGuard& guard,
- Register obj, Register scratch, Label* miss, bool checkNullExpando)
+ Register obj, Register scratch, Label* miss)
{
if (guard.group) {
masm.branchTestObjGroup(Assembler::NotEqual, obj, guard.group, miss);
@@ -3049,13 +3050,11 @@ CodeGenerator::emitGetPropertyPolymorphic(LInstruction* ins, Register obj, Regis
Label next;
masm.comment("GuardReceiver");
- GuardReceiver(masm, receiver, obj, scratch, &next, /* checkNullExpando = */ false);
+ GuardReceiver(masm, receiver, obj, scratch, &next);
if (receiver.shape) {
masm.comment("loadTypedOrValue");
- // If this is an unboxed expando access, GuardReceiver loaded the
- // expando object into scratch.
- Register target = receiver.group ? scratch : obj;
+ Register target = obj;
Shape* shape = mir->shape(i);
if (shape->slot() < shape->numFixedSlots()) {
@@ -3121,12 +3120,10 @@ CodeGenerator::emitSetPropertyPolymorphic(LInstruction* ins, Register obj, Regis
ReceiverGuard receiver = mir->receiver(i);
Label next;
- GuardReceiver(masm, receiver, obj, scratch, &next, /* checkNullExpando = */ false);
+ GuardReceiver(masm, receiver, obj, scratch, &next);
if (receiver.shape) {
- // If this is an unboxed expando access, GuardReceiver loaded the
- // expando object into scratch.
- Register target = receiver.group ? scratch : obj;
+ Register target = obj;
Shape* shape = mir->shape(i);
if (shape->slot() < shape->numFixedSlots()) {
@@ -3292,7 +3289,7 @@ CodeGenerator::visitGuardReceiverPolymorphic(LGuardReceiverPolymorphic* lir)
const ReceiverGuard& receiver = mir->receiver(i);
Label next;
- GuardReceiver(masm, receiver, obj, temp, &next, /* checkNullExpando = */ true);
+ GuardReceiver(masm, receiver, obj, temp, &next);
if (i == mir->numReceivers() - 1) {
bailoutFrom(&next, lir->snapshot());
@@ -8382,11 +8379,6 @@ CodeGenerator::visitStoreUnboxedPointer(LStoreUnboxedPointer* lir)
}
}
-typedef bool (*ConvertUnboxedObjectToNativeFn)(JSContext*, JSObject*);
-static const VMFunction ConvertUnboxedPlainObjectToNativeInfo =
- FunctionInfo<ConvertUnboxedObjectToNativeFn>(UnboxedPlainObject::convertToNative,
- "UnboxedPlainObject::convertToNative");
-
typedef bool (*ArrayPopShiftFn)(JSContext*, HandleObject, MutableHandleValue);
static const VMFunction ArrayPopDenseInfo =
FunctionInfo<ArrayPopShiftFn>(jit::ArrayPopDense, "ArrayPopDense");
@@ -8679,11 +8671,11 @@ CodeGenerator::visitIteratorStartO(LIteratorStartO* lir)
masm.loadPtr(Address(niTemp, offsetof(NativeIterator, guard_array)), temp2);
// Compare object with the first receiver guard. The last iterator can only
- // match for native objects and unboxed objects.
+ // match for native objects.
{
Address groupAddr(temp2, offsetof(ReceiverGuard, group));
Address shapeAddr(temp2, offsetof(ReceiverGuard, shape));
- Label guardDone, shapeMismatch, noExpando;
+ Label guardDone, shapeMismatch;
masm.loadObjShape(obj, temp1);
masm.branchPtr(Assembler::NotEqual, shapeAddr, temp1, &shapeMismatch);
@@ -8695,12 +8687,6 @@ CodeGenerator::visitIteratorStartO(LIteratorStartO* lir)
masm.bind(&shapeMismatch);
masm.loadObjGroup(obj, temp1);
masm.branchPtr(Assembler::NotEqual, groupAddr, temp1, ool->entry());
- masm.loadPtr(Address(obj, UnboxedPlainObject::offsetOfExpando()), temp1);
- masm.branchTestPtr(Assembler::Zero, temp1, temp1, &noExpando);
- branchIfNotEmptyObjectElements(temp1, ool->entry());
- masm.loadObjShape(temp1, temp1);
- masm.bind(&noExpando);
- masm.branchPtr(Assembler::NotEqual, shapeAddr, temp1, ool->entry());
masm.bind(&guardDone);
}
diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp
index fc864a197..a54a58add 100644
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -10925,63 +10925,6 @@ IonBuilder::getDefiniteSlot(TemporaryTypeSet* types, PropertyName* name, uint32_
return slot;
}
-uint32_t
-IonBuilder::getUnboxedOffset(TemporaryTypeSet* types, PropertyName* name, JSValueType* punboxedType)
-{
- if (!types || types->unknownObject() || !types->objectOrSentinel()) {
- trackOptimizationOutcome(TrackedOutcome::NoTypeInfo);
- return UINT32_MAX;
- }
-
- uint32_t offset = UINT32_MAX;
-
- for (size_t i = 0; i < types->getObjectCount(); i++) {
- TypeSet::ObjectKey* key = types->getObject(i);
- if (!key)
- continue;
-
- if (key->unknownProperties()) {
- trackOptimizationOutcome(TrackedOutcome::UnknownProperties);
- return UINT32_MAX;
- }
-
- if (key->isSingleton()) {
- trackOptimizationOutcome(TrackedOutcome::Singleton);
- return UINT32_MAX;
- }
-
- UnboxedLayout* layout = key->group()->maybeUnboxedLayout();
- if (!layout) {
- trackOptimizationOutcome(TrackedOutcome::NotUnboxed);
- return UINT32_MAX;
- }
-
- const UnboxedLayout::Property* property = layout->lookup(name);
- if (!property) {
- trackOptimizationOutcome(TrackedOutcome::StructNoField);
- return UINT32_MAX;
- }
-
- if (layout->nativeGroup()) {
- trackOptimizationOutcome(TrackedOutcome::UnboxedConvertedToNative);
- return UINT32_MAX;
- }
-
- if (offset == UINT32_MAX) {
- offset = property->offset;
- *punboxedType = property->type;
- } else if (offset != property->offset) {
- trackOptimizationOutcome(TrackedOutcome::InconsistentFieldOffset);
- return UINT32_MAX;
- } else if (*punboxedType != property->type) {
- trackOptimizationOutcome(TrackedOutcome::InconsistentFieldType);
- return UINT32_MAX;
- }
- }
-
- return offset;
-}
-
bool
IonBuilder::jsop_runonce()
{
@@ -11948,72 +11891,6 @@ IonBuilder::getPropTryModuleNamespace(bool* emitted, MDefinition* obj, PropertyN
return true;
}
-MInstruction*
-IonBuilder::loadUnboxedProperty(MDefinition* obj, size_t offset, JSValueType unboxedType,
- BarrierKind barrier, TemporaryTypeSet* types)
-{
- // loadUnboxedValue is designed to load any value as if it were contained in
- // an array. Thus a property offset is converted to an index, when the
- // object is reinterpreted as an array of properties of the same size.
- size_t index = offset / UnboxedTypeSize(unboxedType);
- MInstruction* indexConstant = MConstant::New(alloc(), Int32Value(index));
- current->add(indexConstant);
-
- return loadUnboxedValue(obj, UnboxedPlainObject::offsetOfData(),
- indexConstant, unboxedType, barrier, types);
-}
-
-MInstruction*
-IonBuilder::loadUnboxedValue(MDefinition* elements, size_t elementsOffset,
- MDefinition* index, JSValueType unboxedType,
- BarrierKind barrier, TemporaryTypeSet* types)
-{
- MInstruction* load;
- switch (unboxedType) {
- case JSVAL_TYPE_BOOLEAN:
- load = MLoadUnboxedScalar::New(alloc(), elements, index, Scalar::Uint8,
- DoesNotRequireMemoryBarrier, elementsOffset);
- load->setResultType(MIRType::Boolean);
- break;
-
- case JSVAL_TYPE_INT32:
- load = MLoadUnboxedScalar::New(alloc(), elements, index, Scalar::Int32,
- DoesNotRequireMemoryBarrier, elementsOffset);
- load->setResultType(MIRType::Int32);
- break;
-
- case JSVAL_TYPE_DOUBLE:
- load = MLoadUnboxedScalar::New(alloc(), elements, index, Scalar::Float64,
- DoesNotRequireMemoryBarrier, elementsOffset,
- /* canonicalizeDoubles = */ false);
- load->setResultType(MIRType::Double);
- break;
-
- case JSVAL_TYPE_STRING:
- load = MLoadUnboxedString::New(alloc(), elements, index, elementsOffset);
- break;
-
- case JSVAL_TYPE_OBJECT: {
- MLoadUnboxedObjectOrNull::NullBehavior nullBehavior;
- if (types->hasType(TypeSet::NullType()))
- nullBehavior = MLoadUnboxedObjectOrNull::HandleNull;
- else if (barrier != BarrierKind::NoBarrier)
- nullBehavior = MLoadUnboxedObjectOrNull::BailOnNull;
- else
- nullBehavior = MLoadUnboxedObjectOrNull::NullNotPossible;
- load = MLoadUnboxedObjectOrNull::New(alloc(), elements, index, nullBehavior,
- elementsOffset);
- break;
- }
-
- default:
- MOZ_CRASH();
- }
-
- current->add(load);
- return load;
-}
-
MDefinition*
IonBuilder::addShapeGuardsForGetterSetter(MDefinition* obj, JSObject* holder, Shape* holderShape,
const BaselineInspector::ReceiverVector& receivers,
@@ -12835,66 +12712,6 @@ IonBuilder::setPropTryDefiniteSlot(bool* emitted, MDefinition* obj,
return true;
}
-MInstruction*
-IonBuilder::storeUnboxedProperty(MDefinition* obj, size_t offset, JSValueType unboxedType,
- MDefinition* value)
-{
- size_t scaledOffsetConstant = offset / UnboxedTypeSize(unboxedType);
- MInstruction* scaledOffset = MConstant::New(alloc(), Int32Value(scaledOffsetConstant));
- current->add(scaledOffset);
-
- return storeUnboxedValue(obj, obj, UnboxedPlainObject::offsetOfData(),
- scaledOffset, unboxedType, value);
-}
-
-MInstruction*
-IonBuilder::storeUnboxedValue(MDefinition* obj, MDefinition* elements, int32_t elementsOffset,
- MDefinition* scaledOffset, JSValueType unboxedType,
- MDefinition* value, bool preBarrier /* = true */)
-{
- MInstruction* store;
- switch (unboxedType) {
- case JSVAL_TYPE_BOOLEAN:
- store = MStoreUnboxedScalar::New(alloc(), elements, scaledOffset, value, Scalar::Uint8,
- MStoreUnboxedScalar::DontTruncateInput,
- DoesNotRequireMemoryBarrier, elementsOffset);
- break;
-
- case JSVAL_TYPE_INT32:
- store = MStoreUnboxedScalar::New(alloc(), elements, scaledOffset, value, Scalar::Int32,
- MStoreUnboxedScalar::DontTruncateInput,
- DoesNotRequireMemoryBarrier, elementsOffset);
- break;
-
- case JSVAL_TYPE_DOUBLE:
- store = MStoreUnboxedScalar::New(alloc(), elements, scaledOffset, value, Scalar::Float64,
- MStoreUnboxedScalar::DontTruncateInput,
- DoesNotRequireMemoryBarrier, elementsOffset);
- break;
-
- case JSVAL_TYPE_STRING:
- store = MStoreUnboxedString::New(alloc(), elements, scaledOffset, value,
- elementsOffset, preBarrier);
- break;
-
- case JSVAL_TYPE_OBJECT:
- MOZ_ASSERT(value->type() == MIRType::Object ||
- value->type() == MIRType::Null ||
- value->type() == MIRType::Value);
- MOZ_ASSERT(!value->mightBeType(MIRType::Undefined),
- "MToObjectOrNull slow path is invalid for unboxed objects");
- store = MStoreUnboxedObjectOrNull::New(alloc(), elements, scaledOffset, value, obj,
- elementsOffset, preBarrier);
- break;
-
- default:
- MOZ_CRASH();
- }
-
- current->add(store);
- return store;
-}
-
bool
IonBuilder::setPropTryInlineAccess(bool* emitted, MDefinition* obj,
PropertyName* name, MDefinition* value,
diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h
index 1b97c4743..dd40b4bd6 100644
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -1048,19 +1048,6 @@ class IonBuilder
ResultWithOOM<bool> testNotDefinedProperty(MDefinition* obj, jsid id);
uint32_t getDefiniteSlot(TemporaryTypeSet* types, PropertyName* name, uint32_t* pnfixed);
- uint32_t getUnboxedOffset(TemporaryTypeSet* types, PropertyName* name,
- JSValueType* punboxedType);
- MInstruction* loadUnboxedProperty(MDefinition* obj, size_t offset, JSValueType unboxedType,
- BarrierKind barrier, TemporaryTypeSet* types);
- MInstruction* loadUnboxedValue(MDefinition* elements, size_t elementsOffset,
- MDefinition* scaledOffset, JSValueType unboxedType,
- BarrierKind barrier, TemporaryTypeSet* types);
- MInstruction* storeUnboxedProperty(MDefinition* obj, size_t offset, JSValueType unboxedType,
- MDefinition* value);
- MInstruction* storeUnboxedValue(MDefinition* obj,
- MDefinition* elements, int32_t elementsOffset,
- MDefinition* scaledOffset, JSValueType unboxedType,
- MDefinition* value, bool preBarrier = true);
MOZ_MUST_USE bool checkPreliminaryGroups(MDefinition *obj);
MOZ_MUST_USE bool freezePropTypeSets(TemporaryTypeSet* types,
JSObject* foundProto, PropertyName* name);
diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp
index 81cf9d9bb..9901bdd07 100644
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -31,7 +31,6 @@
#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;
@@ -620,26 +619,7 @@ TestMatchingReceiver(MacroAssembler& masm, IonCache::StubAttacher& attacher,
Register object, JSObject* obj, Label* failure,
bool alwaysCheckGroup = false)
{
- if (obj->is<UnboxedPlainObject>()) {
- MOZ_ASSERT(failure);
-
- masm.branchTestObjGroup(Assembler::NotEqual, object, obj->group(), failure);
- Address expandoAddress(object, UnboxedPlainObject::offsetOfExpando());
- if (UnboxedExpandoObject* expando = obj->as<UnboxedPlainObject>().maybeExpando()) {
- masm.branchPtr(Assembler::Equal, expandoAddress, ImmWord(0), failure);
- Label success;
- masm.push(object);
- masm.loadPtr(expandoAddress, object);
- masm.branchTestObjShape(Assembler::Equal, object, expando->lastProperty(),
- &success);
- masm.pop(object);
- masm.jump(failure);
- masm.bind(&success);
- masm.pop(object);
- } else {
- masm.branchPtr(Assembler::NotEqual, expandoAddress, ImmWord(0), failure);
- }
- } else if (obj->is<TypedObject>()) {
+ if (obj->is<TypedObject>()) {
attacher.branchNextStubOrLabel(masm, Assembler::NotEqual,
Address(object, JSObject::offsetOfGroup()),
ImmGCPtr(obj->group()), failure);
@@ -756,7 +736,6 @@ GenerateReadSlot(JSContext* cx, IonScript* ion, MacroAssembler& masm,
// jump directly. Otherwise, jump to the end of the stub, so there's a
// common point to patch.
bool multipleFailureJumps = (obj != holder)
- || obj->is<UnboxedPlainObject>()
|| (checkTDZ && output.hasValue())
|| (failures != nullptr && failures->used());
@@ -775,7 +754,6 @@ GenerateReadSlot(JSContext* cx, IonScript* ion, MacroAssembler& masm,
Register scratchReg = Register::FromCode(0); // Quell compiler warning.
if (obj != holder ||
- obj->is<UnboxedPlainObject>() ||
!holder->as<NativeObject>().isFixedSlot(shape->slot()))
{
if (output.hasValue()) {
@@ -836,10 +814,6 @@ GenerateReadSlot(JSContext* cx, IonScript* ion, MacroAssembler& masm,
holderReg = InvalidReg;
}
- } else if (obj->is<UnboxedPlainObject>()) {
- holder = obj->as<UnboxedPlainObject>().maybeExpando();
- holderReg = scratchReg;
- masm.loadPtr(Address(object, UnboxedPlainObject::offsetOfExpando()), holderReg);
} else {
holderReg = object;
}
@@ -867,30 +841,6 @@ GenerateReadSlot(JSContext* cx, IonScript* ion, MacroAssembler& masm,
attacher.jumpNextStub(masm);
}
-static void
-GenerateReadUnboxed(JSContext* cx, IonScript* ion, MacroAssembler& masm,
- IonCache::StubAttacher& attacher, JSObject* obj,
- const UnboxedLayout::Property* property,
- Register object, TypedOrValueRegister output,
- Label* failures = nullptr)
-{
- // Guard on the group of the object.
- attacher.branchNextStubOrLabel(masm, Assembler::NotEqual,
- Address(object, JSObject::offsetOfGroup()),
- ImmGCPtr(obj->group()), failures);
-
- Address address(object, UnboxedPlainObject::offsetOfData() + property->offset);
-
- masm.loadUnboxedProperty(address, property->type, output);
-
- attacher.jumpRejoin(masm);
-
- if (failures) {
- masm.bind(failures);
- attacher.jumpNextStub(masm);
- }
-}
-
static bool
EmitGetterCall(JSContext* cx, MacroAssembler& masm,
IonCache::StubAttacher& attacher, JSObject* obj,
@@ -1498,67 +1448,6 @@ GetPropertyIC::tryAttachNative(JSContext* cx, HandleScript outerScript, IonScrip
}
bool
-GetPropertyIC::tryAttachUnboxed(JSContext* cx, HandleScript outerScript, IonScript* ion,
- HandleObject obj, HandleId id, void* returnAddr, bool* emitted)
-{
- MOZ_ASSERT(canAttachStub());
- MOZ_ASSERT(!*emitted);
- MOZ_ASSERT(outerScript->ionScript() == ion);
-
- if (!obj->is<UnboxedPlainObject>())
- return true;
- const UnboxedLayout::Property* property = obj->as<UnboxedPlainObject>().layout().lookup(id);
- if (!property)
- return true;
-
- *emitted = true;
-
- MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
-
- Label failures;
- emitIdGuard(masm, id, &failures);
- Label* maybeFailures = failures.used() ? &failures : nullptr;
-
- StubAttacher attacher(*this);
- GenerateReadUnboxed(cx, ion, masm, attacher, obj, property, object(), output(), maybeFailures);
- return linkAndAttachStub(cx, masm, attacher, ion, "read unboxed",
- JS::TrackedOutcome::ICGetPropStub_UnboxedRead);
-}
-
-bool
-GetPropertyIC::tryAttachUnboxedExpando(JSContext* cx, HandleScript outerScript, IonScript* ion,
- HandleObject obj, HandleId id, void* returnAddr, bool* emitted)
-{
- MOZ_ASSERT(canAttachStub());
- MOZ_ASSERT(!*emitted);
- MOZ_ASSERT(outerScript->ionScript() == ion);
-
- if (!obj->is<UnboxedPlainObject>())
- return true;
- Rooted<UnboxedExpandoObject*> expando(cx, obj->as<UnboxedPlainObject>().maybeExpando());
- if (!expando)
- return true;
-
- Shape* shape = expando->lookup(cx, id);
- if (!shape || !shape->hasDefaultGetter() || !shape->hasSlot())
- return true;
-
- *emitted = true;
-
- MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
-
- Label failures;
- emitIdGuard(masm, id, &failures);
- Label* maybeFailures = failures.used() ? &failures : nullptr;
-
- StubAttacher attacher(*this);
- GenerateReadSlot(cx, ion, masm, attacher, DontCheckTDZ, obj, obj,
- shape, object(), output(), maybeFailures);
- return linkAndAttachStub(cx, masm, attacher, ion, "read unboxed expando",
- JS::TrackedOutcome::ICGetPropStub_UnboxedReadExpando);
-}
-
-bool
GetPropertyIC::tryAttachTypedArrayLength(JSContext* cx, HandleScript outerScript, IonScript* ion,
HandleObject obj, HandleId id, bool* emitted)
{
@@ -2127,12 +2016,6 @@ GetPropertyIC::tryAttachStub(JSContext* cx, HandleScript outerScript, IonScript*
if (!*emitted && !tryAttachNative(cx, outerScript, ion, obj, id, returnAddr, emitted))
return false;
- if (!*emitted && !tryAttachUnboxed(cx, outerScript, ion, obj, id, returnAddr, emitted))
- return false;
-
- if (!*emitted && !tryAttachUnboxedExpando(cx, outerScript, ion, obj, id, returnAddr, emitted))
- return false;
-
if (!*emitted && !tryAttachTypedArrayLength(cx, outerScript, ion, obj, id, emitted))
return false;
}
@@ -2311,12 +2194,6 @@ GenerateSetSlot(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& att
NativeObject::slotsSizeMustNotOverflow();
- if (obj->is<UnboxedPlainObject>()) {
- obj = obj->as<UnboxedPlainObject>().maybeExpando();
- masm.loadPtr(Address(object, UnboxedPlainObject::offsetOfExpando()), tempReg);
- object = tempReg;
- }
-
if (obj->as<NativeObject>().isFixedSlot(shape->slot())) {
Address addr(object, NativeObject::getFixedSlotOffset(shape->slot()));
@@ -2954,23 +2831,13 @@ GenerateAddSlot(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& att
masm.branchTestObjGroup(Assembler::NotEqual, object, oldGroup, failures);
if (obj->maybeShape()) {
masm.branchTestObjShape(Assembler::NotEqual, object, oldShape, failures);
- } else {
- MOZ_ASSERT(obj->is<UnboxedPlainObject>());
-
- Address expandoAddress(object, UnboxedPlainObject::offsetOfExpando());
- masm.branchPtr(Assembler::Equal, expandoAddress, ImmWord(0), failures);
-
- masm.loadPtr(expandoAddress, tempReg);
- masm.branchTestObjShape(Assembler::NotEqual, tempReg, oldShape, failures);
}
Shape* newShape = obj->maybeShape();
- if (!newShape)
- newShape = obj->as<UnboxedPlainObject>().maybeExpando()->lastProperty();
// Guard that the incoming value is in the type set for the property
// if a type barrier is required.
- if (checkTypeset)
+ if (newShape && checkTypeset)
CheckTypeSetForWrite(masm, obj, newShape->propid(), tempReg, value, failures);
// Guard shapes along prototype chain.
@@ -2991,9 +2858,7 @@ GenerateAddSlot(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& att
}
// Call a stub to (re)allocate dynamic slots, if necessary.
- uint32_t newNumDynamicSlots = obj->is<UnboxedPlainObject>()
- ? obj->as<UnboxedPlainObject>().maybeExpando()->numDynamicSlots()
- : obj->as<NativeObject>().numDynamicSlots();
+ uint32_t newNumDynamicSlots = obj->as<NativeObject>().numDynamicSlots();
if (NativeObject::dynamicSlotsCount(oldShape) != newNumDynamicSlots) {
AllocatableRegisterSet regs(RegisterSet::Volatile());
LiveRegisterSet save(regs.asLiveSet());
@@ -3004,12 +2869,6 @@ GenerateAddSlot(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& att
Register temp1 = regs.takeAnyGeneral();
Register temp2 = regs.takeAnyGeneral();
- if (obj->is<UnboxedPlainObject>()) {
- // Pass the expando object to the stub.
- masm.Push(object);
- masm.loadPtr(Address(object, UnboxedPlainObject::offsetOfExpando()), object);
- }
-
masm.setupUnalignedABICall(temp1);
masm.loadJSContext(temp1);
masm.passABIArg(temp1);
@@ -3026,27 +2885,16 @@ GenerateAddSlot(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& att
masm.jump(&allocDone);
masm.bind(&allocFailed);
- if (obj->is<UnboxedPlainObject>())
- masm.Pop(object);
masm.PopRegsInMask(save);
masm.jump(failures);
masm.bind(&allocDone);
masm.setFramePushed(framePushedAfterCall);
- if (obj->is<UnboxedPlainObject>())
- masm.Pop(object);
masm.PopRegsInMask(save);
}
bool popObject = false;
- if (obj->is<UnboxedPlainObject>()) {
- masm.push(object);
- popObject = true;
- obj = obj->as<UnboxedPlainObject>().maybeExpando();
- masm.loadPtr(Address(object, UnboxedPlainObject::offsetOfExpando()), object);
- }
-
// Write the object or expando object's new shape.
Address shapeAddr(object, ShapedObject::offsetOfShape());
if (cx->zone()->needsIncrementalBarrier())
@@ -3054,8 +2902,6 @@ GenerateAddSlot(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& att
masm.storePtr(ImmGCPtr(newShape), shapeAddr);
if (oldGroup != obj->group()) {
- MOZ_ASSERT(!obj->is<UnboxedPlainObject>());
-
// Changing object's group from a partially to fully initialized group,
// per the acquired properties analysis. Only change the group if the
// old group still has a newScript.
@@ -3298,141 +3144,6 @@ CanAttachNativeSetProp(JSContext* cx, HandleObject obj, HandleId id, const Const
return SetPropertyIC::CanAttachNone;
}
-static void
-GenerateSetUnboxed(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& attacher,
- JSObject* obj, jsid id, uint32_t unboxedOffset, JSValueType unboxedType,
- Register object, Register tempReg, const ConstantOrRegister& value,
- bool checkTypeset, Label* failures)
-{
- // Guard on the type of the object.
- masm.branchPtr(Assembler::NotEqual,
- Address(object, JSObject::offsetOfGroup()),
- ImmGCPtr(obj->group()), failures);
-
- if (checkTypeset)
- CheckTypeSetForWrite(masm, obj, id, tempReg, value, failures);
-
- Address address(object, UnboxedPlainObject::offsetOfData() + unboxedOffset);
-
- if (cx->zone()->needsIncrementalBarrier()) {
- if (unboxedType == JSVAL_TYPE_OBJECT)
- masm.callPreBarrier(address, MIRType::Object);
- else if (unboxedType == JSVAL_TYPE_STRING)
- masm.callPreBarrier(address, MIRType::String);
- else
- MOZ_ASSERT(!UnboxedTypeNeedsPreBarrier(unboxedType));
- }
-
- masm.storeUnboxedProperty(address, unboxedType, value, failures);
-
- attacher.jumpRejoin(masm);
-
- masm.bind(failures);
- attacher.jumpNextStub(masm);
-}
-
-static bool
-CanAttachSetUnboxed(JSContext* cx, HandleObject obj, HandleId id, const ConstantOrRegister& val,
- bool needsTypeBarrier, bool* checkTypeset,
- uint32_t* unboxedOffset, JSValueType* unboxedType)
-{
- if (!obj->is<UnboxedPlainObject>())
- return false;
-
- const UnboxedLayout::Property* property = obj->as<UnboxedPlainObject>().layout().lookup(id);
- if (property) {
- *checkTypeset = false;
- if (needsTypeBarrier && !CanInlineSetPropTypeCheck(obj, id, val, checkTypeset))
- return false;
- *unboxedOffset = property->offset;
- *unboxedType = property->type;
- return true;
- }
-
- return false;
-}
-
-static bool
-CanAttachSetUnboxedExpando(JSContext* cx, HandleObject obj, HandleId id,
- const ConstantOrRegister& val,
- bool needsTypeBarrier, bool* checkTypeset, Shape** pshape)
-{
- if (!obj->is<UnboxedPlainObject>())
- return false;
-
- Rooted<UnboxedExpandoObject*> expando(cx, obj->as<UnboxedPlainObject>().maybeExpando());
- if (!expando)
- return false;
-
- Shape* shape = expando->lookupPure(id);
- if (!shape || !shape->hasDefaultSetter() || !shape->hasSlot() || !shape->writable())
- return false;
-
- *checkTypeset = false;
- if (needsTypeBarrier && !CanInlineSetPropTypeCheck(obj, id, val, checkTypeset))
- return false;
-
- *pshape = shape;
- return true;
-}
-
-static bool
-CanAttachAddUnboxedExpando(JSContext* cx, HandleObject obj, HandleShape oldShape,
- HandleId id, const ConstantOrRegister& val,
- bool needsTypeBarrier, bool* checkTypeset)
-{
- if (!obj->is<UnboxedPlainObject>())
- return false;
-
- Rooted<UnboxedExpandoObject*> expando(cx, obj->as<UnboxedPlainObject>().maybeExpando());
- if (!expando || expando->inDictionaryMode())
- return false;
-
- Shape* newShape = expando->lastProperty();
- if (newShape->isEmptyShape() || newShape->propid() != id || newShape->previous() != oldShape)
- return false;
-
- MOZ_ASSERT(newShape->hasDefaultSetter() && newShape->hasSlot() && newShape->writable());
-
- if (PrototypeChainShadowsPropertyAdd(cx, obj, id))
- return false;
-
- *checkTypeset = false;
- if (needsTypeBarrier && !CanInlineSetPropTypeCheck(obj, id, val, checkTypeset))
- return false;
-
- return true;
-}
-
-bool
-SetPropertyIC::tryAttachUnboxed(JSContext* cx, HandleScript outerScript, IonScript* ion,
- HandleObject obj, HandleId id, bool* emitted)
-{
- MOZ_ASSERT(!*emitted);
-
- bool checkTypeset = false;
- uint32_t unboxedOffset;
- JSValueType unboxedType;
- if (!CanAttachSetUnboxed(cx, obj, id, value(), needsTypeBarrier(), &checkTypeset,
- &unboxedOffset, &unboxedType))
- {
- return true;
- }
-
- *emitted = true;
-
- MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
- StubAttacher attacher(*this);
-
- Label failures;
- emitIdGuard(masm, id, &failures);
-
- GenerateSetUnboxed(cx, masm, attacher, obj, id, unboxedOffset, unboxedType,
- object(), temp(), value(), checkTypeset, &failures);
- return linkAndAttachStub(cx, masm, attacher, ion, "set_unboxed",
- JS::TrackedOutcome::ICSetPropStub_SetUnboxed);
-}
-
bool
SetPropertyIC::tryAttachProxy(JSContext* cx, HandleScript outerScript, IonScript* ion,
HandleObject obj, HandleId id, bool* emitted)
@@ -3514,26 +3225,6 @@ SetPropertyIC::tryAttachNative(JSContext* cx, HandleScript outerScript, IonScrip
}
bool
-SetPropertyIC::tryAttachUnboxedExpando(JSContext* cx, HandleScript outerScript, IonScript* ion,
- HandleObject obj, HandleId id, bool* emitted)
-{
- MOZ_ASSERT(!*emitted);
-
- RootedShape shape(cx);
- bool checkTypeset = false;
- if (!CanAttachSetUnboxedExpando(cx, obj, id, value(), needsTypeBarrier(),
- &checkTypeset, shape.address()))
- {
- return true;
- }
-
- if (!attachSetSlot(cx, outerScript, ion, obj, shape, checkTypeset))
- return false;
- *emitted = true;
- return true;
-}
-
-bool
SetPropertyIC::tryAttachStub(JSContext* cx, HandleScript outerScript, IonScript* ion,
HandleObject obj, HandleValue idval, HandleValue value,
MutableHandleId id, bool* emitted, bool* tryNativeAddSlot)
@@ -3558,12 +3249,6 @@ SetPropertyIC::tryAttachStub(JSContext* cx, HandleScript outerScript, IonScript*
if (!*emitted && !tryAttachNative(cx, outerScript, ion, obj, id, emitted, tryNativeAddSlot))
return false;
-
- if (!*emitted && !tryAttachUnboxed(cx, outerScript, ion, obj, id, emitted))
- return false;
-
- if (!*emitted && !tryAttachUnboxedExpando(cx, outerScript, ion, obj, id, emitted))
- return false;
}
if (idval.isInt32()) {
@@ -3615,16 +3300,6 @@ SetPropertyIC::tryAttachAddSlot(JSContext* cx, HandleScript outerScript, IonScri
return true;
}
- checkTypeset = false;
- if (CanAttachAddUnboxedExpando(cx, obj, oldShape, id, value(), needsTypeBarrier(),
- &checkTypeset))
- {
- if (!attachAddSlot(cx, outerScript, ion, obj, id, oldShape, oldGroup, checkTypeset))
- return false;
- *emitted = true;
- return true;
- }
-
return true;
}
@@ -3646,11 +3321,6 @@ SetPropertyIC::update(JSContext* cx, HandleScript outerScript, size_t cacheIndex
return false;
oldShape = obj->maybeShape();
- if (obj->is<UnboxedPlainObject>()) {
- MOZ_ASSERT(!oldShape);
- if (UnboxedExpandoObject* expando = obj->as<UnboxedPlainObject>().maybeExpando())
- oldShape = expando->lastProperty();
- }
}
RootedId id(cx);
diff --git a/js/src/jit/IonCaches.h b/js/src/jit/IonCaches.h
index 173e06c6b..b00646538 100644
--- a/js/src/jit/IonCaches.h
+++ b/js/src/jit/IonCaches.h
@@ -529,18 +529,6 @@ class GetPropertyIC : public IonCache
HandleObject obj, HandleId id, void* returnAddr,
bool* emitted);
- MOZ_MUST_USE bool tryAttachUnboxed(JSContext* cx, HandleScript outerScript, IonScript* ion,
- HandleObject obj, HandleId id, void* returnAddr,
- bool* emitted);
-
- MOZ_MUST_USE bool tryAttachUnboxedExpando(JSContext* cx, HandleScript outerScript,
- IonScript* ion, HandleObject obj, HandleId id,
- void* returnAddr, bool* emitted);
-
- MOZ_MUST_USE bool tryAttachUnboxedArrayLength(JSContext* cx, HandleScript outerScript,
- IonScript* ion, HandleObject obj, HandleId id,
- void* returnAddr, bool* emitted);
-
MOZ_MUST_USE bool tryAttachTypedArrayLength(JSContext* cx, HandleScript outerScript,
IonScript* ion, HandleObject obj, HandleId id,
bool* emitted);
diff --git a/js/src/jit/JitOptions.cpp b/js/src/jit/JitOptions.cpp
index b9a7c7b27..3f9d9db88 100644
--- a/js/src/jit/JitOptions.cpp
+++ b/js/src/jit/JitOptions.cpp
@@ -221,9 +221,6 @@ DefaultJitOptions::DefaultJitOptions()
Warn(forcedRegisterAllocatorEnv, env);
}
- // Toggles whether unboxed plain objects can be created by the VM.
- SET_DEFAULT(disableUnboxedObjects, true);
-
// Test whether Atomics are allowed in asm.js code.
SET_DEFAULT(asmJSAtomicsEnable, false);
diff --git a/js/src/jit/JitOptions.h b/js/src/jit/JitOptions.h
index 076980b4e..719ee14d9 100644
--- a/js/src/jit/JitOptions.h
+++ b/js/src/jit/JitOptions.h
@@ -91,9 +91,6 @@ struct DefaultJitOptions
mozilla::Maybe<uint32_t> forcedDefaultIonSmallFunctionWarmUpThreshold;
mozilla::Maybe<IonRegisterAllocator> forcedRegisterAllocator;
- // The options below affect the rest of the VM, and not just the JIT.
- bool disableUnboxedObjects;
-
DefaultJitOptions();
bool isSmallFunction(JSScript* script) const;
void setEagerCompilation();
diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp
index fed5aefe5..359f04639 100644
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -30,7 +30,6 @@
#include "jit/shared/Lowering-shared-inl.h"
#include "vm/NativeObject-inl.h"
#include "vm/StringObject-inl.h"
-#include "vm/UnboxedObject-inl.h"
using mozilla::ArrayLength;
using mozilla::AssertedCast;
diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp
index 190b40bb2..fa9cc3019 100644
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -4817,15 +4817,14 @@ MCreateThisWithTemplate::canRecoverOnBailout() const
MObjectState::MObjectState(MObjectState* state)
: numSlots_(state->numSlots_),
- numFixedSlots_(state->numFixedSlots_),
- operandIndex_(state->operandIndex_)
+ numFixedSlots_(state->numFixedSlots_)
{
// This instruction is only used as a summary for bailout paths.
setResultType(MIRType::Object);
setRecoveredOnBailout();
}
-MObjectState::MObjectState(JSObject *templateObject, OperandIndexMap* operandIndex)
+MObjectState::MObjectState(JSObject* templateObject)
{
// This instruction is only used as a summary for bailout paths.
setResultType(MIRType::Object);
@@ -4836,8 +4835,6 @@ MObjectState::MObjectState(JSObject *templateObject, OperandIndexMap* operandInd
NativeObject* nativeObject = &templateObject->as<NativeObject>();
numSlots_ = nativeObject->slotSpan();
numFixedSlots_ = nativeObject->numFixedSlots();
-
- operandIndex_ = operandIndex;
}
JSObject*
@@ -4897,7 +4894,7 @@ MObjectState::New(TempAllocator& alloc, MDefinition* obj)
JSObject* templateObject = templateObjectOf(obj);
MOZ_ASSERT(templateObject, "Unexpected object creation.");
- MObjectState* res = new(alloc) MObjectState(templateObject, nullptr);
+ MObjectState* res = new(alloc) MObjectState(templateObject);
if (!res || !res->init(alloc, obj))
return nullptr;
return res;
diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h
index 6526e0931..0992768bf 100644
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -375,7 +375,7 @@ class AliasSet {
Element = 1 << 1, // A Value member of obj->elements or
// a typed object.
UnboxedElement = 1 << 2, // An unboxed scalar or reference member of
- // typed object or unboxed object.
+ // typed object.
DynamicSlot = 1 << 3, // A Value member of obj->slots.
FixedSlot = 1 << 4, // A Value member of obj->fixedSlots().
DOMProperty = 1 << 5, // A DOM property
@@ -3758,14 +3758,9 @@ class MObjectState
{
private:
uint32_t numSlots_;
- uint32_t numFixedSlots_; // valid if isUnboxed() == false.
- OperandIndexMap* operandIndex_; // valid if isUnboxed() == true.
+ uint32_t numFixedSlots_;
- bool isUnboxed() const {
- return operandIndex_ != nullptr;
- }
-
- MObjectState(JSObject *templateObject, OperandIndexMap* operandIndex);
+ MObjectState(JSObject *templateObject);
explicit MObjectState(MObjectState* state);
MOZ_MUST_USE bool init(TempAllocator& alloc, MDefinition* obj);
@@ -3826,18 +3821,6 @@ class MObjectState
setSlot(slot + numFixedSlots(), def);
}
- // Interface reserved for unboxed objects.
- bool hasOffset(uint32_t offset) const {
- MOZ_ASSERT(isUnboxed());
- return offset < operandIndex_->map.length() && operandIndex_->map[offset] != 0;
- }
- MDefinition* getOffset(uint32_t offset) const {
- return getOperand(operandIndex_->map[offset]);
- }
- void setOffset(uint32_t offset, MDefinition* def) {
- replaceOperand(operandIndex_->map[offset], def);
- }
-
MOZ_MUST_USE bool writeRecoverData(CompactBufferWriter& writer) const override;
bool canRecoverOnBailout() const override {
return true;
diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp
index e50f68722..a739b9325 100644
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -126,20 +126,14 @@ MacroAssembler::guardTypeSetMightBeIncomplete(TypeSet* types, Register obj, Regi
{
// Type set guards might miss when an object's group changes. In this case
// either its old group's properties will become unknown, or it will change
- // to a native object with an original unboxed group. Jump to label if this
- // might have happened for the input object.
+ // to a native object. Jump to label if this might have happened for the
+ // input object.
if (types->unknownObject()) {
jump(label);
return;
}
- loadPtr(Address(obj, JSObject::offsetOfGroup()), scratch);
- load32(Address(scratch, ObjectGroup::offsetOfFlags()), scratch);
- and32(Imm32(OBJECT_FLAG_ADDENDUM_MASK), scratch);
- branch32(Assembler::Equal,
- scratch, Imm32(ObjectGroup::addendumOriginalUnboxedGroupValue()), label);
-
for (size_t i = 0; i < types->getObjectCount(); i++) {
if (JSObject* singleton = types->getSingletonNoBarrier(i)) {
movePtr(ImmGCPtr(singleton), scratch);
@@ -468,243 +462,6 @@ template void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const A
template void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const BaseIndex& src, const ValueOperand& dest,
bool allowDouble, Register temp, Label* fail);
-template <typename T>
-void
-MacroAssembler::loadUnboxedProperty(T address, JSValueType type, TypedOrValueRegister output)
-{
- switch (type) {
- case JSVAL_TYPE_INT32: {
- // Handle loading an int32 into a double reg.
- if (output.type() == MIRType::Double) {
- convertInt32ToDouble(address, output.typedReg().fpu());
- break;
- }
- MOZ_FALLTHROUGH;
- }
-
- case JSVAL_TYPE_BOOLEAN:
- case JSVAL_TYPE_STRING: {
- Register outReg;
- if (output.hasValue()) {
- outReg = output.valueReg().scratchReg();
- } else {
- MOZ_ASSERT(output.type() == MIRTypeFromValueType(type));
- outReg = output.typedReg().gpr();
- }
-
- switch (type) {
- case JSVAL_TYPE_BOOLEAN:
- load8ZeroExtend(address, outReg);
- break;
- case JSVAL_TYPE_INT32:
- load32(address, outReg);
- break;
- case JSVAL_TYPE_STRING:
- loadPtr(address, outReg);
- break;
- default:
- MOZ_CRASH();
- }
-
- if (output.hasValue())
- tagValue(type, outReg, output.valueReg());
- break;
- }
-
- case JSVAL_TYPE_OBJECT:
- if (output.hasValue()) {
- Register scratch = output.valueReg().scratchReg();
- loadPtr(address, scratch);
-
- Label notNull, done;
- branchPtr(Assembler::NotEqual, scratch, ImmWord(0), &notNull);
-
- moveValue(NullValue(), output.valueReg());
- jump(&done);
-
- bind(&notNull);
- tagValue(JSVAL_TYPE_OBJECT, scratch, output.valueReg());
-
- bind(&done);
- } else {
- // Reading null can't be possible here, as otherwise the result
- // would be a value (either because null has been read before or
- // because there is a barrier).
- Register reg = output.typedReg().gpr();
- loadPtr(address, reg);
-#ifdef DEBUG
- Label ok;
- branchTestPtr(Assembler::NonZero, reg, reg, &ok);
- assumeUnreachable("Null not possible");
- bind(&ok);
-#endif
- }
- break;
-
- case JSVAL_TYPE_DOUBLE:
- // Note: doubles in unboxed objects are not accessed through other
- // views and do not need canonicalization.
- if (output.hasValue())
- loadValue(address, output.valueReg());
- else
- loadDouble(address, output.typedReg().fpu());
- break;
-
- default:
- MOZ_CRASH();
- }
-}
-
-template void
-MacroAssembler::loadUnboxedProperty(Address address, JSValueType type,
- TypedOrValueRegister output);
-
-template void
-MacroAssembler::loadUnboxedProperty(BaseIndex address, JSValueType type,
- TypedOrValueRegister output);
-
-static void
-StoreUnboxedFailure(MacroAssembler& masm, Label* failure)
-{
- // Storing a value to an unboxed property is a fallible operation and
- // the caller must provide a failure label if a particular unboxed store
- // might fail. Sometimes, however, a store that cannot succeed (such as
- // storing a string to an int32 property) will be marked as infallible.
- // This can only happen if the code involved is unreachable.
- if (failure)
- masm.jump(failure);
- else
- masm.assumeUnreachable("Incompatible write to unboxed property");
-}
-
-template <typename T>
-void
-MacroAssembler::storeUnboxedProperty(T address, JSValueType type,
- const ConstantOrRegister& value, Label* failure)
-{
- switch (type) {
- case JSVAL_TYPE_BOOLEAN:
- if (value.constant()) {
- if (value.value().isBoolean())
- store8(Imm32(value.value().toBoolean()), address);
- else
- StoreUnboxedFailure(*this, failure);
- } else if (value.reg().hasTyped()) {
- if (value.reg().type() == MIRType::Boolean)
- store8(value.reg().typedReg().gpr(), address);
- else
- StoreUnboxedFailure(*this, failure);
- } else {
- if (failure)
- branchTestBoolean(Assembler::NotEqual, value.reg().valueReg(), failure);
- storeUnboxedPayload(value.reg().valueReg(), address, /* width = */ 1);
- }
- break;
-
- case JSVAL_TYPE_INT32:
- if (value.constant()) {
- if (value.value().isInt32())
- store32(Imm32(value.value().toInt32()), address);
- else
- StoreUnboxedFailure(*this, failure);
- } else if (value.reg().hasTyped()) {
- if (value.reg().type() == MIRType::Int32)
- store32(value.reg().typedReg().gpr(), address);
- else
- StoreUnboxedFailure(*this, failure);
- } else {
- if (failure)
- branchTestInt32(Assembler::NotEqual, value.reg().valueReg(), failure);
- storeUnboxedPayload(value.reg().valueReg(), address, /* width = */ 4);
- }
- break;
-
- case JSVAL_TYPE_DOUBLE:
- if (value.constant()) {
- if (value.value().isNumber()) {
- loadConstantDouble(value.value().toNumber(), ScratchDoubleReg);
- storeDouble(ScratchDoubleReg, address);
- } else {
- StoreUnboxedFailure(*this, failure);
- }
- } else if (value.reg().hasTyped()) {
- if (value.reg().type() == MIRType::Int32) {
- convertInt32ToDouble(value.reg().typedReg().gpr(), ScratchDoubleReg);
- storeDouble(ScratchDoubleReg, address);
- } else if (value.reg().type() == MIRType::Double) {
- storeDouble(value.reg().typedReg().fpu(), address);
- } else {
- StoreUnboxedFailure(*this, failure);
- }
- } else {
- ValueOperand reg = value.reg().valueReg();
- Label notInt32, end;
- branchTestInt32(Assembler::NotEqual, reg, &notInt32);
- int32ValueToDouble(reg, ScratchDoubleReg);
- storeDouble(ScratchDoubleReg, address);
- jump(&end);
- bind(&notInt32);
- if (failure)
- branchTestDouble(Assembler::NotEqual, reg, failure);
- storeValue(reg, address);
- bind(&end);
- }
- break;
-
- case JSVAL_TYPE_OBJECT:
- if (value.constant()) {
- if (value.value().isObjectOrNull())
- storePtr(ImmGCPtr(value.value().toObjectOrNull()), address);
- else
- StoreUnboxedFailure(*this, failure);
- } else if (value.reg().hasTyped()) {
- MOZ_ASSERT(value.reg().type() != MIRType::Null);
- if (value.reg().type() == MIRType::Object)
- storePtr(value.reg().typedReg().gpr(), address);
- else
- StoreUnboxedFailure(*this, failure);
- } else {
- if (failure) {
- Label ok;
- branchTestNull(Assembler::Equal, value.reg().valueReg(), &ok);
- branchTestObject(Assembler::NotEqual, value.reg().valueReg(), failure);
- bind(&ok);
- }
- storeUnboxedPayload(value.reg().valueReg(), address, /* width = */ sizeof(uintptr_t));
- }
- break;
-
- case JSVAL_TYPE_STRING:
- if (value.constant()) {
- if (value.value().isString())
- storePtr(ImmGCPtr(value.value().toString()), address);
- else
- StoreUnboxedFailure(*this, failure);
- } else if (value.reg().hasTyped()) {
- if (value.reg().type() == MIRType::String)
- storePtr(value.reg().typedReg().gpr(), address);
- else
- StoreUnboxedFailure(*this, failure);
- } else {
- if (failure)
- branchTestString(Assembler::NotEqual, value.reg().valueReg(), failure);
- storeUnboxedPayload(value.reg().valueReg(), address, /* width = */ sizeof(uintptr_t));
- }
- break;
-
- default:
- MOZ_CRASH();
- }
-}
-
-template void
-MacroAssembler::storeUnboxedProperty(Address address, JSValueType type,
- const ConstantOrRegister& value, Label* failure);
-
-template void
-MacroAssembler::storeUnboxedProperty(BaseIndex address, JSValueType type,
- const ConstantOrRegister& value, Label* failure);
-
// Inlined version of gc::CheckAllocatorState that checks the bare essentials
// and bails for anything that cannot be handled with our jit allocators.
void
@@ -1252,10 +1009,6 @@ MacroAssembler::initGCThing(Register obj, Register temp, JSObject* templateObj,
nbytes = (nbytes < sizeof(uintptr_t)) ? 0 : nbytes - sizeof(uintptr_t);
offset += sizeof(uintptr_t);
}
- } else if (templateObj->is<UnboxedPlainObject>()) {
- storePtr(ImmWord(0), Address(obj, UnboxedPlainObject::offsetOfExpando()));
- if (initContents)
- initUnboxedObjectContents(obj, &templateObj->as<UnboxedPlainObject>());
} else {
MOZ_CRASH("Unknown object");
}
@@ -1277,29 +1030,6 @@ MacroAssembler::initGCThing(Register obj, Register temp, JSObject* templateObj,
}
void
-MacroAssembler::initUnboxedObjectContents(Register object, UnboxedPlainObject* templateObject)
-{
- const UnboxedLayout& layout = templateObject->layoutDontCheckGeneration();
-
- // Initialize reference fields of the object, per UnboxedPlainObject::create.
- if (const int32_t* list = layout.traceList()) {
- while (*list != -1) {
- storePtr(ImmGCPtr(GetJitContext()->runtime->names().empty),
- Address(object, UnboxedPlainObject::offsetOfData() + *list));
- list++;
- }
- list++;
- while (*list != -1) {
- storePtr(ImmWord(0),
- Address(object, UnboxedPlainObject::offsetOfData() + *list));
- list++;
- }
- // Unboxed objects don't have Values to initialize.
- MOZ_ASSERT(*(list + 1) == -1);
- }
-}
-
-void
MacroAssembler::compareStrings(JSOp op, Register left, Register right, Register result,
Label* fail)
{
diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h
index 6ee989463..d5cc95839 100644
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -36,7 +36,6 @@
#include "vm/ProxyObject.h"
#include "vm/Shape.h"
#include "vm/TypedArrayObject.h"
-#include "vm/UnboxedObject.h"
using mozilla::FloatingPoint;
@@ -1626,17 +1625,6 @@ class MacroAssembler : public MacroAssemblerSpecific
void storeToTypedFloatArray(Scalar::Type arrayType, FloatRegister value, const Address& dest,
unsigned numElems = 0);
- // Load a property from an UnboxedPlainObject.
- template <typename T>
- void loadUnboxedProperty(T address, JSValueType type, TypedOrValueRegister output);
-
- // Store a property to an UnboxedPlainObject, without triggering barriers.
- // If failure is null, the value definitely has a type suitable for storing
- // in the property.
- template <typename T>
- void storeUnboxedProperty(T address, JSValueType type,
- const ConstantOrRegister& value, Label* failure);
-
Register extractString(const Address& address, Register scratch) {
return extractObject(address, scratch);
}
@@ -1713,8 +1701,6 @@ class MacroAssembler : public MacroAssemblerSpecific
LiveRegisterSet liveRegs, Label* fail,
TypedArrayObject* templateObj, TypedArrayLength lengthKind);
- void initUnboxedObjectContents(Register object, UnboxedPlainObject* templateObject);
-
void newGCString(Register result, Register temp, Label* fail);
void newGCFatInlineString(Register result, Register temp, Label* fail);
diff --git a/js/src/jit/OptimizationTracking.cpp b/js/src/jit/OptimizationTracking.cpp
index b42634d43..7d72795a0 100644
--- a/js/src/jit/OptimizationTracking.cpp
+++ b/js/src/jit/OptimizationTracking.cpp
@@ -15,11 +15,9 @@
#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;
@@ -846,8 +844,6 @@ MaybeConstructorFromType(TypeSet::Type ty)
return nullptr;
ObjectGroup* obj = ty.group();
TypeNewScript* newScript = obj->newScript();
- if (!newScript && obj->maybeUnboxedLayout())
- newScript = obj->unboxedLayout().newScript();
return newScript ? newScript->function() : nullptr;
}
diff --git a/js/src/jit/Recover.cpp b/js/src/jit/Recover.cpp
index 8fe6ee3fb..793b631df 100644
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -30,7 +30,6 @@
#include "vm/Interpreter-inl.h"
#include "vm/NativeObject-inl.h"
-#include "vm/UnboxedObject-inl.h"
using namespace js;
using namespace js::jit;
@@ -1540,37 +1539,12 @@ RObjectState::recover(JSContext* cx, SnapshotIterator& iter) const
RootedObject object(cx, &iter.read().toObject());
RootedValue val(cx);
- if (object->is<UnboxedPlainObject>()) {
- const UnboxedLayout& layout = object->as<UnboxedPlainObject>().layout();
+ RootedNativeObject nativeObject(cx, &object->as<NativeObject>());
+ MOZ_ASSERT(nativeObject->slotSpan() == numSlots());
- RootedId id(cx);
- RootedValue receiver(cx, ObjectValue(*object));
- const UnboxedLayout::PropertyVector& properties = layout.properties();
- for (size_t i = 0; i < properties.length(); i++) {
- val = iter.read();
-
- // This is the default placeholder value of MObjectState, when no
- // properties are defined yet.
- if (val.isUndefined())
- continue;
-
- id = NameToId(properties[i].name);
- ObjectOpResult result;
-
- // SetProperty can only fail due to OOM.
- if (!SetProperty(cx, object, id, val, receiver, result))
- return false;
- if (!result)
- return result.reportError(cx, object, id);
- }
- } else {
- RootedNativeObject nativeObject(cx, &object->as<NativeObject>());
- MOZ_ASSERT(nativeObject->slotSpan() == numSlots());
-
- for (size_t i = 0; i < numSlots(); i++) {
- val = iter.read();
- nativeObject->setSlot(i, val);
- }
+ for (size_t i = 0; i < numSlots(); i++) {
+ val = iter.read();
+ nativeObject->setSlot(i, val);
}
val.setObject(*object);
diff --git a/js/src/jit/ScalarReplacement.cpp b/js/src/jit/ScalarReplacement.cpp
index be9ceee2e..97ba52349 100644
--- a/js/src/jit/ScalarReplacement.cpp
+++ b/js/src/jit/ScalarReplacement.cpp
@@ -285,10 +285,6 @@ class ObjectMemoryView : public MDefinitionVisitorDefaultNoop
void visitGuardShape(MGuardShape* ins);
void visitFunctionEnvironment(MFunctionEnvironment* ins);
void visitLambda(MLambda* ins);
-
- private:
- void storeOffset(MInstruction* ins, size_t offset, MDefinition* value);
- void loadOffset(MInstruction* ins, size_t offset);
};
const char* ObjectMemoryView::phaseName = "Scalar Replacement of Object";
@@ -630,35 +626,6 @@ ObjectMemoryView::visitLambda(MLambda* ins)
ins->setIncompleteObject();
}
-void
-ObjectMemoryView::storeOffset(MInstruction* ins, size_t offset, MDefinition* value)
-{
- // Clone the state and update the slot value.
- MOZ_ASSERT(state_->hasOffset(offset));
- state_ = BlockState::Copy(alloc_, state_);
- if (!state_) {
- oom_ = true;
- return;
- }
-
- state_->setOffset(offset, value);
- ins->block()->insertBefore(ins, state_);
-
- // Remove original instruction.
- ins->block()->discard(ins);
-}
-
-void
-ObjectMemoryView::loadOffset(MInstruction* ins, size_t offset)
-{
- // Replace load by the slot value.
- MOZ_ASSERT(state_->hasOffset(offset));
- ins->replaceAllUsesWith(state_->getOffset(offset));
-
- // Remove original instruction.
- ins->block()->discard(ins);
-}
-
static bool
IndexOf(MDefinition* ins, int32_t* res)
{
diff --git a/js/src/jit/SharedIC.cpp b/js/src/jit/SharedIC.cpp
index 313957462..05a95824f 100644
--- a/js/src/jit/SharedIC.cpp
+++ b/js/src/jit/SharedIC.cpp
@@ -2244,8 +2244,7 @@ IsCacheableProtoChain(JSObject* obj, JSObject* holder, bool isDOMProxy)
if (!isDOMProxy && !obj->isNative()) {
if (obj == holder)
return false;
- if (!obj->is<UnboxedPlainObject>() &&
- !obj->is<TypedObject>())
+ if (!obj->is<TypedObject>())
{
return false;
}
@@ -2573,9 +2572,6 @@ CheckHasNoSuchProperty(JSContext* cx, JSObject* obj, PropertyName* name,
} else if (curObj != obj) {
// Non-native objects are only handled as the original receiver.
return false;
- } else if (curObj->is<UnboxedPlainObject>()) {
- if (curObj->as<UnboxedPlainObject>().containsUnboxedOrExpandoProperty(cx, NameToId(name)))
- return false;
} else if (curObj->is<TypedObject>()) {
if (curObj->as<TypedObject>().typeDescr().hasProperty(cx->names(), NameToId(name)))
return false;
@@ -2840,34 +2836,15 @@ GuardReceiverObject(MacroAssembler& masm, ReceiverGuard guard,
{
Address groupAddress(ICStubReg, receiverGuardOffset + HeapReceiverGuard::offsetOfGroup());
Address shapeAddress(ICStubReg, receiverGuardOffset + HeapReceiverGuard::offsetOfShape());
- Address expandoAddress(object, UnboxedPlainObject::offsetOfExpando());
if (guard.group) {
masm.loadPtr(groupAddress, scratch);
masm.branchTestObjGroup(Assembler::NotEqual, object, scratch, failure);
-
- if (guard.group->clasp() == &UnboxedPlainObject::class_ && !guard.shape) {
- // Guard the unboxed object has no expando object.
- masm.branchPtr(Assembler::NotEqual, expandoAddress, ImmWord(0), failure);
- }
}
if (guard.shape) {
masm.loadPtr(shapeAddress, scratch);
- if (guard.group && guard.group->clasp() == &UnboxedPlainObject::class_) {
- // Guard the unboxed object has a matching expando object.
- masm.branchPtr(Assembler::Equal, expandoAddress, ImmWord(0), failure);
- Label done;
- masm.push(object);
- masm.loadPtr(expandoAddress, object);
- masm.branchTestObjShape(Assembler::Equal, object, scratch, &done);
- masm.pop(object);
- masm.jump(failure);
- masm.bind(&done);
- masm.pop(object);
- } else {
- masm.branchTestObjShape(Assembler::NotEqual, object, scratch, failure);
- }
+ masm.branchTestObjShape(Assembler::NotEqual, object, scratch, failure);
}
}
@@ -4251,8 +4228,7 @@ DoNewObject(JSContext* cx, void* payload, ICNewObject_Fallback* stub, MutableHan
return false;
if (!stub->invalid() &&
- (templateObject->is<UnboxedPlainObject>() ||
- !templateObject->as<PlainObject>().hasDynamicSlots()))
+ !templateObject->as<PlainObject>().hasDynamicSlots())
{
JitCode* code = GenerateNewObjectWithTemplateCode(cx, templateObject);
if (!code)
diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp
index 297357b1e..402d910b9 100644
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -28,7 +28,7 @@
#include "vm/NativeObject-inl.h"
#include "vm/StringObject-inl.h"
#include "vm/TypeInference-inl.h"
-#include "vm/UnboxedObject-inl.h"
+#include "gc/StoreBuffer-inl.h"
using namespace js;
using namespace js::jit;