Bug 1166711 part 2.6 - ScalarReplacement: Replace M{Store,Load}UnboxedObjectOrNull by an offset on the MObjectState. r=bhackett

This commit is contained in:
Nicolas B. Pierron 2015-06-11 14:30:34 +02:00
parent a4b849305e
commit 563e2fe0c1

View File

@ -181,6 +181,8 @@ IsObjectEscaped(MInstruction* ins, JSObject* objDefault)
case MDefinition::Op_LoadUnboxedScalar:
case MDefinition::Op_StoreUnboxedScalar:
case MDefinition::Op_LoadUnboxedObjectOrNull:
case MDefinition::Op_StoreUnboxedObjectOrNull:
// Not escaped if it is the first argument.
if (def->indexOf(*i) != 0) {
JitSpewDef(JitSpew_Escape, "is escaped by\n", def);
@ -295,6 +297,8 @@ class ObjectMemoryView : public MDefinitionVisitorDefaultNoop
void visitLambda(MLambda* ins);
void visitStoreUnboxedScalar(MStoreUnboxedScalar* ins);
void visitLoadUnboxedScalar(MLoadUnboxedScalar* ins);
void visitStoreUnboxedObjectOrNull(MStoreUnboxedObjectOrNull* ins);
void visitLoadUnboxedObjectOrNull(MLoadUnboxedObjectOrNull* ins);
};
const char* ObjectMemoryView::phaseName = "Scalar Replacement of Object";
@ -607,16 +611,21 @@ ObjectMemoryView::visitLambda(MLambda* ins)
ins->setIncompleteObject();
}
size_t
GetOffsetOf(MDefinition* index, Scalar::Type type, int32_t baseOffset)
static size_t
GetOffsetOf(MDefinition* index, size_t width, int32_t baseOffset)
{
int32_t idx = index->toConstant()->value().toInt32();
size_t width = Scalar::byteSize(type);
MOZ_ASSERT(idx >= 0);
MOZ_ASSERT(baseOffset >= 0 && size_t(baseOffset) >= UnboxedPlainObject::offsetOfData());
return idx * width + baseOffset - UnboxedPlainObject::offsetOfData();
}
static size_t
GetOffsetOf(MDefinition* index, Scalar::Type type, int32_t baseOffset)
{
return GetOffsetOf(index, Scalar::byteSize(type), baseOffset);
}
void
ObjectMemoryView::visitStoreUnboxedScalar(MStoreUnboxedScalar* ins)
{
@ -651,6 +660,40 @@ ObjectMemoryView::visitLoadUnboxedScalar(MLoadUnboxedScalar* ins)
ins->block()->discard(ins);
}
void
ObjectMemoryView::visitStoreUnboxedObjectOrNull(MStoreUnboxedObjectOrNull* ins)
{
// Skip stores made on other objects.
if (ins->elements() != obj_)
return;
// Clone the state and update the slot value.
size_t offset = GetOffsetOf(ins->index(), sizeof(uintptr_t), ins->offsetAdjustment());
MOZ_ASSERT(state_->hasOffset(offset));
state_ = BlockState::Copy(alloc_, state_);
state_->setOffset(offset, ins->value());
ins->block()->insertBefore(ins->toInstruction(), state_);
// Remove original instruction.
ins->block()->discard(ins);
}
void
ObjectMemoryView::visitLoadUnboxedObjectOrNull(MLoadUnboxedObjectOrNull* ins)
{
// Skip loads made on other objects.
if (ins->elements() != obj_)
return;
// Replace load by the slot value.
size_t offset = GetOffsetOf(ins->index(), sizeof(uintptr_t), ins->offsetAdjustment());
MOZ_ASSERT(state_->hasOffset(offset));
ins->replaceAllUsesWith(state_->getOffset(offset));
// Remove original instruction.
ins->block()->discard(ins);
}
static bool
IndexOf(MDefinition* ins, int32_t* res)
{