From 1fa5c74e78f3bf34add0bf93b56d3f9299f5847d Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Wed, 21 Feb 2018 09:38:33 -0500 Subject: [PATCH 01/21] Bug 1439637 - skew-1.svg fails to pass on new windows 10 hardware. r=dholbert --- layout/reftests/svg/smil/transform/reftest.list | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/reftests/svg/smil/transform/reftest.list b/layout/reftests/svg/smil/transform/reftest.list index 72b8b79998c0..75d2540a807c 100644 --- a/layout/reftests/svg/smil/transform/reftest.list +++ b/layout/reftests/svg/smil/transform/reftest.list @@ -11,7 +11,7 @@ fuzzy-if(skiaContent,7,90) == rotate-angle-4.svg rotate-angle-ref.svg fuzzy-if(skiaContent,7,60) == rotate-angle-5.svg rotate-angle-ref.svg fuzzy(12,27) fuzzy-if(skiaContent,1,180) fuzzy-if(Android,16,3) == scale-1.svg scale-1-ref.svg # bug 981004 == set-transform-1.svg lime.svg -fuzzy-if(winWidget||gtkWidget||OSX,1,27) fuzzy-if(skiaContent,7,1548) == skew-1.svg skew-1-ref.svg # bug 983671, Bug 1260629 +fuzzy-if(winWidget||gtkWidget||OSX,3,27) fuzzy-if(skiaContent,7,1548) == skew-1.svg skew-1-ref.svg # bug 983671, Bug 1260629 == translate-clipPath-1.svg lime.svg == translate-gradient-1.svg lime.svg == translate-pattern-1.svg lime.svg From 77d40712b5ca215e748d9bfd3656e2153c9761cf Mon Sep 17 00:00:00 2001 From: Gijs Kruitbosch Date: Wed, 21 Feb 2018 12:18:40 +0000 Subject: [PATCH 02/21] Bug 1439396, r=mak --HG-- extra : rebase_source : 8d92f674148d4edc985e1c6ae9bfcb91b7ff5403 --- browser/base/content/browser.js | 2 +- .../test/urlbar/browser_removeUnsafeProtocolsFromURLBarPaste.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 2f49eb5e93c2..9b732c5fb5e1 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -6076,7 +6076,7 @@ function stripUnsafeProtocolOnPaste(pasteData) { try { scheme = Services.io.extractScheme(pasteData); } catch (ex) { } - if (scheme != "javascript") { + if (scheme.toLowerCase() != "javascript") { break; } diff --git a/browser/base/content/test/urlbar/browser_removeUnsafeProtocolsFromURLBarPaste.js b/browser/base/content/test/urlbar/browser_removeUnsafeProtocolsFromURLBarPaste.js index 70ecaa048626..94b417eb7435 100644 --- a/browser/base/content/test/urlbar/browser_removeUnsafeProtocolsFromURLBarPaste.js +++ b/browser/base/content/test/urlbar/browser_removeUnsafeProtocolsFromURLBarPaste.js @@ -13,6 +13,8 @@ var pairs = [ ["http://\nexample.com", "http://example.com"], ["http://\nexample.com\n", "http://example.com"], ["data:text/html,hi", "data:text/html,hi"], + ["javaScript:foopy", "foopy"], + ["javaScript:javaScript:alert('hi')", "alert('hi')"], // Nested things get confusing because some things don't parse as URIs: ["javascript:javascript:alert('hi!')", "alert('hi!')"], ["data:data:text/html,hi", "data:data:text/html,hi"], From 4d6cdba649660ea00a820e71b47a4279c9096771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20Kne=C5=BEevi=C4=87?= Date: Wed, 21 Feb 2018 16:10:33 +0100 Subject: [PATCH 03/21] Bug 1433406 - [MIPS32] - Simplify 64-bit arithmetics. r=luke --- .../jit/mips-shared/Assembler-mips-shared.cpp | 16 +- .../jit/mips-shared/Assembler-mips-shared.h | 4 + .../mips-shared/CodeGenerator-mips-shared.cpp | 14 +- .../jit/mips-shared/Lowering-mips-shared.cpp | 10 +- .../MacroAssembler-mips-shared.cpp | 10 +- js/src/jit/mips32/MacroAssembler-mips32-inl.h | 430 ++++++++---------- js/src/jit/mips32/Simulator-mips32.cpp | 24 +- 7 files changed, 248 insertions(+), 260 deletions(-) diff --git a/js/src/jit/mips-shared/Assembler-mips-shared.cpp b/js/src/jit/mips-shared/Assembler-mips-shared.cpp index d7efcf97e6ee..fff5fd00675b 100644 --- a/js/src/jit/mips-shared/Assembler-mips-shared.cpp +++ b/js/src/jit/mips-shared/Assembler-mips-shared.cpp @@ -601,6 +601,20 @@ AssemblerMIPSShared::as_mul(Register rd, Register rs, Register rt) return writeInst(InstReg(op_special2, rs, rt, rd, ff_mul).encode()); } +BufferOffset +AssemblerMIPSShared::as_madd(Register rs, Register rt) +{ + spew("madd %3s,%3s", rs.name(), rt.name()); + return writeInst(InstReg(op_special2, rs, rt, ff_madd).encode()); +} + +BufferOffset +AssemblerMIPSShared::as_maddu(Register rs, Register rt) +{ + spew("maddu %3s,%3s", rs.name(), rt.name()); + return writeInst(InstReg(op_special2, rs, rt, ff_maddu).encode()); +} + // Shift instructions BufferOffset AssemblerMIPSShared::as_sll(Register rd, Register rt, uint16_t sa) @@ -1043,7 +1057,7 @@ AssemblerMIPSShared::as_slti(Register rd, Register rs, int32_t j) BufferOffset AssemblerMIPSShared::as_sltiu(Register rd, Register rs, uint32_t j) { - MOZ_ASSERT(Imm16::IsInUnsignedRange(j)); + MOZ_ASSERT(Imm16::IsInSignedRange(int32_t(j))); spew("sltiu %3s,%3s, 0x%x", rd.name(), rs.name(), j); return writeInst(InstImm(op_sltiu, rs, rd, Imm16(j)).encode()); } diff --git a/js/src/jit/mips-shared/Assembler-mips-shared.h b/js/src/jit/mips-shared/Assembler-mips-shared.h index 88fa6c4f4373..060dc3f7fa3c 100644 --- a/js/src/jit/mips-shared/Assembler-mips-shared.h +++ b/js/src/jit/mips-shared/Assembler-mips-shared.h @@ -397,6 +397,8 @@ enum FunctionField { ff_dsra32 = 63, // special2 encoding of function field. + ff_madd = 0, + ff_maddu = 1, ff_mul = 2, ff_clz = 32, ff_clo = 33, @@ -1019,6 +1021,8 @@ class AssemblerMIPSShared : public AssemblerShared BufferOffset as_div(Register rs, Register rt); BufferOffset as_divu(Register rs, Register rt); BufferOffset as_mul(Register rd, Register rs, Register rt); + BufferOffset as_madd(Register rs, Register rt); + BufferOffset as_maddu(Register rs, Register rt); BufferOffset as_ddiv(Register rs, Register rt); BufferOffset as_ddivu(Register rs, Register rt); diff --git a/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp b/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp index 227f94bea3d6..1ee066aced6c 100644 --- a/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp +++ b/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp @@ -519,8 +519,7 @@ CodeGeneratorMIPSShared::visitMulI64(LMulI64* lir) { const LInt64Allocation lhs = lir->getInt64Operand(LMulI64::Lhs); const LInt64Allocation rhs = lir->getInt64Operand(LMulI64::Rhs); - - MOZ_ASSERT(ToRegister64(lhs) == ToOutRegister64(lir)); + const Register64 output = ToOutRegister64(lir); if (IsConstant(rhs)) { int64_t constant = ToInt64(rhs); @@ -536,6 +535,17 @@ CodeGeneratorMIPSShared::visitMulI64(LMulI64* lir) return; default: if (constant > 0) { + if (mozilla::IsPowerOfTwo(static_cast(constant + 1))) { + masm.move64(ToRegister64(lhs), output); + masm.lshift64(Imm32(FloorLog2(constant + 1)), output); + masm.sub64(ToRegister64(lhs), output); + return; + } else if (mozilla::IsPowerOfTwo(static_cast(constant - 1))) { + masm.move64(ToRegister64(lhs), output); + masm.lshift64(Imm32(FloorLog2(constant - 1u)), output); + masm.add64(ToRegister64(lhs), output); + return; + } // Use shift if constant is power of 2. int32_t shift = mozilla::FloorLog2(constant); if (int64_t(1) << shift == constant) { diff --git a/js/src/jit/mips-shared/Lowering-mips-shared.cpp b/js/src/jit/mips-shared/Lowering-mips-shared.cpp index 33706fde056c..0d2142e71362 100644 --- a/js/src/jit/mips-shared/Lowering-mips-shared.cpp +++ b/js/src/jit/mips-shared/Lowering-mips-shared.cpp @@ -75,6 +75,7 @@ LIRGeneratorMIPSShared::lowerForMulInt64(LMulI64* ins, MMul* mir, MDefinition* l { bool needsTemp = false; bool cannotAliasRhs = false; + bool reuseInput = true; #ifdef JS_CODEGEN_MIPS32 needsTemp = true; @@ -87,6 +88,9 @@ LIRGeneratorMIPSShared::lowerForMulInt64(LMulI64* ins, MMul* mir, MDefinition* l needsTemp = false; if (int64_t(1) << shift == constant) needsTemp = false; + if (mozilla::IsPowerOfTwo(static_cast(constant + 1)) || + mozilla::IsPowerOfTwo(static_cast(constant - 1))) + reuseInput = false; } #endif ins->setInt64Operand(0, useInt64RegisterAtStart(lhs)); @@ -95,8 +99,10 @@ LIRGeneratorMIPSShared::lowerForMulInt64(LMulI64* ins, MMul* mir, MDefinition* l if (needsTemp) ins->setTemp(0, temp()); - - defineInt64ReuseInput(ins, mir, 0); + if(reuseInput) + defineInt64ReuseInput(ins, mir, 0); + else + defineInt64(ins, mir); } template diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp b/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp index d29b05b0b76b..ea790af1a181 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp @@ -290,12 +290,12 @@ MacroAssemblerMIPSShared::ma_xor(Register rd, Register rs, Imm32 imm) void MacroAssemblerMIPSShared::ma_ctz(Register rd, Register rs) { - ma_negu(ScratchRegister, rs); - as_and(rd, ScratchRegister, rs); + as_addiu(ScratchRegister, rs, -1); + as_xor(rd, ScratchRegister, rs); + as_and(rd, rd, ScratchRegister); as_clz(rd, rd); - ma_negu(SecondScratchReg, rd); - ma_addu(SecondScratchReg, Imm32(0x1f)); - as_movn(rd, SecondScratchReg, ScratchRegister); + ma_li(ScratchRegister, Imm32(0x20)); + as_subu(rd, ScratchRegister, rd); } // Arithmetic-based ops. diff --git a/js/src/jit/mips32/MacroAssembler-mips32-inl.h b/js/src/jit/mips32/MacroAssembler-mips32-inl.h index a810a8609a56..914ed1d7c9ba 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h +++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h @@ -192,10 +192,13 @@ MacroAssembler::addPtr(ImmWord imm, Register dest) void MacroAssembler::add64(Register64 src, Register64 dest) { - MOZ_ASSERT(dest.low != src.low); - - as_addu(dest.low, dest.low, src.low); - as_sltu(ScratchRegister, dest.low, src.low); + if (dest.low == src.low) { + as_sltu(ScratchRegister, src.low, zero); + as_addu(dest.low, dest.low, src.low); + } else { + as_addu(dest.low, dest.low, src.low); + as_sltu(ScratchRegister, dest.low, src.low); + } as_addu(dest.high, dest.high, src.high); as_addu(dest.high, dest.high, ScratchRegister); } @@ -203,9 +206,14 @@ MacroAssembler::add64(Register64 src, Register64 dest) void MacroAssembler::add64(Imm32 imm, Register64 dest) { - ma_li(ScratchRegister, imm); - as_addu(dest.low, dest.low, ScratchRegister); - as_sltu(ScratchRegister, dest.low, ScratchRegister); + if (Imm16::IsInSignedRange(imm.value)) { + as_addiu(dest.low, dest.low, imm.value); + as_sltiu(ScratchRegister, dest.low, imm.value); + } else { + ma_li(ScratchRegister, imm); + as_addu(dest.low, dest.low, ScratchRegister); + as_sltu(ScratchRegister, dest.low, ScratchRegister); + } as_addu(dest.high, dest.high, ScratchRegister); } @@ -263,10 +271,16 @@ MacroAssembler::sub64(Register64 src, Register64 dest) void MacroAssembler::sub64(Imm64 imm, Register64 dest) { - ma_li(ScratchRegister, imm.low()); - as_sltu(ScratchRegister, dest.low, ScratchRegister); - as_subu(dest.high, dest.high, ScratchRegister); - ma_subu(dest.low, dest.low, imm.low()); + if (Imm16::IsInSignedRange(imm.low().value) && Imm16::IsInSignedRange(-imm.value)) { + as_sltiu(ScratchRegister, dest.low, imm.low().value); + as_subu(dest.high, dest.high, ScratchRegister); + as_addiu(dest.low, dest.low, -imm.value); + } else { + ma_li(SecondScratchReg, imm.low()); + as_sltu(ScratchRegister, dest.low, SecondScratchReg); + as_subu(dest.high, dest.high, ScratchRegister); + as_subu(dest.low, dest.low, SecondScratchReg); + } ma_subu(dest.high, dest.high, imm.hi()); } @@ -278,40 +292,31 @@ MacroAssembler::mul64(Imm64 imm, const Register64& dest) // + LOW(LOW(dest) * HIGH(imm)) [multiply dest into upper bits] // + HIGH(LOW(dest) * LOW(imm)) [carry] - // HIGH(dest) = LOW(HIGH(dest) * LOW(imm)); - ma_li(ScratchRegister, Imm32(imm.value & LOW_32_MASK)); - as_multu(dest.high, ScratchRegister); - as_mflo(dest.high); - - // mfhi:mflo = LOW(dest) * LOW(imm); - as_multu(dest.low, ScratchRegister); - - // HIGH(dest) += mfhi; - as_mfhi(ScratchRegister); - as_addu(dest.high, dest.high, ScratchRegister); - - if (((imm.value >> 32) & LOW_32_MASK) == 5) { + if (imm.low().value == 5) { // Optimized case for Math.random(). - - // HIGH(dest) += LOW(LOW(dest) * HIGH(imm)); as_sll(ScratchRegister, dest.low, 2); - as_addu(ScratchRegister, ScratchRegister, dest.low); - as_addu(dest.high, dest.high, ScratchRegister); - - // LOW(dest) = mflo; - as_mflo(dest.low); + as_srl(SecondScratchReg, dest.low, 32-2); + as_addu(dest.low, ScratchRegister, dest.low); + as_sltu(ScratchRegister, dest.low, ScratchRegister); + as_addu(ScratchRegister, ScratchRegister, SecondScratchReg); + as_sll(SecondScratchReg, dest.high, 2); + as_addu(SecondScratchReg, SecondScratchReg, dest.high); + as_addu(dest.high, ScratchRegister, SecondScratchReg); } else { - // tmp = mflo - as_mflo(SecondScratchReg); - - // HIGH(dest) += LOW(LOW(dest) * HIGH(imm)); - ma_li(ScratchRegister, Imm32((imm.value >> 32) & LOW_32_MASK)); + // HIGH32 = LOW(HIGH(dest) * LOW(imm)) [multiply imm into upper bits] + // + LOW(LOW(dest) * HIGH(imm)) [multiply dest into upper bits] + ma_li(ScratchRegister, imm.low()); + as_mult(dest.high, ScratchRegister); + ma_li(ScratchRegister, imm.hi()); + as_madd(dest.low, ScratchRegister); + as_mflo(dest.high); + // + HIGH(LOW(dest) * LOW(imm)) [carry] + // LOW32 = LOW(LOW(dest) * LOW(imm)); + ma_li(ScratchRegister, imm.low()); as_multu(dest.low, ScratchRegister); - as_mflo(ScratchRegister); + as_mfhi(ScratchRegister); + as_mflo(dest.low); as_addu(dest.high, dest.high, ScratchRegister); - - // LOW(dest) = tmp; - ma_move(dest.low, SecondScratchReg); } } @@ -323,23 +328,21 @@ MacroAssembler::mul64(Imm64 imm, const Register64& dest, const Register temp) // + LOW(LOW(dest) * HIGH(imm)) [multiply dest into upper bits] // + HIGH(LOW(dest) * LOW(imm)) [carry] - // HIGH(dest) = LOW(HIGH(dest) * LOW(imm)); MOZ_ASSERT(temp != dest.high && temp != dest.low); - ma_li(ScratchRegister, imm.firstHalf()); - as_multu(dest.high, ScratchRegister); + // HIGH32 = LOW(HIGH(dest) * LOW(imm)) [multiply imm into upper bits] + // + LOW(LOW(dest) * HIGH(imm)) [multiply dest into upper bits] + ma_li(ScratchRegister, imm.low()); + as_mult(dest.high, ScratchRegister); + ma_li(temp, imm.hi()); + as_madd(dest.low, temp); as_mflo(dest.high); - - ma_li(ScratchRegister, imm.secondHalf()); + // + HIGH(LOW(dest) * LOW(imm)) [carry] + // LOW32 = LOW(LOW(dest) * LOW(imm)); as_multu(dest.low, ScratchRegister); - as_mflo(temp); - as_addu(temp, dest.high, temp); - - ma_li(ScratchRegister, imm.firstHalf()); - as_multu(dest.low, ScratchRegister); - as_mfhi(dest.high); + as_mfhi(ScratchRegister); as_mflo(dest.low); - as_addu(dest.high, dest.high, temp); + as_addu(dest.high, dest.high, ScratchRegister); } void @@ -350,29 +353,29 @@ MacroAssembler::mul64(const Register64& src, const Register64& dest, const Regis // + LOW(LOW(dest) * HIGH(imm)) [multiply dest into upper bits] // + HIGH(LOW(dest) * LOW(imm)) [carry] - // HIGH(dest) = LOW(HIGH(dest) * LOW(imm)); MOZ_ASSERT(dest != src); MOZ_ASSERT(dest.low != src.high && dest.high != src.low); - as_multu(dest.high, src.low); // (2) + // HIGH32 = LOW(HIGH(dest) * LOW(src)) [multiply src into upper bits] + // + LOW(LOW(dest) * HIGH(src)) [multiply dest into upper bits] + as_mult(dest.high, src.low); + as_madd(dest.low, src.high); as_mflo(dest.high); - as_multu(dest.low, src.high); // (3) - as_mflo(temp); - as_addu(temp, dest.high, temp); - as_multu(dest.low, src.low); // (4) + (1) - as_mfhi(dest.high); + // + HIGH(LOW(dest) * LOW(src)) [carry] + // LOW32 = LOW(LOW(dest) * LOW(src)); + as_multu(dest.low, src.low); + as_mfhi(ScratchRegister); as_mflo(dest.low); - as_addu(dest.high, dest.high, temp); + as_addu(dest.high, dest.high, ScratchRegister); } void MacroAssembler::neg64(Register64 reg) { - ma_li(ScratchRegister, Imm32(1)); - as_movz(ScratchRegister, zero, reg.low); - ma_negu(reg.low, reg.low); - as_addu(reg.high, reg.high, ScratchRegister); - ma_negu(reg.high, reg.high); + as_subu(ScratchRegister, zero, reg.low); + as_sltu(ScratchRegister, reg.low, ScratchRegister); + as_subu(reg.high, zero, reg.high); + as_subu(reg.high, reg.high, ScratchRegister); } void @@ -433,27 +436,24 @@ MacroAssembler::lshift64(Imm32 imm, Register64 dest) void MacroAssembler::lshift64(Register unmaskedShift, Register64 dest) { - Label done, less; + Label done; ScratchRegisterScope shift(*this); ma_and(shift, unmaskedShift, Imm32(0x3f)); ma_b(shift, Imm32(0), &done, Equal); - ma_sll(dest.high, dest.high, shift); - ma_subu(shift, shift, Imm32(32)); - ma_b(shift, Imm32(0), &less, LessThan); - - ma_sll(dest.high, dest.low, shift); - move32(Imm32(0), dest.low); - ma_b(&done); - - bind(&less); - ma_li(SecondScratchReg, Imm32(0)); - as_subu(shift, SecondScratchReg, shift); - ma_srl(SecondScratchReg, dest.low, shift); - as_or(dest.high, dest.high, SecondScratchReg); - ma_and(shift, unmaskedShift, Imm32(0x3f)); + mov(dest.low, SecondScratchReg); ma_sll(dest.low, dest.low, shift); + as_nor(shift, zero, shift); + as_srl(SecondScratchReg, SecondScratchReg, 1); + ma_srl(SecondScratchReg, SecondScratchReg, shift); + ma_and(shift, unmaskedShift, Imm32(0x3f)); + ma_sll(dest.high, dest.high, shift); + as_or(dest.high, dest.high, SecondScratchReg); + + ma_and(SecondScratchReg, shift, Imm32(0x20)); + as_movn(dest.high, dest.low, SecondScratchReg); + as_movn(dest.low, zero, SecondScratchReg); bind(&done); } @@ -478,7 +478,9 @@ MacroAssembler::rshift64(Imm32 imm, Register64 dest) MOZ_ASSERT(0 <= imm.value && imm.value < 64); ScratchRegisterScope scratch(*this); - if (imm.value < 32) { + if (imm.value == 0) { + return; + } else if (imm.value < 32) { as_srl(dest.low, dest.low, imm.value); as_sll(scratch, dest.high, (32 - imm.value)%32); as_or(dest.low, dest.low, scratch); @@ -495,27 +497,23 @@ MacroAssembler::rshift64(Imm32 imm, Register64 dest) void MacroAssembler::rshift64(Register unmaskedShift, Register64 dest) { - Label done, less; + Label done; ScratchRegisterScope shift(*this); ma_and(shift, unmaskedShift, Imm32(0x3f)); ma_b(shift, Imm32(0), &done, Equal); - ma_srl(dest.low, dest.low, shift); - ma_subu(shift, shift, Imm32(32)); - ma_b(shift, Imm32(0), &less, LessThan); - - ma_srl(dest.low, dest.high, shift); - move32(Imm32(0), dest.high); - ma_b(&done); - - bind(&less); - ma_li(SecondScratchReg, Imm32(0)); - as_subu(shift, SecondScratchReg, shift); - ma_sll(SecondScratchReg, dest.high, shift); - as_or(dest.low, dest.low, SecondScratchReg); - ma_and(shift, unmaskedShift, Imm32(0x3f)); + mov(dest.high, SecondScratchReg); ma_srl(dest.high, dest.high, shift); + as_nor(shift, zero, shift); + as_sll(SecondScratchReg, SecondScratchReg, 1); + ma_sll(SecondScratchReg, SecondScratchReg, shift); + ma_and(shift, unmaskedShift, Imm32(0x3f)); + ma_srl(dest.low, dest.low, shift); + as_or(dest.low, dest.low, SecondScratchReg); + ma_and(SecondScratchReg, shift, Imm32(0x20)); + as_movn(dest.low, dest.high, SecondScratchReg); + as_movn(dest.high, zero, SecondScratchReg); bind(&done); } @@ -526,7 +524,9 @@ MacroAssembler::rshift64Arithmetic(Imm32 imm, Register64 dest) MOZ_ASSERT(0 <= imm.value && imm.value < 64); ScratchRegisterScope scratch(*this); - if (imm.value < 32) { + if (imm.value == 0) { + return; + } else if (imm.value < 32) { as_srl(dest.low, dest.low, imm.value); as_sll(scratch, dest.high, (32 - imm.value)%32); as_or(dest.low, dest.low, scratch); @@ -543,27 +543,24 @@ MacroAssembler::rshift64Arithmetic(Imm32 imm, Register64 dest) void MacroAssembler::rshift64Arithmetic(Register unmaskedShift, Register64 dest) { - Label done, less; + Label done; ScratchRegisterScope shift(*this); ma_and(shift, unmaskedShift, Imm32(0x3f)); ma_b(shift, Imm32(0), &done, Equal); - ma_srl(dest.low, dest.low, shift); - ma_subu(shift, shift, Imm32(32)); - ma_b(shift, Imm32(0), &less, LessThan); - - ma_sra(dest.low, dest.high, shift); - as_sra(dest.high, dest.high, 31); - ma_b(&done); - - bind(&less); - ma_li(SecondScratchReg, Imm32(0)); - as_subu(shift, SecondScratchReg, shift); - ma_sll(SecondScratchReg, dest.high, shift); - as_or(dest.low, dest.low, SecondScratchReg); - ma_and(shift, unmaskedShift, Imm32(0x3f)); + mov(dest.high, SecondScratchReg); ma_sra(dest.high, dest.high, shift); + as_nor(shift, zero, shift); + as_sll(SecondScratchReg, SecondScratchReg, 1); + ma_sll(SecondScratchReg, SecondScratchReg, shift); + ma_and(shift, unmaskedShift, Imm32(0x3f)); + ma_srl(dest.low, dest.low, shift); + as_or(dest.low, dest.low, SecondScratchReg); + ma_and(SecondScratchReg, shift, Imm32(0x20)); + as_sra(shift, dest.high, 31); + as_movn(dest.low, dest.high, SecondScratchReg); + as_movn(dest.high, shift, SecondScratchReg); bind(&done); } @@ -610,57 +607,26 @@ MacroAssembler::rotateLeft64(Register shift, Register64 src, Register64 dest, Re MOZ_ASSERT(shift != src.low && shift != src.high); MOZ_ASSERT(temp != InvalidReg); - ScratchRegisterScope shift_value(*this); - Label high, swap, done, zero; - ma_and(shift, shift, Imm32(0x3f)); - ma_b(shift, Imm32(32), &swap, Equal); - ma_b(shift, Imm32(32), &high, GreaterThan); + ScratchRegisterScope scratch(*this); - // high = high << shift | low >> 32 - shift - // low = low << shift | high >> 32 - shift - ma_move(temp, src.high); - ma_sll(dest.high, src.high, shift); - ma_b(shift, Imm32(0), &zero, Equal); - ma_li(SecondScratchReg, Imm32(32)); - as_subu(shift_value, SecondScratchReg, shift); - - ma_srl(SecondScratchReg, src.low, shift_value); - as_or(dest.high, dest.high, SecondScratchReg); - - ma_sll(dest.low, src.low, shift); - ma_srl(SecondScratchReg, temp, shift_value); - as_or(dest.low, dest.low, SecondScratchReg); - ma_b(&done); - - bind(&zero); - ma_move(dest.low, src.low); - ma_move(dest.high, src.high); - ma_b(&done); - - bind(&swap); - ma_move(SecondScratchReg, src.low); - ma_move(dest.low, src.high); - ma_move(dest.high, SecondScratchReg); - ma_b(&done); - // A 32 - 64 shift is a 0 - 32 shift in the other direction. - bind(&high); - ma_li(SecondScratchReg, Imm32(64)); - as_subu(shift_value, SecondScratchReg, shift); - - ma_move(temp, src.high); - ma_srl(dest.high, src.high, shift_value); - ma_li(SecondScratchReg, Imm32(32)); - as_subu(shift_value, SecondScratchReg, shift_value); - ma_sll(SecondScratchReg, src.low, shift_value); - as_or(dest.high, dest.high, SecondScratchReg); - - ma_sll(temp, temp, shift_value); - ma_li(SecondScratchReg, Imm32(64)); - as_subu(shift_value, SecondScratchReg, shift); - ma_srl(dest.low, src.low, shift_value); + ma_and(scratch, shift, Imm32(0x3f)); + as_nor(SecondScratchReg, zero, scratch); + ma_sll(temp, src.low, scratch); + ma_move(scratch, src.low); + as_srl(dest.low, src.high, 1); + ma_srl(dest.low, dest.low, SecondScratchReg); as_or(dest.low, dest.low, temp); - - bind(&done); + ma_move(SecondScratchReg, src.high); + as_srl(dest.high, scratch, 1); + ma_and(scratch, shift, Imm32(0x3f)); + ma_sll(temp, SecondScratchReg, scratch); + as_nor(SecondScratchReg, zero, scratch); + ma_srl(dest.high, dest.high, SecondScratchReg); + as_or(dest.high, dest.high, temp); + ma_and(temp, scratch, Imm32(32)); + as_movn(SecondScratchReg, dest.high, temp); + as_movn(dest.high, dest.low, temp); + as_movn(dest.low, SecondScratchReg, temp); } void @@ -701,62 +667,26 @@ MacroAssembler::rotateRight64(Register shift, Register64 src, Register64 dest, R MOZ_ASSERT(shift != src.low && shift != src.high); MOZ_ASSERT(temp != InvalidReg); - ScratchRegisterScope shift_value(*this); - Label high, swap, done, zero; + ScratchRegisterScope scratch(*this); - ma_and(shift, shift, Imm32(0x3f)); - ma_b(shift, Imm32(32), &swap, Equal); - ma_b(shift, Imm32(32), &high, GreaterThan); - - // high = high >> shift | low << 32 - shift - // low = low >> shift | high << 32 - shift - ma_move(temp, src.high); - ma_srl(dest.high, src.high, shift); - ma_b(shift, Imm32(0), &zero, Equal); - ma_li(SecondScratchReg, Imm32(32)); - as_subu(shift_value, SecondScratchReg, shift); - - ma_sll(SecondScratchReg, src.low, shift_value); - as_or(dest.high, dest.high, SecondScratchReg); - - ma_srl(dest.low, src.low, shift); - - //ma_li(SecondScratchReg, Imm32(32)); - //as_subu(shift_value, SecondScratchReg, shift_value); - ma_sll(SecondScratchReg, temp, shift_value); - as_or(dest.low, dest.low, SecondScratchReg); - - ma_b(&done); - - bind(&zero); - ma_move(dest.low, src.low); - ma_move(dest.high, src.high); - ma_b(&done); - - bind(&swap); - ma_move(SecondScratchReg, src.low); - ma_move(dest.low, src.high); - ma_move(dest.high, SecondScratchReg); - ma_b(&done); - // A 32 - 64 shift is a 0 - 32 shift in the other direction. - bind(&high); - ma_li(SecondScratchReg, Imm32(64)); - as_subu(shift_value, SecondScratchReg, shift); - - ma_move(temp, src.high); - ma_sll(dest.high, src.high, shift_value); - ma_li(SecondScratchReg, Imm32(32)); - as_subu(shift_value, SecondScratchReg, shift_value); - ma_srl(SecondScratchReg, src.low, shift_value); - as_or(dest.high, dest.high, SecondScratchReg); - - ma_srl(temp, temp, shift_value); - ma_li(SecondScratchReg, Imm32(64)); - as_subu(shift_value, SecondScratchReg, shift); - ma_sll(dest.low, src.low, shift_value); + ma_and(scratch, shift, Imm32(0x3f)); + as_nor(SecondScratchReg, zero, scratch); + ma_srl(temp, src.low, scratch); + ma_move(scratch, src.low); + as_sll(dest.low, src.high, 1); + ma_sll(dest.low, dest.low, SecondScratchReg); as_or(dest.low, dest.low, temp); - - bind(&done); + ma_move(SecondScratchReg, src.high); + as_sll(dest.high, scratch, 1); + ma_and(scratch, shift, Imm32(0x3f)); + ma_srl(temp, SecondScratchReg, scratch); + as_nor(SecondScratchReg, zero, scratch); + ma_sll(dest.high, dest.high, SecondScratchReg); + as_or(dest.high, dest.high, temp); + ma_and(temp, scratch, Imm32(32)); + as_movn(SecondScratchReg, dest.high, temp); + as_movn(dest.high, dest.low, temp); + as_movn(dest.low, SecondScratchReg, temp); } template @@ -779,34 +709,22 @@ MacroAssembler::cmp32Set(Condition cond, T1 lhs, T2 rhs, Register dest) void MacroAssembler::clz64(Register64 src, Register dest) { - Label done, low; - - ma_b(src.high, Imm32(0), &low, Equal); - as_clz(dest, src.high); - ma_b(&done); - - bind(&low); - as_clz(dest, src.low); - ma_addu(dest, Imm32(32)); - - bind(&done); + as_clz(ScratchRegister, src.high); + as_clz(SecondScratchReg, src.low); + as_movn(SecondScratchReg, zero, src.high); + as_addu(dest, ScratchRegister, SecondScratchReg); } void MacroAssembler::ctz64(Register64 src, Register dest) { - Label done, high; + as_movz(SecondScratchReg, src.high, src.low); + as_movn(SecondScratchReg, src.low, src.low); + ma_ctz(SecondScratchReg, SecondScratchReg); + ma_li(ScratchRegister, Imm32(0x20)); + as_movn(ScratchRegister, zero, src.low); + as_addu(dest, SecondScratchReg, ScratchRegister); - ma_b(src.low, Imm32(0), &high, Equal); - - ma_ctz(dest, src.low); - ma_b(&done); - - bind(&high); - ma_ctz(dest, src.high); - ma_addu(dest, Imm32(32)); - - bind(&done); } void @@ -816,17 +734,31 @@ MacroAssembler::popcnt64(Register64 src, Register64 dest, Register tmp) MOZ_ASSERT(dest.high != tmp); MOZ_ASSERT(dest.low != dest.high); - if (dest.low != src.high) { - popcnt32(src.low, dest.low, tmp); - popcnt32(src.high, dest.high, tmp); - } else { - MOZ_ASSERT(dest.high != src.high); - popcnt32(src.low, dest.high, tmp); - popcnt32(src.high, dest.low, tmp); - } - - ma_addu(dest.low, dest.high); - move32(Imm32(0), dest.high); + as_srl(tmp, src.low, 1); + as_srl(SecondScratchReg, src.high, 1); + ma_li(ScratchRegister, Imm32(0x55555555)); + as_and(tmp, tmp, ScratchRegister); + as_subu(tmp, src.low, tmp); + as_and(SecondScratchReg, SecondScratchReg, ScratchRegister); + as_subu(SecondScratchReg, src.high, SecondScratchReg); + ma_li(ScratchRegister, Imm32(0x33333333)); + as_and(dest.low, tmp, ScratchRegister); + as_srl(tmp, tmp, 2); + as_and(tmp, tmp, ScratchRegister); + as_addu(tmp, dest.low, tmp); + as_and(dest.high, SecondScratchReg, ScratchRegister); + as_srl(SecondScratchReg, SecondScratchReg, 2); + as_and(SecondScratchReg, SecondScratchReg, ScratchRegister); + as_addu(SecondScratchReg, dest.high, SecondScratchReg); + ma_li(ScratchRegister, Imm32(0x0F0F0F0F)); + as_addu(tmp, SecondScratchReg, tmp); + as_srl(dest.low, tmp, 4); + as_and(dest.low, dest.low, ScratchRegister); + as_and(tmp, tmp, ScratchRegister); + as_addu(dest.low, dest.low, tmp); + ma_mul(dest.low, dest.low, Imm32(0x01010101)); + as_srl(dest.low, dest.low, 24); + ma_move(dest.high, zero); } // =============================================================== @@ -1105,7 +1037,7 @@ MacroAssembler::branchToComputedAddress(const BaseIndex& addr) int32_t shift = Imm32::ShiftOf(addr.scale).value; if (shift) { // 4 instructions : lui ori jr nop - ma_mul(ScratchRegister, addr.index, Imm32(4 * 4)); + as_sll(ScratchRegister, addr.index, 4); as_addu(ScratchRegister, addr.base, ScratchRegister); } else { as_addu(ScratchRegister, addr.base, addr.index); diff --git a/js/src/jit/mips32/Simulator-mips32.cpp b/js/src/jit/mips32/Simulator-mips32.cpp index 14a740a1e6d2..b666bc95c030 100644 --- a/js/src/jit/mips32/Simulator-mips32.cpp +++ b/js/src/jit/mips32/Simulator-mips32.cpp @@ -392,6 +392,8 @@ SimInstruction::instructionType() const case op_special2: switch (functionFieldRaw()) { case ff_mul: + case ff_madd: + case ff_maddu: case ff_clz: return kRegisterType; default: @@ -2651,6 +2653,18 @@ Simulator::configureTypeRegister(SimInstruction* instr, case ff_mul: alu_out = rs_u * rt_u; // Only the lower 32 bits are kept. break; + case ff_mult: + i64hilo = static_cast(rs) * static_cast(rt); + break; + case ff_multu: + u64hilo = static_cast(rs_u) * static_cast(rt_u); + break; + case ff_madd: + i64hilo += static_cast(rs) * static_cast(rt); + break; + case ff_maddu: + u64hilo += static_cast(rs_u) * static_cast(rt_u); + break; case ff_clz: alu_out = rs_u ? __builtin_clz(rs_u) : 32; break; @@ -3204,6 +3218,14 @@ Simulator::decodeTypeRegister(SimInstruction* instr) setRegister(LO, Unpredictable); setRegister(HI, Unpredictable); break; + case ff_madd: + setRegister(LO, getRegister(LO) + static_cast(i64hilo & 0xffffffff)); + setRegister(HI, getRegister(HI) + static_cast(i64hilo >> 32)); + break; + case ff_maddu: + setRegister(LO, getRegister(LO) + static_cast(u64hilo & 0xffffffff)); + setRegister(HI, getRegister(HI) + static_cast(u64hilo >> 32)); + break; default: // For other special2 opcodes we do the default operation. setRegister(rd_reg, alu_out); } @@ -3617,7 +3639,7 @@ Simulator::instructionDecode(SimInstruction* instr) UNSUPPORTED(); } if (!pc_modified_) - setRegister(pc, reinterpret_cast(instr) + SimInstruction::kInstrSize); + setRegister(pc, reinterpret_cast(instr) + SimInstruction::kInstrSize); } void From cbd71d5b84d628a2f9ee989e64bceb1057827863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20Kne=C5=BEevi=C4=87?= Date: Tue, 20 Feb 2018 16:28:24 +0100 Subject: [PATCH 04/21] Bug 1437039 - [MIPS32] - Simplify 64-bit branching. r=lth --- js/src/jit-test/tests/wasm/integer.js | 11 + .../mips-shared/CodeGenerator-mips-shared.cpp | 4 +- js/src/jit/mips32/CodeGenerator-mips32.cpp | 34 +-- js/src/jit/mips32/MacroAssembler-mips32-inl.h | 139 ++++--------- js/src/jit/mips32/MacroAssembler-mips32.cpp | 193 ++++++++++++++++++ js/src/jit/mips32/MacroAssembler-mips32.h | 5 + js/src/wasm/WasmBaselineCompile.cpp | 4 +- 7 files changed, 261 insertions(+), 129 deletions(-) diff --git a/js/src/jit-test/tests/wasm/integer.js b/js/src/jit-test/tests/wasm/integer.js index 2b422fbb79cd..7c53d822520f 100644 --- a/js/src/jit-test/tests/wasm/integer.js +++ b/js/src/jit-test/tests/wasm/integer.js @@ -302,17 +302,28 @@ testComparison64('gt_u', 40, 40, 0); testComparison64('ge_s', 40, 40, 1); testComparison64('ge_u', 40, 40, 1); testComparison64('eq', "0x400012345678", "0x400012345678", 1); +testComparison64('eq', "0x400012345678", "0x500012345678", 0); testComparison64('ne', "0x400012345678", "0x400012345678", 0); testComparison64('ne', "0x400012345678", "0x500012345678", 1); testComparison64('eq', "0xffffffffffffffff", -1, 1); testComparison64('lt_s', "0x8000000012345678", "0x1", 1); +testComparison64('lt_s', "0x1", "0x8000000012345678", 0); testComparison64('lt_u', "0x8000000012345678", "0x1", 0); +testComparison64('lt_u', "0x1", "0x8000000012345678", 1); testComparison64('le_s', -1, 0, 1); +testComparison64('le_s', -1, -1, 1); +testComparison64('le_s', 0, -1, 0); +testComparison64('le_u', -1, 0, 0); testComparison64('le_u', -1, -1, 1); +testComparison64('le_u', 0, -1, 1); testComparison64('gt_s', 1, "0x8000000000000000", 1); +testComparison64('gt_s', "0x8000000000000000", 1, 0); testComparison64('gt_u', 1, "0x8000000000000000", 0); +testComparison64('gt_u', "0x8000000000000000", 1, 1); testComparison64('ge_s', 1, "0x8000000000000000", 1); +testComparison64('ge_s', "0x8000000000000000", 1, 0); testComparison64('ge_u', 1, "0x8000000000000000", 0); +testComparison64('ge_u', "0x8000000000000000", 1, 1); testUnary('i64', 'clz', 40, 58); testUnary('i64', 'clz', "0x8000000000000000", 0); diff --git a/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp b/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp index 1ee066aced6c..83447409ca23 100644 --- a/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp +++ b/js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp @@ -603,7 +603,7 @@ CodeGeneratorMIPSShared::visitDivI(LDivI* ins) masm.move32(Imm32(-1), temp); if (mir->trapOnError()) { Label ok; - masm.ma_b(rhs, temp, &ok, Assembler::NoEqual); + masm.ma_b(rhs, temp, &ok, Assembler::NotEqual); masm.wasmTrap(wasm::Trap::IntegerOverflow, mir->bytecodeOffset()); masm.bind(&ok); } else if (mir->canTruncateOverflow()) { @@ -2235,7 +2235,7 @@ CodeGeneratorMIPSShared::visitUDivOrMod(LUDivOrMod* ins) Label nonZero; masm.ma_b(rhs, rhs, &nonZero, Assembler::NonZero); masm.wasmTrap(wasm::Trap::IntegerDivideByZero, ins->bytecodeOffset()); - masm.bind(&nonZero) + masm.bind(&nonZero); } else { // Infinity|0 == 0 Label notzero; diff --git a/js/src/jit/mips32/CodeGenerator-mips32.cpp b/js/src/jit/mips32/CodeGenerator-mips32.cpp index 3dc37c15cf92..3d39edef7ae7 100644 --- a/js/src/jit/mips32/CodeGenerator-mips32.cpp +++ b/js/src/jit/mips32/CodeGenerator-mips32.cpp @@ -309,19 +309,14 @@ CodeGeneratorMIPS::visitCompareI64(LCompareI64* lir) bool isSigned = mir->compareType() == MCompare::Compare_Int64; Assembler::Condition condition = JSOpToCondition(lir->jsop(), isSigned); - Label done; - masm.move32(Imm32(1), output); if (IsConstant(rhs)) { Imm64 imm = Imm64(ToInt64(rhs)); - masm.branch64(condition, lhsRegs, imm, &done); + masm.cmp64Set(condition, lhsRegs, imm, output); } else { Register64 rhsRegs = ToRegister64(rhs); - masm.branch64(condition, lhsRegs, rhsRegs, &done); + masm.cmp64Set(condition, lhsRegs, rhsRegs, output); } - - masm.move32(Imm32(0), output); - masm.bind(&done); } void @@ -367,22 +362,12 @@ CodeGeneratorMIPS::visitDivOrModI64(LDivOrModI64* lir) MOZ_ASSERT(output == ReturnReg64); - // All inputs are useAtStart for a call instruction. As a result we cannot - // ask for a non-aliasing temp. Using the following to get such a temp. - AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); - regs.take(lhs.low); - regs.take(lhs.high); - if (lhs != rhs) { - regs.take(rhs.low); - regs.take(rhs.high); - } - Register temp = regs.takeAny(); Label done; // Handle divide by zero. if (lir->canBeDivideByZero()) { Label nonZero; - masm.branchTest64(Assembler::NonZero, rhs, rhs, temp, &nonZero); + masm.branchTest64(Assembler::NonZero, rhs, rhs, InvalidReg, &nonZero); masm.wasmTrap(wasm::Trap::IntegerDivideByZero, lir->bytecodeOffset()); masm.bind(&nonZero); } @@ -424,21 +409,10 @@ CodeGeneratorMIPS::visitUDivOrModI64(LUDivOrModI64* lir) MOZ_ASSERT(ToOutRegister64(lir) == ReturnReg64); - // All inputs are useAtStart for a call instruction. As a result we cannot - // ask for a non-aliasing temp. Using the following to get such a temp. - AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); - regs.take(lhs.low); - regs.take(lhs.high); - if (lhs != rhs) { - regs.take(rhs.low); - regs.take(rhs.high); - } - Register temp = regs.takeAny(); - // Prevent divide by zero. if (lir->canBeDivideByZero()) { Label nonZero; - masm.branchTest64(Assembler::NonZero, rhs, rhs, temp, &nonZero); + masm.branchTest64(Assembler::NonZero, rhs, rhs, InvalidReg, &nonZero); masm.wasmTrap(wasm::Trap::IntegerDivideByZero, lir->bytecodeOffset()); masm.bind(&nonZero); } diff --git a/js/src/jit/mips32/MacroAssembler-mips32-inl.h b/js/src/jit/mips32/MacroAssembler-mips32-inl.h index 914ed1d7c9ba..30b5c0e7de98 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h +++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h @@ -793,107 +793,54 @@ MacroAssembler::branch64(Condition cond, const Address& lhs, const Address& rhs, void MacroAssembler::branch64(Condition cond, Register64 lhs, Imm64 val, Label* success, Label* fail) { - bool fallthrough = false; - Label fallthroughLabel; - - if (!fail) { - fail = &fallthroughLabel; - fallthrough = true; + if (val.value == 0) { + switch(cond){ + case Assembler::Equal: + case Assembler::BelowOrEqual: + case Assembler::NotEqual: + case Assembler::Above: + as_or(ScratchRegister, lhs.high, lhs.low); + ma_b(ScratchRegister, ScratchRegister, success, + (cond == Assembler::Equal || + cond == Assembler::BelowOrEqual) ? Assembler::Zero : Assembler::NonZero); + break; + case Assembler::LessThan: + case Assembler::GreaterThanOrEqual: + ma_b(lhs.high, Imm32(0), success, cond); + break; + case Assembler::LessThanOrEqual: + case Assembler::GreaterThan: + as_or(SecondScratchReg, lhs.high, lhs.low); + as_sra(ScratchRegister, lhs.high, 31); + as_sltu(ScratchRegister, ScratchRegister, SecondScratchReg); + ma_b(ScratchRegister, ScratchRegister, success, + (cond == Assembler::LessThanOrEqual) ? Assembler::Zero : Assembler::NonZero); + break; + case Assembler::Below: + // This condition is always false. No branch required. + break; + case Assembler::AboveOrEqual: + ma_b(success); + break; + default: + MOZ_CRASH("Condition code not supported"); + } + return; } - switch(cond) { - case Assembler::Equal: - branch32(Assembler::NotEqual, lhs.low, val.low(), fail); - branch32(Assembler::Equal, lhs.high, val.hi(), success); - if (!fallthrough) - jump(fail); - break; - case Assembler::NotEqual: - branch32(Assembler::NotEqual, lhs.low, val.low(), success); - branch32(Assembler::NotEqual, lhs.high, val.hi(), success); - if (!fallthrough) - jump(fail); - break; - case Assembler::LessThan: - case Assembler::LessThanOrEqual: - case Assembler::GreaterThan: - case Assembler::GreaterThanOrEqual: - case Assembler::Below: - case Assembler::BelowOrEqual: - case Assembler::Above: - case Assembler::AboveOrEqual: { - Assembler::Condition invert_cond = Assembler::InvertCondition(cond); - Assembler::Condition cond1 = Assembler::ConditionWithoutEqual(cond); - Assembler::Condition cond2 = Assembler::ConditionWithoutEqual(invert_cond); - Assembler::Condition cond3 = Assembler::UnsignedCondition(cond); - - ma_b(lhs.high, val.hi(), success, cond1); - ma_b(lhs.high, val.hi(), fail, cond2); - ma_b(lhs.low, val.low(), success, cond3); - if (!fallthrough) - jump(fail); - break; - } - default: - MOZ_CRASH("Condition code not supported"); - break; - } - - if (fallthrough) - bind(fail); + Condition c = ma_cmp64(cond, lhs, val, SecondScratchReg); + ma_b(SecondScratchReg, SecondScratchReg, success, c); + if (fail) + jump(fail); } void MacroAssembler::branch64(Condition cond, Register64 lhs, Register64 rhs, Label* success, Label* fail) { - bool fallthrough = false; - Label fallthroughLabel; - - if (!fail) { - fail = &fallthroughLabel; - fallthrough = true; - } - - switch(cond) { - case Assembler::Equal: - branch32(Assembler::NotEqual, lhs.low, rhs.low, fail); - branch32(Assembler::Equal, lhs.high, rhs.high, success); - if (!fallthrough) - jump(fail); - break; - case Assembler::NotEqual: - branch32(Assembler::NotEqual, lhs.low, rhs.low, success); - branch32(Assembler::NotEqual, lhs.high, rhs.high, success); - if (!fallthrough) - jump(fail); - break; - case Assembler::LessThan: - case Assembler::LessThanOrEqual: - case Assembler::GreaterThan: - case Assembler::GreaterThanOrEqual: - case Assembler::Below: - case Assembler::BelowOrEqual: - case Assembler::Above: - case Assembler::AboveOrEqual: { - Assembler::Condition invert_cond = Assembler::InvertCondition(cond); - Assembler::Condition cond1 = Assembler::ConditionWithoutEqual(cond); - Assembler::Condition cond2 = Assembler::ConditionWithoutEqual(invert_cond); - Assembler::Condition cond3 = Assembler::UnsignedCondition(cond); - - ma_b(lhs.high, rhs.high, success, cond1); - ma_b(lhs.high, rhs.high, fail, cond2); - ma_b(lhs.low, rhs.low, success, cond3); - if (!fallthrough) - jump(fail); - break; - } - default: - MOZ_CRASH("Condition code not supported"); - break; - } - - if (fallthrough) - bind(fail); + Condition c = ma_cmp64(cond, lhs, rhs, SecondScratchReg); + ma_b(SecondScratchReg, SecondScratchReg, success, c); + if (fail) + jump(fail); } void @@ -907,11 +854,11 @@ void MacroAssembler::branchTest64(Condition cond, Register64 lhs, Register64 rhs, Register temp, L label) { - if (cond == Assembler::Zero) { + if (cond == Assembler::Zero || cond == Assembler::NonZero) { MOZ_ASSERT(lhs.low == rhs.low); MOZ_ASSERT(lhs.high == rhs.high); as_or(ScratchRegister, lhs.low, lhs.high); - branchTestPtr(cond, ScratchRegister, ScratchRegister, label); + ma_b(ScratchRegister, ScratchRegister, label, cond); } else { MOZ_CRASH("Unsupported condition"); } diff --git a/js/src/jit/mips32/MacroAssembler-mips32.cpp b/js/src/jit/mips32/MacroAssembler-mips32.cpp index 2da8478dd5e7..2b726d1859c8 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.cpp +++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp @@ -619,6 +619,199 @@ MacroAssemblerMIPS::ma_cmp_set(Register dst, Address lhs, Register rhs, Conditio ma_cmp_set(dst, ScratchRegister, rhs, c); } +void +MacroAssemblerMIPSCompat::cmp64Set(Condition cond, Register64 lhs, Imm64 val, Register dest) { + + if (val.value == 0) { + switch(cond){ + case Assembler::Equal: + case Assembler::BelowOrEqual: + as_or(dest, lhs.high, lhs.low); + as_sltiu(dest, dest, 1); + break; + case Assembler::NotEqual: + case Assembler::Above: + as_or(dest, lhs.high, lhs.low); + as_sltu(dest, zero, dest); + break; + case Assembler::LessThan: + case Assembler::GreaterThanOrEqual: + as_slt(dest, lhs.high, zero); + if (cond == Assembler::GreaterThanOrEqual) + as_xori(dest, dest, 1); + break; + case Assembler::GreaterThan: + case Assembler::LessThanOrEqual: + as_or(SecondScratchReg, lhs.high, lhs.low); + as_sra(ScratchRegister, lhs.high, 31); + as_sltu(dest, ScratchRegister, SecondScratchReg); + if (cond == Assembler::LessThanOrEqual) + as_xori(dest, dest, 1); + break; + case Assembler::Below: + case Assembler::AboveOrEqual: + as_ori(dest, zero, cond == Assembler::AboveOrEqual ? 1 : 0); + break; + default: + MOZ_CRASH("Condition code not supported"); + break; + } + return; + } + + Condition c = ma_cmp64(cond, lhs, val, dest); + + switch(cond) { + // For Equal/NotEqual cond ma_cmp64 dest holds non boolean result. + case Assembler::Equal: + as_sltiu(dest, dest, 1); + break; + case Assembler::NotEqual: + as_sltu(dest, zero, dest); + break; + default: + if(c == Assembler::Zero) + as_xori(dest, dest, 1); + break; + } +} + +void +MacroAssemblerMIPSCompat::cmp64Set(Condition cond, Register64 lhs, Register64 rhs, Register dest) { + + Condition c = ma_cmp64(cond, lhs, rhs, dest); + + switch(cond) { + // For Equal/NotEqual cond ma_cmp64 dest holds non boolean result. + case Assembler::Equal: + as_sltiu(dest, dest, 1); + break; + case Assembler::NotEqual: + as_sltu(dest, zero, dest); + break; + default: + if(c == Assembler::Zero) + as_xori(dest, dest, 1); + break; + } +} + +Assembler::Condition +MacroAssemblerMIPSCompat::ma_cmp64(Condition cond, Register64 lhs, Register64 rhs, Register dest) { + + switch(cond) { + case Assembler::Equal: + case Assembler::NotEqual: + as_xor(SecondScratchReg, lhs.high, rhs.high); + as_xor(ScratchRegister, lhs.low, rhs.low); + as_or(dest, SecondScratchReg, ScratchRegister); + return (cond == Assembler::Equal) ? Assembler::Zero : Assembler::NonZero; + break; + case Assembler::LessThan: + case Assembler::GreaterThanOrEqual: + as_slt(SecondScratchReg, rhs.high, lhs.high); + as_sltu(ScratchRegister, lhs.low, rhs.low); + as_slt(SecondScratchReg, SecondScratchReg, ScratchRegister); + as_slt(ScratchRegister, lhs.high, rhs.high); + as_or(dest, ScratchRegister, SecondScratchReg); + return (cond == Assembler::GreaterThanOrEqual) ? Assembler::Zero : Assembler::NonZero; + break; + case Assembler::GreaterThan: + case Assembler::LessThanOrEqual: + as_slt(SecondScratchReg, lhs.high, rhs.high); + as_sltu(ScratchRegister, rhs.low, lhs.low); + as_slt(SecondScratchReg, SecondScratchReg, ScratchRegister); + as_slt(ScratchRegister, rhs.high, lhs.high); + as_or(dest, ScratchRegister, SecondScratchReg); + return (cond == Assembler::LessThanOrEqual) ? Assembler::Zero : Assembler::NonZero; + break; + case Assembler::Below: + case Assembler::AboveOrEqual: + as_sltu(SecondScratchReg, rhs.high, lhs.high); + as_sltu(ScratchRegister, lhs.low, rhs.low); + as_slt(SecondScratchReg, SecondScratchReg, ScratchRegister); + as_sltu(ScratchRegister, lhs.high, rhs.high); + as_or(dest, ScratchRegister, SecondScratchReg); + return (cond == Assembler::AboveOrEqual) ? Assembler::Zero : Assembler::NonZero; + break; + case Assembler::Above: + case Assembler::BelowOrEqual: + as_sltu(SecondScratchReg, lhs.high, rhs.high); + as_sltu(ScratchRegister, rhs.low, lhs.low); + as_slt(SecondScratchReg, SecondScratchReg, ScratchRegister); + as_sltu(ScratchRegister, rhs.high, lhs.high); + as_or(dest, ScratchRegister, SecondScratchReg); + return (cond == Assembler::BelowOrEqual) ? Assembler::Zero : Assembler::NonZero; + break; + default: + MOZ_CRASH("Condition code not supported"); + break; + } +} + +Assembler::Condition +MacroAssemblerMIPSCompat::ma_cmp64(Condition cond, Register64 lhs, Imm64 val, Register dest) { + + MOZ_ASSERT(val.value != 0); + + switch(cond) { + case Assembler::Equal: + case Assembler::NotEqual: + ma_xor(SecondScratchReg, lhs.high, val.hi()); + ma_xor(ScratchRegister, lhs.low, val.low()); + as_or(dest, SecondScratchReg, ScratchRegister); + return (cond == Assembler::Equal) ? Assembler::Zero : Assembler::NonZero; + break; + case Assembler::LessThan: + case Assembler::GreaterThanOrEqual: + ma_li(SecondScratchReg, val.hi()); + as_slt(ScratchRegister, lhs.high, SecondScratchReg); + as_slt(SecondScratchReg, SecondScratchReg, lhs.high); + as_subu(SecondScratchReg, SecondScratchReg, ScratchRegister); + ma_li(ScratchRegister, val.low()); + as_sltu(ScratchRegister, lhs.low, ScratchRegister); + as_slt(dest, SecondScratchReg, ScratchRegister); + return (cond == Assembler::GreaterThanOrEqual) ? Assembler::Zero : Assembler::NonZero; + break; + case Assembler::GreaterThan: + case Assembler::LessThanOrEqual: + ma_li(SecondScratchReg, val.hi()); + as_slt(ScratchRegister, SecondScratchReg, lhs.high); + as_slt(SecondScratchReg, lhs.high, SecondScratchReg); + as_subu(SecondScratchReg, SecondScratchReg, ScratchRegister); + ma_li(ScratchRegister, val.low()); + as_sltu(ScratchRegister, ScratchRegister, lhs.low); + as_slt(dest, SecondScratchReg, ScratchRegister); + return (cond == Assembler::LessThanOrEqual) ? Assembler::Zero : Assembler::NonZero; + break; + case Assembler::Below: + case Assembler::AboveOrEqual: + ma_li(SecondScratchReg, val.hi()); + as_sltu(ScratchRegister, lhs.high, SecondScratchReg); + as_sltu(SecondScratchReg, SecondScratchReg, lhs.high); + as_subu(SecondScratchReg, SecondScratchReg, ScratchRegister); + ma_li(ScratchRegister, val.low()); + as_sltu(ScratchRegister, lhs.low, ScratchRegister); + as_slt(dest, SecondScratchReg, ScratchRegister); + return (cond == Assembler::AboveOrEqual) ? Assembler::Zero : Assembler::NonZero; + break; + case Assembler::Above: + case Assembler::BelowOrEqual: + ma_li(SecondScratchReg, val.hi()); + as_sltu(ScratchRegister, SecondScratchReg, lhs.high); + as_sltu(SecondScratchReg, lhs.high, SecondScratchReg); + as_subu(SecondScratchReg, SecondScratchReg, ScratchRegister); + ma_li(ScratchRegister, val.low()); + as_sltu(ScratchRegister, ScratchRegister, lhs.low); + as_slt(dest, SecondScratchReg, ScratchRegister); + return (cond == Assembler::BelowOrEqual) ? Assembler::Zero : Assembler::NonZero; + break; + default: + MOZ_CRASH("Condition code not supported"); + break; + } +} + // fp instructions void MacroAssemblerMIPS::ma_lid(FloatRegister dest, double value) diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index 50f27c3820b7..32f9754df24a 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -713,6 +713,9 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS // convert it to double. Else, branch to failure. void ensureDouble(const ValueOperand& source, FloatRegister dest, Label* failure); + void cmp64Set(Condition cond, Register64 lhs, Register64 rhs, Register dest); + void cmp64Set(Condition cond, Register64 lhs, Imm64 val, Register dest); + protected: bool buildOOLFakeExitFrame(void* fakeReturnAddr); @@ -722,6 +725,8 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS Register ptrScratch, Register64 output, Register tmp); void wasmStoreI64Impl(const wasm::MemoryAccessDesc& access, Register64 value, Register memoryBase, Register ptr, Register ptrScratch, Register tmp); + Condition ma_cmp64(Condition cond, Register64 lhs, Register64 rhs, Register dest); + Condition ma_cmp64(Condition cond, Register64 lhs, Imm64 val, Register dest); public: CodeOffset labelForPatch() { diff --git a/js/src/wasm/WasmBaselineCompile.cpp b/js/src/wasm/WasmBaselineCompile.cpp index d3da150848bd..b3bc9841b455 100644 --- a/js/src/wasm/WasmBaselineCompile.cpp +++ b/js/src/wasm/WasmBaselineCompile.cpp @@ -3807,8 +3807,10 @@ class BaseCompiler final : public BaseCompilerInterface #endif // RABALDR_I64_TO_FLOAT_CALLOUT void cmp64Set(Assembler::Condition cond, RegI64 lhs, RegI64 rhs, RegI32 dest) { -#ifdef JS_PUNBOX64 +#if defined(JS_PUNBOX64) masm.cmpPtrSet(cond, lhs.reg, rhs.reg, dest); +#elif defined(JS_CODEGEN_MIPS32) + masm.cmp64Set(cond, lhs, rhs, dest); #else // TODO / OPTIMIZE (Bug 1316822): This is pretty branchy, we should be // able to do better. From ded8fd38e249538bc8eafe948651f1e55f1a9e8b Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Wed, 21 Feb 2018 15:24:24 +0000 Subject: [PATCH 05/21] Bug 1439416 - Relax line number assertions when creating module objects r=anba --- js/src/builtin/ModuleObject.cpp | 24 ++++++++----------- .../jit-test/tests/modules/bug-1439416-2.js | 10 ++++++++ js/src/jit-test/tests/modules/bug-1439416.js | 10 ++++++++ 3 files changed, 30 insertions(+), 14 deletions(-) create mode 100644 js/src/jit-test/tests/modules/bug-1439416-2.js create mode 100644 js/src/jit-test/tests/modules/bug-1439416.js diff --git a/js/src/builtin/ModuleObject.cpp b/js/src/builtin/ModuleObject.cpp index c4551f4bac2f..440849377807 100644 --- a/js/src/builtin/ModuleObject.cpp +++ b/js/src/builtin/ModuleObject.cpp @@ -80,8 +80,10 @@ ModuleValueGetter(JSContext* cx, unsigned argc, Value* vp) cls::name() const \ { \ Value value = cls##_##name##Value(this); \ - MOZ_ASSERT(value.toInt32() >= 0); \ - return value.toInt32(); \ + MOZ_ASSERT(value.toNumber() >= 0); \ + if (value.isInt32()) \ + return value.toInt32(); \ + return JS::ToUint32(value.toDouble()); \ } /////////////////////////////////////////////////////////////////////////// @@ -143,8 +145,6 @@ ImportEntryObject::create(JSContext* cx, uint32_t lineNumber, uint32_t columnNumber) { - MOZ_ASSERT(lineNumber > 0); - RootedObject proto(cx, GlobalObject::getOrCreateImportEntryPrototype(cx, cx->global())); if (!proto) return nullptr; @@ -157,8 +157,8 @@ ImportEntryObject::create(JSContext* cx, self->initReservedSlot(ModuleRequestSlot, StringValue(moduleRequest)); self->initReservedSlot(ImportNameSlot, StringValue(importName)); self->initReservedSlot(LocalNameSlot, StringValue(localName)); - self->initReservedSlot(LineNumberSlot, Int32Value(lineNumber)); - self->initReservedSlot(ColumnNumberSlot, Int32Value(columnNumber)); + self->initReservedSlot(LineNumberSlot, NumberValue(lineNumber)); + self->initReservedSlot(ColumnNumberSlot, NumberValue(columnNumber)); return self; } @@ -247,8 +247,8 @@ ExportEntryObject::create(JSContext* cx, self->initReservedSlot(ModuleRequestSlot, StringOrNullValue(maybeModuleRequest)); self->initReservedSlot(ImportNameSlot, StringOrNullValue(maybeImportName)); self->initReservedSlot(LocalNameSlot, StringOrNullValue(maybeLocalName)); - self->initReservedSlot(LineNumberSlot, Int32Value(lineNumber)); - self->initReservedSlot(ColumnNumberSlot, Int32Value(columnNumber)); + self->initReservedSlot(LineNumberSlot, NumberValue(lineNumber)); + self->initReservedSlot(ColumnNumberSlot, NumberValue(columnNumber)); return self; } @@ -303,8 +303,6 @@ RequestedModuleObject::create(JSContext* cx, uint32_t lineNumber, uint32_t columnNumber) { - MOZ_ASSERT(lineNumber > 0); - RootedObject proto(cx, GlobalObject::getOrCreateRequestedModulePrototype(cx, cx->global())); if (!proto) return nullptr; @@ -315,8 +313,8 @@ RequestedModuleObject::create(JSContext* cx, RootedRequestedModuleObject self(cx, &obj->as()); self->initReservedSlot(ModuleSpecifierSlot, StringValue(moduleSpecifier)); - self->initReservedSlot(LineNumberSlot, Int32Value(lineNumber)); - self->initReservedSlot(ColumnNumberSlot, Int32Value(columnNumber)); + self->initReservedSlot(LineNumberSlot, NumberValue(lineNumber)); + self->initReservedSlot(ColumnNumberSlot, NumberValue(columnNumber)); return self; } @@ -1252,7 +1250,6 @@ ModuleBuilder::buildTables() if (!localExportEntries_.append(exp)) return false; } else { - MOZ_ASSERT(exp->lineNumber()); RootedAtom exportName(cx_, exp->exportName()); RootedAtom moduleRequest(cx_, importEntry->moduleRequest()); RootedAtom importName(cx_, importEntry->importName()); @@ -1272,7 +1269,6 @@ ModuleBuilder::buildTables() if (!starExportEntries_.append(exp)) return false; } else { - MOZ_ASSERT(exp->lineNumber()); if (!indirectExportEntries_.append(exp)) return false; } diff --git a/js/src/jit-test/tests/modules/bug-1439416-2.js b/js/src/jit-test/tests/modules/bug-1439416-2.js new file mode 100644 index 000000000000..b9202c112c2b --- /dev/null +++ b/js/src/jit-test/tests/modules/bug-1439416-2.js @@ -0,0 +1,10 @@ +function parseAsModule(source) { + return Reflect.parse(source, { + target: "module", + line: 0x7FFFFFFF + 1, + }); +} +parseAsModule(` + import {a} from ""; + export {a}; +`); diff --git a/js/src/jit-test/tests/modules/bug-1439416.js b/js/src/jit-test/tests/modules/bug-1439416.js new file mode 100644 index 000000000000..9dfe55b49a58 --- /dev/null +++ b/js/src/jit-test/tests/modules/bug-1439416.js @@ -0,0 +1,10 @@ +// Test that zero-based line numbers supplied by Reflect.parse don't cause +// assertions. + +function parseAsModule(source) { + return Reflect.parse(source, { + target: "module", + line: 0 + }); +} +parseAsModule("import d from 'a'"); From 585141844f391b370b18fbed2c2bc2d90cefff6a Mon Sep 17 00:00:00 2001 From: Ted Campbell Date: Tue, 20 Feb 2018 23:33:42 -0500 Subject: [PATCH 06/21] Bug 1439336 - Make guards consistent for TypedObjects. r=jandem MozReview-Commit-ID: CmOMoFq5DgP --- js/src/jit/CacheIR.cpp | 51 +++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/js/src/jit/CacheIR.cpp b/js/src/jit/CacheIR.cpp index a3045f3ddb0f..04aa450d9469 100644 --- a/js/src/jit/CacheIR.cpp +++ b/js/src/jit/CacheIR.cpp @@ -1463,12 +1463,11 @@ GetTypedThingLayout(const Class* clasp) bool GetPropIRGenerator::tryAttachTypedObject(HandleObject obj, ObjOperandId objId, HandleId id) { - if (!obj->is() || - !cx_->runtime()->jitSupportsFloatingPoint || - cx_->compartment()->detachedTypedObjects) - { + if (!obj->is()) + return false; + + if (!cx_->runtime()->jitSupportsFloatingPoint || cx_->compartment()->detachedTypedObjects) return false; - } TypedObject* typedObj = &obj->as(); if (!typedObj->typeDescr().is()) @@ -1483,15 +1482,14 @@ GetPropIRGenerator::tryAttachTypedObject(HandleObject obj, ObjOperandId objId, H if (!fieldDescr->is()) return false; - Shape* shape = typedObj->maybeShape(); - TypedThingLayout layout = GetTypedThingLayout(shape->getObjectClass()); + TypedThingLayout layout = GetTypedThingLayout(obj->getClass()); uint32_t fieldOffset = structDescr->fieldOffset(fieldIndex); uint32_t typeDescr = SimpleTypeDescrKey(&fieldDescr->as()); maybeEmitIdGuard(id); writer.guardNoDetachedTypedObjects(); - writer.guardShape(objId, shape); + writer.guardGroupForLayout(objId, obj->group()); writer.loadTypedObjectResult(objId, fieldOffset, layout, typeDescr); // Only monitor the result if the type produced by this stub might vary. @@ -1938,10 +1936,13 @@ GetPropIRGenerator::tryAttachTypedElement(HandleObject obj, ObjOperandId objId, return false; TypedThingLayout layout = GetTypedThingLayout(obj->getClass()); - if (layout != Layout_TypedArray) - writer.guardNoDetachedTypedObjects(); - writer.guardShape(objId, obj->as().shape()); + if (IsPrimitiveArrayTypedObject(obj)) { + writer.guardNoDetachedTypedObjects(); + writer.guardGroupForLayout(objId, obj->group()); + } else { + writer.guardShape(objId, obj->as().shape()); + } writer.loadTypedElementResult(objId, indexId, layout, TypedThingElementType(obj)); @@ -2644,13 +2645,12 @@ HasPropIRGenerator::tryAttachTypedArray(HandleObject obj, ObjOperandId objId, if (!obj->is() && !IsPrimitiveArrayTypedObject(obj)) return false; - // Don't attach typed object stubs if the underlying storage could be - // detached, as the stub will always bail out. - if (IsPrimitiveArrayTypedObject(obj) && cx_->compartment()->detachedTypedObjects) - return false; - TypedThingLayout layout = GetTypedThingLayout(obj->getClass()); - writer.guardShape(objId, obj->as().shape()); + + if (IsPrimitiveArrayTypedObject(obj)) + writer.guardGroupForLayout(objId, obj->group()); + else + writer.guardShape(objId, obj->as().shape()); writer.loadTypedElementExistsResult(objId, indexId, layout); @@ -3083,7 +3083,10 @@ bool SetPropIRGenerator::tryAttachUnboxedProperty(HandleObject obj, ObjOperandId objId, HandleId id, ValOperandId rhsId) { - if (!obj->is() || !cx_->runtime()->jitSupportsFloatingPoint) + if (!obj->is()) + return false; + + if (!cx_->runtime()->jitSupportsFloatingPoint) return false; const UnboxedLayout::Property* property = obj->as().layout().lookup(id); @@ -3109,10 +3112,10 @@ bool SetPropIRGenerator::tryAttachTypedObjectProperty(HandleObject obj, ObjOperandId objId, HandleId id, ValOperandId rhsId) { - if (!obj->is() || !cx_->runtime()->jitSupportsFloatingPoint) + if (!obj->is()) return false; - if (cx_->compartment()->detachedTypedObjects) + if (!cx_->runtime()->jitSupportsFloatingPoint || cx_->compartment()->detachedTypedObjects) return false; if (!obj->as().typeDescr().is()) @@ -3132,7 +3135,6 @@ SetPropIRGenerator::tryAttachTypedObjectProperty(HandleObject obj, ObjOperandId maybeEmitIdGuard(id); writer.guardNoDetachedTypedObjects(); - writer.guardShape(objId, obj->as().shape()); writer.guardGroupForLayout(objId, obj->group()); typeCheckInfo_.set(obj->group(), id); @@ -3523,10 +3525,13 @@ SetPropIRGenerator::tryAttachSetTypedElement(HandleObject obj, ObjOperandId objI Scalar::Type elementType = TypedThingElementType(obj); TypedThingLayout layout = GetTypedThingLayout(obj->getClass()); - if (!obj->is()) + if (IsPrimitiveArrayTypedObject(obj)) { writer.guardNoDetachedTypedObjects(); + writer.guardGroupForLayout(objId, obj->group()); + } else { + writer.guardShape(objId, obj->as().shape()); + } - writer.guardShape(objId, obj->as().shape()); writer.storeTypedElement(objId, indexId, rhsId, layout, elementType, handleOutOfBounds); writer.returnFromIC(); From 8a855818ec37bafb04fbf406de8f5a5d2f538a0c Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Wed, 21 Feb 2018 07:28:32 -0800 Subject: [PATCH 07/21] Bug 1437760 P1 Propagate the FetchEvent.request.url fragment to the synthesized Response.url. r=asuth --- dom/serviceworkers/ServiceWorkerEvents.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/dom/serviceworkers/ServiceWorkerEvents.cpp b/dom/serviceworkers/ServiceWorkerEvents.cpp index 049901ded9c6..9a9e3c080830 100644 --- a/dom/serviceworkers/ServiceWorkerEvents.cpp +++ b/dom/serviceworkers/ServiceWorkerEvents.cpp @@ -418,6 +418,7 @@ class RespondWithHandler final : public PromiseNativeHandler #endif const nsCString mScriptSpec; const nsString mRequestURL; + const nsCString mRequestFragment; const nsCString mRespondWithScriptSpec; const uint32_t mRespondWithLineNumber; const uint32_t mRespondWithColumnNumber; @@ -431,6 +432,7 @@ public: RequestRedirect aRedirectMode, const nsACString& aScriptSpec, const nsAString& aRequestURL, + const nsACString& aRequestFragment, const nsACString& aRespondWithScriptSpec, uint32_t aRespondWithLineNumber, uint32_t aRespondWithColumnNumber) @@ -443,6 +445,7 @@ public: #endif , mScriptSpec(aScriptSpec) , mRequestURL(aRequestURL) + , mRequestFragment(aRequestFragment) , mRespondWithScriptSpec(aRespondWithScriptSpec) , mRespondWithLineNumber(aRespondWithLineNumber) , mRespondWithColumnNumber(aRespondWithColumnNumber) @@ -716,6 +719,18 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle aValu nsCString responseURL; if (mRequestMode != RequestMode::Navigate) { responseURL = ir->GetUnfilteredURL(); + + // Similar to how we apply the request fragment to redirects automatically + // we also want to apply it automatically when propagating the response + // URL from a service worker interception. Currently response.url strips + // the fragment, so this will never conflict with an existing fragment + // on the response. In the future we will have to check for a response + // fragment and avoid overriding in that case. + if (!mRequestFragment.IsEmpty()) { + MOZ_ASSERT(!responseURL.Contains('#')); + responseURL.Append(NS_LITERAL_CSTRING("#")); + responseURL.Append(mRequestFragment); + } } UniquePtr closure(new RespondWithClosure(mInterceptedChannel, @@ -816,7 +831,7 @@ FetchEvent::RespondWith(JSContext* aCx, Promise& aArg, ErrorResult& aRv) new RespondWithHandler(mChannel, mRegistration, mRequest->Mode(), ir->IsClientRequest(), mRequest->Redirect(), mScriptSpec, NS_ConvertUTF8toUTF16(requestURL), - spec, line, column); + ir->GetFragment(), spec, line, column); aArg.AppendNativeHandler(handler); if (!WaitOnPromise(aArg)) { From 331d0e0c4e0599e76ddf58eca7601facab9ee157 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Wed, 21 Feb 2018 07:28:33 -0800 Subject: [PATCH 08/21] Bug 1437760 P2 Add a reftest that verifies svg images with fragment based targets renders properly when service workers intercept. r=xidorn --- testing/web-platform/meta/MANIFEST.json | 71 +++++++++++++++++-- testing/web-platform/tests/images/colors.svg | 11 +++ .../resources/pass-through-worker.js | 3 + .../svg-target-reftest-001-frame.html | 3 + .../resources/svg-target-reftest-001.html | 5 ++ .../resources/svg-target-reftest-frame.html | 2 + .../svg-target-reftest.https.html | 28 ++++++++ 7 files changed, 118 insertions(+), 5 deletions(-) create mode 100644 testing/web-platform/tests/images/colors.svg create mode 100644 testing/web-platform/tests/service-workers/service-worker/resources/pass-through-worker.js create mode 100644 testing/web-platform/tests/service-workers/service-worker/resources/svg-target-reftest-001-frame.html create mode 100644 testing/web-platform/tests/service-workers/service-worker/resources/svg-target-reftest-001.html create mode 100644 testing/web-platform/tests/service-workers/service-worker/resources/svg-target-reftest-frame.html create mode 100644 testing/web-platform/tests/service-workers/service-worker/svg-target-reftest.https.html diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index 548d6cf11691..51474dd6ba10 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -178869,6 +178869,18 @@ {} ] ], + "service-workers/service-worker/svg-target-reftest.https.html": [ + [ + "/service-workers/service-worker/svg-target-reftest.https.html", + [ + [ + "/service-workers/service-worker/resources/svg-target-reftest-001.html", + "==" + ] + ], + {} + ] + ], "shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest.html": [ [ "/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest.html", @@ -281857,6 +281869,11 @@ {} ] ], + "images/colors.svg": [ + [ + {} + ] + ], "images/fail.gif": [ [ {} @@ -289222,6 +289239,11 @@ {} ] ], + "service-workers/service-worker/resources/pass-through-worker.js": [ + [ + {} + ] + ], "service-workers/service-worker/resources/pass.txt": [ [ {} @@ -289452,6 +289474,21 @@ {} ] ], + "service-workers/service-worker/resources/svg-target-reftest-001-frame.html": [ + [ + {} + ] + ], + "service-workers/service-worker/resources/svg-target-reftest-001.html": [ + [ + {} + ] + ], + "service-workers/service-worker/resources/svg-target-reftest-frame.html": [ + [ + {} + ] + ], "service-workers/service-worker/resources/test-helpers.sub.js": [ [ {} @@ -485312,7 +485349,7 @@ "support" ], "css/css-fonts/font-feature-settings-serialization-001.html": [ - "d1032e08aee1e9a7d1309ad94bd5633535ce9315", + "bf557e7f93663a36dab3ea358401b16c2e88811a", "testharness" ], "css/css-fonts/font-features-across-space-1-ref.html": [ @@ -537440,7 +537477,7 @@ "testharness" ], "dom/events/event-disabled-dynamic.html": [ - "2a358fff53f3f6eb14ff87520a84e68f10533c9f", + "40ab5636653dfd105738ab38e7d22316132eb630", "testharness" ], "dom/historical.html": [ @@ -538792,7 +538829,7 @@ "support" ], "domparsing/XMLSerializer-serializeToString.html": [ - "71314752b8552c19b0951647594b9c5c85ca01b6", + "0ff2295477d3d2d690b19976eceae8a8a79720fe", "testharness" ], "domparsing/createContextualFragment.html": [ @@ -542884,7 +542921,7 @@ "support" ], "fetch/nosniff/script.html": [ - "762b6033a5b75465417f9921f7d06781ad036cbe", + "812bf9d241272d5fb455d36e156b4d15474e8306", "testharness" ], "fetch/nosniff/stylesheet.html": [ @@ -562855,6 +562892,10 @@ "16f9dc971ee76bcc71599af602a04b9b64e960d2", "support" ], + "images/colors.svg": [ + "6ebe57def787860ab404f2be9536a0e081d50bb6", + "support" + ], "images/fail.gif": [ "a4dad89f8247eef2a574d1d96b0d188e84f1b57f", "support" @@ -563132,7 +563173,7 @@ "support" ], "interfaces/dom.idl": [ - "52236516620dac45213fa06dc169f0c02e63a0c5", + "773c449a2f9a6bd9e35d0dd8a4c2e1eaa0266150", "support" ], "interfaces/fullscreen.idl": [ @@ -584371,6 +584412,10 @@ "df15579b54fc14412435eee789c81a6523a394fc", "support" ], + "service-workers/service-worker/resources/pass-through-worker.js": [ + "9bea44e9ab6d8452aadc57d5e6d5a1eaa017ac78", + "support" + ], "service-workers/service-worker/resources/pass.txt": [ "27d2303f215d7d1a8f12f0b80b9b56a2cdf6c9a7", "support" @@ -584555,6 +584600,18 @@ "628bc36bef749e1a2ffda104f71a17acee69b13b", "support" ], + "service-workers/service-worker/resources/svg-target-reftest-001-frame.html": [ + "898cb16d911e94eb36506a07c6cceae41d9bcbda", + "support" + ], + "service-workers/service-worker/resources/svg-target-reftest-001.html": [ + "31ca62ad01049549f05ec52dda828defcbe2ac6e", + "support" + ], + "service-workers/service-worker/resources/svg-target-reftest-frame.html": [ + "0f7bf8a7cccb1fb4aa5948fb7a684857006b295f", + "support" + ], "service-workers/service-worker/resources/test-helpers.sub.js": [ "fee1648c02422cd2607b008b9a1ef0834385c69c", "support" @@ -584683,6 +584740,10 @@ "ecb0e2fd22e7c92a98ae612a2032a92edf8520d9", "testharness" ], + "service-workers/service-worker/svg-target-reftest.https.html": [ + "c8d97ffed68ca40b4154bde36d9a0ca65d2e3816", + "reftest" + ], "service-workers/service-worker/synced-state.https.html": [ "c6a3d6e8aa7a70e1bc670f89192240bac081bfe9", "testharness" diff --git a/testing/web-platform/tests/images/colors.svg b/testing/web-platform/tests/images/colors.svg new file mode 100644 index 000000000000..024de84a5bba --- /dev/null +++ b/testing/web-platform/tests/images/colors.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/testing/web-platform/tests/service-workers/service-worker/resources/pass-through-worker.js b/testing/web-platform/tests/service-workers/service-worker/resources/pass-through-worker.js new file mode 100644 index 000000000000..5eaf48d5887d --- /dev/null +++ b/testing/web-platform/tests/service-workers/service-worker/resources/pass-through-worker.js @@ -0,0 +1,3 @@ +addEventListener('fetch', evt => { + evt.respondWith(fetch(evt.request)); +}); diff --git a/testing/web-platform/tests/service-workers/service-worker/resources/svg-target-reftest-001-frame.html b/testing/web-platform/tests/service-workers/service-worker/resources/svg-target-reftest-001-frame.html new file mode 100644 index 000000000000..59fb524049d8 --- /dev/null +++ b/testing/web-platform/tests/service-workers/service-worker/resources/svg-target-reftest-001-frame.html @@ -0,0 +1,3 @@ + + + diff --git a/testing/web-platform/tests/service-workers/service-worker/resources/svg-target-reftest-001.html b/testing/web-platform/tests/service-workers/service-worker/resources/svg-target-reftest-001.html new file mode 100644 index 000000000000..9a93d3b37047 --- /dev/null +++ b/testing/web-platform/tests/service-workers/service-worker/resources/svg-target-reftest-001.html @@ -0,0 +1,5 @@ + + +Green svg box reference file +

Pass if you see a green box below.

+