Remove Unboxed Object code from jit, Part 4.

This commit is contained in:
wolfbeast 2019-06-25 11:12:26 +00:00 committed by Roy Tam
commit 7ec709fb70
7 changed files with 20 additions and 406 deletions

View file

@ -1148,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;
@ -1445,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,
@ -1857,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()) {
@ -4494,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
@ -4546,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();
@ -4689,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 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);
// 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);
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

View file

@ -8383,11 +8383,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");
@ -8680,11 +8675,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);
@ -8696,12 +8691,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);
}

View file

@ -10923,63 +10923,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()
{
@ -11946,72 +11889,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,
@ -12833,66 +12710,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,

View file

@ -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);

View file

@ -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;
}
@ -2220,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()));
@ -2863,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.
@ -2900,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());
@ -2913,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);
@ -2935,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())
@ -2963,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.

View file

@ -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;

View file

@ -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)