1/* 2 * Copyright (C) 2008 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef ExecutableAllocator_h 27#define ExecutableAllocator_h 28#include "JITCompilationEffort.h" 29#include <stddef.h> // for ptrdiff_t 30#include <limits> 31#include <wtf/Assertions.h> 32#include <wtf/MetaAllocatorHandle.h> 33#include <wtf/MetaAllocator.h> 34#include <wtf/PageAllocation.h> 35#include <wtf/PassRefPtr.h> 36#include <wtf/RefCounted.h> 37#include <wtf/Vector.h> 38 39#if OS(IOS) 40#include <libkern/OSCacheControl.h> 41#endif 42 43#if OS(IOS) 44#include <sys/mman.h> 45#endif 46 47#if CPU(MIPS) && OS(LINUX) 48#include <sys/cachectl.h> 49#endif 50 51#if CPU(SH4) && OS(LINUX) 52#include <asm/cachectl.h> 53#include <asm/unistd.h> 54#include <sys/syscall.h> 55#include <unistd.h> 56#endif 57 58#if OS(WINCE) 59// From pkfuncs.h (private header file from the Platform Builder) 60#define CACHE_SYNC_ALL 0x07F 61extern "C" __declspec(dllimport) void CacheRangeFlush(LPVOID pAddr, DWORD dwLength, DWORD dwFlags); 62#endif 63 64#define JIT_ALLOCATOR_LARGE_ALLOC_SIZE (pageSize() * 4) 65 66#if ENABLE(ASSEMBLER_WX_EXCLUSIVE) 67#define PROTECTION_FLAGS_RW (PROT_READ | PROT_WRITE) 68#define PROTECTION_FLAGS_RX (PROT_READ | PROT_EXEC) 69#define EXECUTABLE_POOL_WRITABLE false 70#else 71#define EXECUTABLE_POOL_WRITABLE true 72#endif 73 74namespace JSC { 75 76class VM; 77void releaseExecutableMemory(VM&); 78 79static const unsigned jitAllocationGranule = 32; 80 81typedef WTF::MetaAllocatorHandle ExecutableMemoryHandle; 82 83#if ENABLE(ASSEMBLER) 84 85#if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND) 86class DemandExecutableAllocator; 87#endif 88 89#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED) 90#if CPU(ARM) || CPU(ARM64) 91static const size_t fixedExecutableMemoryPoolSize = 16 * 1024 * 1024; 92#elif CPU(X86_64) 93static const size_t fixedExecutableMemoryPoolSize = 1024 * 1024 * 1024; 94#else 95static const size_t fixedExecutableMemoryPoolSize = 32 * 1024 * 1024; 96#endif 97 98extern uintptr_t startOfFixedExecutableMemoryPool; 99#endif 100 101class ExecutableAllocator { 102 enum ProtectionSetting { Writable, Executable }; 103 104public: 105 ExecutableAllocator(VM&); 106 ~ExecutableAllocator(); 107 108 static void initializeAllocator(); 109 110 bool isValid() const; 111 112 static bool underMemoryPressure(); 113 114 static double memoryPressureMultiplier(size_t addedMemoryUsage); 115 116#if ENABLE(META_ALLOCATOR_PROFILE) 117 static void dumpProfile(); 118#else 119 static void dumpProfile() { } 120#endif 121 122 PassRefPtr<ExecutableMemoryHandle> allocate(VM&, size_t sizeInBytes, void* ownerUID, JITCompilationEffort); 123 124#if ENABLE(ASSEMBLER_WX_EXCLUSIVE) 125 static void makeWritable(void* start, size_t size) 126 { 127 reprotectRegion(start, size, Writable); 128 } 129 130 static void makeExecutable(void* start, size_t size) 131 { 132 reprotectRegion(start, size, Executable); 133 } 134#else 135 static void makeWritable(void*, size_t) {} 136 static void makeExecutable(void*, size_t) {} 137#endif 138 139 static size_t committedByteCount(); 140 141private: 142 143#if ENABLE(ASSEMBLER_WX_EXCLUSIVE) 144 static void reprotectRegion(void*, size_t, ProtectionSetting); 145#if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND) 146 // We create a MetaAllocator for each JS global object. 147 OwnPtr<DemandExecutableAllocator> m_allocator; 148 DemandExecutableAllocator* allocator() { return m_allocator.get(); } 149#endif 150#endif 151 152}; 153 154#endif // ENABLE(JIT) && ENABLE(ASSEMBLER) 155 156} // namespace JSC 157 158#endif // !defined(ExecutableAllocator) 159