Remove excessive headers from JavaScriptCore
[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 #pragma once
27
28 #include "ArityCheckMode.h"
29 #include "CallFrame.h"
30 #include "CodeOrigin.h"
31 #include "JSCJSValue.h"
32 #include "MacroAssemblerCodeRef.h"
33 #include "RegisterSet.h"
34 #include <wtf/Optional.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 #if ENABLE(JIT)
197     virtual RegisterSet liveRegistersToPreserveAtExceptionHandlingCallSite(CodeBlock*, CallSiteIndex);
198     virtual std::optional<CodeOrigin> findPC(CodeBlock*, void* pc) { UNUSED_PARAM(pc); return std::nullopt; }
199 #endif
200
201 private:
202     JITType m_jitType;
203 };
204
205 class JITCodeWithCodeRef : public JITCode {
206 protected:
207     JITCodeWithCodeRef(JITType);
208     JITCodeWithCodeRef(CodeRef, JITType);
209
210 public:
211     virtual ~JITCodeWithCodeRef();
212
213     void* executableAddressAtOffset(size_t offset) override;
214     void* dataAddressAtOffset(size_t offset) override;
215     unsigned offsetOf(void* pointerIntoCode) override;
216     size_t size() override;
217     bool contains(void*) override;
218
219 protected:
220     CodeRef m_ref;
221 };
222
223 class DirectJITCode : public JITCodeWithCodeRef {
224 public:
225     DirectJITCode(JITType);
226     DirectJITCode(CodeRef, CodePtr withArityCheck, JITType);
227     virtual ~DirectJITCode();
228     
229     void initializeCodeRef(CodeRef, CodePtr withArityCheck);
230
231     CodePtr addressForCall(ArityCheckMode) override;
232
233 private:
234     CodePtr m_withArityCheck;
235 };
236
237 class NativeJITCode : public JITCodeWithCodeRef {
238 public:
239     NativeJITCode(JITType);
240     NativeJITCode(CodeRef, JITType);
241     virtual ~NativeJITCode();
242     
243     void initializeCodeRef(CodeRef);
244
245     CodePtr addressForCall(ArityCheckMode) override;
246 };
247
248 } // namespace JSC
249
250 namespace WTF {
251
252 class PrintStream;
253 void printInternal(PrintStream&, JSC::JITCode::JITType);
254
255 } // namespace WTF