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 55namespace JSC { 56 57// FunctionPtr: 58// 59// FunctionPtr should be used to wrap pointers to C/C++ functions in JSC 60// (particularly, the stub functions). 61class FunctionPtr { 62public: 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 117private: 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. 127class ReturnAddressPtr { 128public: 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 148private: 149 void* m_value; 150}; 151 152// MacroAssemblerCodePtr: 153// 154// MacroAssemblerCodePtr should be used to wrap pointers to JIT generated code. 155class MacroAssemblerCodePtr { 156public: 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 192private: 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. 201class MacroAssemblerCodeRef { 202public: 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