2 * Copyright (C) 2009, 2012 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.
26 #ifndef MacroAssemblerCodeRef_h
27 #define MacroAssemblerCodeRef_h
29 #include "Disassembler.h"
30 #include "ExecutableAllocator.h"
31 #include "LLIntData.h"
32 #include <wtf/DataLog.h>
33 #include <wtf/PassRefPtr.h>
34 #include <wtf/RefPtr.h>
35 #include <wtf/UnusedParam.h>
37 // ASSERT_VALID_CODE_POINTER checks that ptr is a non-null pointer, and that it is a valid
38 // instruction address on the platform (for example, check any alignment requirements).
40 // ARM/thumb instructions must be 16-bit aligned, but all code pointers to be loaded
41 // into the processor are decorated with the bottom bit set, indicating that this is
42 // thumb code (as oposed to 32-bit traditional ARM). The first test checks for both
43 // decorated and undectorated null, and the second test ensures that the pointer is
45 #define ASSERT_VALID_CODE_POINTER(ptr) \
46 ASSERT(reinterpret_cast<intptr_t>(ptr) & ~1); \
47 ASSERT(reinterpret_cast<intptr_t>(ptr) & 1)
48 #define ASSERT_VALID_CODE_OFFSET(offset) \
49 ASSERT(!(offset & 1)) // Must be multiple of 2.
51 #define ASSERT_VALID_CODE_POINTER(ptr) \
53 #define ASSERT_VALID_CODE_OFFSET(offset) // Anything goes!
56 #if CPU(X86) && OS(WINDOWS)
57 #define CALLING_CONVENTION_IS_STDCALL 1
62 #define CDECL __attribute__ ((__cdecl))
63 #endif // COMPILER(MSVC)
66 #define CALLING_CONVENTION_IS_STDCALL 0
70 #define HAS_FASTCALL_CALLING_CONVENTION 1
73 #define FASTCALL __fastcall
75 #define FASTCALL __attribute__ ((fastcall))
76 #endif // COMPILER(MSVC)
79 #define HAS_FASTCALL_CALLING_CONVENTION 0
86 // FunctionPtr should be used to wrap pointers to C/C++ functions in JSC
87 // (particularly, the stub functions).
95 template<typename returnType>
96 FunctionPtr(returnType(*value)())
97 : m_value((void*)value)
99 ASSERT_VALID_CODE_POINTER(m_value);
102 template<typename returnType, typename argType1>
103 FunctionPtr(returnType(*value)(argType1))
104 : m_value((void*)value)
106 ASSERT_VALID_CODE_POINTER(m_value);
109 template<typename returnType, typename argType1, typename argType2>
110 FunctionPtr(returnType(*value)(argType1, argType2))
111 : m_value((void*)value)
113 ASSERT_VALID_CODE_POINTER(m_value);
116 template<typename returnType, typename argType1, typename argType2, typename argType3>
117 FunctionPtr(returnType(*value)(argType1, argType2, argType3))
118 : m_value((void*)value)
120 ASSERT_VALID_CODE_POINTER(m_value);
123 template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4>
124 FunctionPtr(returnType(*value)(argType1, argType2, argType3, argType4))
125 : m_value((void*)value)
127 ASSERT_VALID_CODE_POINTER(m_value);
130 template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4, typename argType5>
131 FunctionPtr(returnType(*value)(argType1, argType2, argType3, argType4, argType5))
132 : m_value((void*)value)
134 ASSERT_VALID_CODE_POINTER(m_value);
137 // MSVC doesn't seem to treat functions with different calling conventions as
138 // different types; these methods already defined for fastcall, below.
139 #if CALLING_CONVENTION_IS_STDCALL && !OS(WINDOWS)
141 template<typename returnType>
142 FunctionPtr(returnType (CDECL *value)())
143 : m_value((void*)value)
145 ASSERT_VALID_CODE_POINTER(m_value);
148 template<typename returnType, typename argType1>
149 FunctionPtr(returnType (CDECL *value)(argType1))
150 : m_value((void*)value)
152 ASSERT_VALID_CODE_POINTER(m_value);
155 template<typename returnType, typename argType1, typename argType2>
156 FunctionPtr(returnType (CDECL *value)(argType1, argType2))
157 : m_value((void*)value)
159 ASSERT_VALID_CODE_POINTER(m_value);
162 template<typename returnType, typename argType1, typename argType2, typename argType3>
163 FunctionPtr(returnType (CDECL *value)(argType1, argType2, argType3))
164 : m_value((void*)value)
166 ASSERT_VALID_CODE_POINTER(m_value);
169 template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4>
170 FunctionPtr(returnType (CDECL *value)(argType1, argType2, argType3, argType4))
171 : m_value((void*)value)
173 ASSERT_VALID_CODE_POINTER(m_value);
177 #if HAS_FASTCALL_CALLING_CONVENTION
179 template<typename returnType>
180 FunctionPtr(returnType (FASTCALL *value)())
181 : m_value((void*)value)
183 ASSERT_VALID_CODE_POINTER(m_value);
186 template<typename returnType, typename argType1>
187 FunctionPtr(returnType (FASTCALL *value)(argType1))
188 : m_value((void*)value)
190 ASSERT_VALID_CODE_POINTER(m_value);
193 template<typename returnType, typename argType1, typename argType2>
194 FunctionPtr(returnType (FASTCALL *value)(argType1, argType2))
195 : m_value((void*)value)
197 ASSERT_VALID_CODE_POINTER(m_value);
200 template<typename returnType, typename argType1, typename argType2, typename argType3>
201 FunctionPtr(returnType (FASTCALL *value)(argType1, argType2, argType3))
202 : m_value((void*)value)
204 ASSERT_VALID_CODE_POINTER(m_value);
207 template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4>
208 FunctionPtr(returnType (FASTCALL *value)(argType1, argType2, argType3, argType4))
209 : m_value((void*)value)
211 ASSERT_VALID_CODE_POINTER(m_value);
215 template<typename FunctionType>
216 explicit FunctionPtr(FunctionType* value)
217 // Using a C-ctyle cast here to avoid compiler error on RVTC:
218 // Error: #694: reinterpret_cast cannot cast away const or other type qualifiers
219 // (I guess on RVTC function pointers have a different constness to GCC/MSVC?)
220 : m_value((void*)value)
222 ASSERT_VALID_CODE_POINTER(m_value);
225 void* value() const { return m_value; }
226 void* executableAddress() const { return m_value; }
235 // ReturnAddressPtr should be used to wrap return addresses generated by processor
236 // 'call' instructions exectued in JIT code. We use return addresses to look up
237 // exception and optimization information, and to repatch the call instruction
238 // that is the source of the return address.
239 class ReturnAddressPtr {
246 explicit ReturnAddressPtr(void* value)
249 ASSERT_VALID_CODE_POINTER(m_value);
252 explicit ReturnAddressPtr(FunctionPtr function)
253 : m_value(function.value())
255 ASSERT_VALID_CODE_POINTER(m_value);
258 void* value() const { return m_value; }
264 // MacroAssemblerCodePtr:
266 // MacroAssemblerCodePtr should be used to wrap pointers to JIT generated code.
267 class MacroAssemblerCodePtr {
269 MacroAssemblerCodePtr()
274 explicit MacroAssemblerCodePtr(void* value)
276 // Decorate the pointer as a thumb code pointer.
277 : m_value(reinterpret_cast<char*>(value) + 1)
282 ASSERT_VALID_CODE_POINTER(m_value);
285 static MacroAssemblerCodePtr createFromExecutableAddress(void* value)
287 ASSERT_VALID_CODE_POINTER(value);
288 MacroAssemblerCodePtr result;
289 result.m_value = value;
294 static MacroAssemblerCodePtr createLLIntCodePtr(LLIntCode codeId)
296 return createFromExecutableAddress(LLInt::getCodePtr(codeId));
300 explicit MacroAssemblerCodePtr(ReturnAddressPtr ra)
301 : m_value(ra.value())
303 ASSERT_VALID_CODE_POINTER(m_value);
306 void* executableAddress() const { return m_value; }
308 // To use this pointer as a data address remove the decoration.
309 void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return reinterpret_cast<char*>(m_value) - 1; }
311 void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return m_value; }
314 bool operator!() const
323 // MacroAssemblerCodeRef:
325 // A reference to a section of JIT generated code. A CodeRef consists of a
326 // pointer to the code, and a ref pointer to the pool from within which it
328 class MacroAssemblerCodeRef {
330 // This is private because it's dangerous enough that we want uses of it
331 // to be easy to find - hence the static create method below.
332 explicit MacroAssemblerCodeRef(MacroAssemblerCodePtr codePtr)
339 MacroAssemblerCodeRef()
343 MacroAssemblerCodeRef(PassRefPtr<ExecutableMemoryHandle> executableMemory)
344 : m_codePtr(executableMemory->start())
345 , m_executableMemory(executableMemory)
347 ASSERT(m_executableMemory->isManaged());
348 ASSERT(m_executableMemory->start());
352 // Use this only when you know that the codePtr refers to code that is
353 // already being kept alive through some other means. Typically this means
354 // that codePtr is immortal.
355 static MacroAssemblerCodeRef createSelfManagedCodeRef(MacroAssemblerCodePtr codePtr)
357 return MacroAssemblerCodeRef(codePtr);
361 // Helper for creating self-managed code refs from LLInt.
362 static MacroAssemblerCodeRef createLLIntCodeRef(LLIntCode codeId)
364 return createSelfManagedCodeRef(MacroAssemblerCodePtr::createFromExecutableAddress(LLInt::getCodePtr(codeId)));
368 ExecutableMemoryHandle* executableMemory() const
370 return m_executableMemory.get();
373 MacroAssemblerCodePtr code() const
380 if (!m_executableMemory)
382 return m_executableMemory->sizeInBytes();
385 bool tryToDisassemble(const char* prefix) const
387 return JSC::tryToDisassemble(m_codePtr, size(), prefix, WTF::dataFile());
390 bool operator!() const { return !m_codePtr; }
393 MacroAssemblerCodePtr m_codePtr;
394 RefPtr<ExecutableMemoryHandle> m_executableMemory;
399 #endif // MacroAssemblerCodeRef_h