#if ENABLE(ASSEMBLER) && CPU(MIPS)
#include "AssemblerBuffer.h"
+#include "JITCompilationEffort.h"
#include <wtf/Assertions.h>
#include <wtf/SegmentedVector.h>
return m_buffer.codeSize();
}
- void* executableCopy(JSGlobalData& globalData, ExecutablePool* allocator)
+ PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort)
{
- void *result = m_buffer.executableCopy(globalData, allocator);
+ RefPtr<ExecutableMemoryHandle> result = m_buffer.executableCopy(globalData, ownerUID, effort);
if (!result)
return 0;
- relocateJumps(m_buffer.data(), result);
- return result;
+ relocateJumps(m_buffer.data(), result->start());
+ return result.release();
}
-#ifndef NDEBUG
unsigned debugOffset() { return m_buffer.debugOffset(); }
-#endif
static unsigned getCallReturnOffset(AssemblerLabel call)
{
insn = insn - 6;
int flushSize = linkWithOffset(insn, to);
- ExecutableAllocator::cacheFlush(insn, flushSize);
+ cacheFlush(insn, flushSize);
}
static void relinkCall(void* from, void* to)
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)
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)
int32_t result = (*insn & 0x0000ffff) << 16;
insn++;
ASSERT((*insn & 0xfc000000) == 0x34000000); // ori
- result |= *insn & 0x0000ffff
+ result |= *insn & 0x0000ffff;
+ return result;
}
static void repatchCompact(void* where, int32_t value)
static void* readPointer(void* from)
{
- return static_cast<void*>(readInt32(from));
+ return reinterpret_cast<void*>(readInt32(from));
+ }
+
+ static void* readCallTarget(void* from)
+ {
+ MIPSWord* insn = reinterpret_cast<MIPSWord*>(from);
+ insn -= 4;
+ ASSERT((*insn & 0xffe00000) == 0x3c000000); // lui
+ int32_t result = (*insn & 0x0000ffff) << 16;
+ insn++;
+ ASSERT((*insn & 0xfc000000) == 0x34000000); // ori
+ result |= *insn & 0x0000ffff;
+ 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: