2 * Copyright (C) 2008, 2012, 2013 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #if ENABLE(JIT) || ENABLE(LLINT)
30 #include "CallFrame.h"
31 #include "Disassembler.h"
33 #include "JSCJSValue.h"
34 #include "LegacyProfiler.h"
35 #include "MacroAssemblerCodeRef.h"
53 class JITCode : public ThreadSafeRefCounted<JITCode> {
55 typedef MacroAssemblerCodeRef CodeRef;
56 typedef MacroAssemblerCodePtr CodePtr;
58 enum JITType { None, HostCallThunk, InterpreterThunk, BaselineJIT, DFGJIT, FTLJIT };
60 static JITType bottomTierJIT()
65 static JITType topTierJIT()
70 static JITType nextTierJIT(JITType jitType)
78 RELEASE_ASSERT_NOT_REACHED();
82 static bool couldBeInterpreted(JITType jitType)
85 case InterpreterThunk:
93 static bool isJIT(JITType jitType)
105 static bool isLowerTier(JITType expectedLower, JITType expectedHigher)
107 RELEASE_ASSERT(isJIT(expectedLower));
108 RELEASE_ASSERT(isJIT(expectedHigher));
109 return expectedLower < expectedHigher;
112 static bool isHigherTier(JITType expectedHigher, JITType expectedLower)
114 return isLowerTier(expectedLower, expectedHigher);
117 static bool isLowerOrSameTier(JITType expectedLower, JITType expectedHigher)
119 return !isHigherTier(expectedLower, expectedHigher);
122 static bool isHigherOrSameTier(JITType expectedHigher, JITType expectedLower)
124 return isLowerOrSameTier(expectedLower, expectedHigher);
127 static bool isOptimizingJIT(JITType jitType)
129 return jitType == DFGJIT || jitType == FTLJIT;
132 static bool isBaselineCode(JITType jitType)
134 return jitType == InterpreterThunk || jitType == BaselineJIT;
143 JITType jitType() const
148 template<typename PointerType>
149 static JITType jitTypeFor(PointerType jitCode)
153 return jitCode->jitType();
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;
162 virtual DFG::CommonData* dfgCommon();
163 virtual DFG::JITCode* dfg();
164 virtual FTL::JITCode* ftl();
166 JSValue execute(JSStack*, CallFrame*, VM*);
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()); }
172 virtual bool contains(void*) = 0;
174 static PassRefPtr<JITCode> hostFunction(CodeRef);
180 class DirectJITCode : public JITCode {
182 DirectJITCode(JITType);
183 DirectJITCode(const CodeRef, JITType);
186 void initializeCodeRef(CodeRef ref);
188 CodePtr addressForCall();
189 void* executableAddressAtOffset(size_t offset);
190 void* dataAddressAtOffset(size_t offset);
191 unsigned offsetOf(void* pointerIntoCode);
193 bool contains(void*);
204 void printInternal(PrintStream&, JSC::JITCode::JITType);