Home | History | Annotate | Download | only in assembler
      1 /*
      2  * Copyright (C) 2009 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 #ifndef MacroAssemblerCodeRef_h
     27 #define MacroAssemblerCodeRef_h
     28 
     29 #include "ExecutableAllocator.h"
     30 #include "PassRefPtr.h"
     31 #include "RefPtr.h"
     32 #include "UnusedParam.h"
     33 
     34 #if ENABLE(ASSEMBLER)
     35 
     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).
     38 #if CPU(ARM_THUMB2)
     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
     43 // decorated.
     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.
     49 #else
     50 #define ASSERT_VALID_CODE_POINTER(ptr) \
     51     ASSERT(ptr)
     52 #define ASSERT_VALID_CODE_OFFSET(offset) // Anything goes!
     53 #endif
     54 
     55 namespace JSC {
     56 
     57 // FunctionPtr:
     58 //
     59 // FunctionPtr should be used to wrap pointers to C/C++ functions in JSC
     60 // (particularly, the stub functions).
     61 class FunctionPtr {
     62 public:
     63     FunctionPtr()
     64         : m_value(0)
     65     {
     66     }
     67 
     68     template<typename returnType>
     69     FunctionPtr(returnType(*value)())
     70         : m_value((void*)value)
     71     {
     72         ASSERT_VALID_CODE_POINTER(m_value);
     73     }
     74 
     75     template<typename returnType, typename argType1>
     76     FunctionPtr(returnType(*value)(argType1))
     77         : m_value((void*)value)
     78     {
     79         ASSERT_VALID_CODE_POINTER(m_value);
     80     }
     81 
     82     template<typename returnType, typename argType1, typename argType2>
     83     FunctionPtr(returnType(*value)(argType1, argType2))
     84         : m_value((void*)value)
     85     {
     86         ASSERT_VALID_CODE_POINTER(m_value);
     87     }
     88 
     89     template<typename returnType, typename argType1, typename argType2, typename argType3>
     90     FunctionPtr(returnType(*value)(argType1, argType2, argType3))
     91         : m_value((void*)value)
     92     {
     93         ASSERT_VALID_CODE_POINTER(m_value);
     94     }
     95 
     96     template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4>
     97     FunctionPtr(returnType(*value)(argType1, argType2, argType3, argType4))
     98         : m_value((void*)value)
     99     {
    100         ASSERT_VALID_CODE_POINTER(m_value);
    101     }
    102 
    103     template<typename FunctionType>
    104     explicit FunctionPtr(FunctionType* value)
    105         // Using a C-ctyle cast here to avoid compiler error on RVTC:
    106         // Error:  #694: reinterpret_cast cannot cast away const or other type qualifiers
    107         // (I guess on RVTC function pointers have a different constness to GCC/MSVC?)
    108         : m_value((void*)value)
    109     {
    110         ASSERT_VALID_CODE_POINTER(m_value);
    111     }
    112 
    113     void* value() const { return m_value; }
    114     void* executableAddress() const { return m_value; }
    115 
    116 
    117 private:
    118     void* m_value;
    119 };
    120 
    121 // ReturnAddressPtr:
    122 //
    123 // ReturnAddressPtr should be used to wrap return addresses generated by processor
    124 // 'call' instructions exectued in JIT code.  We use return addresses to look up
    125 // exception and optimization information, and to repatch the call instruction
    126 // that is the source of the return address.
    127 class ReturnAddressPtr {
    128 public:
    129     ReturnAddressPtr()
    130         : m_value(0)
    131     {
    132     }
    133 
    134     explicit ReturnAddressPtr(void* value)
    135         : m_value(value)
    136     {
    137         ASSERT_VALID_CODE_POINTER(m_value);
    138     }
    139 
    140     explicit ReturnAddressPtr(FunctionPtr function)
    141         : m_value(function.value())
    142     {
    143         ASSERT_VALID_CODE_POINTER(m_value);
    144     }
    145 
    146     void* value() const { return m_value; }
    147 
    148 private:
    149     void* m_value;
    150 };
    151 
    152 // MacroAssemblerCodePtr:
    153 //
    154 // MacroAssemblerCodePtr should be used to wrap pointers to JIT generated code.
    155 class MacroAssemblerCodePtr {
    156 public:
    157     MacroAssemblerCodePtr()
    158         : m_value(0)
    159     {
    160     }
    161 
    162     explicit MacroAssemblerCodePtr(void* value)
    163 #if CPU(ARM_THUMB2)
    164         // Decorate the pointer as a thumb code pointer.
    165         : m_value(reinterpret_cast<char*>(value) + 1)
    166 #else
    167         : m_value(value)
    168 #endif
    169     {
    170         ASSERT_VALID_CODE_POINTER(m_value);
    171     }
    172 
    173     explicit MacroAssemblerCodePtr(ReturnAddressPtr ra)
    174         : m_value(ra.value())
    175     {
    176         ASSERT_VALID_CODE_POINTER(m_value);
    177     }
    178 
    179     void* executableAddress() const { return m_value; }
    180 #if CPU(ARM_THUMB2)
    181     // To use this pointer as a data address remove the decoration.
    182     void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return reinterpret_cast<char*>(m_value) - 1; }
    183 #else
    184     void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return m_value; }
    185 #endif
    186 
    187     bool operator!()
    188     {
    189         return !m_value;
    190     }
    191 
    192 private:
    193     void* m_value;
    194 };
    195 
    196 // MacroAssemblerCodeRef:
    197 //
    198 // A reference to a section of JIT generated code.  A CodeRef consists of a
    199 // pointer to the code, and a ref pointer to the pool from within which it
    200 // was allocated.
    201 class MacroAssemblerCodeRef {
    202 public:
    203     MacroAssemblerCodeRef()
    204         : m_size(0)
    205     {
    206     }
    207 
    208     MacroAssemblerCodeRef(void* code, PassRefPtr<ExecutablePool> executablePool, size_t size)
    209         : m_code(code)
    210         , m_executablePool(executablePool)
    211         , m_size(size)
    212     {
    213     }
    214 
    215     MacroAssemblerCodePtr m_code;
    216     RefPtr<ExecutablePool> m_executablePool;
    217     size_t m_size;
    218 };
    219 
    220 } // namespace JSC
    221 
    222 #endif // ENABLE(ASSEMBLER)
    223 
    224 #endif // MacroAssemblerCodeRef_h
    225