зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1647250 - Fix MArrayLength to check for non-int32 array lengths in Warp. r=evilpie
Differential Revision: https://phabricator.services.mozilla.com/D81670
This commit is contained in:
Родитель
8ad6c00a5a
Коммит
ac180368d0
|
@ -0,0 +1,10 @@
|
|||
function f(arr, len) {
|
||||
for (var i = 0; i < 2000; i++) {
|
||||
assertEq(arr.length, len);
|
||||
}
|
||||
}
|
||||
var arr = [0];
|
||||
f(arr, 1);
|
||||
|
||||
arr.length = 0xffff_ffff;
|
||||
f(arr, 0xffff_ffff);
|
|
@ -2001,6 +2001,7 @@ bool jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfoArg) {
|
|||
case Bailout_Debugger:
|
||||
case Bailout_SpecificAtomGuard:
|
||||
case Bailout_SpecificSymbolGuard:
|
||||
case Bailout_NonInt32ArrayLength:
|
||||
// Do nothing.
|
||||
break;
|
||||
|
||||
|
|
|
@ -7640,8 +7640,19 @@ void CodeGenerator::visitArrowNewTarget(LArrowNewTarget* lir) {
|
|||
}
|
||||
|
||||
void CodeGenerator::visitArrayLength(LArrayLength* lir) {
|
||||
Address length(ToRegister(lir->elements()), ObjectElements::offsetOfLength());
|
||||
masm.load32(length, ToRegister(lir->output()));
|
||||
Register elements = ToRegister(lir->elements());
|
||||
Register output = ToRegister(lir->output());
|
||||
|
||||
Address length(elements, ObjectElements::offsetOfLength());
|
||||
masm.load32(length, output);
|
||||
|
||||
// IonBuilder relies on TI knowing the length fits in int32, but Warp needs to
|
||||
// check this dynamically.
|
||||
if (JitOptions.warpBuilder) {
|
||||
Label bail;
|
||||
masm.branchTest32(Assembler::Signed, output, output, &bail);
|
||||
bailoutFrom(&bail, lir->snapshot());
|
||||
}
|
||||
}
|
||||
|
||||
static void SetLengthFromIndex(MacroAssembler& masm, const LAllocation* index,
|
||||
|
|
|
@ -144,6 +144,9 @@ enum BailoutKind {
|
|||
// We hit this code for the first time.
|
||||
Bailout_FirstExecution,
|
||||
|
||||
// Array length did not fit in int32.
|
||||
Bailout_NonInt32ArrayLength,
|
||||
|
||||
// END Normal bailouts
|
||||
|
||||
// Bailouts caused by invalid assumptions based on Baseline code.
|
||||
|
@ -246,6 +249,8 @@ inline const char* BailoutKindString(BailoutKind kind) {
|
|||
return "Bailout_Debugger";
|
||||
case Bailout_FirstExecution:
|
||||
return "Bailout_FirstExecution";
|
||||
case Bailout_NonInt32ArrayLength:
|
||||
return "Bailout_NonInt32ArrayLength";
|
||||
|
||||
// Bailouts caused by invalid assumptions.
|
||||
case Bailout_OverflowInvalidate:
|
||||
|
|
|
@ -2996,7 +2996,11 @@ void LIRGenerator::visitPostWriteElementBarrier(MPostWriteElementBarrier* ins) {
|
|||
|
||||
void LIRGenerator::visitArrayLength(MArrayLength* ins) {
|
||||
MOZ_ASSERT(ins->elements()->type() == MIRType::Elements);
|
||||
define(new (alloc()) LArrayLength(useRegisterAtStart(ins->elements())), ins);
|
||||
auto* lir = new (alloc()) LArrayLength(useRegisterAtStart(ins->elements()));
|
||||
if (JitOptions.warpBuilder) {
|
||||
assignSnapshot(lir, Bailout_NonInt32ArrayLength);
|
||||
}
|
||||
define(lir, ins);
|
||||
}
|
||||
|
||||
void LIRGenerator::visitSetArrayLength(MSetArrayLength* ins) {
|
||||
|
|
|
@ -1769,10 +1769,12 @@ void MLoadDataViewElement::computeRange(TempAllocator& alloc) {
|
|||
}
|
||||
|
||||
void MArrayLength::computeRange(TempAllocator& alloc) {
|
||||
// Array lengths can go up to UINT32_MAX, but we only create MArrayLength
|
||||
// Array lengths can go up to UINT32_MAX. IonBuilder only creates MArrayLength
|
||||
// nodes when the value is known to be int32 (see the
|
||||
// OBJECT_FLAG_LENGTH_OVERFLOW flag).
|
||||
setRange(Range::NewUInt32Range(alloc, 0, INT32_MAX));
|
||||
// OBJECT_FLAG_LENGTH_OVERFLOW flag). WarpBuilder does a dynamic check and we
|
||||
// have to return the range pre-bailouts, so use UINT32_MAX for Warp.
|
||||
uint32_t max = JitOptions.warpBuilder ? UINT32_MAX : INT32_MAX;
|
||||
setRange(Range::NewUInt32Range(alloc, 0, max));
|
||||
}
|
||||
|
||||
void MInitializedLength::computeRange(TempAllocator& alloc) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче