author | André Bargull <andre.bargull@gmail.com> |
Tue, 09 Nov 2021 10:16:46 +0000 | |
changeset 598679 | 5e3fc46b24859b5cc4738dce61ec2df8682962b5 |
parent 598678 | 209297ab2c2fe9ac437cce77b626aaca3579f03f |
child 598680 | 59dbf9d365e5e3fd78383630e897243bba14c6ba |
push id | 152826 |
push user | andre.bargull@gmail.com |
push date | Tue, 09 Nov 2021 10:23:46 +0000 |
treeherder | autoland@5e3fc46b2485 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jandem |
bugs | 1739614 |
milestone | 96.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -13127,21 +13127,19 @@ void CodeGenerator::visitLoadElementV(LL NativeObject::elementsSizeMustNotOverflow(); int32_t offset = ToInt32(load->index()) * sizeof(Value); masm.loadValue(Address(elements, offset), out); } else { masm.loadValue(BaseObjectElementIndex(elements, ToRegister(load->index())), out); } - if (load->mir()->needsHoleCheck()) { - Label testMagic; - masm.branchTestMagic(Assembler::Equal, out, &testMagic); - bailoutFrom(&testMagic, load->snapshot()); - } + Label testMagic; + masm.branchTestMagic(Assembler::Equal, out, &testMagic); + bailoutFrom(&testMagic, load->snapshot()); } void CodeGenerator::visitLoadElementHole(LLoadElementHole* lir) { Register elements = ToRegister(lir->elements()); Register index = ToRegister(lir->index()); Register initLength = ToRegister(lir->initLength()); const ValueOperand out = ToOutValue(lir);
--- a/js/src/jit/IonAnalysis.cpp +++ b/js/src/jit/IonAnalysis.cpp @@ -3876,21 +3876,19 @@ bool jit::FoldLoadsWithUnbox(MIRGenerato // when moving the unbox before a loop. MUnbox* unbox = defUse->toUnbox(); if (unbox->block() != *block) { continue; } MOZ_ASSERT(!IsMagicType(unbox->type())); - // If this is a LoadElement that needs a hole check, we only support - // folding it with a fallible unbox so that we can eliminate the hole - // check. - if (load->isLoadElement() && load->toLoadElement()->needsHoleCheck() && - !unbox->fallible()) { + // If this is a LoadElement, we only support folding it with a fallible + // unbox so that we can eliminate the hole check. + if (load->isLoadElement() && !unbox->fallible()) { continue; } // Combine the load and unbox into a single MIR instruction. if (!graph.alloc().ensureBallast()) { return false; } @@ -3908,17 +3906,17 @@ bool jit::FoldLoadsWithUnbox(MIRGenerato case MDefinition::Opcode::LoadDynamicSlot: { auto* loadIns = load->toLoadDynamicSlot(); replacement = MLoadDynamicSlotAndUnbox::New( graph.alloc(), loadIns->slots(), loadIns->slot(), mode, type); break; } case MDefinition::Opcode::LoadElement: { auto* loadIns = load->toLoadElement(); - MOZ_ASSERT_IF(loadIns->needsHoleCheck(), unbox->fallible()); + MOZ_ASSERT(unbox->fallible()); replacement = MLoadElementAndUnbox::New( graph.alloc(), loadIns->elements(), loadIns->index(), mode, type); break; } default: MOZ_CRASH("Unexpected instruction"); }
--- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -3464,19 +3464,17 @@ void LIRGenerator::visitGuardElementNotH void LIRGenerator::visitLoadElement(MLoadElement* ins) { MOZ_ASSERT(ins->elements()->type() == MIRType::Elements); MOZ_ASSERT(ins->index()->type() == MIRType::Int32); MOZ_ASSERT(ins->type() == MIRType::Value); auto* lir = new (alloc()) LLoadElementV(useRegister(ins->elements()), useRegisterOrConstant(ins->index())); - if (ins->fallible()) { - assignSnapshot(lir, ins->bailoutKind()); - } + assignSnapshot(lir, ins->bailoutKind()); defineBox(lir, ins); } void LIRGenerator::visitLoadElementHole(MLoadElementHole* ins) { MOZ_ASSERT(ins->elements()->type() == MIRType::Elements); MOZ_ASSERT(ins->index()->type() == MIRType::Int32); MOZ_ASSERT(ins->initLength()->type() == MIRType::Int32); MOZ_ASSERT(ins->type() == MIRType::Value);
--- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -6446,53 +6446,38 @@ class MSpectreMaskIndex return congruentIfOperandsEqual(ins); } virtual AliasSet getAliasSet() const override { return AliasSet::None(); } void computeRange(TempAllocator& alloc) override; ALLOW_CLONE(MSpectreMaskIndex) }; -// Load a value from a dense array's element vector and does a hole check if the -// array is not known to be packed. +// Load a value from a dense array's element vector. Bails out if the element is +// a hole. class MLoadElement : public MBinaryInstruction, public NoTypePolicy::Data { - bool needsHoleCheck_; - - MLoadElement(MDefinition* elements, MDefinition* index, bool needsHoleCheck) - : MBinaryInstruction(classOpcode, elements, index), - needsHoleCheck_(needsHoleCheck) { - if (needsHoleCheck) { - // Uses may be optimized away based on this instruction's result - // type. This means it's invalid to DCE this instruction, as we - // have to invalidate when we read a hole. - setGuard(); - } + MLoadElement(MDefinition* elements, MDefinition* index) + : MBinaryInstruction(classOpcode, elements, index) { + // Uses may be optimized away based on this instruction's result + // type. This means it's invalid to DCE this instruction, as we + // have to invalidate when we read a hole. + setGuard(); setResultType(MIRType::Value); setMovable(); MOZ_ASSERT(elements->type() == MIRType::Elements); MOZ_ASSERT(index->type() == MIRType::Int32); } public: INSTRUCTION_HEADER(LoadElement) TRIVIAL_NEW_WRAPPERS NAMED_OPERANDS((0, elements), (1, index)) - bool needsHoleCheck() const { return needsHoleCheck_; } - bool fallible() const { return needsHoleCheck(); } - - bool congruentTo(const MDefinition* ins) const override { - if (!ins->isLoadElement()) { - return false; - } - const MLoadElement* other = ins->toLoadElement(); - if (needsHoleCheck() != other->needsHoleCheck()) { - return false; - } - return congruentIfOperandsEqual(other); + bool congruentTo(const MDefinition* ins) const override { + return congruentIfOperandsEqual(ins); } AliasType mightAlias(const MDefinition* store) const override; MDefinition* foldsTo(TempAllocator& alloc) override; AliasSet getAliasSet() const override { return AliasSet::Load(AliasSet::Element); } ALLOW_CLONE(MLoadElement)
--- a/js/src/jit/WarpCacheIRTranspiler.cpp +++ b/js/src/jit/WarpCacheIRTranspiler.cpp @@ -1730,18 +1730,17 @@ bool WarpCacheIRTranspiler::emitLoadDens auto* elements = MElements::New(alloc(), obj); add(elements); auto* length = MInitializedLength::New(alloc(), elements); add(length); index = addBoundsCheck(index, length); - bool needsHoleCheck = true; - auto* load = MLoadElement::New(alloc(), elements, index, needsHoleCheck); + auto* load = MLoadElement::New(alloc(), elements, index); add(load); pushResult(load); return true; } bool WarpCacheIRTranspiler::emitLoadDenseElementHoleResult( ObjOperandId objId, Int32OperandId indexId) {
--- a/js/src/jit/shared/LIR-shared.h +++ b/js/src/jit/shared/LIR-shared.h @@ -1860,20 +1860,16 @@ class LLoadElementV : public LInstructio LIR_HEADER(LoadElementV) LLoadElementV(const LAllocation& elements, const LAllocation& index) : LInstructionHelper(classOpcode) { setOperand(0, elements); setOperand(1, index); } - const char* extraName() const { - return mir()->needsHoleCheck() ? "HoleCheck" : nullptr; - } - const MLoadElement* mir() const { return mir_->toLoadElement(); } const LAllocation* elements() { return getOperand(0); } const LAllocation* index() { return getOperand(1); } }; // Load a value from an array's elements vector, loading |undefined| if we hit a // hole. Bail out if we get a negative index. class LLoadElementHole : public LInstructionHelper<BOX_PIECES, 3, 0> {