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