diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index b8e2d6f90ae6..6e2e74f269c7 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -6303,7 +6303,7 @@ MDefinition::AliasType MGuardShape::mightAlias(const MDefinition* store) const { } if (object()->isConstantProto()) { const MDefinition* receiverObject = - object()->toConstantProto()->receiverObject()->skipObjectGuards(); + object()->toConstantProto()->getReceiverObject(); switch (store->op()) { case MDefinition::Opcode::StoreFixedSlot: if (store->toStoreFixedSlot()->object()->skipObjectGuards() == diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 05508405db83..a7acddb1b956 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -9175,11 +9175,19 @@ class MObjectStaticProto : public MUnaryInstruction, } }; -class MConstantProto - : public MBinaryInstruction, - public MixPolicy, ObjectPolicy<1>>::Data { +class MConstantProto : public MUnaryInstruction, + public SingleObjectPolicy::Data { + // NOTE: we're not going to actually use the underlying receiver object for + // anything. This is just here for giving extra information to MGuardShape + // to MGuardShape::mightAlias. Accordingly, we don't take it as an operand, + // but instead just keep a pointer to it. This means we need to ensure it's + // not discarded before we try to access it. If this is discarded, we + // basically just become an MConstant for the object's proto, which is fine. + MDefinition* receiverObject_; + explicit MConstantProto(MDefinition* protoObject, MDefinition* receiverObject) - : MBinaryInstruction(classOpcode, protoObject, receiverObject) { + : MUnaryInstruction(classOpcode, protoObject), + receiverObject_(receiverObject) { MOZ_ASSERT(protoObject->isConstant()); setResultType(MIRType::Object); setMovable(); @@ -9190,17 +9198,24 @@ class MConstantProto public: INSTRUCTION_HEADER(ConstantProto) TRIVIAL_NEW_WRAPPERS - NAMED_OPERANDS((0, protoObject), (1, receiverObject)) + NAMED_OPERANDS((0, protoObject)) HashNumber valueHash() const override; bool congruentTo(const MDefinition* ins) const override { - return ins->isConstantProto() && ins->getOperand(0) == getOperand(0) && - getOperand(1)->skipObjectGuards() == - ins->getOperand(1)->skipObjectGuards(); + const MDefinition* receiverObject = getReceiverObject(); + return congruentIfOperandsEqual(ins) && receiverObject && + receiverObject == ins->toConstantProto()->getReceiverObject(); } AliasSet getAliasSet() const override { return AliasSet::None(); } + + const MDefinition* getReceiverObject() const { + if (receiverObject_->isDiscarded()) { + return nullptr; + } + return receiverObject_->skipObjectGuards(); + } }; // Flips the input's sign bit, independently of the rest of the number's diff --git a/js/src/jit/ScalarReplacement.cpp b/js/src/jit/ScalarReplacement.cpp index bf434dd7d3e6..c95469a2d8b5 100644 --- a/js/src/jit/ScalarReplacement.cpp +++ b/js/src/jit/ScalarReplacement.cpp @@ -932,7 +932,7 @@ void ObjectMemoryView::visitCompare(MCompare* ins) { } void ObjectMemoryView::visitConstantProto(MConstantProto* ins) { - if (ins->receiverObject() != obj_) { + if (ins->getReceiverObject() != obj_) { return; }