Commit 1eac4b82 authored by André Bargull's avatar André Bargull
Browse files

Bug 1686692 - Part 18: Remove MLoadElementFromState. r=jandem

Depends on D101887

Differential Revision: https://phabricator.services.mozilla.com/D101889
parent 62cbb303
Loading
Loading
Loading
Loading
+0 −132
Original line number Diff line number Diff line
@@ -13064,138 +13064,6 @@ template void CodeGenerator::visitOutOfLineSwitch(
template void CodeGenerator::visitOutOfLineSwitch(
    OutOfLineSwitch<SwitchTableType::OutOfLine>* jumpTable);
void CodeGenerator::visitLoadElementFromStateV(LLoadElementFromStateV* lir) {
  Register index = ToRegister(lir->index());
  Register temp0 = ToRegister(lir->temp0());
#ifdef JS_NUNBOX32
  Register temp1 = ToRegister(lir->temp1());
#endif
  FloatRegister tempD = ToFloatRegister(lir->tempD());
  ValueOperand out = ToOutValue(lir);
  // For each element, load it and box it.
  MArgumentState* array = lir->array()->toArgumentState();
  Label join;
  // Jump to the code which is loading the element, based on its index.
#if defined(JS_CODEGEN_ARM)
  auto* jumpTable =
      new (alloc()) OutOfLineSwitch<SwitchTableType::Inline>(alloc());
#else
  auto* jumpTable =
      new (alloc()) OutOfLineSwitch<SwitchTableType::OutOfLine>(alloc());
#endif
  {
#if defined(JS_CODEGEN_ARM)
    // Inhibit pools within the following sequence because we are indexing into
    // a pc relative table. The region will have one instruction for ma_ldr, one
    // for breakpoint, and each table case takes one word.
    AutoForbidPoolsAndNops afp(&masm, 1 + 1 + array->numElements());
#endif
    jumpTable->jumpToCodeEntries(masm, index, temp0);
    // Add table entries if the table is inlined.
    for (size_t i = 0, e = array->numElements(); i < e; i++) {
      jumpTable->addTableEntry(masm);
    }
  }
  // Add inlined code for loading arguments from where they are allocated.
  for (size_t i = 0, e = array->numElements(); i < e; i++) {
    MDefinition* elem = array->getElement(i);
    mozilla::Maybe<ConstantOrRegister> input;
    jumpTable->addCodeEntry(masm);
    Register typeReg = Register::Invalid();
    const LAllocation* a = lir->getOperand(1 + BOX_PIECES * i);
    if (a->isBogus()) {
      if (elem->type() == MIRType::Null) {
        input.emplace(NullValue());
      } else if (elem->type() == MIRType::Undefined) {
        input.emplace(UndefinedValue());
      } else if (elem->isConstant() && elem->isEmittedAtUses()) {
        input.emplace(elem->toConstant()->toJSValue());
      } else {
        MOZ_CRASH("Unsupported element constant allocation.");
      }
    } else if (a->isMemory()) {
      if (elem->type() == MIRType::Double) {
        masm.loadDouble(ToAddress(a), tempD);
        input.emplace(TypedOrValueRegister(elem->type(), AnyRegister(tempD)));
      } else if (elem->type() == MIRType::Value) {
        typeReg = temp0;
        masm.loadPtr(ToAddress(a), temp0);
#ifdef JS_PUNBOX64
        input.emplace(TypedOrValueRegister(ValueOperand(temp0)));
#endif
      } else {
        typeReg = temp0;
        size_t width =
            StackSlotAllocator::width(LDefinition::TypeFrom(elem->type()));
        if (width == 4) {
          masm.load32(ToAddress(a), temp0);
        } else if (width == 8) {
          masm.loadPtr(ToAddress(a), temp0);
        } else {
          MOZ_CRASH("Unsupported load size");
        }
        input.emplace(TypedOrValueRegister(elem->type(), AnyRegister(typeReg)));
      }
    } else if (a->isGeneralReg()) {
      typeReg = ToRegister(a);
#ifdef JS_PUNBOX64
      if (elem->type() != MIRType::Value) {
        input.emplace(TypedOrValueRegister(elem->type(), AnyRegister(typeReg)));
      } else {
        input.emplace(TypedOrValueRegister(ValueOperand(typeReg)));
      }
#else
      if (elem->type() != MIRType::Value) {
        input.emplace(TypedOrValueRegister(elem->type(), AnyRegister(typeReg)));
      }
#endif
    } else if (a->isFloatReg()) {
      input.emplace(
          TypedOrValueRegister(elem->type(), AnyRegister(ToFloatRegister(a))));
    } else if (a->isConstantValue()) {
      input.emplace(a->toConstant()->toJSValue());
    } else {
      MOZ_CRASH("Unsupported element allocation.");
    }
#ifdef JS_NUNBOX32
    if (elem->type() == MIRType::Value) {
      static_assert(TYPE_INDEX == 0, "Unexpected type allocation index");
      static_assert(PAYLOAD_INDEX == 1, "Unexpected payload allocation index");
      const LAllocation* a1 = lir->getOperand(1 + BOX_PIECES * i + 1);
      MOZ_ASSERT(!a1->isBogus());
      MOZ_ASSERT(typeReg != Register::Invalid());
      if (a1->isMemory()) {
        masm.loadPtr(ToAddress(a1), temp1);
        input.emplace(TypedOrValueRegister(ValueOperand(typeReg, temp1)));
      } else if (a1->isGeneralReg()) {
        input.emplace(
            TypedOrValueRegister(ValueOperand(typeReg, ToRegister(a1))));
      } else {
        MOZ_CRASH("Unsupported Value allocation.");
      }
    } else {
      MOZ_ASSERT(lir->getOperand(1 + BOX_PIECES * i + 1)->isBogus());
    }
#endif
    masm.moveValue(input.ref(), out);
    // For the last entry, fall-through.
    if (i + 1 < e) {
      masm.jump(&join);
    }
  }
  addOutOfLineCode(jumpTable, lir->mir());
  masm.bind(&join);
}
template <typename T>
static inline void StoreToTypedArray(MacroAssembler& masm,
                                     Scalar::Type writeType,
+0 −73
Original line number Diff line number Diff line
@@ -3187,79 +3187,6 @@ void LIRGenerator::visitLoadElementHole(MLoadElementHole* ins) {
  defineBox(lir, ins);
}

void LIRGenerator::visitLoadElementFromState(MLoadElementFromState* ins) {
  MOZ_ASSERT(ins->index()->type() == MIRType::Int32);

  LDefinition temp1 = LDefinition::BogusTemp();
#ifdef JS_NUNBOX32
  temp1 = temp();
#endif
  MOZ_ASSERT(
      ins->array()->isArgumentState(),
      "LIRGenerator::visitLoadElementFromState: Unsupported state object");
  MArgumentState* array = ins->array()->toArgumentState();

  //   1                                 -- for the index as a register
  //   BOX_PIECES * array->numElements() -- for using as operand all the
  //                                        elements of the inlined array.
  size_t numOperands = 1 + BOX_PIECES * array->numElements();

  auto* lir = allocateVariadic<LLoadElementFromStateV>(numOperands, temp(),
                                                       temp1, tempDouble());
  if (!lir) {
    abort(AbortReason::Alloc, "OOM: LIRGenerator::visitLoadElementFromState");
    return;
  }

  lir->setOperand(0, useRegister(ins->index()));  // index

  for (size_t i = 0, e = array->numElements(); i < e; i++) {
    MDefinition* elem = array->getElement(i);
    if (elem->isConstant() && elem->isEmittedAtUses()) {
      lir->setOperand(1 + BOX_PIECES * i, LAllocation());
#ifdef JS_NUNBOX32
      lir->setOperand(1 + BOX_PIECES * i + 1, LAllocation());
#endif
      continue;
    }

    switch (array->getElement(i)->type()) {
      case MIRType::Value:
        lir->setBoxOperand(1 + BOX_PIECES * i, useBox(elem, LUse::ANY));
        break;
      // Anything which can be boxed:
      case MIRType::Boolean:
      case MIRType::Int32:
      case MIRType::Double:
      case MIRType::Object:
      case MIRType::String:
      case MIRType::Symbol:
      case MIRType::BigInt:
        lir->setOperand(1 + BOX_PIECES * i, use(elem));
#ifdef JS_NUNBOX32
        // Bogus second operand.
        lir->setOperand(1 + BOX_PIECES * i + 1, LAllocation());
#endif
        break;
      case MIRType::Null:
      case MIRType::Undefined:
        // Bogus operand, as these can be inlined.
        lir->setOperand(1 + BOX_PIECES * i, LAllocation());
#ifdef JS_NUNBOX32
        lir->setOperand(1 + BOX_PIECES * i + 1, LAllocation());
#endif
        break;
      default:
        MOZ_CRASH(
            "LIRGenerator::visitLoadElementFromState: Unsupported element "
            "type.");
        return;
    }
  }

  defineBox(lir, ins);
}

void LIRGenerator::visitStoreElement(MStoreElement* ins) {
  MOZ_ASSERT(ins->elements()->type() == MIRType::Elements);
  MOZ_ASSERT(ins->index()->type() == MIRType::Int32);
+0 −19
Original line number Diff line number Diff line
@@ -7992,25 +7992,6 @@ class MStoreElementCommon {
  void setNeedsBarrier() { needsBarrier_ = true; }
};

// This instruction is used to load an element of a non-escaped inlined array.
class MLoadElementFromState : public MBinaryInstruction,
                              public SingleObjectPolicy::Data {
  MLoadElementFromState(MDefinition* array, MDefinition* index)
      : MBinaryInstruction(classOpcode, array, index) {
    MOZ_ASSERT(array->isArgumentState());
    MOZ_ASSERT(index->type() == MIRType::Int32);
    setResultType(MIRType::Value);
    setMovable();
  }

 public:
  INSTRUCTION_HEADER(LoadElementFromState)
  TRIVIAL_NEW_WRAPPERS
  NAMED_OPERANDS((0, array), (1, index));

  AliasSet getAliasSet() const override { return AliasSet::None(); }
};

// Store a value to a dense array slots vector.
class MStoreElement : public MTernaryInstruction,
                      public MStoreElementCommon,
+0 −30
Original line number Diff line number Diff line
@@ -4342,36 +4342,6 @@ class LUnboxObjectOrNull : public LInstructionHelper<1, 1, 0> {
  const LAllocation* input() { return getOperand(0); }
};

// Load an element from a non-allocated entity represented by its state object
// such as ArgumentState. The elements of the state object are set as operands
// of this variadic LIR instruction and inlined in the code generated for this
// instruction.
//
// Each element is represented with BOX_PIECES allocations, even if 1 (typed
// register) or 0 (constants) is enough. In such case, the unused allocations
// would be bogus.
class LLoadElementFromStateV : public LVariadicInstruction<BOX_PIECES, 3> {
 public:
  LIR_HEADER(LoadElementFromStateV)

  LLoadElementFromStateV(uint32_t numOperands, const LDefinition& temp0,
                         const LDefinition& temp1, const LDefinition& tempD)
      : LVariadicInstruction<BOX_PIECES, 3>(classOpcode, numOperands) {
    setTemp(0, temp0);
    setTemp(1, temp1);
    setTemp(2, tempD);
  }

  const MLoadElementFromState* mir() const {
    return mir_->toLoadElementFromState();
  }
  const LAllocation* index() { return getOperand(0); }
  const LDefinition* temp0() { return getTemp(0); }
  const LDefinition* temp1() { return getTemp(1); }
  const LDefinition* tempD() { return getTemp(2); }
  MDefinition* array() { return mir()->array(); }
};

// Store a boxed value to a dense array's element vector.
class LStoreElementV : public LInstructionHelper<0, 2 + BOX_PIECES, 0> {
 public: