diff options
author | Jiaxun Yang <jiaxun.yang@flygoat.com> | 2020-05-12 12:40:07 +0800 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2020-05-20 14:00:59 +0000 |
commit | 3fb8648bed83c95f601d2c2e20962cbd08bc7dc7 (patch) | |
tree | 2de25a180e7fd42a82be6aad4c8db98ae24d32cf /js/src/jit/mips32 | |
parent | f18d78dea035c5291984d1c468336d20dc0b47b7 (diff) | |
download | UXP-3fb8648bed83c95f601d2c2e20962cbd08bc7dc7.tar UXP-3fb8648bed83c95f601d2c2e20962cbd08bc7dc7.tar.gz UXP-3fb8648bed83c95f601d2c2e20962cbd08bc7dc7.tar.lz UXP-3fb8648bed83c95f601d2c2e20962cbd08bc7dc7.tar.xz UXP-3fb8648bed83c95f601d2c2e20962cbd08bc7dc7.zip |
Bug 1271968 - IonMonkey: MIPS: Replace long jumps by mixed jumps.
Tag: #1542
Diffstat (limited to 'js/src/jit/mips32')
-rw-r--r-- | js/src/jit/mips32/Assembler-mips32.cpp | 101 | ||||
-rw-r--r-- | js/src/jit/mips32/Assembler-mips32.h | 4 | ||||
-rw-r--r-- | js/src/jit/mips32/MacroAssembler-mips32.cpp | 68 | ||||
-rw-r--r-- | js/src/jit/mips32/MacroAssembler-mips32.h | 14 |
4 files changed, 55 insertions, 132 deletions
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()); diff --git a/js/src/jit/mips32/Assembler-mips32.h b/js/src/jit/mips32/Assembler-mips32.h index cf7f0d228..a519b9876 100644 --- a/js/src/jit/mips32/Assembler-mips32.h +++ b/js/src/jit/mips32/Assembler-mips32.h @@ -154,10 +154,6 @@ class Assembler : public AssemblerMIPSShared void bind(InstImm* inst, uintptr_t branch, uintptr_t target); - // Copy the assembly code to the given buffer, and perform any pending - // relocations relying on the target address. - void executableCopy(uint8_t* buffer); - static uint32_t PatchWrite_NearCallSize(); static uint32_t ExtractLuiOriValue(Instruction* inst0, Instruction* inst1); diff --git a/js/src/jit/mips32/MacroAssembler-mips32.cpp b/js/src/jit/mips32/MacroAssembler-mips32.cpp index d3d3a75d1..53d1a7925 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.cpp +++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp @@ -504,16 +504,13 @@ MacroAssemblerMIPS::ma_b(Address addr, ImmGCPtr imm, Label* label, Condition c, } void -MacroAssemblerMIPS::ma_bal(Label* label, DelaySlotFill delaySlotFill) +MacroAssemblerMIPS::ma_jal(Label* label) { if (label->bound()) { - // Generate the long jump for calls because return address has to be - // the address after the reserved block. - addLongJump(nextOffset()); - ma_liPatchable(ScratchRegister, Imm32(label->offset())); - as_jalr(ScratchRegister); - if (delaySlotFill == FillDelaySlot) - as_nop(); + // Generate the mixed jump. + addMixedJump(nextOffset(), ImmPtr((void*)label->offset())); + as_jal(JOffImm26(0)); + as_nop(); return; } @@ -521,16 +518,12 @@ MacroAssemblerMIPS::ma_bal(Label* label, DelaySlotFill delaySlotFill) uint32_t nextInChain = label->used() ? label->offset() : LabelBase::INVALID_OFFSET; // Make the whole branch continous in the buffer. - m_buffer.ensureSpace(4 * sizeof(uint32_t)); + m_buffer.ensureSpace(2 * sizeof(uint32_t)); - BufferOffset bo = writeInst(getBranchCode(BranchIsCall).encode()); + BufferOffset bo = as_jal(JOffImm26(0)); writeInst(nextInChain); if (!oom()) label->use(bo.getOffset()); - // Leave space for long jump. - as_nop(); - if (delaySlotFill == FillDelaySlot) - as_nop(); } void @@ -554,20 +547,18 @@ MacroAssemblerMIPS::branchWithCode(InstImm code, Label* label, JumpKind jumpKind } if (code.encode() == inst_beq.encode()) { - // Handle long jump - addLongJump(nextOffset()); - ma_liPatchable(ScratchRegister, Imm32(label->offset())); - as_jr(ScratchRegister); + // Handle mixed jump + addMixedJump(nextOffset(), ImmPtr((void*)label->offset())); + as_j(JOffImm26(0)); as_nop(); return; } // Handle long conditional branch - writeInst(invertBranch(code, BOffImm16(5 * sizeof(uint32_t))).encode()); - // No need for a "nop" here because we can clobber scratch. - addLongJump(nextOffset()); - ma_liPatchable(ScratchRegister, Imm32(label->offset())); - as_jr(ScratchRegister); + writeInst(invertBranch(code, BOffImm16(4 * sizeof(uint32_t))).encode()); + as_nop(); + addMixedJump(nextOffset(), ImmPtr((void*)label->offset())); + as_j(JOffImm26(0)); as_nop(); return; } @@ -577,33 +568,21 @@ MacroAssemblerMIPS::branchWithCode(InstImm code, Label* label, JumpKind jumpKind // Second word holds a pointer to the next branch in label's chain. uint32_t nextInChain = label->used() ? label->offset() : LabelBase::INVALID_OFFSET; - if (jumpKind == ShortJump) { - // Make the whole branch continous in the buffer. - m_buffer.ensureSpace(2 * sizeof(uint32_t)); + // Make the whole branch continous in the buffer. + m_buffer.ensureSpace(4 * sizeof(uint32_t)); + if (jumpKind == ShortJump) { // Indicate that this is short jump with offset 4. code.setBOffImm16(BOffImm16(4)); - BufferOffset bo = writeInst(code.encode()); - writeInst(nextInChain); - if (!oom()) - label->use(bo.getOffset()); - return; } - - bool conditional = code.encode() != inst_beq.encode(); - - // Make the whole branch continous in the buffer. - m_buffer.ensureSpace((conditional ? 5 : 4) * sizeof(uint32_t)); - BufferOffset bo = writeInst(code.encode()); writeInst(nextInChain); if (!oom()) label->use(bo.getOffset()); - // Leave space for potential long jump. - as_nop(); - as_nop(); - if (conditional) + if (jumpKind != ShortJump && code.encode() != inst_beq.encode()) { as_nop(); + as_nop(); + } } void @@ -1597,13 +1576,12 @@ MacroAssemblerMIPSCompat::jumpWithPatch(RepatchLabel* label, Label* documentatio { // Only one branch per label. MOZ_ASSERT(!label->used()); - uint32_t dest = label->bound() ? label->offset() : LabelBase::INVALID_OFFSET; BufferOffset bo = nextOffset(); label->use(bo.getOffset()); - addLongJump(bo); - ma_liPatchable(ScratchRegister, Imm32(dest)); - as_jr(ScratchRegister); + if (label->bound()) + addMixedJump(bo, ImmPtr((void*)label->offset()), MixedJumpPatch::PATCHABLE); + as_j(JOffImm26(0)); as_nop(); return CodeOffsetJump(bo.getOffset()); } diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index fe36c66be..3b5c06399 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -91,25 +91,25 @@ class MacroAssemblerMIPS : public MacroAssemblerMIPSShared void branchWithCode(InstImm code, Label* label, JumpKind jumpKind); // branches when done from within mips-specific code - void ma_b(Register lhs, ImmWord imm, Label* l, Condition c, JumpKind jumpKind = LongJump) + void ma_b(Register lhs, ImmWord imm, Label* l, Condition c, JumpKind jumpKind = MixedJump) { ma_b(lhs, Imm32(uint32_t(imm.value)), l, c, jumpKind); } - void ma_b(Address addr, ImmWord imm, Label* l, Condition c, JumpKind jumpKind = LongJump) + void ma_b(Address addr, ImmWord imm, Label* l, Condition c, JumpKind jumpKind = MixedJump) { ma_b(addr, Imm32(uint32_t(imm.value)), l, c, jumpKind); } - void ma_b(Register lhs, Address addr, Label* l, Condition c, JumpKind jumpKind = LongJump); - void ma_b(Address addr, Imm32 imm, Label* l, Condition c, JumpKind jumpKind = LongJump); - void ma_b(Address addr, ImmGCPtr imm, Label* l, Condition c, JumpKind jumpKind = LongJump); - void ma_b(Address addr, Register rhs, Label* l, Condition c, JumpKind jumpKind = LongJump) { + void ma_b(Register lhs, Address addr, Label* l, Condition c, JumpKind jumpKind = MixedJump); + void ma_b(Address addr, Imm32 imm, Label* l, Condition c, JumpKind jumpKind = MixedJump); + void ma_b(Address addr, ImmGCPtr imm, Label* l, Condition c, JumpKind jumpKind = MixedJump); + void ma_b(Address addr, Register rhs, Label* l, Condition c, JumpKind jumpKind = MixedJump) { MOZ_ASSERT(rhs != ScratchRegister); ma_load(ScratchRegister, addr, SizeWord); ma_b(ScratchRegister, rhs, l, c, jumpKind); } - void ma_bal(Label* l, DelaySlotFill delaySlotFill = FillDelaySlot); + void ma_jal(Label* l); // fp instructions void ma_lid(FloatRegister dest, double value); |