summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiaxun Yang <jiaxun.yang@flygoat.com>2020-05-12 12:40:08 +0800
committerMoonchild <moonchild@palemoon.org>2020-05-20 14:01:30 +0000
commitac62e4cfdd03369d60e22f78b38b81f5f8daa5bd (patch)
treeb5a32581cefceb2f5380312af673533fc571a599
parent0fa41e2adc3e6b247ccb3051672723547f3c918f (diff)
downloadUXP-ac62e4cfdd03369d60e22f78b38b81f5f8daa5bd.tar
UXP-ac62e4cfdd03369d60e22f78b38b81f5f8daa5bd.tar.gz
UXP-ac62e4cfdd03369d60e22f78b38b81f5f8daa5bd.tar.lz
UXP-ac62e4cfdd03369d60e22f78b38b81f5f8daa5bd.tar.xz
UXP-ac62e4cfdd03369d60e22f78b38b81f5f8daa5bd.zip
Bug 1271968 - IonMonkey: MIPS: Handle conditional branch in out of line code of mixed jump.
Tag: #1542
-rw-r--r--js/src/jit/mips-shared/Assembler-mips-shared.cpp57
-rw-r--r--js/src/jit/mips-shared/Assembler-mips-shared.h3
-rw-r--r--js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp20
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 1b14ef0eb..7b8ead20a 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 bebf8ad57..52e9051bb 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 0f47e3bfb..866a97dc8 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();