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 #include "LLIntThunks.h"
30 #include "JSCInlines.h"
31 #include "RegisterPreservationWrapperGenerator.h"
32 #include <wtf/PrintStream.h>
36 JITCode::JITCode(JITType jitType
)
45 JSValue
JITCode::execute(VM
* vm
, ProtoCallFrame
* protoCallFrame
)
47 JSValue result
= JSValue::decode(callToJavaScript(executableAddress(), vm
, protoCallFrame
));
48 return vm
->exception() ? jsNull() : result
;
51 DFG::CommonData
* JITCode::dfgCommon()
53 RELEASE_ASSERT_NOT_REACHED();
57 DFG::JITCode
* JITCode::dfg()
59 RELEASE_ASSERT_NOT_REACHED();
63 FTL::JITCode
* JITCode::ftl()
65 RELEASE_ASSERT_NOT_REACHED();
69 FTL::ForOSREntryJITCode
* JITCode::ftlForOSREntry()
71 RELEASE_ASSERT_NOT_REACHED();
75 JITCodeWithCodeRef::JITCodeWithCodeRef(JITType jitType
)
80 JITCodeWithCodeRef::JITCodeWithCodeRef(CodeRef ref
, JITType jitType
)
86 JITCodeWithCodeRef::~JITCodeWithCodeRef()
90 void* JITCodeWithCodeRef::executableAddressAtOffset(size_t offset
)
92 RELEASE_ASSERT(m_ref
);
93 return reinterpret_cast<char*>(m_ref
.code().executableAddress()) + offset
;
96 void* JITCodeWithCodeRef::dataAddressAtOffset(size_t offset
)
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
;
103 unsigned JITCodeWithCodeRef::offsetOf(void* pointerIntoCode
)
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
);
111 size_t JITCodeWithCodeRef::size()
113 RELEASE_ASSERT(m_ref
);
117 bool JITCodeWithCodeRef::contains(void* address
)
119 RELEASE_ASSERT(m_ref
);
120 return m_ref
.executableMemory()->contains(address
);
123 DirectJITCode::DirectJITCode(JITType jitType
)
124 : JITCodeWithCodeRef(jitType
)
128 DirectJITCode::DirectJITCode(JITCode::CodeRef ref
, JITCode::CodePtr withArityCheck
, JITType jitType
)
129 : JITCodeWithCodeRef(ref
, jitType
)
130 , m_withArityCheck(withArityCheck
)
134 DirectJITCode::~DirectJITCode()
138 void DirectJITCode::initializeCodeRef(JITCode::CodeRef ref
, JITCode::CodePtr withArityCheck
)
140 RELEASE_ASSERT(!m_ref
);
142 m_withArityCheck
= withArityCheck
;
145 DirectJITCode::RegisterPreservationWrappers
* DirectJITCode::ensureWrappers()
148 m_wrappers
= std::make_unique
<RegisterPreservationWrappers
>();
149 return m_wrappers
.get();
152 JITCode::CodePtr
DirectJITCode::addressForCall(
153 VM
& vm
, ExecutableBase
* executable
, ArityCheckMode arity
,
154 RegisterPreservationMode registers
)
157 case ArityCheckNotRequired
:
159 case RegisterPreservationNotRequired
:
160 RELEASE_ASSERT(m_ref
);
162 case MustPreserveRegisters
: {
164 RegisterPreservationWrappers
* wrappers
= ensureWrappers();
165 if (!wrappers
->withoutArityCheck
)
166 wrappers
->withoutArityCheck
= generateRegisterPreservationWrapper(vm
, executable
, m_ref
.code());
167 return wrappers
->withoutArityCheck
.code();
170 UNUSED_PARAM(executable
);
171 RELEASE_ASSERT_NOT_REACHED();
176 case RegisterPreservationNotRequired
:
177 RELEASE_ASSERT(m_withArityCheck
);
178 return m_withArityCheck
;
179 case MustPreserveRegisters
: {
181 RegisterPreservationWrappers
* wrappers
= ensureWrappers();
182 if (!wrappers
->withArityCheck
)
183 wrappers
->withArityCheck
= generateRegisterPreservationWrapper(vm
, executable
, m_withArityCheck
);
184 return wrappers
->withArityCheck
.code();
186 RELEASE_ASSERT_NOT_REACHED();
190 RELEASE_ASSERT_NOT_REACHED();
194 NativeJITCode::NativeJITCode(JITType jitType
)
195 : JITCodeWithCodeRef(jitType
)
199 NativeJITCode::NativeJITCode(CodeRef ref
, JITType jitType
)
200 : JITCodeWithCodeRef(ref
, jitType
)
204 NativeJITCode::~NativeJITCode()
208 void NativeJITCode::initializeCodeRef(CodeRef ref
)
214 JITCode::CodePtr
NativeJITCode::addressForCall(
215 VM
&, ExecutableBase
*, ArityCheckMode
, RegisterPreservationMode
)
217 RELEASE_ASSERT(!!m_ref
);
225 void printInternal(PrintStream
& out
, JSC::JITCode::JITType type
)
228 case JSC::JITCode::None
:
231 case JSC::JITCode::HostCallThunk
:
234 case JSC::JITCode::InterpreterThunk
:
237 case JSC::JITCode::BaselineJIT
:
238 out
.print("Baseline");
240 case JSC::JITCode::DFGJIT
:
243 case JSC::JITCode::FTLJIT
: