Remove unboxed object code from jit, Part 1

This commit is contained in:
wolfbeast 2019-05-16 19:54:19 +00:00 committed by Roy Tam
commit cc936df2e5
15 changed files with 26 additions and 627 deletions

View file

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