From fa1628f76785e18240c7c7aca63b99d490879461 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Tue, 12 May 2020 12:40:05 +0800 Subject: Bug 1323136 - wasm: MIPS: Do bounds check in 32-bit Tag: #1542 --- js/src/jit/mips32/Assembler-mips32.cpp | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'js/src/jit/mips32/Assembler-mips32.cpp') diff --git a/js/src/jit/mips32/Assembler-mips32.cpp b/js/src/jit/mips32/Assembler-mips32.cpp index 6283c1d5a..1b86e9d32 100644 --- a/js/src/jit/mips32/Assembler-mips32.cpp +++ b/js/src/jit/mips32/Assembler-mips32.cpp @@ -124,7 +124,7 @@ jit::PatchJump(CodeLocationJump& jump_, CodeLocationLabel label, ReprotectCode r Instruction* inst2 = inst1->next(); MaybeAutoWritableJitCode awjc(inst1, 8, reprotect); - Assembler::UpdateLuiOriValue(inst1, inst2, (uint32_t)label.raw()); + AssemblerMIPSShared::UpdateLuiOriValue(inst1, inst2, (uint32_t)label.raw()); AutoFlushICache::flush(uintptr_t(inst1), 8); } @@ -146,12 +146,12 @@ jit::PatchBackedge(CodeLocationJump& jump, CodeLocationLabel label, } else { if (target == JitRuntime::BackedgeLoopHeader) { Instruction* lui = &branch[1]; - Assembler::UpdateLuiOriValue(lui, lui->next(), targetAddr); + AssemblerMIPSShared::UpdateLuiOriValue(lui, lui->next(), targetAddr); // Jump to ori. The lui will be executed in delay slot. branch->setBOffImm16(BOffImm16(2 * sizeof(uint32_t))); } else { Instruction* lui = &branch[4]; - Assembler::UpdateLuiOriValue(lui, lui->next(), targetAddr); + AssemblerMIPSShared::UpdateLuiOriValue(lui, lui->next(), targetAddr); branch->setBOffImm16(BOffImm16(4 * sizeof(uint32_t))); } } @@ -168,7 +168,7 @@ Assembler::executableCopy(uint8_t* buffer) Instruction* inst1 = (Instruction*) ((uint32_t)buffer + longJumps_[i]); uint32_t value = Assembler::ExtractLuiOriValue(inst1, inst1->next()); - Assembler::UpdateLuiOriValue(inst1, inst1->next(), (uint32_t)buffer + value); + AssemblerMIPSShared::UpdateLuiOriValue(inst1, inst1->next(), (uint32_t)buffer + value); } AutoFlushICache::setRange(uintptr_t(buffer), m_buffer.size()); @@ -207,7 +207,7 @@ TraceOneDataRelocation(JSTracer* trc, Instruction* inst) TraceManuallyBarrieredGenericPointerEdge(trc, reinterpret_cast(&ptr), "ion-masm-ptr"); if (ptr != prior) { - Assembler::UpdateLuiOriValue(inst, inst->next(), uint32_t(ptr)); + AssemblerMIPSShared::UpdateLuiOriValue(inst, inst->next(), uint32_t(ptr)); AutoFlushICache::flush(uintptr_t(inst), 8); } } @@ -306,7 +306,7 @@ Assembler::Bind(uint8_t* rawCode, CodeOffset* label, const void* address) if (label->bound()) { intptr_t offset = label->offset(); Instruction* inst = (Instruction*) (rawCode + offset); - Assembler::UpdateLuiOriValue(inst, inst->next(), (uint32_t)address); + AssemblerMIPSShared::UpdateLuiOriValue(inst, inst->next(), (uint32_t)address); } } @@ -385,7 +385,7 @@ Assembler::bind(RepatchLabel* label) // For unconditional long branches generated by ma_liPatchable, // such as under: // jumpWithpatch - Assembler::UpdateLuiOriValue(inst, inst->next(), dest.getOffset()); + AssemblerMIPSShared::UpdateLuiOriValue(inst, inst->next(), dest.getOffset()); } else if (inst[1].extractOpcode() == (uint32_t(op_lui) >> OpcodeShift) || BOffImm16::IsInRange(offset)) { @@ -466,16 +466,6 @@ Assembler::ExtractLuiOriValue(Instruction* inst0, Instruction* inst1) return value; } -void -Assembler::UpdateLuiOriValue(Instruction* inst0, Instruction* inst1, uint32_t value) -{ - MOZ_ASSERT(inst0->extractOpcode() == ((uint32_t)op_lui >> OpcodeShift)); - MOZ_ASSERT(inst1->extractOpcode() == ((uint32_t)op_ori >> OpcodeShift)); - - ((InstImm*) inst0)->setImm16(Imm16::Upper(Imm32(value))); - ((InstImm*) inst1)->setImm16(Imm16::Lower(Imm32(value))); -} - void Assembler::WriteLuiOriInstructions(Instruction* inst0, Instruction* inst1, Register reg, uint32_t value) @@ -503,7 +493,7 @@ Assembler::PatchDataWithValueCheck(CodeLocationLabel label, PatchedImmPtr newVal MOZ_ASSERT(value == uint32_t(expectedValue.value)); // Replace with new value - Assembler::UpdateLuiOriValue(inst, inst->next(), uint32_t(newValue.value)); + AssemblerMIPSShared::UpdateLuiOriValue(inst, inst->next(), uint32_t(newValue.value)); AutoFlushICache::flush(uintptr_t(inst), 8); } @@ -512,7 +502,7 @@ void Assembler::PatchInstructionImmediate(uint8_t* code, PatchedImmPtr imm) { InstImm* inst = (InstImm*)code; - Assembler::UpdateLuiOriValue(inst, inst->next(), (uint32_t)imm.value); + AssemblerMIPSShared::UpdateLuiOriValue(inst, inst->next(), (uint32_t)imm.value); } uint32_t -- cgit v1.2.3 From 3fb8648bed83c95f601d2c2e20962cbd08bc7dc7 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Tue, 12 May 2020 12:40:07 +0800 Subject: Bug 1271968 - IonMonkey: MIPS: Replace long jumps by mixed jumps. Tag: #1542 --- js/src/jit/mips32/Assembler-mips32.cpp | 101 ++++++++------------------------- 1 file changed, 25 insertions(+), 76 deletions(-) (limited to 'js/src/jit/mips32/Assembler-mips32.cpp') diff --git a/js/src/jit/mips32/Assembler-mips32.cpp b/js/src/jit/mips32/Assembler-mips32.cpp index 1b86e9d32..461f8d813 100644 --- a/js/src/jit/mips32/Assembler-mips32.cpp +++ b/js/src/jit/mips32/Assembler-mips32.cpp @@ -120,8 +120,11 @@ js::jit::SA(FloatRegister r) void jit::PatchJump(CodeLocationJump& jump_, CodeLocationLabel label, ReprotectCode reprotect) { - Instruction* inst1 = (Instruction*)jump_.raw(); - Instruction* inst2 = inst1->next(); + Instruction* inst1; + Instruction* inst2; + + inst1 = AssemblerMIPSShared::GetInstructionImmediateFromJump((Instruction*)jump_.raw()); + inst2 = inst1->next(); MaybeAutoWritableJitCode awjc(inst1, 8, reprotect); AssemblerMIPSShared::UpdateLuiOriValue(inst1, inst2, (uint32_t)label.raw()); @@ -157,23 +160,6 @@ jit::PatchBackedge(CodeLocationJump& jump, CodeLocationLabel label, } } -void -Assembler::executableCopy(uint8_t* buffer) -{ - MOZ_ASSERT(isFinished); - m_buffer.executableCopy(buffer); - - // Patch all long jumps during code copy. - for (size_t i = 0; i < longJumps_.length(); i++) { - Instruction* inst1 = (Instruction*) ((uint32_t)buffer + longJumps_[i]); - - uint32_t value = Assembler::ExtractLuiOriValue(inst1, inst1->next()); - AssemblerMIPSShared::UpdateLuiOriValue(inst1, inst1->next(), (uint32_t)buffer + value); - } - - AutoFlushICache::setRange(uintptr_t(buffer), m_buffer.size()); -} - uintptr_t Assembler::GetPointer(uint8_t* instPtr) { @@ -314,8 +300,12 @@ void Assembler::bind(InstImm* inst, uintptr_t branch, uintptr_t target) { int32_t offset = target - branch; - InstImm inst_bgezal = InstImm(op_regimm, zero, rt_bgezal, BOffImm16(0)); - InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0)); + + // Generate the patchable mixed jump for call. + if (inst->extractOpcode() == ((uint32_t)op_jal >> OpcodeShift)) { + addMixedJump(BufferOffset(branch), ImmPtr((void*)target)); + return; + } // If encoded offset is 4, then the jump must be short if (BOffImm16(inst[0]).decode() == 4) { @@ -325,46 +315,13 @@ Assembler::bind(InstImm* inst, uintptr_t branch, uintptr_t target) return; } - // Generate the long jump for calls because return address has to be the - // address after the reserved block. - if (inst[0].encode() == inst_bgezal.encode()) { - addLongJump(BufferOffset(branch)); - Assembler::WriteLuiOriInstructions(inst, &inst[1], ScratchRegister, target); - inst[2] = InstReg(op_special, ScratchRegister, zero, ra, ff_jalr).encode(); - // There is 1 nop after this. - return; - } - if (BOffImm16::IsInRange(offset)) { - bool conditional = (inst[0].encode() != inst_bgezal.encode() && - inst[0].encode() != inst_beq.encode()); - inst[0].setBOffImm16(BOffImm16(offset)); inst[1].makeNop(); - - // Skip the trailing nops in conditional branches. - if (conditional) { - inst[2] = InstImm(op_regimm, zero, rt_bgez, BOffImm16(3 * sizeof(void*))).encode(); - // There are 2 nops after this - } return; } - if (inst[0].encode() == inst_beq.encode()) { - // Handle long unconditional jump. - addLongJump(BufferOffset(branch)); - Assembler::WriteLuiOriInstructions(inst, &inst[1], ScratchRegister, target); - inst[2] = InstReg(op_special, ScratchRegister, zero, zero, ff_jr).encode(); - // There is 1 nop after this. - } else { - // Handle long conditional jump. - inst[0] = invertBranch(inst[0], BOffImm16(5 * sizeof(void*))); - // No need for a "nop" here because we can clobber scratch. - addLongJump(BufferOffset(branch + sizeof(void*))); - Assembler::WriteLuiOriInstructions(&inst[1], &inst[2], ScratchRegister, target); - inst[3] = InstReg(op_special, ScratchRegister, zero, zero, ff_jr).encode(); - // There is 1 nop after this. - } + addMixedJump(BufferOffset(branch), ImmPtr((const void*)target)); } void @@ -379,19 +336,16 @@ Assembler::bind(RepatchLabel* label) InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0)); uint32_t offset = dest.getOffset() - label->offset(); - // If first instruction is lui, then this is a long jump. + // If first instruction is j, then this is a mixed jump. // If second instruction is lui, then this is a loop backedge. - if (inst[0].extractOpcode() == (uint32_t(op_lui) >> OpcodeShift)) { - // For unconditional long branches generated by ma_liPatchable, - // such as under: - // jumpWithpatch - AssemblerMIPSShared::UpdateLuiOriValue(inst, inst->next(), dest.getOffset()); + if (inst[0].extractOpcode() == (uint32_t(op_j) >> OpcodeShift)) { + // For unconditional long branches generated by jumpWithPatch + addMixedJump(b, ImmPtr((void*)dest.getOffset()), MixedJumpPatch::PATCHABLE); } else if (inst[1].extractOpcode() == (uint32_t(op_lui) >> OpcodeShift) || BOffImm16::IsInRange(offset)) { // Handle code produced by: // backedgeJump - // branchWithCode MOZ_ASSERT(BOffImm16::IsInRange(offset)); MOZ_ASSERT(inst[0].extractOpcode() == (uint32_t(op_beq) >> OpcodeShift) || inst[0].extractOpcode() == (uint32_t(op_bne) >> OpcodeShift) || @@ -399,30 +353,25 @@ Assembler::bind(RepatchLabel* label) inst[0].extractOpcode() == (uint32_t(op_bgtz) >> OpcodeShift)); inst[0].setBOffImm16(BOffImm16(offset)); } else if (inst[0].encode() == inst_beq.encode()) { - // Handle open long unconditional jumps created by + // Handle open mixed unconditional jumps created by // MacroAssemblerMIPSShared::ma_b(..., wasm::Trap, ...). - // We need to add it to long jumps array here. + // We need to add it to mixed jumps array here. // See MacroAssemblerMIPS::branchWithCode(). MOZ_ASSERT(inst[1].encode() == NopInst); - MOZ_ASSERT(inst[2].encode() == NopInst); - MOZ_ASSERT(inst[3].encode() == NopInst); - addLongJump(BufferOffset(label->offset())); - Assembler::WriteLuiOriInstructions(inst, &inst[1], ScratchRegister, dest.getOffset()); - inst[2] = InstReg(op_special, ScratchRegister, zero, zero, ff_jr).encode(); + addMixedJump(b, ImmPtr((void*)dest.getOffset()), MixedJumpPatch::PATCHABLE); + inst[0] = InstJump(op_j, JOffImm26(0)).encode(); } else { - // Handle open long conditional jumps created by + // Handle open mixed conditional jumps created by // MacroAssemblerMIPSShared::ma_b(..., wasm::Trap, ...). - inst[0] = invertBranch(inst[0], BOffImm16(5 * sizeof(void*))); + inst[0] = invertBranch(inst[0], BOffImm16(4 * sizeof(void*))); // No need for a "nop" here because we can clobber scratch. - // We need to add it to long jumps array here. + // We need to add it to mixed jumps array here. // See MacroAssemblerMIPS::branchWithCode(). MOZ_ASSERT(inst[1].encode() == NopInst); MOZ_ASSERT(inst[2].encode() == NopInst); MOZ_ASSERT(inst[3].encode() == NopInst); - MOZ_ASSERT(inst[4].encode() == NopInst); - addLongJump(BufferOffset(label->offset() + sizeof(void*))); - Assembler::WriteLuiOriInstructions(&inst[1], &inst[2], ScratchRegister, dest.getOffset()); - inst[3] = InstReg(op_special, ScratchRegister, zero, zero, ff_jr).encode(); + addMixedJump(b, ImmPtr((void*)dest.getOffset()), MixedJumpPatch::PATCHABLE); + inst[2] = InstJump(op_j, JOffImm26(0)).encode(); } } label->bind(dest.getOffset()); -- cgit v1.2.3 From c3a21acaee65f9fde0f76b635ce906ca9c901889 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Tue, 12 May 2020 12:40:07 +0800 Subject: Bug 1271968 - IonMonkey: MIPS: Merge Assembler::bind. Tag: #1542 --- js/src/jit/mips32/Assembler-mips32.cpp | 81 ---------------------------------- 1 file changed, 81 deletions(-) (limited to 'js/src/jit/mips32/Assembler-mips32.cpp') diff --git a/js/src/jit/mips32/Assembler-mips32.cpp b/js/src/jit/mips32/Assembler-mips32.cpp index 461f8d813..89c7a8c44 100644 --- a/js/src/jit/mips32/Assembler-mips32.cpp +++ b/js/src/jit/mips32/Assembler-mips32.cpp @@ -296,87 +296,6 @@ Assembler::Bind(uint8_t* rawCode, CodeOffset* label, const void* address) } } -void -Assembler::bind(InstImm* inst, uintptr_t branch, uintptr_t target) -{ - int32_t offset = target - branch; - - // Generate the patchable mixed jump for call. - if (inst->extractOpcode() == ((uint32_t)op_jal >> OpcodeShift)) { - addMixedJump(BufferOffset(branch), ImmPtr((void*)target)); - return; - } - - // If encoded offset is 4, then the jump must be short - if (BOffImm16(inst[0]).decode() == 4) { - MOZ_ASSERT(BOffImm16::IsInRange(offset)); - inst[0].setBOffImm16(BOffImm16(offset)); - inst[1].makeNop(); - return; - } - - if (BOffImm16::IsInRange(offset)) { - inst[0].setBOffImm16(BOffImm16(offset)); - inst[1].makeNop(); - return; - } - - addMixedJump(BufferOffset(branch), ImmPtr((const void*)target)); -} - -void -Assembler::bind(RepatchLabel* label) -{ - BufferOffset dest = nextOffset(); - if (label->used() && !oom()) { - // If the label has a use, then change this use to refer to - // the bound label; - BufferOffset b(label->offset()); - InstImm* inst = (InstImm*)editSrc(b); - InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0)); - uint32_t offset = dest.getOffset() - label->offset(); - - // If first instruction is j, then this is a mixed jump. - // If second instruction is lui, then this is a loop backedge. - if (inst[0].extractOpcode() == (uint32_t(op_j) >> OpcodeShift)) { - // For unconditional long branches generated by jumpWithPatch - addMixedJump(b, ImmPtr((void*)dest.getOffset()), MixedJumpPatch::PATCHABLE); - } else if (inst[1].extractOpcode() == (uint32_t(op_lui) >> OpcodeShift) || - BOffImm16::IsInRange(offset)) - { - // Handle code produced by: - // backedgeJump - MOZ_ASSERT(BOffImm16::IsInRange(offset)); - MOZ_ASSERT(inst[0].extractOpcode() == (uint32_t(op_beq) >> OpcodeShift) || - inst[0].extractOpcode() == (uint32_t(op_bne) >> OpcodeShift) || - inst[0].extractOpcode() == (uint32_t(op_blez) >> OpcodeShift) || - inst[0].extractOpcode() == (uint32_t(op_bgtz) >> OpcodeShift)); - inst[0].setBOffImm16(BOffImm16(offset)); - } else if (inst[0].encode() == inst_beq.encode()) { - // Handle open mixed unconditional jumps created by - // MacroAssemblerMIPSShared::ma_b(..., wasm::Trap, ...). - // We need to add it to mixed jumps array here. - // See MacroAssemblerMIPS::branchWithCode(). - MOZ_ASSERT(inst[1].encode() == NopInst); - addMixedJump(b, ImmPtr((void*)dest.getOffset()), MixedJumpPatch::PATCHABLE); - inst[0] = InstJump(op_j, JOffImm26(0)).encode(); - } else { - // Handle open mixed conditional jumps created by - // MacroAssemblerMIPSShared::ma_b(..., wasm::Trap, ...). - inst[0] = invertBranch(inst[0], BOffImm16(4 * sizeof(void*))); - // No need for a "nop" here because we can clobber scratch. - // We need to add it to mixed jumps array here. - // See MacroAssemblerMIPS::branchWithCode(). - MOZ_ASSERT(inst[1].encode() == NopInst); - MOZ_ASSERT(inst[2].encode() == NopInst); - MOZ_ASSERT(inst[3].encode() == NopInst); - addMixedJump(b, ImmPtr((void*)dest.getOffset()), MixedJumpPatch::PATCHABLE); - inst[2] = InstJump(op_j, JOffImm26(0)).encode(); - } - } - label->bind(dest.getOffset()); -} - uint32_t Assembler::PatchWrite_NearCallSize() { -- cgit v1.2.3 From b4f0be5e9537c6c202443b34f7bb3b99cb08be0f Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Tue, 12 May 2020 12:40:09 +0800 Subject: Bug 1271968 - IonMonkey: MIPS: Refactor PatchWrite_NearCall. Tag: #1542 --- js/src/jit/mips32/Assembler-mips32.cpp | 33 --------------------------------- 1 file changed, 33 deletions(-) (limited to 'js/src/jit/mips32/Assembler-mips32.cpp') diff --git a/js/src/jit/mips32/Assembler-mips32.cpp b/js/src/jit/mips32/Assembler-mips32.cpp index 89c7a8c44..f1fb71609 100644 --- a/js/src/jit/mips32/Assembler-mips32.cpp +++ b/js/src/jit/mips32/Assembler-mips32.cpp @@ -296,31 +296,6 @@ Assembler::Bind(uint8_t* rawCode, CodeOffset* label, const void* address) } } -uint32_t -Assembler::PatchWrite_NearCallSize() -{ - return 4 * sizeof(uint32_t); -} - -void -Assembler::PatchWrite_NearCall(CodeLocationLabel start, CodeLocationLabel toCall) -{ - Instruction* inst = (Instruction*) start.raw(); - uint8_t* dest = toCall.raw(); - - // Overwrite whatever instruction used to be here with a call. - // Always use long jump for two reasons: - // - Jump has to be the same size because of PatchWrite_NearCallSize. - // - Return address has to be at the end of replaced block. - // Short jump wouldn't be more efficient. - Assembler::WriteLuiOriInstructions(inst, &inst[1], ScratchRegister, (uint32_t)dest); - inst[2] = InstReg(op_special, ScratchRegister, zero, ra, ff_jalr); - inst[3] = InstNOP(); - - // Ensure everyone sees the code that was just written into memory. - AutoFlushICache::flush(uintptr_t(inst), PatchWrite_NearCallSize()); -} - uint32_t Assembler::ExtractLuiOriValue(Instruction* inst0, Instruction* inst1) { @@ -334,14 +309,6 @@ Assembler::ExtractLuiOriValue(Instruction* inst0, Instruction* inst1) return value; } -void -Assembler::WriteLuiOriInstructions(Instruction* inst0, Instruction* inst1, - Register reg, uint32_t value) -{ - *inst0 = InstImm(op_lui, zero, reg, Imm16::Upper(Imm32(value))); - *inst1 = InstImm(op_ori, reg, reg, Imm16::Lower(Imm32(value))); -} - void Assembler::PatchDataWithValueCheck(CodeLocationLabel label, ImmPtr newValue, ImmPtr expectedValue) -- cgit v1.2.3