• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
FunctionPtr()63     FunctionPtr()
64         : m_value(0)
65     {
66     }
67 
68     template<typename returnType>
FunctionPtr(returnType (* value)())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>
FunctionPtr(returnType (* value)(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>
FunctionPtr(returnType (* value)(argType1,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>
FunctionPtr(returnType (* value)(argType1,argType2,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>
FunctionPtr(returnType (* value)(argType1,argType2,argType3,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>
FunctionPtr(FunctionType * value)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 
value()113     void* value() const { return m_value; }
executableAddress()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:
ReturnAddressPtr()129     ReturnAddressPtr()
130         : m_value(0)
131     {
132     }
133 
ReturnAddressPtr(void * value)134     explicit ReturnAddressPtr(void* value)
135         : m_value(value)
136     {
137         ASSERT_VALID_CODE_POINTER(m_value);
138     }
139 
ReturnAddressPtr(FunctionPtr function)140     explicit ReturnAddressPtr(FunctionPtr function)
141         : m_value(function.value())
142     {
143         ASSERT_VALID_CODE_POINTER(m_value);
144     }
145 
value()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:
MacroAssemblerCodePtr()157     MacroAssemblerCodePtr()
158         : m_value(0)
159     {
160     }
161 
MacroAssemblerCodePtr(void * value)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 
MacroAssemblerCodePtr(ReturnAddressPtr ra)173     explicit MacroAssemblerCodePtr(ReturnAddressPtr ra)
174         : m_value(ra.value())
175     {
176         ASSERT_VALID_CODE_POINTER(m_value);
177     }
178 
executableAddress()179     void* executableAddress() const { return m_value; }
180 #if CPU(ARM_THUMB2)
181     // To use this pointer as a data address remove the decoration.
dataLocation()182     void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return reinterpret_cast<char*>(m_value) - 1; }
183 #else
dataLocation()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:
MacroAssemblerCodeRef()203     MacroAssemblerCodeRef()
204         : m_size(0)
205     {
206     }
207 
MacroAssemblerCodeRef(void * code,PassRefPtr<ExecutablePool> executablePool,size_t size)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