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