]>
Commit | Line | Data |
---|---|---|
ba379fdc | 1 | /* |
81345200 | 2 | * Copyright (C) 2008, 2012, 2013 Apple Inc. All rights reserved. |
ba379fdc A |
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 | ||
81345200 | 29 | #include "ArityCheckMode.h" |
ba379fdc | 30 | #include "CallFrame.h" |
93a37866 A |
31 | #include "Disassembler.h" |
32 | #include "JITStubs.h" | |
33 | #include "JSCJSValue.h" | |
ba379fdc | 34 | #include "MacroAssemblerCodeRef.h" |
81345200 | 35 | #include "RegisterPreservationMode.h" |
ba379fdc A |
36 | |
37 | namespace JSC { | |
38 | ||
81345200 A |
39 | namespace DFG { |
40 | class CommonData; | |
41 | class JITCode; | |
42 | } | |
43 | namespace FTL { | |
44 | class ForOSREntryJITCode; | |
45 | class JITCode; | |
46 | } | |
47 | ||
48 | struct ProtoCallFrame; | |
ed1e77d3 | 49 | class TrackedReferences; |
81345200 A |
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 | }; | |
6fe7ccc8 | 65 | |
ed1e77d3 A |
66 | static const char* typeName(JITType); |
67 | ||
81345200 A |
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: | |
6fe7ccc8 | 82 | return DFGJIT; |
81345200 A |
83 | case DFGJIT: |
84 | return FTLJIT; | |
85 | default: | |
86 | RELEASE_ASSERT_NOT_REACHED(); | |
87 | return None; | |
6fe7ccc8 | 88 | } |
81345200 A |
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; | |
ba379fdc | 99 | } |
81345200 A |
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; | |
ba379fdc | 110 | } |
81345200 A |
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; | |
ba379fdc | 122 | } |
81345200 A |
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 | ||
ed1e77d3 A |
187 | virtual void validateReferences(const TrackedReferences&); |
188 | ||
81345200 A |
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; | |
ba379fdc | 196 | |
81345200 A |
197 | private: |
198 | JITType m_jitType; | |
199 | }; | |
6fe7ccc8 | 200 | |
81345200 A |
201 | class JITCodeWithCodeRef : public JITCode { |
202 | protected: | |
203 | JITCodeWithCodeRef(JITType); | |
204 | JITCodeWithCodeRef(CodeRef, JITType); | |
ba379fdc | 205 | |
81345200 A |
206 | public: |
207 | virtual ~JITCodeWithCodeRef(); | |
ba379fdc | 208 | |
81345200 A |
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; | |
ba379fdc | 214 | |
81345200 A |
215 | protected: |
216 | CodeRef m_ref; | |
217 | }; | |
ba379fdc | 218 | |
81345200 A |
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); | |
ba379fdc | 226 | |
81345200 | 227 | virtual CodePtr addressForCall(VM&, ExecutableBase*, ArityCheckMode, RegisterPreservationMode) override; |
ba379fdc | 228 | |
81345200 A |
229 | private: |
230 | struct RegisterPreservationWrappers { | |
231 | CodeRef withoutArityCheck; | |
232 | CodeRef withArityCheck; | |
233 | }; | |
ba379fdc | 234 | |
81345200 A |
235 | RegisterPreservationWrappers* ensureWrappers(); |
236 | ||
237 | CodePtr m_withArityCheck; | |
238 | ||
239 | std::unique_ptr<RegisterPreservationWrappers> m_wrappers; | |
240 | }; | |
14957cd0 | 241 | |
81345200 A |
242 | class NativeJITCode : public JITCodeWithCodeRef { |
243 | public: | |
244 | NativeJITCode(JITType); | |
245 | NativeJITCode(CodeRef, JITType); | |
246 | virtual ~NativeJITCode(); | |
247 | ||
248 | void initializeCodeRef(CodeRef); | |
ba379fdc | 249 | |
81345200 A |
250 | virtual CodePtr addressForCall(VM&, ExecutableBase*, ArityCheckMode, RegisterPreservationMode) override; |
251 | }; | |
ba379fdc | 252 | |
93a37866 A |
253 | } // namespace JSC |
254 | ||
255 | namespace WTF { | |
256 | ||
257 | class PrintStream; | |
258 | void printInternal(PrintStream&, JSC::JITCode::JITType); | |
259 | ||
260 | } // namespace WTF | |
ba379fdc A |
261 | |
262 | #endif |