]> git.saurik.com Git - apple/javascriptcore.git/blob - jit/JITCode.cpp
JavaScriptCore-7600.1.4.16.1.tar.gz
[apple/javascriptcore.git] / jit / JITCode.cpp
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 #include "config.h"
27 #include "JITCode.h"
28
29 #include "LLIntThunks.h"
30 #include "JSCInlines.h"
31 #include "RegisterPreservationWrapperGenerator.h"
32 #include <wtf/PrintStream.h>
33
34 namespace JSC {
35
36 JITCode::JITCode(JITType jitType)
37 : m_jitType(jitType)
38 {
39 }
40
41 JITCode::~JITCode()
42 {
43 }
44
45 JSValue JITCode::execute(VM* vm, ProtoCallFrame* protoCallFrame)
46 {
47 JSValue result = JSValue::decode(callToJavaScript(executableAddress(), vm, protoCallFrame));
48 return vm->exception() ? jsNull() : result;
49 }
50
51 DFG::CommonData* JITCode::dfgCommon()
52 {
53 RELEASE_ASSERT_NOT_REACHED();
54 return 0;
55 }
56
57 DFG::JITCode* JITCode::dfg()
58 {
59 RELEASE_ASSERT_NOT_REACHED();
60 return 0;
61 }
62
63 FTL::JITCode* JITCode::ftl()
64 {
65 RELEASE_ASSERT_NOT_REACHED();
66 return 0;
67 }
68
69 FTL::ForOSREntryJITCode* JITCode::ftlForOSREntry()
70 {
71 RELEASE_ASSERT_NOT_REACHED();
72 return 0;
73 }
74
75 JITCodeWithCodeRef::JITCodeWithCodeRef(JITType jitType)
76 : JITCode(jitType)
77 {
78 }
79
80 JITCodeWithCodeRef::JITCodeWithCodeRef(CodeRef ref, JITType jitType)
81 : JITCode(jitType)
82 , m_ref(ref)
83 {
84 }
85
86 JITCodeWithCodeRef::~JITCodeWithCodeRef()
87 {
88 }
89
90 void* JITCodeWithCodeRef::executableAddressAtOffset(size_t offset)
91 {
92 RELEASE_ASSERT(m_ref);
93 return reinterpret_cast<char*>(m_ref.code().executableAddress()) + offset;
94 }
95
96 void* JITCodeWithCodeRef::dataAddressAtOffset(size_t offset)
97 {
98 RELEASE_ASSERT(m_ref);
99 ASSERT(offset <= size()); // use <= instead of < because it is valid to ask for an address at the exclusive end of the code.
100 return reinterpret_cast<char*>(m_ref.code().dataLocation()) + offset;
101 }
102
103 unsigned JITCodeWithCodeRef::offsetOf(void* pointerIntoCode)
104 {
105 RELEASE_ASSERT(m_ref);
106 intptr_t result = reinterpret_cast<intptr_t>(pointerIntoCode) - reinterpret_cast<intptr_t>(m_ref.code().executableAddress());
107 ASSERT(static_cast<intptr_t>(static_cast<unsigned>(result)) == result);
108 return static_cast<unsigned>(result);
109 }
110
111 size_t JITCodeWithCodeRef::size()
112 {
113 RELEASE_ASSERT(m_ref);
114 return m_ref.size();
115 }
116
117 bool JITCodeWithCodeRef::contains(void* address)
118 {
119 RELEASE_ASSERT(m_ref);
120 return m_ref.executableMemory()->contains(address);
121 }
122
123 DirectJITCode::DirectJITCode(JITType jitType)
124 : JITCodeWithCodeRef(jitType)
125 {
126 }
127
128 DirectJITCode::DirectJITCode(JITCode::CodeRef ref, JITCode::CodePtr withArityCheck, JITType jitType)
129 : JITCodeWithCodeRef(ref, jitType)
130 , m_withArityCheck(withArityCheck)
131 {
132 }
133
134 DirectJITCode::~DirectJITCode()
135 {
136 }
137
138 void DirectJITCode::initializeCodeRef(JITCode::CodeRef ref, JITCode::CodePtr withArityCheck)
139 {
140 RELEASE_ASSERT(!m_ref);
141 m_ref = ref;
142 m_withArityCheck = withArityCheck;
143 }
144
145 DirectJITCode::RegisterPreservationWrappers* DirectJITCode::ensureWrappers()
146 {
147 if (!m_wrappers)
148 m_wrappers = std::make_unique<RegisterPreservationWrappers>();
149 return m_wrappers.get();
150 }
151
152 JITCode::CodePtr DirectJITCode::addressForCall(
153 VM& vm, ExecutableBase* executable, ArityCheckMode arity,
154 RegisterPreservationMode registers)
155 {
156 switch (arity) {
157 case ArityCheckNotRequired:
158 switch (registers) {
159 case RegisterPreservationNotRequired:
160 RELEASE_ASSERT(m_ref);
161 return m_ref.code();
162 case MustPreserveRegisters: {
163 #if ENABLE(JIT)
164 RegisterPreservationWrappers* wrappers = ensureWrappers();
165 if (!wrappers->withoutArityCheck)
166 wrappers->withoutArityCheck = generateRegisterPreservationWrapper(vm, executable, m_ref.code());
167 return wrappers->withoutArityCheck.code();
168 #else
169 UNUSED_PARAM(vm);
170 UNUSED_PARAM(executable);
171 RELEASE_ASSERT_NOT_REACHED();
172 #endif
173 } }
174 case MustCheckArity:
175 switch (registers) {
176 case RegisterPreservationNotRequired:
177 RELEASE_ASSERT(m_withArityCheck);
178 return m_withArityCheck;
179 case MustPreserveRegisters: {
180 #if ENABLE(JIT)
181 RegisterPreservationWrappers* wrappers = ensureWrappers();
182 if (!wrappers->withArityCheck)
183 wrappers->withArityCheck = generateRegisterPreservationWrapper(vm, executable, m_withArityCheck);
184 return wrappers->withArityCheck.code();
185 #else
186 RELEASE_ASSERT_NOT_REACHED();
187 #endif
188 } }
189 }
190 RELEASE_ASSERT_NOT_REACHED();
191 return CodePtr();
192 }
193
194 NativeJITCode::NativeJITCode(JITType jitType)
195 : JITCodeWithCodeRef(jitType)
196 {
197 }
198
199 NativeJITCode::NativeJITCode(CodeRef ref, JITType jitType)
200 : JITCodeWithCodeRef(ref, jitType)
201 {
202 }
203
204 NativeJITCode::~NativeJITCode()
205 {
206 }
207
208 void NativeJITCode::initializeCodeRef(CodeRef ref)
209 {
210 ASSERT(!m_ref);
211 m_ref = ref;
212 }
213
214 JITCode::CodePtr NativeJITCode::addressForCall(
215 VM&, ExecutableBase*, ArityCheckMode, RegisterPreservationMode)
216 {
217 RELEASE_ASSERT(!!m_ref);
218 return m_ref.code();
219 }
220
221 } // namespace JSC
222
223 namespace WTF {
224
225 void printInternal(PrintStream& out, JSC::JITCode::JITType type)
226 {
227 switch (type) {
228 case JSC::JITCode::None:
229 out.print("None");
230 return;
231 case JSC::JITCode::HostCallThunk:
232 out.print("Host");
233 return;
234 case JSC::JITCode::InterpreterThunk:
235 out.print("LLInt");
236 return;
237 case JSC::JITCode::BaselineJIT:
238 out.print("Baseline");
239 return;
240 case JSC::JITCode::DFGJIT:
241 out.print("DFG");
242 return;
243 case JSC::JITCode::FTLJIT:
244 out.print("FTL");
245 return;
246 default:
247 CRASH();
248 return;
249 }
250 }
251
252 } // namespace WTF
253