diff options
Diffstat (limited to 'Source/JavaScriptCore/assembler')
-rw-r--r-- | Source/JavaScriptCore/assembler/ARMAssembler.cpp | 17 | ||||
-rw-r--r-- | Source/JavaScriptCore/assembler/ARMAssembler.h | 36 | ||||
-rw-r--r-- | Source/JavaScriptCore/assembler/ARMv7Assembler.h | 37 | ||||
-rw-r--r-- | Source/JavaScriptCore/assembler/AbstractMacroAssembler.h | 8 | ||||
-rw-r--r-- | Source/JavaScriptCore/assembler/LinkBuffer.h | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/assembler/MIPSAssembler.h | 32 | ||||
-rw-r--r-- | Source/JavaScriptCore/assembler/SH4Assembler.h | 13 | ||||
-rw-r--r-- | Source/JavaScriptCore/assembler/X86Assembler.h | 3 |
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) |