]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - jit/ExecutableAllocator.h
JavaScriptCore-554.1.tar.gz
[apple/javascriptcore.git] / jit / ExecutableAllocator.h
index 154125642e1f8eb5b0996216cd10e2c87674cab5..5223bf38fcd7f7f5aa1e126e52783afe08ab4b94 100644 (file)
 #ifndef ExecutableAllocator_h
 #define ExecutableAllocator_h
 
-#if ENABLE(ASSEMBLER)
-
+#include <limits>
 #include <wtf/Assertions.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
+#include <wtf/UnusedParam.h>
 #include <wtf/Vector.h>
 
-#include <limits>
+#include <libkern/OSCacheControl.h>
+#include <sys/mman.h>
 
 #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
+#else
+#define INITIAL_PROTECTION_FLAGS (PROT_READ | PROT_WRITE | PROT_EXEC)
+#endif
+
+namespace JSC {
+
+inline size_t roundUpAllocationSize(size_t request, size_t granularity)
+{
+    if ((std::numeric_limits<size_t>::max() - granularity) <= request)
+        CRASH(); // Allocation is too large
+    
+    // Round up to next page boundary
+    size_t size = request + (granularity - 1);
+    size = size & ~(granularity - 1);
+    ASSERT(size >= request);
+    return size;
+}
+
+}
+
+#if ENABLE(ASSEMBLER)
+
 namespace JSC {
 
 class ExecutablePool : public RefCounted<ExecutablePool> {
@@ -86,18 +113,6 @@ private:
     static Allocation systemAlloc(size_t n);
     static void systemRelease(const Allocation& alloc);
 
-    inline size_t roundUpAllocationSize(size_t request, size_t granularity)
-    {
-        if ((std::numeric_limits<size_t>::max() - granularity) <= request)
-            CRASH(); // Allocation is too large
-        
-        // Round up to next page boundary
-        size_t size = request + (granularity - 1);
-        size = size & ~(granularity - 1);
-        ASSERT(size >= request);
-        return size;
-    }
-
     ExecutablePool(size_t n);
 
     void* poolAllocate(size_t n);
@@ -108,6 +123,8 @@ private:
 };
 
 class ExecutableAllocator {
+    enum ProtectionSeting { Writable, Executable };
+
 public:
     static size_t pageSize;
     ExecutableAllocator()
@@ -137,7 +154,42 @@ public:
         return pool.release();
     }
 
+#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
+    static void makeWritable(void* start, size_t size)
+    {
+        reprotectRegion(start, size, Writable);
+    }
+
+    static void makeExecutable(void* start, size_t size)
+    {
+        reprotectRegion(start, size, Executable);
+    }
+#else
+    static void makeWritable(void*, size_t) {}
+    static void makeExecutable(void*, size_t) {}
+#endif
+
+
+#if PLATFORM(X86) || PLATFORM(X86_64)
+    static void cacheFlush(void*, size_t)
+    {
+    }
+#elif PLATFORM_ARM_ARCH(7) && PLATFORM(IPHONE)
+    static void cacheFlush(void* code, size_t size)
+    {
+        sys_dcache_flush(code, size);
+        sys_icache_invalidate(code, size);
+    }
+#else
+#error "ExecutableAllocator::cacheFlush not implemented on this platform."
+#endif
+
 private:
+
+#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
+    static void reprotectRegion(void*, size_t, ProtectionSeting);
+#endif
+
     RefPtr<ExecutablePool> m_smallAllocationPool;
     static void intializePageSize();
 };
@@ -173,7 +225,6 @@ inline void* ExecutablePool::poolAllocate(size_t n)
 }
 
 }
-
 #endif // ENABLE(ASSEMBLER)
 
 #endif // !defined(ExecutableAllocator)