]> git.saurik.com Git - apple/javascriptcore.git/blob - jit/JITCode.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / jit / JITCode.h
1 /*
2 * Copyright (C) 2008, 2012, 2013 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 JITCode_h
27 #define JITCode_h
28
29 #include "ArityCheckMode.h"
30 #include "CallFrame.h"
31 #include "Disassembler.h"
32 #include "JITStubs.h"
33 #include "JSCJSValue.h"
34 #include "MacroAssemblerCodeRef.h"
35 #include "RegisterPreservationMode.h"
36
37 namespace JSC {
38
39 namespace DFG {
40 class CommonData;
41 class JITCode;
42 }
43 namespace FTL {
44 class ForOSREntryJITCode;
45 class JITCode;
46 }
47
48 struct ProtoCallFrame;
49 class TrackedReferences;
50 class VM;
51
52 class JITCode : public ThreadSafeRefCounted<JITCode> {
53 public:
54 typedef MacroAssemblerCodeRef CodeRef;
55 typedef MacroAssemblerCodePtr CodePtr;
56
57 enum JITType : uint8_t {
58 None,
59 HostCallThunk,
60 InterpreterThunk,
61 BaselineJIT,
62 DFGJIT,
63 FTLJIT
64 };
65
66 static const char* typeName(JITType);
67
68 static JITType bottomTierJIT()
69 {
70 return BaselineJIT;
71 }
72
73 static JITType topTierJIT()
74 {
75 return FTLJIT;
76 }
77
78 static JITType nextTierJIT(JITType jitType)
79 {
80 switch (jitType) {
81 case BaselineJIT:
82 return DFGJIT;
83 case DFGJIT:
84 return FTLJIT;
85 default:
86 RELEASE_ASSERT_NOT_REACHED();
87 return None;
88 }
89 }
90
91 static bool isExecutableScript(JITType jitType)
92 {
93 switch (jitType) {
94 case None:
95 case HostCallThunk:
96 return false;
97 default:
98 return true;
99 }
100 }
101
102 static bool couldBeInterpreted(JITType jitType)
103 {
104 switch (jitType) {
105 case InterpreterThunk:
106 case BaselineJIT:
107 return true;
108 default:
109 return false;
110 }
111 }
112
113 static bool isJIT(JITType jitType)
114 {
115 switch (jitType) {
116 case BaselineJIT:
117 case DFGJIT:
118 case FTLJIT:
119 return true;
120 default:
121 return false;
122 }
123 }
124
125 static bool isLowerTier(JITType expectedLower, JITType expectedHigher)
126 {
127 RELEASE_ASSERT(isExecutableScript(expectedLower));
128 RELEASE_ASSERT(isExecutableScript(expectedHigher));
129 return expectedLower < expectedHigher;
130 }
131
132 static bool isHigherTier(JITType expectedHigher, JITType expectedLower)
133 {
134 return isLowerTier(expectedLower, expectedHigher);
135 }
136
137 static bool isLowerOrSameTier(JITType expectedLower, JITType expectedHigher)
138 {
139 return !isHigherTier(expectedLower, expectedHigher);
140 }
141
142 static bool isHigherOrSameTier(JITType expectedHigher, JITType expectedLower)
143 {
144 return isLowerOrSameTier(expectedLower, expectedHigher);
145 }
146
147 static bool isOptimizingJIT(JITType jitType)
148 {
149 return jitType == DFGJIT || jitType == FTLJIT;
150 }
151
152 static bool isBaselineCode(JITType jitType)
153 {
154 return jitType == InterpreterThunk || jitType == BaselineJIT;
155 }
156
157 protected:
158 JITCode(JITType);
159
160 public:
161 virtual ~JITCode();
162
163 JITType jitType() const
164 {
165 return m_jitType;
166 }
167
168 template<typename PointerType>
169 static JITType jitTypeFor(PointerType jitCode)
170 {
171 if (!jitCode)
172 return None;
173 return jitCode->jitType();
174 }
175
176 virtual CodePtr addressForCall(VM&, ExecutableBase*, ArityCheckMode, RegisterPreservationMode) = 0;
177 virtual void* executableAddressAtOffset(size_t offset) = 0;
178 void* executableAddress() { return executableAddressAtOffset(0); }
179 virtual void* dataAddressAtOffset(size_t offset) = 0;
180 virtual unsigned offsetOf(void* pointerIntoCode) = 0;
181
182 virtual DFG::CommonData* dfgCommon();
183 virtual DFG::JITCode* dfg();
184 virtual FTL::JITCode* ftl();
185 virtual FTL::ForOSREntryJITCode* ftlForOSREntry();
186
187 virtual void validateReferences(const TrackedReferences&);
188
189 JSValue execute(VM*, ProtoCallFrame*);
190
191 void* start() { return dataAddressAtOffset(0); }
192 virtual size_t size() = 0;
193 void* end() { return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(start()) + size()); }
194
195 virtual bool contains(void*) = 0;
196
197 private:
198 JITType m_jitType;
199 };
200
201 class JITCodeWithCodeRef : public JITCode {
202 protected:
203 JITCodeWithCodeRef(JITType);
204 JITCodeWithCodeRef(CodeRef, JITType);
205
206 public:
207 virtual ~JITCodeWithCodeRef();
208
209 virtual void* executableAddressAtOffset(size_t offset) override;
210 virtual void* dataAddressAtOffset(size_t offset) override;
211 virtual unsigned offsetOf(void* pointerIntoCode) override;
212 virtual size_t size() override;
213 virtual bool contains(void*) override;
214
215 protected:
216 CodeRef m_ref;
217 };
218
219 class DirectJITCode : public JITCodeWithCodeRef {
220 public:
221 DirectJITCode(JITType);
222 DirectJITCode(CodeRef, CodePtr withArityCheck, JITType);
223 virtual ~DirectJITCode();
224
225 void initializeCodeRef(CodeRef, CodePtr withArityCheck);
226
227 virtual CodePtr addressForCall(VM&, ExecutableBase*, ArityCheckMode, RegisterPreservationMode) override;
228
229 private:
230 struct RegisterPreservationWrappers {
231 CodeRef withoutArityCheck;
232 CodeRef withArityCheck;
233 };
234
235 RegisterPreservationWrappers* ensureWrappers();
236
237 CodePtr m_withArityCheck;
238
239 std::unique_ptr<RegisterPreservationWrappers> m_wrappers;
240 };
241
242 class NativeJITCode : public JITCodeWithCodeRef {
243 public:
244 NativeJITCode(JITType);
245 NativeJITCode(CodeRef, JITType);
246 virtual ~NativeJITCode();
247
248 void initializeCodeRef(CodeRef);
249
250 virtual CodePtr addressForCall(VM&, ExecutableBase*, ArityCheckMode, RegisterPreservationMode) override;
251 };
252
253 } // namespace JSC
254
255 namespace WTF {
256
257 class PrintStream;
258 void printInternal(PrintStream&, JSC::JITCode::JITType);
259
260 } // namespace WTF
261
262 #endif