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/Lock.h>
33#include <wtf/MetaAllocatorHandle.h>
34#include <wtf/MetaAllocator.h>
35#include <wtf/PageAllocation.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#define JIT_ALLOCATOR_LARGE_ALLOC_SIZE (pageSize() * 4)
59
60#define EXECUTABLE_POOL_WRITABLE true
61
62namespace JSC {
63
64class VM;
65
66static const unsigned jitAllocationGranule = 32;
67
68typedef WTF::MetaAllocatorHandle ExecutableMemoryHandle;
69
70#if ENABLE(ASSEMBLER)
71
72#if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND)
73class DemandExecutableAllocator;
74#endif
75
76#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
77#if defined(FIXED_EXECUTABLE_MEMORY_POOL_SIZE_IN_MB) && FIXED_EXECUTABLE_MEMORY_POOL_SIZE_IN_MB > 0
78static const size_t fixedExecutableMemoryPoolSize = FIXED_EXECUTABLE_MEMORY_POOL_SIZE_IN_MB * 1024 * 1024;
79#elif CPU(ARM) || CPU(MIPS)
80static const size_t fixedExecutableMemoryPoolSize = 16 * 1024 * 1024;
81#elif CPU(ARM64)
82static const size_t fixedExecutableMemoryPoolSize = 32 * 1024 * 1024;
83#elif CPU(X86_64)
84static const size_t fixedExecutableMemoryPoolSize = 1024 * 1024 * 1024;
85#else
86static const size_t fixedExecutableMemoryPoolSize = 32 * 1024 * 1024;
87#endif
88#if CPU(ARM)
89static const double executablePoolReservationFraction = 0.15;
90#else
91static const double executablePoolReservationFraction = 0.25;
92#endif
93
94extern uintptr_t startOfFixedExecutableMemoryPool;
95#endif
96
97class ExecutableAllocator {
98 enum ProtectionSetting { Writable, Executable };
99
100public:
101 ExecutableAllocator(VM&);
102 ~ExecutableAllocator();
103
104 static void initializeAllocator();
105
106 bool isValid() const;
107
108 static bool underMemoryPressure();
109
110 static double memoryPressureMultiplier(size_t addedMemoryUsage);
111
112#if ENABLE(META_ALLOCATOR_PROFILE)
113 static void dumpProfile();
114#else
115 static void dumpProfile() { }
116#endif
117
118 RefPtr<ExecutableMemoryHandle> allocate(VM&, size_t sizeInBytes, void* ownerUID, JITCompilationEffort);
119
120 bool isValidExecutableMemory(const LockHolder&, void* address);
121
122 static size_t committedByteCount();
123
124 Lock& getLock() const;
125};
126
127#endif // ENABLE(JIT) && ENABLE(ASSEMBLER)
128
129} // namespace JSC
130
131#endif // !defined(ExecutableAllocator)
132