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>
36 // ASSERT_VALID_CODE_POINTER checks that ptr is a non-null pointer, and that it is a valid
37 // instruction address on the platform (for example, check any alignment requirements).
39 // ARM/thumb instructions must be 16-bit aligned, but all code pointers to be loaded
40 // into the processor are decorated with the bottom bit set, indicating that this is
41 // thumb code (as oposed to 32-bit traditional ARM). The first test checks for both
42 // decorated and undectorated null, and the second test ensures that the pointer is
44 #define ASSERT_VALID_CODE_POINTER(ptr) \
45 ASSERT(reinterpret_cast<intptr_t>(ptr) & ~1); \
46 ASSERT(reinterpret_cast<intptr_t>(ptr) & 1)
47 #define ASSERT_VALID_CODE_OFFSET(offset) \
48 ASSERT(!(offset & 1)) // Must be multiple of 2.
50 #define ASSERT_VALID_CODE_POINTER(ptr) \
52 #define ASSERT_VALID_CODE_OFFSET(offset) // Anything goes!
55 #if CPU(X86) && OS(WINDOWS)
56 #define CALLING_CONVENTION_IS_STDCALL 1
61 #define CDECL __attribute__ ((__cdecl))
62 #endif // COMPILER(MSVC)
65 #define CALLING_CONVENTION_IS_STDCALL 0
69 #define HAS_FASTCALL_CALLING_CONVENTION 1
72 #define FASTCALL __fastcall
74 #define FASTCALL __attribute__ ((fastcall))
75 #endif // COMPILER(MSVC)
78 #define HAS_FASTCALL_CALLING_CONVENTION 0
85 // FunctionPtr should be used to wrap pointers to C/C++ functions in JSC
86 // (particularly, the stub functions).
94 template<typename returnType
>
95 FunctionPtr(returnType(*value
)())
96 : m_value((void*)value
)
98 ASSERT_VALID_CODE_POINTER(m_value
);
101 template<typename returnType
, typename argType1
>
102 FunctionPtr(returnType(*value
)(argType1
))
103 : m_value((void*)value
)
105 ASSERT_VALID_CODE_POINTER(m_value
);
108 template<typename returnType
, typename argType1
, typename argType2
>
109 FunctionPtr(returnType(*value
)(argType1
, argType2
))
110 : m_value((void*)value
)
112 ASSERT_VALID_CODE_POINTER(m_value
);
115 template<typename returnType
, typename argType1
, typename argType2
, typename argType3
>
116 FunctionPtr(returnType(*value
)(argType1
, argType2
, argType3
))
117 : m_value((void*)value
)
119 ASSERT_VALID_CODE_POINTER(m_value
);
122 template<typename returnType
, typename argType1
, typename argType2
, typename argType3
, typename argType4
>
123 FunctionPtr(returnType(*value
)(argType1
, argType2
, argType3
, argType4
))
124 : m_value((void*)value
)
126 ASSERT_VALID_CODE_POINTER(m_value
);
129 template<typename returnType
, typename argType1
, typename argType2
, typename argType3
, typename argType4
, typename argType5
>
130 FunctionPtr(returnType(*value
)(argType1
, argType2
, argType3
, argType4
, argType5
))
131 : m_value((void*)value
)
133 ASSERT_VALID_CODE_POINTER(m_value
);
136 // MSVC doesn't seem to treat functions with different calling conventions as
137 // different types; these methods already defined for fastcall, below.
138 #if CALLING_CONVENTION_IS_STDCALL && !OS(WINDOWS)
140 template<typename returnType
>
141 FunctionPtr(returnType (CDECL
*value
)())
142 : m_value((void*)value
)
144 ASSERT_VALID_CODE_POINTER(m_value
);
147 template<typename returnType
, typename argType1
>
148 FunctionPtr(returnType (CDECL
*value
)(argType1
))
149 : m_value((void*)value
)
151 ASSERT_VALID_CODE_POINTER(m_value
);
154 template<typename returnType
, typename argType1
, typename argType2
>
155 FunctionPtr(returnType (CDECL
*value
)(argType1
, argType2
))
156 : m_value((void*)value
)
158 ASSERT_VALID_CODE_POINTER(m_value
);
161 template<typename returnType
, typename argType1
, typename argType2
, typename argType3
>
162 FunctionPtr(returnType (CDECL
*value
)(argType1
, argType2
, argType3
))
163 : m_value((void*)value
)
165 ASSERT_VALID_CODE_POINTER(m_value
);
168 template<typename returnType
, typename argType1
, typename argType2
, typename argType3
, typename argType4
>
169 FunctionPtr(returnType (CDECL
*value
)(argType1
, argType2
, argType3
, argType4
))
170 : m_value((void*)value
)
172 ASSERT_VALID_CODE_POINTER(m_value
);
176 #if HAS_FASTCALL_CALLING_CONVENTION
178 template<typename returnType
>
179 FunctionPtr(returnType (FASTCALL
*value
)())
180 : m_value((void*)value
)
182 ASSERT_VALID_CODE_POINTER(m_value
);
185 template<typename returnType
, typename argType1
>
186 FunctionPtr(returnType (FASTCALL
*value
)(argType1
))
187 : m_value((void*)value
)
189 ASSERT_VALID_CODE_POINTER(m_value
);
192 template<typename returnType
, typename argType1
, typename argType2
>
193 FunctionPtr(returnType (FASTCALL
*value
)(argType1
, argType2
))
194 : m_value((void*)value
)
196 ASSERT_VALID_CODE_POINTER(m_value
);
199 template<typename returnType
, typename argType1
, typename argType2
, typename argType3
>
200 FunctionPtr(returnType (FASTCALL
*value
)(argType1
, argType2
, argType3
))
201 : m_value((void*)value
)
203 ASSERT_VALID_CODE_POINTER(m_value
);
206 template<typename returnType
, typename argType1
, typename argType2
, typename argType3
, typename argType4
>
207 FunctionPtr(returnType (FASTCALL
*value
)(argType1
, argType2
, argType3
, argType4
))
208 : m_value((void*)value
)
210 ASSERT_VALID_CODE_POINTER(m_value
);
214 template<typename FunctionType
>
215 explicit FunctionPtr(FunctionType
* value
)
216 // Using a C-ctyle cast here to avoid compiler error on RVTC:
217 // Error: #694: reinterpret_cast cannot cast away const or other type qualifiers
218 // (I guess on RVTC function pointers have a different constness to GCC/MSVC?)
219 : m_value((void*)value
)
221 ASSERT_VALID_CODE_POINTER(m_value
);
224 void* value() const { return m_value
; }
225 void* executableAddress() const { return m_value
; }
234 // ReturnAddressPtr should be used to wrap return addresses generated by processor
235 // 'call' instructions exectued in JIT code. We use return addresses to look up
236 // exception and optimization information, and to repatch the call instruction
237 // that is the source of the return address.
238 class ReturnAddressPtr
{
245 explicit ReturnAddressPtr(void* value
)
248 ASSERT_VALID_CODE_POINTER(m_value
);
251 explicit ReturnAddressPtr(FunctionPtr function
)
252 : m_value(function
.value())
254 ASSERT_VALID_CODE_POINTER(m_value
);
257 void* value() const { return m_value
; }
263 // MacroAssemblerCodePtr:
265 // MacroAssemblerCodePtr should be used to wrap pointers to JIT generated code.
266 class MacroAssemblerCodePtr
{
268 MacroAssemblerCodePtr()
273 explicit MacroAssemblerCodePtr(void* value
)
275 // Decorate the pointer as a thumb code pointer.
276 : m_value(reinterpret_cast<char*>(value
) + 1)
281 ASSERT_VALID_CODE_POINTER(m_value
);
284 static MacroAssemblerCodePtr
createFromExecutableAddress(void* value
)
286 ASSERT_VALID_CODE_POINTER(value
);
287 MacroAssemblerCodePtr result
;
288 result
.m_value
= value
;
293 static MacroAssemblerCodePtr
createLLIntCodePtr(LLIntCode codeId
)
295 return createFromExecutableAddress(LLInt::getCodePtr(codeId
));
299 explicit MacroAssemblerCodePtr(ReturnAddressPtr ra
)
300 : m_value(ra
.value())
302 ASSERT_VALID_CODE_POINTER(m_value
);
305 void* executableAddress() const { return m_value
; }
307 // To use this pointer as a data address remove the decoration.
308 void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value
); return reinterpret_cast<char*>(m_value
) - 1; }
310 void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value
); return m_value
; }
313 bool operator!() const
322 // MacroAssemblerCodeRef:
324 // A reference to a section of JIT generated code. A CodeRef consists of a
325 // pointer to the code, and a ref pointer to the pool from within which it
327 class MacroAssemblerCodeRef
{
329 // This is private because it's dangerous enough that we want uses of it
330 // to be easy to find - hence the static create method below.
331 explicit MacroAssemblerCodeRef(MacroAssemblerCodePtr codePtr
)
338 MacroAssemblerCodeRef()
342 MacroAssemblerCodeRef(PassRefPtr
<ExecutableMemoryHandle
> executableMemory
)
343 : m_codePtr(executableMemory
->start())
344 , m_executableMemory(executableMemory
)
346 ASSERT(m_executableMemory
->isManaged());
347 ASSERT(m_executableMemory
->start());
351 // Use this only when you know that the codePtr refers to code that is
352 // already being kept alive through some other means. Typically this means
353 // that codePtr is immortal.
354 static MacroAssemblerCodeRef
createSelfManagedCodeRef(MacroAssemblerCodePtr codePtr
)
356 return MacroAssemblerCodeRef(codePtr
);
360 // Helper for creating self-managed code refs from LLInt.
361 static MacroAssemblerCodeRef
createLLIntCodeRef(LLIntCode codeId
)
363 return createSelfManagedCodeRef(MacroAssemblerCodePtr::createFromExecutableAddress(LLInt::getCodePtr(codeId
)));
367 ExecutableMemoryHandle
* executableMemory() const
369 return m_executableMemory
.get();
372 MacroAssemblerCodePtr
code() const
379 if (!m_executableMemory
)
381 return m_executableMemory
->sizeInBytes();
384 bool tryToDisassemble(const char* prefix
) const
386 return JSC::tryToDisassemble(m_codePtr
, size(), prefix
, WTF::dataFile());
389 bool operator!() const { return !m_codePtr
; }
392 MacroAssemblerCodePtr m_codePtr
;
393 RefPtr
<ExecutableMemoryHandle
> m_executableMemory
;
398 #endif // MacroAssemblerCodeRef_h