]>
Commit | Line | Data |
---|---|---|
f9bf01c6 | 1 | /* |
81345200 | 2 | * Copyright (C) 2008, 2012, 2013 Apple Inc. All rights reserved. |
f9bf01c6 A |
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" | |
93a37866 | 27 | #include "JITCode.h" |
f9bf01c6 | 28 | |
81345200 A |
29 | #include "LLIntThunks.h" |
30 | #include "JSCInlines.h" | |
31 | #include "RegisterPreservationWrapperGenerator.h" | |
93a37866 | 32 | #include <wtf/PrintStream.h> |
f9bf01c6 | 33 | |
81345200 A |
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 | ||
93a37866 | 223 | namespace WTF { |
f9bf01c6 | 224 | |
93a37866 | 225 | void printInternal(PrintStream& out, JSC::JITCode::JITType type) |
f9bf01c6 | 226 | { |
93a37866 A |
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; | |
81345200 A |
243 | case JSC::JITCode::FTLJIT: |
244 | out.print("FTL"); | |
245 | return; | |
93a37866 A |
246 | default: |
247 | CRASH(); | |
248 | return; | |
249 | } | |
f9bf01c6 A |
250 | } |
251 | ||
93a37866 | 252 | } // namespace WTF |
f9bf01c6 | 253 |