246caf8b5b68f8543dad6b2bbd663af34e8a1b25
[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         }
80     }
81     
82     static bool couldBeInterpreted(JITType jitType)
83     {
84         switch (jitType) {
85         case InterpreterThunk:
86         case BaselineJIT:
87             return true;
88         default:
89             return false;
90         }
91     }
92     
93     static bool isJIT(JITType jitType)
94     {
95         switch (jitType) {
96         case BaselineJIT:
97         case DFGJIT:
98         case FTLJIT:
99             return true;
100         default:
101             return false;
102         }
103     }
104     
105     static bool isLowerTier(JITType expectedLower, JITType expectedHigher)
106     {
107         RELEASE_ASSERT(isJIT(expectedLower));
108         RELEASE_ASSERT(isJIT(expectedHigher));
109         return expectedLower < expectedHigher;
110     }
111     
112     static bool isHigherTier(JITType expectedHigher, JITType expectedLower)
113     {
114         return isLowerTier(expectedLower, expectedHigher);
115     }
116     
117     static bool isLowerOrSameTier(JITType expectedLower, JITType expectedHigher)
118     {
119         return !isHigherTier(expectedLower, expectedHigher);
120     }
121     
122     static bool isHigherOrSameTier(JITType expectedHigher, JITType expectedLower)
123     {
124         return isLowerOrSameTier(expectedLower, expectedHigher);
125     }
126     
127     static bool isOptimizingJIT(JITType jitType)
128     {
129         return jitType == DFGJIT || jitType == FTLJIT;
130     }
131     
132     static bool isBaselineCode(JITType jitType)
133     {
134         return jitType == InterpreterThunk || jitType == BaselineJIT;
135     }
136     
137 protected:
138     JITCode(JITType);
139     
140 public:
141     virtual ~JITCode();
142     
143     JITType jitType() const
144     {
145         return m_jitType;
146     }
147     
148     template<typename PointerType>
149     static JITType jitTypeFor(PointerType jitCode)
150     {
151         if (!jitCode)
152             return None;
153         return jitCode->jitType();
154     }
155     
156     virtual CodePtr addressForCall() = 0;
157     virtual void* executableAddressAtOffset(size_t offset) = 0;
158     void* executableAddress() { return executableAddressAtOffset(0); }
159     virtual void* dataAddressAtOffset(size_t offset) = 0;
160     virtual unsigned offsetOf(void* pointerIntoCode) = 0;
161     
162     virtual DFG::CommonData* dfgCommon();
163     virtual DFG::JITCode* dfg();
164     virtual FTL::JITCode* ftl();
165     
166     JSValue execute(JSStack*, CallFrame*, VM*);
167     
168     void* start() { return dataAddressAtOffset(0); }
169     virtual size_t size() = 0;
170     void* end() { return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(start()) + size()); }
171     
172     virtual bool contains(void*) = 0;
173
174     static PassRefPtr<JITCode> hostFunction(CodeRef);
175
176 private:
177     JITType m_jitType;
178 };
179
180 class DirectJITCode : public JITCode {
181 public:
182     DirectJITCode(JITType);
183     DirectJITCode(const CodeRef, JITType);
184     ~DirectJITCode();
185     
186     void initializeCodeRef(CodeRef ref);
187
188     CodePtr addressForCall();
189     void* executableAddressAtOffset(size_t offset);
190     void* dataAddressAtOffset(size_t offset);
191     unsigned offsetOf(void* pointerIntoCode);
192     size_t size();
193     bool contains(void*);
194
195 private:
196     CodeRef m_ref;
197 };
198
199 } // namespace JSC
200
201 namespace WTF {
202
203 class PrintStream;
204 void printInternal(PrintStream&, JSC::JITCode::JITType);
205
206 } // namespace WTF
207
208 #endif