1/*
2 * Copyright (C) 2008-2018 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 "JSCInlines.h"
30#include "ProtoCallFrame.h"
31#include <wtf/PrintStream.h>
32
33namespace JSC {
34
35JITCode::JITCode(JITType jitType, ShareAttribute shareAttribute)
36 : m_jitType(jitType)
37 , m_shareAttribute(shareAttribute)
38{
39}
40
41JITCode::~JITCode()
42{
43}
44
45const char* JITCode::typeName(JITType jitType)
46{
47 switch (jitType) {
48 case JITType::None:
49 return "None";
50 case JITType::HostCallThunk:
51 return "Host";
52 case JITType::InterpreterThunk:
53 return "LLInt";
54 case JITType::BaselineJIT:
55 return "Baseline";
56 case JITType::DFGJIT:
57 return "DFG";
58 case JITType::FTLJIT:
59 return "FTL";
60 default:
61 CRASH();
62 return "";
63 }
64}
65
66void JITCode::validateReferences(const TrackedReferences&)
67{
68}
69
70DFG::CommonData* JITCode::dfgCommon()
71{
72 RELEASE_ASSERT_NOT_REACHED();
73 return 0;
74}
75
76DFG::JITCode* JITCode::dfg()
77{
78 RELEASE_ASSERT_NOT_REACHED();
79 return 0;
80}
81
82FTL::JITCode* JITCode::ftl()
83{
84 RELEASE_ASSERT_NOT_REACHED();
85 return 0;
86}
87
88FTL::ForOSREntryJITCode* JITCode::ftlForOSREntry()
89{
90 RELEASE_ASSERT_NOT_REACHED();
91 return 0;
92}
93
94JITCodeWithCodeRef::JITCodeWithCodeRef(JITType jitType)
95 : JITCode(jitType)
96{
97}
98
99JITCodeWithCodeRef::JITCodeWithCodeRef(CodeRef<JSEntryPtrTag> ref, JITType jitType, JITCode::ShareAttribute shareAttribute)
100 : JITCode(jitType, shareAttribute)
101 , m_ref(ref)
102{
103}
104
105JITCodeWithCodeRef::~JITCodeWithCodeRef()
106{
107 if ((Options::dumpDisassembly() || (isOptimizingJIT(jitType()) && Options::dumpDFGDisassembly()))
108 && m_ref.executableMemory())
109 dataLog("Destroying JIT code at ", pointerDump(m_ref.executableMemory()), "\n");
110}
111
112void* JITCodeWithCodeRef::executableAddressAtOffset(size_t offset)
113{
114 RELEASE_ASSERT(m_ref);
115 assertIsTaggedWith(m_ref.code().executableAddress(), JSEntryPtrTag);
116 if (!offset)
117 return m_ref.code().executableAddress();
118
119 char* executableAddress = untagCodePtr<char*, JSEntryPtrTag>(m_ref.code().executableAddress());
120 return tagCodePtr<JSEntryPtrTag>(executableAddress + offset);
121}
122
123void* JITCodeWithCodeRef::dataAddressAtOffset(size_t offset)
124{
125 RELEASE_ASSERT(m_ref);
126 ASSERT(offset <= size()); // use <= instead of < because it is valid to ask for an address at the exclusive end of the code.
127 return m_ref.code().dataLocation<char*>() + offset;
128}
129
130unsigned JITCodeWithCodeRef::offsetOf(void* pointerIntoCode)
131{
132 RELEASE_ASSERT(m_ref);
133 intptr_t result = reinterpret_cast<intptr_t>(pointerIntoCode) - m_ref.code().executableAddress<intptr_t>();
134 ASSERT(static_cast<intptr_t>(static_cast<unsigned>(result)) == result);
135 return static_cast<unsigned>(result);
136}
137
138size_t JITCodeWithCodeRef::size()
139{
140 RELEASE_ASSERT(m_ref);
141 return m_ref.size();
142}
143
144bool JITCodeWithCodeRef::contains(void* address)
145{
146 RELEASE_ASSERT(m_ref);
147 return m_ref.executableMemory()->contains(address);
148}
149
150DirectJITCode::DirectJITCode(JITType jitType)
151 : JITCodeWithCodeRef(jitType)
152{
153}
154
155DirectJITCode::DirectJITCode(JITCode::CodeRef<JSEntryPtrTag> ref, JITCode::CodePtr<JSEntryPtrTag> withArityCheck, JITType jitType, JITCode::ShareAttribute shareAttribute)
156 : JITCodeWithCodeRef(ref, jitType, shareAttribute)
157 , m_withArityCheck(withArityCheck)
158{
159 ASSERT(m_ref);
160 ASSERT(m_withArityCheck);
161}
162
163DirectJITCode::DirectJITCode(JITCode::CodeRef<JSEntryPtrTag> ref, JITCode::CodePtr<JSEntryPtrTag> withArityCheck, JITType jitType, Intrinsic intrinsic, JITCode::ShareAttribute shareAttribute)
164 : JITCodeWithCodeRef(ref, jitType, shareAttribute)
165 , m_withArityCheck(withArityCheck)
166{
167 m_intrinsic = intrinsic;
168 ASSERT(m_ref);
169 ASSERT(m_withArityCheck);
170}
171
172DirectJITCode::~DirectJITCode()
173{
174}
175
176void DirectJITCode::initializeCodeRefForDFG(JITCode::CodeRef<JSEntryPtrTag> ref, JITCode::CodePtr<JSEntryPtrTag> withArityCheck)
177{
178 RELEASE_ASSERT(!m_ref);
179 m_ref = ref;
180 m_withArityCheck = withArityCheck;
181 ASSERT(m_ref);
182 ASSERT(m_withArityCheck);
183}
184
185JITCode::CodePtr<JSEntryPtrTag> DirectJITCode::addressForCall(ArityCheckMode arity)
186{
187 switch (arity) {
188 case ArityCheckNotRequired:
189 RELEASE_ASSERT(m_ref);
190 return m_ref.code();
191 case MustCheckArity:
192 RELEASE_ASSERT(m_withArityCheck);
193 return m_withArityCheck;
194 }
195 RELEASE_ASSERT_NOT_REACHED();
196 return CodePtr<JSEntryPtrTag>();
197}
198
199NativeJITCode::NativeJITCode(JITType jitType)
200 : JITCodeWithCodeRef(jitType)
201{
202}
203
204NativeJITCode::NativeJITCode(CodeRef<JSEntryPtrTag> ref, JITType jitType, Intrinsic intrinsic, JITCode::ShareAttribute shareAttribute)
205 : JITCodeWithCodeRef(ref, jitType, shareAttribute)
206{
207 m_intrinsic = intrinsic;
208}
209
210NativeJITCode::~NativeJITCode()
211{
212}
213
214JITCode::CodePtr<JSEntryPtrTag> NativeJITCode::addressForCall(ArityCheckMode arity)
215{
216 RELEASE_ASSERT(m_ref);
217 switch (arity) {
218 case ArityCheckNotRequired:
219 return m_ref.code();
220 case MustCheckArity:
221 return m_ref.code();
222 }
223 RELEASE_ASSERT_NOT_REACHED();
224 return CodePtr<JSEntryPtrTag>();
225}
226
227NativeDOMJITCode::NativeDOMJITCode(CodeRef<JSEntryPtrTag> ref, JITType type, Intrinsic intrinsic, const DOMJIT::Signature* signature)
228 : NativeJITCode(ref, type, intrinsic)
229 , m_signature(signature)
230{
231}
232
233#if ENABLE(JIT)
234RegisterSet JITCode::liveRegistersToPreserveAtExceptionHandlingCallSite(CodeBlock*, CallSiteIndex)
235{
236 return { };
237}
238#endif
239
240} // namespace JSC
241
242namespace WTF {
243
244void printInternal(PrintStream& out, JSC::JITType type)
245{
246 out.print(JSC::JITCode::typeName(type));
247}
248
249} // namespace WTF
250
251