summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/assembler
diff options
context:
space:
mode:
authorZoltan Herczeg <zherczeg@webkit.org>2013-03-21 14:51:21 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-03-25 11:56:18 +0100
commitb420ac14cdd37fcef0b33bdbca2c10240f0f3272 (patch)
treec26c066eaf1fd601a1490b34f776f36bd14b8857 /Source/JavaScriptCore/assembler
parente8a56c51780cd3e3a0043c4f6a8849d4c2d87dd6 (diff)
downloadqtwebkit-b420ac14cdd37fcef0b33bdbca2c10240f0f3272.tar.gz
ARMv7 replaceWithJump ASSERT failure after r135330.
https://bugs.webkit.org/show_bug.cgi?id=103146 Reviewed by Filip Pizlo. On Linux, the 24 bit distance range of jumps sometimes does not enough to cover all targets addresses. This patch supports jumps outside of this range using a mov/movt/bx 10 byte long sequence. * assembler/ARMv7Assembler.h: (ARMv7Assembler): (JSC::ARMv7Assembler::revertJumpTo_movT3movtcmpT2): (JSC::ARMv7Assembler::nopw): (JSC::ARMv7Assembler::label): (JSC::ARMv7Assembler::replaceWithJump): (JSC::ARMv7Assembler::maxJumpReplacementSize): * assembler/MacroAssemblerARMv7.h: (JSC::MacroAssemblerARMv7::revertJumpReplacementToBranchPtrWithPatch): Change-Id: Ic90230b5f5d74023b5476897966a01ce7152071a git-svn-id: http://svn.webkit.org/repository/webkit/trunk@146396 268f45cc-cd09-0410-ab3c-d52691b4dbfc Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com> Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'Source/JavaScriptCore/assembler')
-rw-r--r--Source/JavaScriptCore/assembler/ARMv7Assembler.h45
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h7
2 files changed, 48 insertions, 4 deletions
diff --git a/Source/JavaScriptCore/assembler/ARMv7Assembler.h b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
index b93ec6e63..70eb2f0ba 100644
--- a/Source/JavaScriptCore/assembler/ARMv7Assembler.h
+++ b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
@@ -1262,6 +1262,20 @@ public:
m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_MOV_imm_T3, imm.m_value.imm4, rd, imm);
}
+#if OS(LINUX)
+ static void revertJumpTo_movT3movtcmpT2(void* instructionStart, RegisterID left, RegisterID right, uintptr_t imm)
+ {
+ uint16_t* address = static_cast<uint16_t*>(instructionStart);
+ ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(imm));
+ ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(imm >> 16));
+ address[0] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOV_imm_T3, lo16);
+ address[1] = twoWordOp5i6Imm4Reg4EncodedImmSecond(right, lo16);
+ address[2] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16);
+ address[3] = twoWordOp5i6Imm4Reg4EncodedImmSecond(right, hi16);
+ address[4] = OP_CMP_reg_T2 | left;
+ cacheFlush(address, sizeof(uint16_t) * 5);
+ }
+#else
static void revertJumpTo_movT3(void* instructionStart, RegisterID rd, ARMThumbImmediate imm)
{
ASSERT(imm.isValid());
@@ -1273,6 +1287,7 @@ public:
address[1] = twoWordOp5i6Imm4Reg4EncodedImmSecond(rd, imm);
cacheFlush(address, sizeof(uint16_t) * 2);
}
+#endif
ALWAYS_INLINE void mov(RegisterID rd, ARMThumbImmediate imm)
{
@@ -1858,7 +1873,12 @@ public:
{
m_formatter.oneWordOp8Imm8(OP_NOP_T1, 0);
}
-
+
+ void nopw()
+ {
+ m_formatter.twoWordOp16Op16(OP_NOP_T2a, OP_NOP_T2b);
+ }
+
AssemblerLabel labelIgnoringWatchpoints()
{
return m_formatter.label();
@@ -1878,7 +1898,10 @@ public:
{
AssemblerLabel result = m_formatter.label();
while (UNLIKELY(static_cast<int>(result.m_offset) < m_indexOfTailOfLastWatchpoint)) {
- nop();
+ if (UNLIKELY(static_cast<int>(result.m_offset) + 4 <= m_indexOfTailOfLastWatchpoint))
+ nopw();
+ else
+ nop();
result = m_formatter.label();
}
return result;
@@ -2136,15 +2159,31 @@ public:
{
ASSERT(!(bitwise_cast<uintptr_t>(instructionStart) & 1));
ASSERT(!(bitwise_cast<uintptr_t>(to) & 1));
+
+#if OS(LINUX)
+ if (canBeJumpT4(reinterpret_cast<uint16_t*>(instructionStart), to)) {
+ uint16_t* ptr = reinterpret_cast<uint16_t*>(instructionStart) + 2;
+ linkJumpT4(ptr, to);
+ cacheFlush(ptr - 2, sizeof(uint16_t) * 2);
+ } else {
+ uint16_t* ptr = reinterpret_cast<uint16_t*>(instructionStart) + 5;
+ linkBX(ptr, to);
+ cacheFlush(ptr - 5, sizeof(uint16_t) * 5);
+ }
+#else
uint16_t* ptr = reinterpret_cast<uint16_t*>(instructionStart) + 2;
-
linkJumpT4(ptr, to);
cacheFlush(ptr - 2, sizeof(uint16_t) * 2);
+#endif
}
static ptrdiff_t maxJumpReplacementSize()
{
+#if OS(LINUX)
+ return 10;
+#else
return 4;
+#endif
}
static void replaceWithLoad(void* instructionStart)
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
index 8d7a3a69a..13c67520f 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
@@ -1767,9 +1767,14 @@ public:
return label.labelAtOffset(-twoWordOpSize * 2);
}
- static void revertJumpReplacementToBranchPtrWithPatch(CodeLocationLabel instructionStart, RegisterID, void* initialValue)
+ static void revertJumpReplacementToBranchPtrWithPatch(CodeLocationLabel instructionStart, RegisterID rd, void* initialValue)
{
+#if OS(LINUX)
+ ARMv7Assembler::revertJumpTo_movT3movtcmpT2(instructionStart.dataLocation(), rd, dataTempRegister, reinterpret_cast<uintptr_t>(initialValue));
+#else
+ UNUSED_PARAM(rd);
ARMv7Assembler::revertJumpTo_movT3(instructionStart.dataLocation(), dataTempRegister, ARMThumbImmediate::makeUInt16(reinterpret_cast<uintptr_t>(initialValue) & 0xffff));
+#endif
}
static CodeLocationLabel startOfPatchableBranchPtrWithPatchOnAddress(CodeLocationDataLabelPtr)