diff options
author | Jiaxun Yang <jiaxun.yang@flygoat.com> | 2020-05-12 12:40:08 +0800 |
---|---|---|
committer | Jiaxun Yang <jiaxun.yang@flygoat.com> | 2020-05-14 16:31:57 +0800 |
commit | 8055c99af4bea1c54d0af960447f6ba5cc72751c (patch) | |
tree | cc5bffddd1f50244c30674156dcc7981048d5190 /js/src | |
parent | 98620e3c1e67d60b4a338ba7fe2fa1fd885357b6 (diff) | |
download | uxp-8055c99af4bea1c54d0af960447f6ba5cc72751c.tar.gz |
Bug 1271968 - IonMonkey: MIPS: Handle conditional branch in out of line code of mixed jump.
Tag: #1542
Diffstat (limited to 'js/src')
-rw-r--r-- | js/src/jit/mips-shared/Assembler-mips-shared.cpp | 57 | ||||
-rw-r--r-- | js/src/jit/mips-shared/Assembler-mips-shared.h | 3 | ||||
-rw-r--r-- | js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp | 20 |
3 files changed, 39 insertions, 41 deletions
diff --git a/js/src/jit/mips-shared/Assembler-mips-shared.cpp b/js/src/jit/mips-shared/Assembler-mips-shared.cpp index 1b14ef0eb2..7b8ead20ac 100644 --- a/js/src/jit/mips-shared/Assembler-mips-shared.cpp +++ b/js/src/jit/mips-shared/Assembler-mips-shared.cpp @@ -1621,7 +1621,12 @@ AssemblerMIPSShared::bind(InstImm* inst, uintptr_t branch, uintptr_t target) return; } - addMixedJump(BufferOffset(branch), ImmPtr((void*)target)); + MixedJumpPatch::Kind kind = MixedJumpPatch::NONE; + InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0)); + if (inst[0].encode() != inst_beq.encode()) + kind = MixedJumpPatch::CONDITIONAL; + + addMixedJump(BufferOffset(branch), ImmPtr((const void*)target), kind); } void @@ -1763,6 +1768,8 @@ AssemblerMIPSShared::GetInstructionImmediateFromJump(Instruction* jump) uint32_t index = j->extractImm26Value() << 2; jump = (Instruction*)(base | index); + if (jump->extractOpcode() != ((uint32_t)op_lui >> OpcodeShift)) + jump = jump->next(); } return jump; @@ -1776,8 +1783,16 @@ AssemblerMIPSShared::PatchMixedJump(uint8_t* src, uint8_t* mid, uint8_t* target) int offset; if (mid) { + int o = 0; + InstImm* insn = (InstImm*)mid; + offset = intptr_t(mid); - Assembler::PatchInstructionImmediate(mid, PatchedImmPtr(target)); + if (insn->extractOpcode() != ((uint32_t)op_lui >> OpcodeShift)) { + o = 1 * sizeof(uint32_t); + Assembler::PatchInstructionImmediate(mid + Assembler::PatchWrite_NearCallSize(), + PatchedImmPtr(&b[2])); + } + Assembler::PatchInstructionImmediate(mid + o, PatchedImmPtr(target)); } else { offset = intptr_t(target); } @@ -1789,10 +1804,7 @@ AssemblerMIPSShared::PatchMixedJump(uint8_t* src, uint8_t* mid, uint8_t* target) j->setJOffImm26(JOffImm26(offset)); } else { - InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0)); - int i = (b[0].encode() == inst_beq.encode()) ? 0 : 2; - - b[i] = InstJump(op_j, JOffImm26(offset)).encode(); + b[0] = InstJump(op_j, JOffImm26(offset)).encode(); } } @@ -1802,35 +1814,20 @@ AssemblerMIPSShared::PatchMixedJumps(uint8_t* buffer) // Patch all mixed jumps. for (size_t i = 0; i < numMixedJumps(); i++) { MixedJumpPatch& mjp = mixedJump(i); - InstImm* b = (InstImm*)(buffer + mjp.src.getOffset()); - uint32_t opcode = b->extractOpcode(); - int offset; + uint8_t* src = buffer + mjp.src.getOffset(); + uint8_t* mid = nullptr; + uint8_t* target = buffer + uintptr_t(mjp.target); + InstImm* b = (InstImm*)src; if (mjp.mid.assigned()) { - offset = intptr_t(buffer) + mjp.mid.getOffset(); - Assembler::PatchInstructionImmediate(buffer + mjp.mid.getOffset(), - PatchedImmPtr(buffer + uintptr_t(mjp.target))); - } else { - offset = intptr_t(buffer) + intptr_t(mjp.target); - } - - if (((uint32_t)op_j >> OpcodeShift) == opcode || - ((uint32_t)op_jal >> OpcodeShift) == opcode) - { - InstJump* j = (InstJump*)b; - - j->setJOffImm26(JOffImm26(offset)); - } else { - InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0)); - - if (b[0].encode() == inst_beq.encode()) { - b[0] = InstJump(op_j, JOffImm26(offset)).encode(); - } else { - b[0] = invertBranch(b[0], BOffImm16(4 * sizeof(uint32_t))); - b[2] = InstJump(op_j, JOffImm26(offset)).encode(); + mid = buffer + mjp.mid.getOffset(); + if (MixedJumpPatch::CONDITIONAL & mjp.kind) { + InstImm* bc = (InstImm*)(buffer + mjp.mid.getOffset()); + bc[0] = invertBranch(b[0], BOffImm16(Assembler::PatchWrite_NearCallSize())); } } + PatchMixedJump(src, mid, target); b[1].makeNop(); } } diff --git a/js/src/jit/mips-shared/Assembler-mips-shared.h b/js/src/jit/mips-shared/Assembler-mips-shared.h index bebf8ad578..52e9051bb5 100644 --- a/js/src/jit/mips-shared/Assembler-mips-shared.h +++ b/js/src/jit/mips-shared/Assembler-mips-shared.h @@ -836,7 +836,8 @@ class AssemblerMIPSShared : public AssemblerShared { enum Kind { NONE, - PATCHABLE + PATCHABLE, + CONDITIONAL, }; BufferOffset src; diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp b/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp index 0f47e3bfbc..866a97dc87 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp @@ -647,7 +647,6 @@ void MacroAssemblerMIPSShared::branchWithCode(InstImm code, Label* label, JumpKind jumpKind) { MOZ_ASSERT(code.encode() != InstImm(op_regimm, zero, rt_bgezal, BOffImm16(0)).encode()); - InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0)); if (label->bound()) { int32_t offset = label->offset() - m_buffer.nextOffset().getOffset(); @@ -663,6 +662,7 @@ MacroAssemblerMIPSShared::branchWithCode(InstImm code, Label* label, JumpKind ju return; } + InstImm inst_beq = InstImm(op_beq, zero, zero, BOffImm16(0)); if (code.encode() == inst_beq.encode()) { // Handle mixed jump addMixedJump(nextOffset(), ImmPtr((void*)label->offset())); @@ -672,10 +672,8 @@ MacroAssemblerMIPSShared::branchWithCode(InstImm code, Label* label, JumpKind ju } // Handle long conditional branch - writeInst(invertBranch(code, BOffImm16(4 * sizeof(uint32_t))).encode()); - as_nop(); - addMixedJump(nextOffset(), ImmPtr((void*)label->offset())); - as_j(JOffImm26(0)); + addMixedJump(nextOffset(), ImmPtr((void*)label->offset()), MixedJumpPatch::CONDITIONAL); + writeInst(code.encode()); as_nop(); return; } @@ -686,7 +684,7 @@ MacroAssemblerMIPSShared::branchWithCode(InstImm code, Label* label, JumpKind ju 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)); if (jumpKind == ShortJump) { // Indicate that this is short jump with offset 4. @@ -696,10 +694,6 @@ MacroAssemblerMIPSShared::branchWithCode(InstImm code, Label* label, JumpKind ju writeInst(nextInChain); if (!oom()) label->use(bo.getOffset()); - if (jumpKind != ShortJump && code.encode() != inst_beq.encode()) { - as_nop(); - as_nop(); - } } // Branches when done from within mips-specific code. @@ -1050,6 +1044,12 @@ MacroAssemblerMIPSShared::GenerateMixedJumps() if (MixedJumpPatch::NONE == mjp.kind && uintptr_t(mjp.target) <= size()) continue; BufferOffset bo = m_buffer.nextOffset(); + if (MixedJumpPatch::CONDITIONAL & mjp.kind) { + // Leave space for conditional branch. + as_nop(); + asMasm().ma_liPatchable(ScratchRegister, ImmWord(0)); + as_jr(ScratchRegister); + } asMasm().ma_liPatchable(ScratchRegister, ImmWord(0)); as_jr(ScratchRegister); as_nop(); |