mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-06 15:58:39 +09:00
Remove Unboxed Object code from jit, Part 4.
This commit is contained in:
parent
bc5121a769
commit
7ec709fb70
7 changed files with 20 additions and 406 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue