summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/assembler
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/assembler')
-rw-r--r--Source/JavaScriptCore/assembler/ARMAssembler.cpp17
-rw-r--r--Source/JavaScriptCore/assembler/ARMAssembler.h36
-rw-r--r--Source/JavaScriptCore/assembler/ARMv7Assembler.h37
-rw-r--r--Source/JavaScriptCore/assembler/AbstractMacroAssembler.h8
-rw-r--r--Source/JavaScriptCore/assembler/LinkBuffer.h2
-rw-r--r--Source/JavaScriptCore/assembler/MIPSAssembler.h32
-rw-r--r--Source/JavaScriptCore/assembler/SH4Assembler.h13
-rw-r--r--Source/JavaScriptCore/assembler/X86Assembler.h3
8 files changed, 140 insertions, 8 deletions
diff --git a/Source/JavaScriptCore/assembler/ARMAssembler.cpp b/Source/JavaScriptCore/assembler/ARMAssembler.cpp
index b880f50bf..74809cadb 100644
--- a/Source/JavaScriptCore/assembler/ARMAssembler.cpp
+++ b/Source/JavaScriptCore/assembler/ARMAssembler.cpp
@@ -375,6 +375,23 @@ PassRefPtr<ExecutableMemoryHandle> ARMAssembler::executableCopy(JSGlobalData& gl
return result;
}
+#if OS(LINUX) && COMPILER(RVCT)
+
+__asm void ARMAssembler::cacheFlush(void* code, size_t size)
+{
+ ARM
+ push {r7}
+ add r1, r1, r0
+ mov r7, #0xf0000
+ add r7, r7, #0x2
+ mov r2, #0x0
+ svc #0x0
+ pop {r7}
+ bx lr
+}
+
+#endif
+
} // namespace JSC
#endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
diff --git a/Source/JavaScriptCore/assembler/ARMAssembler.h b/Source/JavaScriptCore/assembler/ARMAssembler.h
index a9ecf5091..16dc0cfc2 100644
--- a/Source/JavaScriptCore/assembler/ARMAssembler.h
+++ b/Source/JavaScriptCore/assembler/ARMAssembler.h
@@ -864,6 +864,42 @@ namespace JSC {
return AL | B | (offset & BRANCH_MASK);
}
+#if OS(LINUX) && COMPILER(RVCT)
+ static __asm void cacheFlush(void* code, size_t);
+#else
+ static void cacheFlush(void* code, size_t size)
+ {
+#if OS(LINUX) && COMPILER(GCC)
+ uintptr_t currentPage = reinterpret_cast<uintptr_t>(code) & ~(pageSize() - 1);
+ uintptr_t lastPage = (reinterpret_cast<uintptr_t>(code) + size) & ~(pageSize() - 1);
+ do {
+ asm volatile(
+ "push {r7}\n"
+ "mov r0, %0\n"
+ "mov r1, %1\n"
+ "mov r7, #0xf0000\n"
+ "add r7, r7, #0x2\n"
+ "mov r2, #0x0\n"
+ "svc 0x0\n"
+ "pop {r7}\n"
+ :
+ : "r" (currentPage), "r" (currentPage + pageSize())
+ : "r0", "r1", "r2");
+ currentPage += pageSize();
+ } while (lastPage >= currentPage);
+#elif OS(WINCE)
+ CacheRangeFlush(code, size, CACHE_SYNC_ALL);
+#elif OS(QNX) && ENABLE(ASSEMBLER_WX_EXCLUSIVE)
+ UNUSED_PARAM(code);
+ UNUSED_PARAM(size);
+#elif OS(QNX)
+ msync(code, size, MS_INVALIDATE_ICACHE);
+#else
+#error "The cacheFlush support is missing on this platform."
+#endif
+ }
+#endif
+
private:
ARMWord RM(int reg)
{
diff --git a/Source/JavaScriptCore/assembler/ARMv7Assembler.h b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
index 5b523c277..0cbe799b4 100644
--- a/Source/JavaScriptCore/assembler/ARMv7Assembler.h
+++ b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
@@ -2026,7 +2026,7 @@ public:
linkJumpAbsolute(reinterpret_cast<uint16_t*>(from), to);
- ExecutableAllocator::cacheFlush(reinterpret_cast<uint16_t*>(from) - 5, 5 * sizeof(uint16_t));
+ cacheFlush(reinterpret_cast<uint16_t*>(from) - 5, 5 * sizeof(uint16_t));
}
static void relinkCall(void* from, void* to)
@@ -2070,6 +2070,37 @@ public:
unsigned debugOffset() { return m_formatter.debugOffset(); }
+ static void cacheFlush(void* code, size_t size)
+ {
+#if OS(IOS)
+ sys_cache_control(kCacheFunctionPrepareForExecution, code, size);
+#elif OS(LINUX)
+ asm volatile(
+ "push {r7}\n"
+ "mov r0, %0\n"
+ "mov r1, %1\n"
+ "movw r7, #0x2\n"
+ "movt r7, #0xf\n"
+ "movs r2, #0x0\n"
+ "svc 0x0\n"
+ "pop {r7}\n"
+ :
+ : "r" (code), "r" (reinterpret_cast<char*>(code) + size)
+ : "r0", "r1", "r2");
+#elif OS(WINCE)
+ CacheRangeFlush(code, size, CACHE_SYNC_ALL);
+#elif OS(QNX)
+#if !ENABLE(ASSEMBLER_WX_EXCLUSIVE)
+ msync(code, size, MS_INVALIDATE_ICACHE);
+#else
+ UNUSED_PARAM(code);
+ UNUSED_PARAM(size);
+#endif
+#else
+#error "The cacheFlush support is missing on this platform."
+#endif
+ }
+
private:
// VFP operations commonly take one or more 5-bit operands, typically representing a
// floating point register number. This will commonly be encoded in the instruction
@@ -2149,7 +2180,7 @@ private:
location[-2] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16);
location[-1] = twoWordOp5i6Imm4Reg4EncodedImmSecond((location[-1] >> 8) & 0xf, hi16);
- ExecutableAllocator::cacheFlush(location - 4, 4 * sizeof(uint16_t));
+ cacheFlush(location - 4, 4 * sizeof(uint16_t));
}
static int32_t readInt32(void* code)
@@ -2177,7 +2208,7 @@ private:
uint16_t* location = reinterpret_cast<uint16_t*>(code);
location[0] &= ~((static_cast<uint16_t>(0x7f) >> 2) << 6);
location[0] |= (imm.getUInt7() >> 2) << 6;
- ExecutableAllocator::cacheFlush(location, sizeof(uint16_t));
+ cacheFlush(location, sizeof(uint16_t));
}
static void setPointer(void* code, void* value)
diff --git a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
index 4fb60dd2d..a0039cb52 100644
--- a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
+++ b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
@@ -171,6 +171,8 @@ public:
// in a class requiring explicit construction in order to differentiate
// from pointers used as absolute addresses to memory operations
struct TrustedImmPtr {
+ TrustedImmPtr() { }
+
explicit TrustedImmPtr(const void* value)
: m_value(value)
{
@@ -219,6 +221,8 @@ public:
// (which are implemented as an enum) from accidentally being passed as
// immediate values.
struct TrustedImm32 {
+ TrustedImm32() { }
+
explicit TrustedImm32(int32_t value)
: m_value(value)
{
@@ -574,6 +578,10 @@ public:
unsigned debugOffset() { return m_assembler.debugOffset(); }
+ ALWAYS_INLINE static void cacheFlush(void* code, size_t size)
+ {
+ AssemblerType::cacheFlush(code, size);
+ }
protected:
AbstractMacroAssembler()
: m_randomSource(cryptographicallyRandomNumber())
diff --git a/Source/JavaScriptCore/assembler/LinkBuffer.h b/Source/JavaScriptCore/assembler/LinkBuffer.h
index 5e91ef3ce..eff320d57 100644
--- a/Source/JavaScriptCore/assembler/LinkBuffer.h
+++ b/Source/JavaScriptCore/assembler/LinkBuffer.h
@@ -329,7 +329,7 @@ private:
#else
ExecutableAllocator::makeExecutable(code(), m_size);
#endif
- ExecutableAllocator::cacheFlush(code(), m_size);
+ MacroAssembler::cacheFlush(code(), m_size);
}
#if DUMP_LINK_STATISTICS
diff --git a/Source/JavaScriptCore/assembler/MIPSAssembler.h b/Source/JavaScriptCore/assembler/MIPSAssembler.h
index 5e0645129..7212a182c 100644
--- a/Source/JavaScriptCore/assembler/MIPSAssembler.h
+++ b/Source/JavaScriptCore/assembler/MIPSAssembler.h
@@ -718,7 +718,7 @@ public:
insn = insn - 6;
int flushSize = linkWithOffset(insn, to);
- ExecutableAllocator::cacheFlush(insn, flushSize);
+ cacheFlush(insn, flushSize);
}
static void relinkCall(void* from, void* to)
@@ -730,7 +730,7 @@ public:
else
start = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(from) - 4 * sizeof(MIPSWord));
- ExecutableAllocator::cacheFlush(start, size);
+ cacheFlush(start, size);
}
static void repatchInt32(void* from, int32_t to)
@@ -742,7 +742,7 @@ public:
ASSERT((*insn & 0xfc000000) == 0x34000000); // ori
*insn = (*insn & 0xffff0000) | (to & 0xffff);
insn--;
- ExecutableAllocator::cacheFlush(insn, 2 * sizeof(MIPSWord));
+ cacheFlush(insn, 2 * sizeof(MIPSWord));
}
static int32_t readInt32(void* from)
@@ -783,6 +783,32 @@ public:
return reinterpret_cast<void*>(result);
}
+ static void cacheFlush(void* code, size_t size)
+ {
+#if GCC_VERSION_AT_LEAST(4, 3, 0)
+#if WTF_MIPS_ISA_REV(2) && !GCC_VERSION_AT_LEAST(4, 4, 3)
+ int lineSize;
+ asm("rdhwr %0, $1" : "=r" (lineSize));
+ //
+ // Modify "start" and "end" to avoid GCC 4.3.0-4.4.2 bug in
+ // mips_expand_synci_loop that may execute synci one more time.
+ // "start" points to the fisrt byte of the cache line.
+ // "end" points to the last byte of the line before the last cache line.
+ // Because size is always a multiple of 4, this is safe to set
+ // "end" to the last byte.
+ //
+ intptr_t start = reinterpret_cast<intptr_t>(code) & (-lineSize);
+ intptr_t end = ((reinterpret_cast<intptr_t>(code) + size - 1) & (-lineSize)) - 1;
+ __builtin___clear_cache(reinterpret_cast<char*>(start), reinterpret_cast<char*>(end));
+#else
+ intptr_t end = reinterpret_cast<intptr_t>(code) + size;
+ __builtin___clear_cache(reinterpret_cast<char*>(code), reinterpret_cast<char*>(end));
+#endif
+#else
+ _flush_cache(reinterpret_cast<char*>(code), size, BCACHE);
+#endif
+ }
+
private:
/* Update each jump in the buffer of newBase. */
void relocateJumps(void* oldBase, void* newBase)
diff --git a/Source/JavaScriptCore/assembler/SH4Assembler.h b/Source/JavaScriptCore/assembler/SH4Assembler.h
index 11e954cad..59d042244 100644
--- a/Source/JavaScriptCore/assembler/SH4Assembler.h
+++ b/Source/JavaScriptCore/assembler/SH4Assembler.h
@@ -1401,7 +1401,7 @@ public:
ASSERT(value >= 0);
ASSERT(value <= 60);
*reinterpret_cast<uint16_t*>(where) = ((*reinterpret_cast<uint16_t*>(where) & 0xfff0) | (value >> 2));
- ExecutableAllocator::cacheFlush(reinterpret_cast<uint16_t*>(where), sizeof(uint16_t));
+ cacheFlush(reinterpret_cast<uint16_t*>(where), sizeof(uint16_t));
}
static void relinkCall(void* from, void* to)
@@ -1546,6 +1546,17 @@ public:
return m_buffer.executableCopy(globalData, ownerUID, effort);
}
+ static void cacheFlush(void* code, size_t size)
+ {
+#if !OS(LINUX)
+#error "The cacheFlush support is missing on this platform."
+#elif defined CACHEFLUSH_D_L2
+ syscall(__NR_cacheflush, reinterpret_cast<unsigned>(code), size, CACHEFLUSH_D_WB | CACHEFLUSH_I | CACHEFLUSH_D_L2);
+#else
+ syscall(__NR_cacheflush, reinterpret_cast<unsigned>(code), size, CACHEFLUSH_D_WB | CACHEFLUSH_I);
+#endif
+ }
+
void prefix(uint16_t pre)
{
m_buffer.putByte(pre);
diff --git a/Source/JavaScriptCore/assembler/X86Assembler.h b/Source/JavaScriptCore/assembler/X86Assembler.h
index b24fffb8f..ff8d25bcd 100644
--- a/Source/JavaScriptCore/assembler/X86Assembler.h
+++ b/Source/JavaScriptCore/assembler/X86Assembler.h
@@ -1816,6 +1816,9 @@ public:
m_formatter.oneByteOp(OP_NOP);
}
+ // This is a no-op on x86
+ ALWAYS_INLINE static void cacheFlush(void*, size_t) { }
+
private:
static void setPointer(void* where, void* value)