diff options
Diffstat (limited to 'JavaScriptCore/jit/ExecutableAllocator.h')
| -rw-r--r-- | JavaScriptCore/jit/ExecutableAllocator.h | 120 |
1 files changed, 95 insertions, 25 deletions
diff --git a/JavaScriptCore/jit/ExecutableAllocator.h b/JavaScriptCore/jit/ExecutableAllocator.h index 1fb8ff7..f362605 100644 --- a/JavaScriptCore/jit/ExecutableAllocator.h +++ b/JavaScriptCore/jit/ExecutableAllocator.h @@ -25,16 +25,16 @@ #ifndef ExecutableAllocator_h #define ExecutableAllocator_h - #include <stddef.h> // for ptrdiff_t #include <limits> #include <wtf/Assertions.h> +#include <wtf/PageAllocation.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> #include <wtf/UnusedParam.h> #include <wtf/Vector.h> -#if OS(IPHONE_OS) +#if OS(IOS) #include <libkern/OSCacheControl.h> #include <sys/mman.h> #endif @@ -43,21 +43,31 @@ #include <e32std.h> #endif +#if CPU(MIPS) && OS(LINUX) +#include <sys/cachectl.h> +#endif + #if OS(WINCE) // From pkfuncs.h (private header file from the Platform Builder) #define CACHE_SYNC_ALL 0x07F extern "C" __declspec(dllimport) void CacheRangeFlush(LPVOID pAddr, DWORD dwLength, DWORD dwFlags); #endif +#if PLATFORM(BREWMP) +#include <AEEIMemCache1.h> +#include <AEEMemCache1.bid> +#include <wtf/brew/RefPtrBrew.h> +#endif + #define JIT_ALLOCATOR_PAGE_SIZE (ExecutableAllocator::pageSize) #define JIT_ALLOCATOR_LARGE_ALLOC_SIZE (ExecutableAllocator::pageSize * 4) #if ENABLE(ASSEMBLER_WX_EXCLUSIVE) #define PROTECTION_FLAGS_RW (PROT_READ | PROT_WRITE) #define PROTECTION_FLAGS_RX (PROT_READ | PROT_EXEC) -#define INITIAL_PROTECTION_FLAGS PROTECTION_FLAGS_RX +#define EXECUTABLE_POOL_WRITABLE false #else -#define INITIAL_PROTECTION_FLAGS (PROT_READ | PROT_WRITE | PROT_EXEC) +#define EXECUTABLE_POOL_WRITABLE true #endif namespace JSC { @@ -76,22 +86,33 @@ inline size_t roundUpAllocationSize(size_t request, size_t granularity) } -#if ENABLE(ASSEMBLER) +#if ENABLE(JIT) && ENABLE(ASSEMBLER) namespace JSC { class ExecutablePool : public RefCounted<ExecutablePool> { -private: - struct Allocation { - char* pages; - size_t size; -#if OS(SYMBIAN) - RChunk* chunk; -#endif +public: +#if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND) + typedef PageAllocation Allocation; +#else + class Allocation { + public: + Allocation(void* base, size_t size) + : m_base(base) + , m_size(size) + { + } + void* base() { return m_base; } + size_t size() { return m_size; } + bool operator!() const { return !m_base; } + + private: + void* m_base; + size_t m_size; }; +#endif typedef Vector<Allocation, 2> AllocationList; -public: static PassRefPtr<ExecutablePool> create(size_t n) { return adoptRef(new ExecutablePool(n)); @@ -116,10 +137,15 @@ public: return poolAllocate(n); } + void returnLastBytes(size_t count) + { + m_freePtr -= count; + } + ~ExecutablePool() { - AllocationList::const_iterator end = m_pools.end(); - for (AllocationList::const_iterator ptr = m_pools.begin(); ptr != end; ++ptr) + AllocationList::iterator end = m_pools.end(); + for (AllocationList::iterator ptr = m_pools.begin(); ptr != end; ++ptr) ExecutablePool::systemRelease(*ptr); } @@ -127,7 +153,7 @@ public: private: static Allocation systemAlloc(size_t n); - static void systemRelease(const Allocation& alloc); + static void systemRelease(Allocation& alloc); ExecutablePool(size_t n); @@ -147,12 +173,20 @@ public: { if (!pageSize) intializePageSize(); - m_smallAllocationPool = ExecutablePool::create(JIT_ALLOCATOR_LARGE_ALLOC_SIZE); + if (isValid()) + m_smallAllocationPool = ExecutablePool::create(JIT_ALLOCATOR_LARGE_ALLOC_SIZE); +#if !ENABLE(INTERPRETER) + else + CRASH(); +#endif } + bool isValid() const; + PassRefPtr<ExecutablePool> poolForSize(size_t n) { // Try to fit in the existing small allocator + ASSERT(m_smallAllocationPool); if (n < m_smallAllocationPool->available()) return m_smallAllocationPool; @@ -190,7 +224,33 @@ public: static void cacheFlush(void*, size_t) { } -#elif CPU(ARM_THUMB2) && OS(IPHONE_OS) +#elif CPU(MIPS) + static void cacheFlush(void* code, size_t size) + { +#if COMPILER(GCC) && 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 + } +#elif CPU(ARM_THUMB2) && OS(IOS) static void cacheFlush(void* code, size_t size) { sys_dcache_flush(code, size); @@ -217,7 +277,9 @@ public: { User::IMB_Range(code, static_cast<char*>(code) + size); } -#elif CPU(ARM_TRADITIONAL) && OS(LINUX) +#elif CPU(ARM_TRADITIONAL) && OS(LINUX) && COMPILER(RVCT) + static __asm void cacheFlush(void* code, size_t size); +#elif CPU(ARM_TRADITIONAL) && OS(LINUX) && COMPILER(GCC) static void cacheFlush(void* code, size_t size) { asm volatile ( @@ -238,9 +300,17 @@ public: { CacheRangeFlush(code, size, CACHE_SYNC_ALL); } +#elif PLATFORM(BREWMP) + static void cacheFlush(void* code, size_t size) + { + PlatformRefPtr<IMemCache1> memCache = createRefPtrInstance<IMemCache1>(AEECLSID_MemCache1); + IMemCache1_ClearCache(memCache.get(), reinterpret_cast<uint32>(code), size, MEMSPACE_CACHE_FLUSH, MEMSPACE_DATACACHE); + IMemCache1_ClearCache(memCache.get(), reinterpret_cast<uint32>(code), size, MEMSPACE_CACHE_INVALIDATE, MEMSPACE_INSTCACHE); + } #else #error "The cacheFlush support is missing on this platform." #endif + static size_t committedByteCount(); private: @@ -257,7 +327,7 @@ inline ExecutablePool::ExecutablePool(size_t n) size_t allocSize = roundUpAllocationSize(n, JIT_ALLOCATOR_PAGE_SIZE); Allocation mem = systemAlloc(allocSize); m_pools.append(mem); - m_freePtr = mem.pages; + m_freePtr = static_cast<char*>(mem.base()); if (!m_freePtr) CRASH(); // Failed to allocate m_end = m_freePtr + allocSize; @@ -268,22 +338,22 @@ inline void* ExecutablePool::poolAllocate(size_t n) size_t allocSize = roundUpAllocationSize(n, JIT_ALLOCATOR_PAGE_SIZE); Allocation result = systemAlloc(allocSize); - if (!result.pages) + if (!result.base()) CRASH(); // Failed to allocate ASSERT(m_end >= m_freePtr); if ((allocSize - n) > static_cast<size_t>(m_end - m_freePtr)) { // Replace allocation pool - m_freePtr = result.pages + n; - m_end = result.pages + allocSize; + m_freePtr = static_cast<char*>(result.base()) + n; + m_end = static_cast<char*>(result.base()) + allocSize; } m_pools.append(result); - return result.pages; + return result.base(); } } -#endif // ENABLE(ASSEMBLER) +#endif // ENABLE(JIT) && ENABLE(ASSEMBLER) #endif // !defined(ExecutableAllocator) |
