mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-05 15:59:45 +00:00
Bug 1687441 part 11 - Add MAdjustDataViewLength. r=anba
The alternative is to add support for MIRType::IntPtr to MSub and MMinMax which seemed more complicated. This also matches the IC code in EmitDataViewBoundsCheck. A later patch will change codegen to branchSubPtr. Depends on D102727 Differential Revision: https://phabricator.services.mozilla.com/D102728
This commit is contained in:
parent
43faccb34b
commit
e72d91e082
@ -1235,6 +1235,24 @@ void CodeGenerator::visitFloat32ToIntegerInt32(LFloat32ToIntegerInt32* lir) {
|
||||
masm.bind(ool->rejoin());
|
||||
}
|
||||
|
||||
void CodeGenerator::visitAdjustDataViewLength(LAdjustDataViewLength* lir) {
|
||||
Register output = ToRegister(lir->output());
|
||||
MOZ_ASSERT(ToRegister(lir->input()) == output);
|
||||
|
||||
uint32_t byteSize = lir->mir()->byteSize();
|
||||
|
||||
#ifdef DEBUG
|
||||
Label ok;
|
||||
masm.branchTest32(Assembler::NotSigned, output, output, &ok);
|
||||
masm.assumeUnreachable("Unexpected negative value in LAdjustDataViewLength");
|
||||
masm.bind(&ok);
|
||||
#endif
|
||||
|
||||
Label bail;
|
||||
masm.branchSub32(Assembler::Signed, Imm32(byteSize - 1), output, &bail);
|
||||
bailoutFrom(&bail, lir->snapshot());
|
||||
}
|
||||
|
||||
void CodeGenerator::emitOOLTestObject(Register objreg,
|
||||
Label* ifEmulatesUndefined,
|
||||
Label* ifDoesntEmulateUndefined,
|
||||
|
@ -2222,6 +2222,15 @@ void LIRGenerator::visitTruncateToInt32(MTruncateToInt32* truncate) {
|
||||
}
|
||||
}
|
||||
|
||||
void LIRGenerator::visitAdjustDataViewLength(MAdjustDataViewLength* ins) {
|
||||
MDefinition* input = ins->input();
|
||||
MOZ_ASSERT(input->type() == MIRType::Int32);
|
||||
|
||||
auto* lir = new (alloc()) LAdjustDataViewLength(useRegisterAtStart(input));
|
||||
assignSnapshot(lir, ins->bailoutKind());
|
||||
defineReuseInput(lir, ins, 0);
|
||||
}
|
||||
|
||||
void LIRGenerator::visitToBigInt(MToBigInt* ins) {
|
||||
MDefinition* opd = ins->input();
|
||||
|
||||
|
@ -3246,10 +3246,7 @@ class MReturnFromCtor : public MBinaryInstruction,
|
||||
class MToFPInstruction : public MUnaryInstruction, public ToDoublePolicy::Data {
|
||||
public:
|
||||
// Types of values which can be converted.
|
||||
enum ConversionKind {
|
||||
NonStringPrimitives,
|
||||
NumbersOnly
|
||||
};
|
||||
enum ConversionKind { NonStringPrimitives, NumbersOnly };
|
||||
|
||||
private:
|
||||
ConversionKind conversion_;
|
||||
@ -3624,6 +3621,39 @@ class MWasmAnyRefFromJSObject : public MUnaryInstruction,
|
||||
AliasSet getAliasSet() const override { return AliasSet::None(); }
|
||||
};
|
||||
|
||||
// Subtracts (byteSize - 1) from the input value. Bails out if the result is
|
||||
// negative. This is used to implement bounds checks for DataView accesses.
|
||||
class MAdjustDataViewLength : public MUnaryInstruction,
|
||||
public NoTypePolicy::Data {
|
||||
const uint32_t byteSize_;
|
||||
|
||||
MAdjustDataViewLength(MDefinition* input, uint32_t byteSize)
|
||||
: MUnaryInstruction(classOpcode, input), byteSize_(byteSize) {
|
||||
MOZ_ASSERT(input->type() == MIRType::Int32);
|
||||
MOZ_ASSERT(byteSize > 1);
|
||||
setResultType(MIRType::Int32);
|
||||
setMovable();
|
||||
setGuard();
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(AdjustDataViewLength)
|
||||
TRIVIAL_NEW_WRAPPERS
|
||||
|
||||
uint32_t byteSize() const { return byteSize_; }
|
||||
|
||||
bool congruentTo(const MDefinition* ins) const override {
|
||||
if (!ins->isAdjustDataViewLength()) {
|
||||
return false;
|
||||
}
|
||||
if (ins->toAdjustDataViewLength()->byteSize() != byteSize()) {
|
||||
return false;
|
||||
}
|
||||
return congruentIfOperandsEqual(ins);
|
||||
}
|
||||
AliasSet getAliasSet() const override { return AliasSet::None(); }
|
||||
};
|
||||
|
||||
class MInt64ToFloatingPoint : public MUnaryInstruction,
|
||||
public NoTypePolicy::Data {
|
||||
bool isUnsigned_;
|
||||
|
@ -2137,25 +2137,10 @@ void WarpCacheIRTranspiler::addDataViewData(MDefinition* obj, Scalar::Type type,
|
||||
|
||||
// Adjust the length to account for accesses near the end of the dataview.
|
||||
if (size_t byteSize = Scalar::byteSize(type); byteSize > 1) {
|
||||
// To ensure |0 <= offset && offset + byteSize <= length|, we can either
|
||||
// emit |BoundsCheck(offset, length)| followed by
|
||||
// |BoundsCheck(offset + (byteSize - 1), length)|, or alternatively emit
|
||||
// |BoundsCheck(offset, Max(length - (byteSize - 1), 0))|. The latter should
|
||||
// result in faster code when LICM moves the length adjustment and also
|
||||
// ensures Spectre index masking occurs after all bounds checks.
|
||||
|
||||
auto* byteSizeMinusOne = MConstant::New(alloc(), Int32Value(byteSize - 1));
|
||||
add(byteSizeMinusOne);
|
||||
|
||||
length = MSub::New(alloc(), length, byteSizeMinusOne, MIRType::Int32);
|
||||
length->toSub()->setTruncateKind(TruncateKind::Truncate);
|
||||
add(length);
|
||||
|
||||
// |length| mustn't be negative for MBoundsCheck.
|
||||
auto* zero = MConstant::New(alloc(), Int32Value(0));
|
||||
add(zero);
|
||||
|
||||
length = MMinMax::New(alloc(), length, zero, MIRType::Int32, true);
|
||||
// To ensure |0 <= offset && offset + byteSize <= length|, first adjust the
|
||||
// length by subtracting |byteSize - 1| (bailing out if that becomes
|
||||
// negative).
|
||||
length = MAdjustDataViewLength::New(alloc(), length, byteSize);
|
||||
add(length);
|
||||
}
|
||||
|
||||
|
@ -5601,6 +5601,20 @@ class LRest : public LCallInstructionHelper<1, 1, 3> {
|
||||
MRest* mir() const { return mir_->toRest(); }
|
||||
};
|
||||
|
||||
class LAdjustDataViewLength : public LInstructionHelper<1, 1, 0> {
|
||||
public:
|
||||
LIR_HEADER(AdjustDataViewLength)
|
||||
|
||||
explicit LAdjustDataViewLength(const LAllocation& input)
|
||||
: LInstructionHelper(classOpcode) {
|
||||
setOperand(0, input);
|
||||
}
|
||||
|
||||
const MAdjustDataViewLength* mir() const {
|
||||
return mir_->toAdjustDataViewLength();
|
||||
}
|
||||
};
|
||||
|
||||
// Convert a Boolean to an Int64, following ToBigInt.
|
||||
class LBooleanToInt64 : public LInstructionHelper<INT64_PIECES, 1, 0> {
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user