1101144083be0e82714e671a524259303946c23d
[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 #if ENABLE(JIT) || ENABLE(LLINT)
30 #include "CallFrame.h"
31 #include "Disassembler.h"
32 #include "JITStubs.h"
33 #include "JSCJSValue.h"
34 #include "LegacyProfiler.h"
35 #include "MacroAssemblerCodeRef.h"
36 #endif
37
38 namespace JSC {
39
40 namespace DFG {
41 class CommonData;
42 class JITCode;
43 }
44 namespace FTL {
45 class JITCode;
46 }
47
48 #if ENABLE(JIT)
49 class VM;
50 class JSStack;
51 #endif
52
53 class JITCode : public ThreadSafeRefCounted<JITCode> {
54 public:
55     typedef MacroAssemblerCodeRef CodeRef;
56     typedef MacroAssemblerCodePtr CodePtr;
57
58     enum JITType { None, HostCallThunk, InterpreterThunk, BaselineJIT, DFGJIT, FTLJIT };
59     
60     static JITType bottomTierJIT()
61     {
62         return BaselineJIT;
63     }
64     
65     static JITType topTierJIT()
66     {
67         return FTLJIT;
68     }
69     
70     static JITType nextTierJIT(JITType jitType)
71     {
72         switch (jitType) {
73         case BaselineJIT:
74             return DFGJIT;
75         case DFGJIT:
76             return FTLJIT;
77         default:
78             RELEASE_ASSERT_NOT_REACHED();
79             return None;
80         }
81     }
82     
83     static bool couldBeInterpreted(JITType jitType)
84     {
85         switch (jitType) {
86         case InterpreterThunk:
87         case BaselineJIT:
88             return true;
89         default:
90             return false;
91         }
92     }
93     
94     static bool isJIT(JITType jitType)
95     {
96         switch (jitType) {
97         case BaselineJIT:
98         case DFGJIT:
99         case FTLJIT:
100             return true;
101         default:
102             return false;
103         }
104     }
105     
106     static bool isLowerTier(JITType expectedLower, JITType expectedHigher)
107     {
108         RELEASE_ASSERT(isJIT(expectedLower));
109         RELEASE_ASSERT(isJIT(expectedHigher));
110         return expectedLower < expectedHigher;
111     }
112     
113     static bool isHigherTier(JITType expectedHigher, JITType expectedLower)
114     {
115         return isLowerTier(expectedLower, expectedHigher);
116     }
117     
118     static bool isLowerOrSameTier(JITType expectedLower, JITType expectedHigher)
119     {
120         return !isHigherTier(expectedLower, expectedHigher);
121     }
122     
123     static bool isHigherOrSameTier(JITType expectedHigher, JITType expectedLower)
124     {
125         return isLowerOrSameTier(expectedLower, expectedHigher);
126     }
127     
128     static bool isOptimizingJIT(JITType jitType)
129     {
130         return jitType == DFGJIT || jitType == FTLJIT;
131     }
132     
133     static bool isBaselineCode(JITType jitType)
134     {
135         return jitType == InterpreterThunk || jitType == BaselineJIT;
136     }
137     
138 protected:
139     JITCode(JITType);
140     
141 public:
142     virtual ~JITCode();
143     
144     JITType jitType() const
145     {
146         return m_jitType;
147     }
148     
149     template<typename PointerType>
150     static JITType jitTypeFor(PointerType jitCode)
151     {
152         if (!jitCode)
153             return None;
154         return jitCode->jitType();
155     }
156     
157     virtual CodePtr addressForCall() = 0;
158     virtual void* executableAddressAtOffset(size_t offset) = 0;
159     void* executableAddress() { return executableAddressAtOffset(0); }
160     virtual void* dataAddressAtOffset(size_t offset) = 0;
161     virtual unsigned offsetOf(void* pointerIntoCode) = 0;
162     
163     virtual DFG::CommonData* dfgCommon();
164     virtual DFG::JITCode* dfg();
165     virtual FTL::JITCode* ftl();
166     
167     JSValue execute(JSStack*, CallFrame*, VM*);
168     
169     void* start() { return dataAddressAtOffset(0); }
170     virtual size_t size() = 0;
171     void* end() { return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(start()) + size()); }
172     
173     virtual bool contains(void*) = 0;
174
175     static PassRefPtr<JITCode> hostFunction(CodeRef);
176
177 private:
178     JITType m_jitType;
179 };
180
181 class DirectJITCode : public JITCode {
182 public:
183     DirectJITCode(JITType);
184     DirectJITCode(const CodeRef, JITType);
185     ~DirectJITCode();
186     
187     void initializeCodeRef(CodeRef ref);
188
189     CodePtr addressForCall();
190     void* executableAddressAtOffset(size_t offset);
191     void* dataAddressAtOffset(size_t offset);
192     unsigned offsetOf(void* pointerIntoCode);
193     size_t size();
194     bool contains(void*);
195
196 private:
197     CodeRef m_ref;
198 };
199
200 } // namespace JSC
201
202 namespace WTF {
203
204 class PrintStream;
205 void printInternal(PrintStream&, JSC::JITCode::JITType);
206
207 } // namespace WTF
208
209 #endif