mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 07:18:39 +09:00
Remove unboxed object code from jit, Part 1
This commit is contained in:
parent
37315e4898
commit
cc936df2e5
15 changed files with 26 additions and 627 deletions
|
|
@ -114,8 +114,6 @@ GetObject(const MDefinition* ins)
|
|||
case MDefinition::Op_GuardObjectGroup:
|
||||
case MDefinition::Op_GuardObjectIdentity:
|
||||
case MDefinition::Op_GuardClass:
|
||||
case MDefinition::Op_GuardUnboxedExpando:
|
||||
case MDefinition::Op_LoadUnboxedExpando:
|
||||
case MDefinition::Op_LoadSlot:
|
||||
case MDefinition::Op_StoreSlot:
|
||||
case MDefinition::Op_InArray:
|
||||
|
|
|
|||
|
|
@ -3031,15 +3031,6 @@ GuardReceiver(MacroAssembler& masm, const ReceiverGuard& guard,
|
|||
{
|
||||
if (guard.group) {
|
||||
masm.branchTestObjGroup(Assembler::NotEqual, obj, guard.group, miss);
|
||||
|
||||
Address expandoAddress(obj, UnboxedPlainObject::offsetOfExpando());
|
||||
if (guard.shape) {
|
||||
masm.loadPtr(expandoAddress, scratch);
|
||||
masm.branchPtr(Assembler::Equal, scratch, ImmWord(0), miss);
|
||||
masm.branchTestObjShape(Assembler::NotEqual, scratch, guard.shape, miss);
|
||||
} else if (checkNullExpando) {
|
||||
masm.branchPtr(Assembler::NotEqual, expandoAddress, ImmWord(0), miss);
|
||||
}
|
||||
} else {
|
||||
masm.branchTestObjShape(Assembler::NotEqual, obj, guard.shape, miss);
|
||||
}
|
||||
|
|
@ -3077,13 +3068,6 @@ CodeGenerator::emitGetPropertyPolymorphic(LInstruction* ins, Register obj, Regis
|
|||
masm.loadPtr(Address(target, NativeObject::offsetOfSlots()), scratch);
|
||||
masm.loadTypedOrValue(Address(scratch, offset), output);
|
||||
}
|
||||
} else {
|
||||
masm.comment("loadUnboxedProperty");
|
||||
const UnboxedLayout::Property* property =
|
||||
receiver.group->unboxedLayout().lookup(mir->name());
|
||||
Address propertyAddr(obj, UnboxedPlainObject::offsetOfData() + property->offset);
|
||||
|
||||
masm.loadUnboxedProperty(propertyAddr, property->type, output);
|
||||
}
|
||||
|
||||
if (i == mir->numReceivers() - 1) {
|
||||
|
|
@ -3124,8 +3108,6 @@ EmitUnboxedPreBarrier(MacroAssembler &masm, T address, JSValueType type)
|
|||
masm.patchableCallPreBarrier(address, MIRType::Object);
|
||||
else if (type == JSVAL_TYPE_STRING)
|
||||
masm.patchableCallPreBarrier(address, MIRType::String);
|
||||
else
|
||||
MOZ_ASSERT(!UnboxedTypeNeedsPreBarrier(type));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -3161,13 +3143,6 @@ CodeGenerator::emitSetPropertyPolymorphic(LInstruction* ins, Register obj, Regis
|
|||
emitPreBarrier(addr);
|
||||
masm.storeConstantOrRegister(value, addr);
|
||||
}
|
||||
} else {
|
||||
const UnboxedLayout::Property* property =
|
||||
receiver.group->unboxedLayout().lookup(mir->name());
|
||||
Address propertyAddr(obj, UnboxedPlainObject::offsetOfData() + property->offset);
|
||||
|
||||
EmitUnboxedPreBarrier(masm, propertyAddr, property->type);
|
||||
masm.storeUnboxedProperty(propertyAddr, property->type, value, nullptr);
|
||||
}
|
||||
|
||||
if (i == mir->numReceivers() - 1) {
|
||||
|
|
@ -3332,27 +3307,6 @@ CodeGenerator::visitGuardReceiverPolymorphic(LGuardReceiverPolymorphic* lir)
|
|||
masm.bind(&done);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::visitGuardUnboxedExpando(LGuardUnboxedExpando* lir)
|
||||
{
|
||||
Label miss;
|
||||
|
||||
Register obj = ToRegister(lir->object());
|
||||
masm.branchPtr(lir->mir()->requireExpando() ? Assembler::Equal : Assembler::NotEqual,
|
||||
Address(obj, UnboxedPlainObject::offsetOfExpando()), ImmWord(0), &miss);
|
||||
|
||||
bailoutFrom(&miss, lir->snapshot());
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::visitLoadUnboxedExpando(LLoadUnboxedExpando* lir)
|
||||
{
|
||||
Register obj = ToRegister(lir->object());
|
||||
Register result = ToRegister(lir->getDef(0));
|
||||
|
||||
masm.loadPtr(Address(obj, UnboxedPlainObject::offsetOfExpando()), result);
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::visitTypeBarrierV(LTypeBarrierV* lir)
|
||||
{
|
||||
|
|
@ -8576,21 +8530,6 @@ static const VMFunction ConvertUnboxedArrayObjectToNativeInfo =
|
|||
FunctionInfo<ConvertUnboxedObjectToNativeFn>(UnboxedArrayObject::convertToNative,
|
||||
"UnboxedArrayObject::convertToNative");
|
||||
|
||||
void
|
||||
CodeGenerator::visitConvertUnboxedObjectToNative(LConvertUnboxedObjectToNative* lir)
|
||||
{
|
||||
Register object = ToRegister(lir->getOperand(0));
|
||||
|
||||
OutOfLineCode* ool = oolCallVM(lir->mir()->group()->unboxedLayoutDontCheckGeneration().isArray()
|
||||
? ConvertUnboxedArrayObjectToNativeInfo
|
||||
: ConvertUnboxedPlainObjectToNativeInfo,
|
||||
lir, ArgList(object), StoreNothing());
|
||||
|
||||
masm.branchPtr(Assembler::Equal, Address(object, JSObject::offsetOfGroup()),
|
||||
ImmGCPtr(lir->mir()->group()), ool->entry());
|
||||
masm.bind(ool->rejoin());
|
||||
}
|
||||
|
||||
typedef bool (*ArrayPopShiftFn)(JSContext*, HandleObject, MutableHandleValue);
|
||||
static const VMFunction ArrayPopDenseInfo =
|
||||
FunctionInfo<ArrayPopShiftFn>(jit::ArrayPopDense, "ArrayPopDense");
|
||||
|
|
|
|||
|
|
@ -148,8 +148,6 @@ class CodeGenerator final : public CodeGeneratorSpecific
|
|||
void visitMaybeCopyElementsForWrite(LMaybeCopyElementsForWrite* lir);
|
||||
void visitGuardObjectIdentity(LGuardObjectIdentity* guard);
|
||||
void visitGuardReceiverPolymorphic(LGuardReceiverPolymorphic* lir);
|
||||
void visitGuardUnboxedExpando(LGuardUnboxedExpando* lir);
|
||||
void visitLoadUnboxedExpando(LLoadUnboxedExpando* lir);
|
||||
void visitTypeBarrierV(LTypeBarrierV* lir);
|
||||
void visitTypeBarrierO(LTypeBarrierO* lir);
|
||||
void visitMonitorTypes(LMonitorTypes* lir);
|
||||
|
|
@ -310,7 +308,6 @@ class CodeGenerator final : public CodeGeneratorSpecific
|
|||
void visitFallibleStoreElementV(LFallibleStoreElementV* lir);
|
||||
void visitFallibleStoreElementT(LFallibleStoreElementT* lir);
|
||||
void visitStoreUnboxedPointer(LStoreUnboxedPointer* lir);
|
||||
void visitConvertUnboxedObjectToNative(LConvertUnboxedObjectToNative* lir);
|
||||
void emitArrayPopShift(LInstruction* lir, const MArrayPopShift* mir, Register obj,
|
||||
Register elementsTemp, Register lengthTemp, TypedOrValueRegister out);
|
||||
void visitArrayPopShiftV(LArrayPopShiftV* lir);
|
||||
|
|
|
|||
|
|
@ -3515,8 +3515,6 @@ PassthroughOperand(MDefinition* def)
|
|||
return def->toConvertElementsToDoubles()->elements();
|
||||
if (def->isMaybeCopyElementsForWrite())
|
||||
return def->toMaybeCopyElementsForWrite()->object();
|
||||
if (def->isConvertUnboxedObjectToNative())
|
||||
return def->toConvertUnboxedObjectToNative()->object();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
#include "vm/EnvironmentObject-inl.h"
|
||||
#include "vm/NativeObject-inl.h"
|
||||
#include "vm/ObjectGroup-inl.h"
|
||||
#include "vm/UnboxedObject-inl.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::jit;
|
||||
|
|
@ -6392,7 +6391,7 @@ IonBuilder::createThisScriptedSingleton(JSFunction* target, MDefinition* callee)
|
|||
JSObject* templateObject = inspector->getTemplateObject(pc);
|
||||
if (!templateObject)
|
||||
return nullptr;
|
||||
if (!templateObject->is<PlainObject>() && !templateObject->is<UnboxedPlainObject>())
|
||||
if (!templateObject->is<PlainObject>())
|
||||
return nullptr;
|
||||
if (templateObject->staticPrototype() != proto)
|
||||
return nullptr;
|
||||
|
|
@ -6429,7 +6428,7 @@ IonBuilder::createThisScriptedBaseline(MDefinition* callee)
|
|||
JSObject* templateObject = inspector->getTemplateObject(pc);
|
||||
if (!templateObject)
|
||||
return nullptr;
|
||||
if (!templateObject->is<PlainObject>() && !templateObject->is<UnboxedPlainObject>())
|
||||
if (!templateObject->is<PlainObject>())
|
||||
return nullptr;
|
||||
|
||||
Shape* shape = target->lookupPure(compartment->runtime()->names().prototype);
|
||||
|
|
@ -7718,8 +7717,6 @@ IonBuilder::jsop_initprop(PropertyName* name)
|
|||
if (templateObject->is<PlainObject>()) {
|
||||
if (!templateObject->as<PlainObject>().containsPure(name))
|
||||
useSlowPath = true;
|
||||
} else {
|
||||
MOZ_ASSERT(templateObject->as<UnboxedPlainObject>().layout().lookup(name));
|
||||
}
|
||||
} else {
|
||||
useSlowPath = true;
|
||||
|
|
@ -8178,8 +8175,7 @@ IonBuilder::maybeMarkEmpty(MDefinition* ins)
|
|||
static bool
|
||||
ClassHasEffectlessLookup(const Class* clasp)
|
||||
{
|
||||
return (clasp == &UnboxedPlainObject::class_) ||
|
||||
(clasp == &UnboxedArrayObject::class_) ||
|
||||
return (clasp == &UnboxedArrayObject::class_) ||
|
||||
IsTypedObjectClass(clasp) ||
|
||||
(clasp->isNative() && !clasp->getOpsLookupProperty());
|
||||
}
|
||||
|
|
@ -10970,11 +10966,8 @@ IonBuilder::getDefiniteSlot(TemporaryTypeSet* types, PropertyName* name, uint32_
|
|||
}
|
||||
|
||||
// Definite slots will always be fixed slots when they are in the
|
||||
// allowable range for fixed slots, except for objects which were
|
||||
// converted from unboxed objects and have a smaller allocation size.
|
||||
// allowable range for fixed slots.
|
||||
size_t nfixed = NativeObject::MAX_FIXED_SLOTS;
|
||||
if (ObjectGroup* group = key->group()->maybeOriginalUnboxedGroup())
|
||||
nfixed = gc::GetGCKindSlots(group->unboxedLayout().getAllocKind());
|
||||
|
||||
uint32_t propertySlot = property.maybeTypes()->definiteSlot();
|
||||
if (slot == UINT32_MAX) {
|
||||
|
|
@ -11031,8 +11024,6 @@ IonBuilder::getUnboxedOffset(TemporaryTypeSet* types, PropertyName* name, JSValu
|
|||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
key->watchStateChangeForUnboxedConvertedToNative(constraints());
|
||||
|
||||
if (offset == UINT32_MAX) {
|
||||
offset = property->offset;
|
||||
*punboxedType = property->type;
|
||||
|
|
@ -11565,11 +11556,6 @@ IonBuilder::jsop_getprop(PropertyName* name)
|
|||
if (!getPropTryDefiniteSlot(&emitted, obj, name, barrier, types) || emitted)
|
||||
return emitted;
|
||||
|
||||
// Try to emit loads from unboxed objects.
|
||||
trackOptimizationAttempt(TrackedStrategy::GetProp_Unboxed);
|
||||
if (!getPropTryUnboxed(&emitted, obj, name, barrier, types) || emitted)
|
||||
return emitted;
|
||||
|
||||
// Try to inline a common property getter, or make a call.
|
||||
trackOptimizationAttempt(TrackedStrategy::GetProp_CommonGetter);
|
||||
if (!getPropTryCommonGetter(&emitted, obj, name, types) || emitted)
|
||||
|
|
@ -12085,34 +12071,6 @@ IonBuilder::loadUnboxedValue(MDefinition* elements, size_t elementsOffset,
|
|||
return load;
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::getPropTryUnboxed(bool* emitted, MDefinition* obj, PropertyName* name,
|
||||
BarrierKind barrier, TemporaryTypeSet* types)
|
||||
{
|
||||
MOZ_ASSERT(*emitted == false);
|
||||
|
||||
JSValueType unboxedType;
|
||||
uint32_t offset = getUnboxedOffset(obj->resultTypeSet(), name, &unboxedType);
|
||||
if (offset == UINT32_MAX)
|
||||
return true;
|
||||
|
||||
if (obj->type() != MIRType::Object) {
|
||||
MGuardObject* guard = MGuardObject::New(alloc(), obj);
|
||||
current->add(guard);
|
||||
obj = guard;
|
||||
}
|
||||
|
||||
MInstruction* load = loadUnboxedProperty(obj, offset, unboxedType, barrier, types);
|
||||
current->push(load);
|
||||
|
||||
if (!pushTypeBarrier(load, types, barrier))
|
||||
return false;
|
||||
|
||||
trackOptimizationSuccess();
|
||||
*emitted = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
MDefinition*
|
||||
IonBuilder::addShapeGuardsForGetterSetter(MDefinition* obj, JSObject* holder, Shape* holderShape,
|
||||
const BaselineInspector::ReceiverVector& receivers,
|
||||
|
|
@ -12356,45 +12314,6 @@ IonBuilder::getPropTryInlineAccess(bool* emitted, MDefinition* obj, PropertyName
|
|||
return true;
|
||||
}
|
||||
|
||||
if (receivers[0].shape) {
|
||||
// Monomorphic load from an unboxed object expando.
|
||||
spew("Inlining monomorphic unboxed expando GETPROP");
|
||||
|
||||
obj = addGroupGuard(obj, receivers[0].group, Bailout_ShapeGuard);
|
||||
obj = addUnboxedExpandoGuard(obj, /* hasExpando = */ true, Bailout_ShapeGuard);
|
||||
|
||||
MInstruction* expando = MLoadUnboxedExpando::New(alloc(), obj);
|
||||
current->add(expando);
|
||||
|
||||
expando = addShapeGuard(expando, receivers[0].shape, Bailout_ShapeGuard);
|
||||
|
||||
Shape* shape = receivers[0].shape->searchLinear(NameToId(name));
|
||||
MOZ_ASSERT(shape);
|
||||
|
||||
if (!loadSlot(expando, shape, rvalType, barrier, types))
|
||||
return false;
|
||||
|
||||
trackOptimizationOutcome(TrackedOutcome::Monomorphic);
|
||||
*emitted = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Monomorphic load from an unboxed object.
|
||||
ObjectGroup* group = receivers[0].group;
|
||||
if (obj->resultTypeSet() && !obj->resultTypeSet()->hasType(TypeSet::ObjectType(group)))
|
||||
return true;
|
||||
|
||||
obj = addGroupGuard(obj, group, Bailout_ShapeGuard);
|
||||
|
||||
const UnboxedLayout::Property* property = group->unboxedLayout().lookup(name);
|
||||
MInstruction* load = loadUnboxedProperty(obj, property->offset, property->type, barrier, types);
|
||||
current->push(load);
|
||||
|
||||
if (!pushTypeBarrier(load, types, barrier))
|
||||
return false;
|
||||
|
||||
trackOptimizationOutcome(TrackedOutcome::Monomorphic);
|
||||
*emitted = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -12669,13 +12588,6 @@ IonBuilder::jsop_setprop(PropertyName* name)
|
|||
bool barrier = PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current, &obj, name, &value,
|
||||
/* canModify = */ true);
|
||||
|
||||
if (!forceInlineCaches()) {
|
||||
// Try to emit stores to unboxed objects.
|
||||
trackOptimizationAttempt(TrackedStrategy::SetProp_Unboxed);
|
||||
if (!setPropTryUnboxed(&emitted, obj, name, value, barrier, objTypes) || emitted)
|
||||
return emitted;
|
||||
}
|
||||
|
||||
// Add post barrier if needed. The instructions above manage any post
|
||||
// barriers they need directly.
|
||||
if (NeedsPostBarrier(value))
|
||||
|
|
@ -13040,40 +12952,6 @@ IonBuilder::storeUnboxedValue(MDefinition* obj, MDefinition* elements, int32_t e
|
|||
return store;
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::setPropTryUnboxed(bool* emitted, MDefinition* obj,
|
||||
PropertyName* name, MDefinition* value,
|
||||
bool barrier, TemporaryTypeSet* objTypes)
|
||||
{
|
||||
MOZ_ASSERT(*emitted == false);
|
||||
|
||||
if (barrier) {
|
||||
trackOptimizationOutcome(TrackedOutcome::NeedsTypeBarrier);
|
||||
return true;
|
||||
}
|
||||
|
||||
JSValueType unboxedType;
|
||||
uint32_t offset = getUnboxedOffset(obj->resultTypeSet(), name, &unboxedType);
|
||||
if (offset == UINT32_MAX)
|
||||
return true;
|
||||
|
||||
if (obj->type() != MIRType::Object) {
|
||||
MGuardObject* guard = MGuardObject::New(alloc(), obj);
|
||||
current->add(guard);
|
||||
obj = guard;
|
||||
}
|
||||
|
||||
MInstruction* store = storeUnboxedProperty(obj, offset, unboxedType, value);
|
||||
|
||||
current->push(value);
|
||||
|
||||
if (!resumeAfter(store))
|
||||
return false;
|
||||
|
||||
*emitted = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::setPropTryInlineAccess(bool* emitted, MDefinition* obj,
|
||||
PropertyName* name, MDefinition* value,
|
||||
|
|
@ -13112,46 +12990,6 @@ IonBuilder::setPropTryInlineAccess(bool* emitted, MDefinition* obj,
|
|||
return true;
|
||||
}
|
||||
|
||||
if (receivers[0].shape) {
|
||||
// Monomorphic store to an unboxed object expando.
|
||||
spew("Inlining monomorphic unboxed expando SETPROP");
|
||||
|
||||
obj = addGroupGuard(obj, receivers[0].group, Bailout_ShapeGuard);
|
||||
obj = addUnboxedExpandoGuard(obj, /* hasExpando = */ true, Bailout_ShapeGuard);
|
||||
|
||||
MInstruction* expando = MLoadUnboxedExpando::New(alloc(), obj);
|
||||
current->add(expando);
|
||||
|
||||
expando = addShapeGuard(expando, receivers[0].shape, Bailout_ShapeGuard);
|
||||
|
||||
Shape* shape = receivers[0].shape->searchLinear(NameToId(name));
|
||||
MOZ_ASSERT(shape);
|
||||
|
||||
bool needsBarrier = objTypes->propertyNeedsBarrier(constraints(), NameToId(name));
|
||||
if (!storeSlot(expando, shape, value, needsBarrier))
|
||||
return false;
|
||||
|
||||
trackOptimizationOutcome(TrackedOutcome::Monomorphic);
|
||||
*emitted = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Monomorphic store to an unboxed object.
|
||||
spew("Inlining monomorphic unboxed SETPROP");
|
||||
|
||||
ObjectGroup* group = receivers[0].group;
|
||||
if (!objTypes->hasType(TypeSet::ObjectType(group)))
|
||||
return true;
|
||||
|
||||
obj = addGroupGuard(obj, group, Bailout_ShapeGuard);
|
||||
|
||||
const UnboxedLayout::Property* property = group->unboxedLayout().lookup(name);
|
||||
storeUnboxedProperty(obj, property->offset, property->type, value);
|
||||
|
||||
current->push(value);
|
||||
|
||||
trackOptimizationOutcome(TrackedOutcome::Monomorphic);
|
||||
*emitted = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -14178,19 +14016,6 @@ IonBuilder::addGroupGuard(MDefinition* obj, ObjectGroup* group, BailoutKind bail
|
|||
return guard;
|
||||
}
|
||||
|
||||
MInstruction*
|
||||
IonBuilder::addUnboxedExpandoGuard(MDefinition* obj, bool hasExpando, BailoutKind bailoutKind)
|
||||
{
|
||||
MGuardUnboxedExpando* guard = MGuardUnboxedExpando::New(alloc(), obj, hasExpando, bailoutKind);
|
||||
current->add(guard);
|
||||
|
||||
// If a shape guard failed in the past, don't optimize group guards.
|
||||
if (failedShapeGuard_)
|
||||
guard->setNotMovable();
|
||||
|
||||
return guard;
|
||||
}
|
||||
|
||||
MInstruction*
|
||||
IonBuilder::addGuardReceiverPolymorphic(MDefinition* obj,
|
||||
const BaselineInspector::ReceiverVector& receivers)
|
||||
|
|
@ -14200,15 +14025,6 @@ IonBuilder::addGuardReceiverPolymorphic(MDefinition* obj,
|
|||
// Monomorphic guard on a native object.
|
||||
return addShapeGuard(obj, receivers[0].shape, Bailout_ShapeGuard);
|
||||
}
|
||||
|
||||
if (!receivers[0].shape) {
|
||||
// Guard on an unboxed object that does not have an expando.
|
||||
obj = addGroupGuard(obj, receivers[0].group, Bailout_ShapeGuard);
|
||||
return addUnboxedExpandoGuard(obj, /* hasExpando = */ false, Bailout_ShapeGuard);
|
||||
}
|
||||
|
||||
// Monomorphic receiver guards are not yet supported when the receiver
|
||||
// is an unboxed object with an expando.
|
||||
}
|
||||
|
||||
MGuardReceiverPolymorphic* guard = MGuardReceiverPolymorphic::New(alloc(), obj);
|
||||
|
|
|
|||
|
|
@ -401,7 +401,6 @@ class IonBuilder
|
|||
MInstruction* addBoundsCheck(MDefinition* index, MDefinition* length);
|
||||
MInstruction* addShapeGuard(MDefinition* obj, Shape* const shape, BailoutKind bailoutKind);
|
||||
MInstruction* addGroupGuard(MDefinition* obj, ObjectGroup* group, BailoutKind bailoutKind);
|
||||
MInstruction* addUnboxedExpandoGuard(MDefinition* obj, bool hasExpando, BailoutKind bailoutKind);
|
||||
MInstruction* addSharedTypedArrayGuard(MDefinition* obj);
|
||||
|
||||
MInstruction*
|
||||
|
|
@ -441,8 +440,6 @@ class IonBuilder
|
|||
BarrierKind barrier, TemporaryTypeSet* types);
|
||||
MOZ_MUST_USE bool getPropTryModuleNamespace(bool* emitted, MDefinition* obj, PropertyName* name,
|
||||
BarrierKind barrier, TemporaryTypeSet* types);
|
||||
MOZ_MUST_USE bool getPropTryUnboxed(bool* emitted, MDefinition* obj, PropertyName* name,
|
||||
BarrierKind barrier, TemporaryTypeSet* types);
|
||||
MOZ_MUST_USE bool getPropTryCommonGetter(bool* emitted, MDefinition* obj, PropertyName* name,
|
||||
TemporaryTypeSet* types);
|
||||
MOZ_MUST_USE bool getPropTryInlineAccess(bool* emitted, MDefinition* obj, PropertyName* name,
|
||||
|
|
@ -475,9 +472,6 @@ class IonBuilder
|
|||
MOZ_MUST_USE bool setPropTryDefiniteSlot(bool* emitted, MDefinition* obj,
|
||||
PropertyName* name, MDefinition* value,
|
||||
bool barrier, TemporaryTypeSet* objTypes);
|
||||
MOZ_MUST_USE bool setPropTryUnboxed(bool* emitted, MDefinition* obj,
|
||||
PropertyName* name, MDefinition* value,
|
||||
bool barrier, TemporaryTypeSet* objTypes);
|
||||
MOZ_MUST_USE bool setPropTryInlineAccess(bool* emitted, MDefinition* obj,
|
||||
PropertyName* name, MDefinition* value,
|
||||
bool barrier, TemporaryTypeSet* objTypes);
|
||||
|
|
|
|||
|
|
@ -3251,14 +3251,6 @@ LIRGenerator::visitStoreUnboxedString(MStoreUnboxedString* ins)
|
|||
add(lir, ins);
|
||||
}
|
||||
|
||||
void
|
||||
LIRGenerator::visitConvertUnboxedObjectToNative(MConvertUnboxedObjectToNative* ins)
|
||||
{
|
||||
LInstruction* check = new(alloc()) LConvertUnboxedObjectToNative(useRegister(ins->object()));
|
||||
add(check, ins);
|
||||
assignSafepoint(check, ins);
|
||||
}
|
||||
|
||||
void
|
||||
LIRGenerator::visitEffectiveAddress(MEffectiveAddress* ins)
|
||||
{
|
||||
|
|
@ -3776,24 +3768,6 @@ LIRGenerator::visitGuardReceiverPolymorphic(MGuardReceiverPolymorphic* ins)
|
|||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
LIRGenerator::visitGuardUnboxedExpando(MGuardUnboxedExpando* ins)
|
||||
{
|
||||
LGuardUnboxedExpando* guard =
|
||||
new(alloc()) LGuardUnboxedExpando(useRegister(ins->object()));
|
||||
assignSnapshot(guard, ins->bailoutKind());
|
||||
add(guard, ins);
|
||||
redefine(ins, ins->object());
|
||||
}
|
||||
|
||||
void
|
||||
LIRGenerator::visitLoadUnboxedExpando(MLoadUnboxedExpando* ins)
|
||||
{
|
||||
LLoadUnboxedExpando* lir =
|
||||
new(alloc()) LLoadUnboxedExpando(useRegisterAtStart(ins->object()));
|
||||
define(lir, ins);
|
||||
}
|
||||
|
||||
void
|
||||
LIRGenerator::visitAssertRange(MAssertRange* ins)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -232,7 +232,6 @@ class LIRGenerator : public LIRGeneratorSpecific
|
|||
void visitFallibleStoreElement(MFallibleStoreElement* ins);
|
||||
void visitStoreUnboxedObjectOrNull(MStoreUnboxedObjectOrNull* ins);
|
||||
void visitStoreUnboxedString(MStoreUnboxedString* ins);
|
||||
void visitConvertUnboxedObjectToNative(MConvertUnboxedObjectToNative* ins);
|
||||
void visitEffectiveAddress(MEffectiveAddress* ins);
|
||||
void visitArrayPopShift(MArrayPopShift* ins);
|
||||
void visitArrayPush(MArrayPush* ins);
|
||||
|
|
@ -256,8 +255,6 @@ class LIRGenerator : public LIRGeneratorSpecific
|
|||
void visitGuardObject(MGuardObject* ins);
|
||||
void visitGuardString(MGuardString* ins);
|
||||
void visitGuardReceiverPolymorphic(MGuardReceiverPolymorphic* ins);
|
||||
void visitGuardUnboxedExpando(MGuardUnboxedExpando* ins);
|
||||
void visitLoadUnboxedExpando(MLoadUnboxedExpando* ins);
|
||||
void visitPolyInlineGuard(MPolyInlineGuard* ins);
|
||||
void visitAssertRange(MAssertRange* ins);
|
||||
void visitCallGetProperty(MCallGetProperty* ins);
|
||||
|
|
|
|||
|
|
@ -4810,35 +4810,8 @@ MBeta::printOpcode(GenericPrinter& out) const
|
|||
bool
|
||||
MCreateThisWithTemplate::canRecoverOnBailout() const
|
||||
{
|
||||
MOZ_ASSERT(templateObject()->is<PlainObject>() || templateObject()->is<UnboxedPlainObject>());
|
||||
MOZ_ASSERT_IF(templateObject()->is<PlainObject>(),
|
||||
!templateObject()->as<PlainObject>().denseElementsAreCopyOnWrite());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
OperandIndexMap::init(TempAllocator& alloc, JSObject* templateObject)
|
||||
{
|
||||
const UnboxedLayout& layout =
|
||||
templateObject->as<UnboxedPlainObject>().layoutDontCheckGeneration();
|
||||
|
||||
const UnboxedLayout::PropertyVector& properties = layout.properties();
|
||||
MOZ_ASSERT(properties.length() < 255);
|
||||
|
||||
// Allocate an array of indexes, where the top of each field correspond to
|
||||
// the index of the operand in the MObjectState instance.
|
||||
if (!map.init(alloc, layout.size()))
|
||||
return false;
|
||||
|
||||
// Reset all indexes to 0, which is an error code.
|
||||
for (size_t i = 0; i < map.length(); i++)
|
||||
map[i] = 0;
|
||||
|
||||
// Map the property offsets to the indexes of MObjectState operands.
|
||||
uint8_t index = 1;
|
||||
for (size_t i = 0; i < properties.length(); i++, index++)
|
||||
map[properties[i].offset] = index;
|
||||
|
||||
MOZ_ASSERT(templateObject()->is<PlainObject>());
|
||||
MOZ_ASSERT(!templateObject()->as<PlainObject>().denseElementsAreCopyOnWrite());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -4858,17 +4831,11 @@ MObjectState::MObjectState(JSObject *templateObject, OperandIndexMap* operandInd
|
|||
setResultType(MIRType::Object);
|
||||
setRecoveredOnBailout();
|
||||
|
||||
if (templateObject->is<NativeObject>()) {
|
||||
NativeObject* nativeObject = &templateObject->as<NativeObject>();
|
||||
numSlots_ = nativeObject->slotSpan();
|
||||
numFixedSlots_ = nativeObject->numFixedSlots();
|
||||
} else {
|
||||
const UnboxedLayout& layout =
|
||||
templateObject->as<UnboxedPlainObject>().layoutDontCheckGeneration();
|
||||
// Same as UnboxedLayout::makeNativeGroup
|
||||
numSlots_ = layout.properties().length();
|
||||
numFixedSlots_ = gc::GetGCKindSlots(layout.getAllocKind());
|
||||
}
|
||||
MOZ_ASSERT(templateObject->is<NativeObject>());
|
||||
|
||||
NativeObject* nativeObject = &templateObject->as<NativeObject>();
|
||||
numSlots_ = nativeObject->slotSpan();
|
||||
numFixedSlots_ = nativeObject->numFixedSlots();
|
||||
|
||||
operandIndex_ = operandIndex;
|
||||
}
|
||||
|
|
@ -4905,39 +4872,21 @@ MObjectState::initFromTemplateObject(TempAllocator& alloc, MDefinition* undefine
|
|||
// the template object. This is needed to account values which are baked in
|
||||
// the template objects and not visible in IonMonkey, such as the
|
||||
// uninitialized-lexical magic value of call objects.
|
||||
if (templateObject->is<UnboxedPlainObject>()) {
|
||||
UnboxedPlainObject& unboxedObject = templateObject->as<UnboxedPlainObject>();
|
||||
const UnboxedLayout& layout = unboxedObject.layoutDontCheckGeneration();
|
||||
const UnboxedLayout::PropertyVector& properties = layout.properties();
|
||||
NativeObject& nativeObject = templateObject->as<NativeObject>();
|
||||
MOZ_ASSERT(nativeObject.slotSpan() == numSlots());
|
||||
|
||||
for (size_t i = 0; i < properties.length(); i++) {
|
||||
Value val = unboxedObject.getValue(properties[i], /* maybeUninitialized = */ true);
|
||||
MDefinition *def = undefinedVal;
|
||||
if (!val.isUndefined()) {
|
||||
MConstant* ins = val.isObject() ?
|
||||
MConstant::NewConstraintlessObject(alloc, &val.toObject()) :
|
||||
MConstant::New(alloc, val);
|
||||
block()->insertBefore(this, ins);
|
||||
def = ins;
|
||||
}
|
||||
initSlot(i, def);
|
||||
}
|
||||
} else {
|
||||
NativeObject& nativeObject = templateObject->as<NativeObject>();
|
||||
MOZ_ASSERT(nativeObject.slotSpan() == numSlots());
|
||||
|
||||
for (size_t i = 0; i < numSlots(); i++) {
|
||||
Value val = nativeObject.getSlot(i);
|
||||
MDefinition *def = undefinedVal;
|
||||
if (!val.isUndefined()) {
|
||||
MConstant* ins = val.isObject() ?
|
||||
MConstant::NewConstraintlessObject(alloc, &val.toObject()) :
|
||||
MConstant::New(alloc, val);
|
||||
block()->insertBefore(this, ins);
|
||||
def = ins;
|
||||
}
|
||||
initSlot(i, def);
|
||||
MOZ_ASSERT(templateObject->is<NativeObject>());
|
||||
for (size_t i = 0; i < numSlots(); i++) {
|
||||
Value val = nativeObject.getSlot(i);
|
||||
MDefinition *def = undefinedVal;
|
||||
if (!val.isUndefined()) {
|
||||
MConstant* ins = val.isObject() ?
|
||||
MConstant::NewConstraintlessObject(alloc, &val.toObject()) :
|
||||
MConstant::New(alloc, val);
|
||||
block()->insertBefore(this, ins);
|
||||
def = ins;
|
||||
}
|
||||
initSlot(i, def);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -4948,14 +4897,7 @@ MObjectState::New(TempAllocator& alloc, MDefinition* obj)
|
|||
JSObject* templateObject = templateObjectOf(obj);
|
||||
MOZ_ASSERT(templateObject, "Unexpected object creation.");
|
||||
|
||||
OperandIndexMap* operandIndex = nullptr;
|
||||
if (templateObject->is<UnboxedPlainObject>()) {
|
||||
operandIndex = new(alloc) OperandIndexMap;
|
||||
if (!operandIndex || !operandIndex->init(alloc, templateObject))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MObjectState* res = new(alloc) MObjectState(templateObject, operandIndex);
|
||||
MObjectState* res = new(alloc) MObjectState(templateObject, nullptr);
|
||||
if (!res || !res->init(alloc, obj))
|
||||
return nullptr;
|
||||
return res;
|
||||
|
|
@ -5862,35 +5804,6 @@ MGetFirstDollarIndex::foldsTo(TempAllocator& alloc)
|
|||
return MConstant::New(alloc, Int32Value(index));
|
||||
}
|
||||
|
||||
MConvertUnboxedObjectToNative*
|
||||
MConvertUnboxedObjectToNative::New(TempAllocator& alloc, MDefinition* obj, ObjectGroup* group)
|
||||
{
|
||||
MConvertUnboxedObjectToNative* res = new(alloc) MConvertUnboxedObjectToNative(obj, group);
|
||||
|
||||
ObjectGroup* nativeGroup = group->unboxedLayout().nativeGroup();
|
||||
|
||||
// Make a new type set for the result of this instruction which replaces
|
||||
// the input group with the native group we will convert it to.
|
||||
TemporaryTypeSet* types = obj->resultTypeSet();
|
||||
if (types && !types->unknownObject()) {
|
||||
TemporaryTypeSet* newTypes = types->cloneWithoutObjects(alloc.lifoAlloc());
|
||||
if (newTypes) {
|
||||
for (size_t i = 0; i < types->getObjectCount(); i++) {
|
||||
TypeSet::ObjectKey* key = types->getObject(i);
|
||||
if (!key)
|
||||
continue;
|
||||
if (key->unknownProperties() || !key->isGroup() || key->group() != group)
|
||||
newTypes->addType(TypeSet::ObjectType(key), alloc.lifoAlloc());
|
||||
else
|
||||
newTypes->addType(TypeSet::ObjectType(nativeGroup), alloc.lifoAlloc());
|
||||
}
|
||||
res->setResultTypeSet(newTypes);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool
|
||||
jit::ElementAccessIsDenseNative(CompilerConstraintList* constraints,
|
||||
MDefinition* obj, MDefinition* id)
|
||||
|
|
@ -5945,8 +5858,6 @@ jit::UnboxedArrayElementType(CompilerConstraintList* constraints, MDefinition* o
|
|||
elementType = layout.elementType();
|
||||
else
|
||||
return JSVAL_TYPE_MAGIC;
|
||||
|
||||
key->watchStateChangeForUnboxedConvertedToNative(constraints);
|
||||
}
|
||||
|
||||
return elementType;
|
||||
|
|
@ -6579,23 +6490,6 @@ jit::PropertyWriteNeedsTypeBarrier(TempAllocator& alloc, CompilerConstraintList*
|
|||
}
|
||||
}
|
||||
|
||||
// Perform additional filtering to make sure that any unboxed property
|
||||
// being written can accommodate the value.
|
||||
for (size_t i = 0; i < types->getObjectCount(); i++) {
|
||||
TypeSet::ObjectKey* key = types->getObject(i);
|
||||
if (key && key->isGroup() && key->group()->maybeUnboxedLayout()) {
|
||||
const UnboxedLayout& layout = key->group()->unboxedLayout();
|
||||
if (name) {
|
||||
const UnboxedLayout::Property* property = layout.lookup(name);
|
||||
if (property && !CanStoreUnboxedType(alloc, property->type, *pvalue))
|
||||
return true;
|
||||
} else {
|
||||
if (layout.isArray() && !CanStoreUnboxedType(alloc, layout.elementType(), *pvalue))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
return false;
|
||||
|
||||
|
|
@ -6626,17 +6520,6 @@ jit::PropertyWriteNeedsTypeBarrier(TempAllocator& alloc, CompilerConstraintList*
|
|||
|
||||
MOZ_ASSERT(excluded);
|
||||
|
||||
// If the excluded object is a group with an unboxed layout, make sure it
|
||||
// does not have a corresponding native group. Objects with the native
|
||||
// group might appear even though they are not in the type set.
|
||||
if (excluded->isGroup()) {
|
||||
if (UnboxedLayout* layout = excluded->group()->maybeUnboxedLayout()) {
|
||||
if (layout->nativeGroup())
|
||||
return true;
|
||||
excluded->watchStateChangeForUnboxedConvertedToNative(constraints);
|
||||
}
|
||||
}
|
||||
|
||||
*pobj = AddGroupGuard(alloc, current, *pobj, excluded, /* bailOnEquality = */ true);
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
131
js/src/jit/MIR.h
131
js/src/jit/MIR.h
|
|
@ -30,7 +30,6 @@
|
|||
#include "vm/EnvironmentObject.h"
|
||||
#include "vm/SharedMem.h"
|
||||
#include "vm/TypedArrayCommon.h"
|
||||
#include "vm/UnboxedObject.h"
|
||||
|
||||
// Undo windows.h damage on Win64
|
||||
#undef MemoryBarrier
|
||||
|
|
@ -9742,59 +9741,6 @@ class MStoreUnboxedString
|
|||
ALLOW_CLONE(MStoreUnboxedString)
|
||||
};
|
||||
|
||||
// Passes through an object, after ensuring it is converted from an unboxed
|
||||
// object to a native representation.
|
||||
class MConvertUnboxedObjectToNative
|
||||
: public MUnaryInstruction,
|
||||
public SingleObjectPolicy::Data
|
||||
{
|
||||
CompilerObjectGroup group_;
|
||||
|
||||
explicit MConvertUnboxedObjectToNative(MDefinition* obj, ObjectGroup* group)
|
||||
: MUnaryInstruction(obj),
|
||||
group_(group)
|
||||
{
|
||||
setGuard();
|
||||
setMovable();
|
||||
setResultType(MIRType::Object);
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(ConvertUnboxedObjectToNative)
|
||||
NAMED_OPERANDS((0, object))
|
||||
|
||||
static MConvertUnboxedObjectToNative* New(TempAllocator& alloc, MDefinition* obj,
|
||||
ObjectGroup* group);
|
||||
|
||||
ObjectGroup* group() const {
|
||||
return group_;
|
||||
}
|
||||
bool congruentTo(const MDefinition* ins) const override {
|
||||
if (!congruentIfOperandsEqual(ins))
|
||||
return false;
|
||||
return ins->toConvertUnboxedObjectToNative()->group() == group();
|
||||
}
|
||||
AliasSet getAliasSet() const override {
|
||||
// This instruction can read and write to all parts of the object, but
|
||||
// is marked as non-effectful so it can be consolidated by LICM and GVN
|
||||
// and avoid inhibiting other optimizations.
|
||||
//
|
||||
// This is valid to do because when unboxed objects might have a native
|
||||
// group they can be converted to, we do not optimize accesses to the
|
||||
// unboxed objects and do not guard on their group or shape (other than
|
||||
// in this opcode).
|
||||
//
|
||||
// Later accesses can assume the object has a native representation
|
||||
// and optimize accordingly. Those accesses cannot be reordered before
|
||||
// this instruction, however. This is prevented by chaining this
|
||||
// instruction with the object itself, in the same way as MBoundsCheck.
|
||||
return AliasSet::None();
|
||||
}
|
||||
bool appendRoots(MRootList& roots) const override {
|
||||
return roots.append(group_);
|
||||
}
|
||||
};
|
||||
|
||||
// Array.prototype.pop or Array.prototype.shift on a dense array.
|
||||
class MArrayPopShift
|
||||
: public MUnaryInstruction,
|
||||
|
|
@ -11174,11 +11120,6 @@ class MGuardShape
|
|||
setMovable();
|
||||
setResultType(MIRType::Object);
|
||||
setResultTypeSet(obj->resultTypeSet());
|
||||
|
||||
// Disallow guarding on unboxed object shapes. The group is better to
|
||||
// guard on, and guarding on the shape can interact badly with
|
||||
// MConvertUnboxedObjectToNative.
|
||||
MOZ_ASSERT(shape->getObjectClass() != &UnboxedPlainObject::class_);
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -11273,11 +11214,6 @@ class MGuardObjectGroup
|
|||
setGuard();
|
||||
setMovable();
|
||||
setResultType(MIRType::Object);
|
||||
|
||||
// Unboxed groups which might be converted to natives can't be guarded
|
||||
// on, due to MConvertUnboxedObjectToNative.
|
||||
MOZ_ASSERT_IF(group->maybeUnboxedLayoutDontCheckGeneration(),
|
||||
!group->unboxedLayoutDontCheckGeneration().nativeGroup());
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -11386,73 +11322,6 @@ class MGuardClass
|
|||
ALLOW_CLONE(MGuardClass)
|
||||
};
|
||||
|
||||
// Guard on the presence or absence of an unboxed object's expando.
|
||||
class MGuardUnboxedExpando
|
||||
: public MUnaryInstruction,
|
||||
public SingleObjectPolicy::Data
|
||||
{
|
||||
bool requireExpando_;
|
||||
BailoutKind bailoutKind_;
|
||||
|
||||
MGuardUnboxedExpando(MDefinition* obj, bool requireExpando, BailoutKind bailoutKind)
|
||||
: MUnaryInstruction(obj),
|
||||
requireExpando_(requireExpando),
|
||||
bailoutKind_(bailoutKind)
|
||||
{
|
||||
setGuard();
|
||||
setMovable();
|
||||
setResultType(MIRType::Object);
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(GuardUnboxedExpando)
|
||||
TRIVIAL_NEW_WRAPPERS
|
||||
NAMED_OPERANDS((0, object))
|
||||
|
||||
bool requireExpando() const {
|
||||
return requireExpando_;
|
||||
}
|
||||
BailoutKind bailoutKind() const {
|
||||
return bailoutKind_;
|
||||
}
|
||||
bool congruentTo(const MDefinition* ins) const override {
|
||||
if (!congruentIfOperandsEqual(ins))
|
||||
return false;
|
||||
if (requireExpando() != ins->toGuardUnboxedExpando()->requireExpando())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
AliasSet getAliasSet() const override {
|
||||
return AliasSet::Load(AliasSet::ObjectFields);
|
||||
}
|
||||
};
|
||||
|
||||
// Load an unboxed plain object's expando.
|
||||
class MLoadUnboxedExpando
|
||||
: public MUnaryInstruction,
|
||||
public SingleObjectPolicy::Data
|
||||
{
|
||||
private:
|
||||
explicit MLoadUnboxedExpando(MDefinition* object)
|
||||
: MUnaryInstruction(object)
|
||||
{
|
||||
setResultType(MIRType::Object);
|
||||
setMovable();
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(LoadUnboxedExpando)
|
||||
TRIVIAL_NEW_WRAPPERS
|
||||
NAMED_OPERANDS((0, object))
|
||||
|
||||
bool congruentTo(const MDefinition* ins) const override {
|
||||
return congruentIfOperandsEqual(ins);
|
||||
}
|
||||
AliasSet getAliasSet() const override {
|
||||
return AliasSet::Load(AliasSet::ObjectFields);
|
||||
}
|
||||
};
|
||||
|
||||
// Load from vp[slot] (slots that are not inline in an object).
|
||||
class MLoadSlot
|
||||
: public MUnaryInstruction,
|
||||
|
|
|
|||
|
|
@ -187,8 +187,6 @@ namespace jit {
|
|||
_(GuardObjectGroup) \
|
||||
_(GuardObjectIdentity) \
|
||||
_(GuardClass) \
|
||||
_(GuardUnboxedExpando) \
|
||||
_(LoadUnboxedExpando) \
|
||||
_(ArrayLength) \
|
||||
_(SetArrayLength) \
|
||||
_(GetNextEntryForIterator) \
|
||||
|
|
@ -219,7 +217,6 @@ namespace jit {
|
|||
_(StoreUnboxedScalar) \
|
||||
_(StoreUnboxedObjectOrNull) \
|
||||
_(StoreUnboxedString) \
|
||||
_(ConvertUnboxedObjectToNative) \
|
||||
_(ArrayPopShift) \
|
||||
_(ArrayPush) \
|
||||
_(ArraySlice) \
|
||||
|
|
|
|||
|
|
@ -5891,22 +5891,6 @@ class LStoreUnboxedPointer : public LInstructionHelper<0, 3, 0>
|
|||
}
|
||||
};
|
||||
|
||||
// If necessary, convert an unboxed object in a particular group to its native
|
||||
// representation.
|
||||
class LConvertUnboxedObjectToNative : public LInstructionHelper<0, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(ConvertUnboxedObjectToNative)
|
||||
|
||||
explicit LConvertUnboxedObjectToNative(const LAllocation& object) {
|
||||
setOperand(0, object);
|
||||
}
|
||||
|
||||
MConvertUnboxedObjectToNative* mir() {
|
||||
return mir_->toConvertUnboxedObjectToNative();
|
||||
}
|
||||
};
|
||||
|
||||
class LArrayPopShiftV : public LInstructionHelper<BOX_PIECES, 1, 2>
|
||||
{
|
||||
public:
|
||||
|
|
@ -7429,38 +7413,6 @@ class LGuardReceiverPolymorphic : public LInstructionHelper<0, 1, 1>
|
|||
}
|
||||
};
|
||||
|
||||
class LGuardUnboxedExpando : public LInstructionHelper<0, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(GuardUnboxedExpando)
|
||||
|
||||
explicit LGuardUnboxedExpando(const LAllocation& in) {
|
||||
setOperand(0, in);
|
||||
}
|
||||
const LAllocation* object() {
|
||||
return getOperand(0);
|
||||
}
|
||||
const MGuardUnboxedExpando* mir() const {
|
||||
return mir_->toGuardUnboxedExpando();
|
||||
}
|
||||
};
|
||||
|
||||
class LLoadUnboxedExpando : public LInstructionHelper<1, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(LoadUnboxedExpando)
|
||||
|
||||
explicit LLoadUnboxedExpando(const LAllocation& in) {
|
||||
setOperand(0, in);
|
||||
}
|
||||
const LAllocation* object() {
|
||||
return getOperand(0);
|
||||
}
|
||||
const MLoadUnboxedExpando* mir() const {
|
||||
return mir_->toLoadUnboxedExpando();
|
||||
}
|
||||
};
|
||||
|
||||
// Guard that a value is in a TypeSet.
|
||||
class LTypeBarrierV : public LInstructionHelper<0, BOX_PIECES, 1>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -258,8 +258,6 @@
|
|||
_(GuardObjectGroup) \
|
||||
_(GuardObjectIdentity) \
|
||||
_(GuardClass) \
|
||||
_(GuardUnboxedExpando) \
|
||||
_(LoadUnboxedExpando) \
|
||||
_(TypeBarrierV) \
|
||||
_(TypeBarrierO) \
|
||||
_(MonitorTypes) \
|
||||
|
|
@ -287,7 +285,6 @@
|
|||
_(StoreElementT) \
|
||||
_(StoreUnboxedScalar) \
|
||||
_(StoreUnboxedPointer) \
|
||||
_(ConvertUnboxedObjectToNative) \
|
||||
_(ArrayPopShiftV) \
|
||||
_(ArrayPopShiftT) \
|
||||
_(ArrayPushV) \
|
||||
|
|
|
|||
|
|
@ -1995,17 +1995,6 @@ TypeSet::ObjectKey::watchStateChangeForTypedArrayData(CompilerConstraintList* co
|
|||
ConstraintDataFreezeObjectForTypedArrayData(tarray)));
|
||||
}
|
||||
|
||||
void
|
||||
TypeSet::ObjectKey::watchStateChangeForUnboxedConvertedToNative(CompilerConstraintList* constraints)
|
||||
{
|
||||
HeapTypeSetKey objectProperty = property(JSID_EMPTY);
|
||||
LifoAlloc* alloc = constraints->alloc();
|
||||
|
||||
typedef CompilerConstraintInstance<ConstraintDataFreezeObjectForUnboxedConvertedToNative> T;
|
||||
constraints->add(alloc->new_<T>(alloc, objectProperty,
|
||||
ConstraintDataFreezeObjectForUnboxedConvertedToNative()));
|
||||
}
|
||||
|
||||
static void
|
||||
ObjectStateChange(ExclusiveContext* cxArg, ObjectGroup* group, bool markingUnknown)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -262,7 +262,6 @@ class TypeSet
|
|||
bool hasStableClassAndProto(CompilerConstraintList* constraints);
|
||||
void watchStateChangeForInlinedCall(CompilerConstraintList* constraints);
|
||||
void watchStateChangeForTypedArrayData(CompilerConstraintList* constraints);
|
||||
void watchStateChangeForUnboxedConvertedToNative(CompilerConstraintList* constraints);
|
||||
HeapTypeSetKey property(jsid id);
|
||||
void ensureTrackedProperty(JSContext* cx, jsid id);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue