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/PrintStream.h> 
  35 #include <wtf/RefPtr.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). 
  39 #if CPU(ARM_THUMB2) && ENABLE(JIT) 
  40 // ARM instructions must be 16-bit aligned. Thumb2 code pointers to be loaded into 
  41 // into the processor are decorated with the bottom bit set, while traditional ARM has 
  42 // the lower bit clear. Since we don't know what kind of pointer, we check for both 
  43 // decorated and undecorated null. 
  44 #define ASSERT_VALID_CODE_POINTER(ptr) \ 
  45     ASSERT(reinterpret_cast<intptr_t>(ptr) & ~1) 
  46 #define ASSERT_VALID_CODE_OFFSET(offset) \ 
  47     ASSERT(!(offset & 1)) // Must be multiple of 2. 
  49 #define ASSERT_VALID_CODE_POINTER(ptr) \ 
  51 #define ASSERT_VALID_CODE_OFFSET(offset) // Anything goes! 
  54 #if CPU(X86) && OS(WINDOWS) 
  55 #define CALLING_CONVENTION_IS_STDCALL 1 
  60 #define CDECL __attribute__ ((__cdecl)) 
  61 #endif // COMPILER(MSVC) 
  64 #define CALLING_CONVENTION_IS_STDCALL 0 
  68 #define HAS_FASTCALL_CALLING_CONVENTION 1 
  71 #define FASTCALL __fastcall 
  73 #define FASTCALL  __attribute__ ((fastcall)) 
  74 #endif // COMPILER(MSVC) 
  77 #define HAS_FASTCALL_CALLING_CONVENTION 0 
  84 // FunctionPtr should be used to wrap pointers to C/C++ functions in JSC 
  85 // (particularly, the stub functions). 
  93     template<typename returnType
> 
  94     FunctionPtr(returnType(*value
)()) 
  95         : m_value((void*)value
) 
  97         ASSERT_VALID_CODE_POINTER(m_value
); 
 100     template<typename returnType
, typename argType1
> 
 101     FunctionPtr(returnType(*value
)(argType1
)) 
 102         : m_value((void*)value
) 
 104         ASSERT_VALID_CODE_POINTER(m_value
); 
 107     template<typename returnType
, typename argType1
, typename argType2
> 
 108     FunctionPtr(returnType(*value
)(argType1
, argType2
)) 
 109         : m_value((void*)value
) 
 111         ASSERT_VALID_CODE_POINTER(m_value
); 
 114     template<typename returnType
, typename argType1
, typename argType2
, typename argType3
> 
 115     FunctionPtr(returnType(*value
)(argType1
, argType2
, argType3
)) 
 116         : m_value((void*)value
) 
 118         ASSERT_VALID_CODE_POINTER(m_value
); 
 121     template<typename returnType
, typename argType1
, typename argType2
, typename argType3
, typename argType4
> 
 122     FunctionPtr(returnType(*value
)(argType1
, argType2
, argType3
, argType4
)) 
 123         : m_value((void*)value
) 
 125         ASSERT_VALID_CODE_POINTER(m_value
); 
 128     template<typename returnType
, typename argType1
, typename argType2
, typename argType3
, typename argType4
, typename argType5
> 
 129     FunctionPtr(returnType(*value
)(argType1
, argType2
, argType3
, argType4
, argType5
)) 
 130         : m_value((void*)value
) 
 132         ASSERT_VALID_CODE_POINTER(m_value
); 
 135     template<typename returnType
, typename argType1
, typename argType2
, typename argType3
, typename argType4
, typename argType5
, typename argType6
> 
 136     FunctionPtr(returnType(*value
)(argType1
, argType2
, argType3
, argType4
, argType5
, argType6
)) 
 137         : m_value((void*)value
) 
 139         ASSERT_VALID_CODE_POINTER(m_value
); 
 141 // MSVC doesn't seem to treat functions with different calling conventions as 
 142 // different types; these methods already defined for fastcall, below. 
 143 #if CALLING_CONVENTION_IS_STDCALL && !OS(WINDOWS) 
 145     template<typename returnType
> 
 146     FunctionPtr(returnType (CDECL 
*value
)()) 
 147         : m_value((void*)value
) 
 149         ASSERT_VALID_CODE_POINTER(m_value
); 
 152     template<typename returnType
, typename argType1
> 
 153     FunctionPtr(returnType (CDECL 
*value
)(argType1
)) 
 154         : m_value((void*)value
) 
 156         ASSERT_VALID_CODE_POINTER(m_value
); 
 159     template<typename returnType
, typename argType1
, typename argType2
> 
 160     FunctionPtr(returnType (CDECL 
*value
)(argType1
, argType2
)) 
 161         : m_value((void*)value
) 
 163         ASSERT_VALID_CODE_POINTER(m_value
); 
 166     template<typename returnType
, typename argType1
, typename argType2
, typename argType3
> 
 167     FunctionPtr(returnType (CDECL 
*value
)(argType1
, argType2
, argType3
)) 
 168         : m_value((void*)value
) 
 170         ASSERT_VALID_CODE_POINTER(m_value
); 
 173     template<typename returnType
, typename argType1
, typename argType2
, typename argType3
, typename argType4
> 
 174     FunctionPtr(returnType (CDECL 
*value
)(argType1
, argType2
, argType3
, argType4
)) 
 175         : m_value((void*)value
) 
 177         ASSERT_VALID_CODE_POINTER(m_value
); 
 181 #if HAS_FASTCALL_CALLING_CONVENTION 
 183     template<typename returnType
> 
 184     FunctionPtr(returnType (FASTCALL 
*value
)()) 
 185         : m_value((void*)value
) 
 187         ASSERT_VALID_CODE_POINTER(m_value
); 
 190     template<typename returnType
, typename argType1
> 
 191     FunctionPtr(returnType (FASTCALL 
*value
)(argType1
)) 
 192         : m_value((void*)value
) 
 194         ASSERT_VALID_CODE_POINTER(m_value
); 
 197     template<typename returnType
, typename argType1
, typename argType2
> 
 198     FunctionPtr(returnType (FASTCALL 
*value
)(argType1
, argType2
)) 
 199         : m_value((void*)value
) 
 201         ASSERT_VALID_CODE_POINTER(m_value
); 
 204     template<typename returnType
, typename argType1
, typename argType2
, typename argType3
> 
 205     FunctionPtr(returnType (FASTCALL 
*value
)(argType1
, argType2
, argType3
)) 
 206         : m_value((void*)value
) 
 208         ASSERT_VALID_CODE_POINTER(m_value
); 
 211     template<typename returnType
, typename argType1
, typename argType2
, typename argType3
, typename argType4
> 
 212     FunctionPtr(returnType (FASTCALL 
*value
)(argType1
, argType2
, argType3
, argType4
)) 
 213         : m_value((void*)value
) 
 215         ASSERT_VALID_CODE_POINTER(m_value
); 
 219     template<typename FunctionType
> 
 220     explicit FunctionPtr(FunctionType
* value
) 
 221         // Using a C-ctyle cast here to avoid compiler error on RVTC: 
 222         // Error:  #694: reinterpret_cast cannot cast away const or other type qualifiers 
 223         // (I guess on RVTC function pointers have a different constness to GCC/MSVC?) 
 224         : m_value((void*)value
) 
 226         ASSERT_VALID_CODE_POINTER(m_value
); 
 229     void* value() const { return m_value
; } 
 230     void* executableAddress() const { return m_value
; } 
 239 // ReturnAddressPtr should be used to wrap return addresses generated by processor 
 240 // 'call' instructions exectued in JIT code.  We use return addresses to look up 
 241 // exception and optimization information, and to repatch the call instruction 
 242 // that is the source of the return address. 
 243 class ReturnAddressPtr 
{ 
 250     explicit ReturnAddressPtr(void* value
) 
 253         ASSERT_VALID_CODE_POINTER(m_value
); 
 256     explicit ReturnAddressPtr(FunctionPtr function
) 
 257         : m_value(function
.value()) 
 259         ASSERT_VALID_CODE_POINTER(m_value
); 
 262     void* value() const { return m_value
; } 
 264     void dump(PrintStream
& out
) const 
 266         out
.print(RawPointer(m_value
)); 
 273 // MacroAssemblerCodePtr: 
 275 // MacroAssemblerCodePtr should be used to wrap pointers to JIT generated code. 
 276 class MacroAssemblerCodePtr 
{ 
 278     MacroAssemblerCodePtr() 
 283     explicit MacroAssemblerCodePtr(void* value
) 
 285         // Decorate the pointer as a thumb code pointer. 
 286         : m_value(reinterpret_cast<char*>(value
) + 1) 
 291         ASSERT_VALID_CODE_POINTER(m_value
); 
 294     static MacroAssemblerCodePtr 
createFromExecutableAddress(void* value
) 
 296         ASSERT_VALID_CODE_POINTER(value
); 
 297         MacroAssemblerCodePtr result
; 
 298         result
.m_value 
= value
; 
 302     static MacroAssemblerCodePtr 
createLLIntCodePtr(OpcodeID codeId
) 
 304         return createFromExecutableAddress(LLInt::getCodePtr(codeId
)); 
 307     explicit MacroAssemblerCodePtr(ReturnAddressPtr ra
) 
 308         : m_value(ra
.value()) 
 310         ASSERT_VALID_CODE_POINTER(m_value
); 
 313     void* executableAddress() const { return m_value
; } 
 315     // To use this pointer as a data address remove the decoration. 
 316     void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value
); return reinterpret_cast<char*>(m_value
) - 1; } 
 318     void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value
); return m_value
; } 
 321     explicit operator bool() const { return m_value
; } 
 323     bool operator==(const MacroAssemblerCodePtr
& other
) const 
 325         return m_value 
== other
.m_value
; 
 328     void dumpWithName(const char* name
, PrintStream
& out
) const 
 330         if (executableAddress() == dataLocation()) { 
 331             out
.print(name
, "(", RawPointer(executableAddress()), ")"); 
 334         out
.print(name
, "(executable = ", RawPointer(executableAddress()), ", dataLocation = ", RawPointer(dataLocation()), ")"); 
 337     void dump(PrintStream
& out
) const 
 339         dumpWithName("CodePtr", out
); 
 342     enum EmptyValueTag 
{ EmptyValue 
}; 
 343     enum DeletedValueTag 
{ DeletedValue 
}; 
 345     MacroAssemblerCodePtr(EmptyValueTag
) 
 346         : m_value(emptyValue()) 
 350     MacroAssemblerCodePtr(DeletedValueTag
) 
 351         : m_value(deletedValue()) 
 355     bool isEmptyValue() const { return m_value 
== emptyValue(); } 
 356     bool isDeletedValue() const { return m_value 
== deletedValue(); } 
 358     unsigned hash() const { return PtrHash
<void*>::hash(m_value
); } 
 361     static void* emptyValue() { return bitwise_cast
<void*>(static_cast<intptr_t>(1)); } 
 362     static void* deletedValue() { return bitwise_cast
<void*>(static_cast<intptr_t>(2)); } 
 367 struct MacroAssemblerCodePtrHash 
{ 
 368     static unsigned hash(const MacroAssemblerCodePtr
& ptr
) { return ptr
.hash(); } 
 369     static bool equal(const MacroAssemblerCodePtr
& a
, const MacroAssemblerCodePtr
& b
) 
 373     static const bool safeToCompareToEmptyOrDeleted 
= true; 
 376 // MacroAssemblerCodeRef: 
 378 // A reference to a section of JIT generated code.  A CodeRef consists of a 
 379 // pointer to the code, and a ref pointer to the pool from within which it 
 381 class MacroAssemblerCodeRef 
{ 
 383     // This is private because it's dangerous enough that we want uses of it 
 384     // to be easy to find - hence the static create method below. 
 385     explicit MacroAssemblerCodeRef(MacroAssemblerCodePtr codePtr
) 
 392     MacroAssemblerCodeRef() 
 396     MacroAssemblerCodeRef(PassRefPtr
<ExecutableMemoryHandle
> executableMemory
) 
 397         : m_codePtr(executableMemory
->start()) 
 398         , m_executableMemory(executableMemory
) 
 400         ASSERT(m_executableMemory
->isManaged()); 
 401         ASSERT(m_executableMemory
->start()); 
 405     // Use this only when you know that the codePtr refers to code that is 
 406     // already being kept alive through some other means. Typically this means 
 407     // that codePtr is immortal. 
 408     static MacroAssemblerCodeRef 
createSelfManagedCodeRef(MacroAssemblerCodePtr codePtr
) 
 410         return MacroAssemblerCodeRef(codePtr
); 
 413     // Helper for creating self-managed code refs from LLInt. 
 414     static MacroAssemblerCodeRef 
createLLIntCodeRef(OpcodeID codeId
) 
 416         return createSelfManagedCodeRef(MacroAssemblerCodePtr::createFromExecutableAddress(LLInt::getCodePtr(codeId
))); 
 419     ExecutableMemoryHandle
* executableMemory() const 
 421         return m_executableMemory
.get(); 
 424     MacroAssemblerCodePtr 
code() const 
 431         if (!m_executableMemory
) 
 433         return m_executableMemory
->sizeInBytes(); 
 436     bool tryToDisassemble(const char* prefix
) const 
 438         return JSC::tryToDisassemble(m_codePtr
, size(), prefix
, WTF::dataFile()); 
 441     explicit operator bool() const { return !!m_codePtr
; } 
 443     void dump(PrintStream
& out
) const 
 445         m_codePtr
.dumpWithName("CodeRef", out
); 
 449     MacroAssemblerCodePtr m_codePtr
; 
 450     RefPtr
<ExecutableMemoryHandle
> m_executableMemory
; 
 457 template<typename T
> struct DefaultHash
; 
 458 template<> struct DefaultHash
<JSC::MacroAssemblerCodePtr
> { 
 459     typedef JSC::MacroAssemblerCodePtrHash Hash
; 
 462 template<typename T
> struct HashTraits
; 
 463 template<> struct HashTraits
<JSC::MacroAssemblerCodePtr
> : public CustomHashTraits
<JSC::MacroAssemblerCodePtr
> { }; 
 467 #endif // MacroAssemblerCodeRef_h