• 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 <wtf/Platform.h>
30 
31 #include "ExecutableAllocator.h"
32 #include "PassRefPtr.h"
33 #include "RefPtr.h"
34 #include "UnusedParam.h"
35 
36 #if ENABLE(ASSEMBLER)
37 
38 // ASSERT_VALID_CODE_POINTER checks that ptr is a non-null pointer, and that it is a valid
39 // instruction address on the platform (for example, check any alignment requirements).
40 #if CPU(ARM_THUMB2)
41 // ARM/thumb instructions must be 16-bit aligned, but all code pointers to be loaded
42 // into the processor are decorated with the bottom bit set, indicating that this is
43 // thumb code (as oposed to 32-bit traditional ARM).  The first test checks for both
44 // decorated and undectorated null, and the second test ensures that the pointer is
45 // decorated.
46 #define ASSERT_VALID_CODE_POINTER(ptr) \
47     ASSERT(reinterpret_cast<intptr_t>(ptr) & ~1); \
48     ASSERT(reinterpret_cast<intptr_t>(ptr) & 1)
49 #define ASSERT_VALID_CODE_OFFSET(offset) \
50     ASSERT(!(offset & 1)) // Must be multiple of 2.
51 #else
52 #define ASSERT_VALID_CODE_POINTER(ptr) \
53     ASSERT(ptr)
54 #define ASSERT_VALID_CODE_OFFSET(offset) // Anything goes!
55 #endif
56 
57 namespace JSC {
58 
59 // FunctionPtr:
60 //
61 // FunctionPtr should be used to wrap pointers to C/C++ functions in JSC
62 // (particularly, the stub functions).
63 class FunctionPtr {
64 public:
FunctionPtr()65     FunctionPtr()
66         : m_value(0)
67     {
68     }
69 
70     template<typename FunctionType>
FunctionPtr(FunctionType * value)71     explicit FunctionPtr(FunctionType* value)
72 #if COMPILER(RVCT)
73      // RVTC compiler needs C-style cast as it fails with the following error
74      // Error:  #694: reinterpret_cast cannot cast away const or other type qualifiers
75         : m_value((void*)(value))
76 #else
77         : m_value(reinterpret_cast<void*>(value))
78 #endif
79     {
80         ASSERT_VALID_CODE_POINTER(m_value);
81     }
82 
value()83     void* value() const { return m_value; }
executableAddress()84     void* executableAddress() const { return m_value; }
85 
86 
87 private:
88     void* m_value;
89 };
90 
91 // ReturnAddressPtr:
92 //
93 // ReturnAddressPtr should be used to wrap return addresses generated by processor
94 // 'call' instructions exectued in JIT code.  We use return addresses to look up
95 // exception and optimization information, and to repatch the call instruction
96 // that is the source of the return address.
97 class ReturnAddressPtr {
98 public:
ReturnAddressPtr()99     ReturnAddressPtr()
100         : m_value(0)
101     {
102     }
103 
ReturnAddressPtr(void * value)104     explicit ReturnAddressPtr(void* value)
105         : m_value(value)
106     {
107         ASSERT_VALID_CODE_POINTER(m_value);
108     }
109 
ReturnAddressPtr(FunctionPtr function)110     explicit ReturnAddressPtr(FunctionPtr function)
111         : m_value(function.value())
112     {
113         ASSERT_VALID_CODE_POINTER(m_value);
114     }
115 
value()116     void* value() const { return m_value; }
117 
118 private:
119     void* m_value;
120 };
121 
122 // MacroAssemblerCodePtr:
123 //
124 // MacroAssemblerCodePtr should be used to wrap pointers to JIT generated code.
125 class MacroAssemblerCodePtr {
126 public:
MacroAssemblerCodePtr()127     MacroAssemblerCodePtr()
128         : m_value(0)
129     {
130     }
131 
MacroAssemblerCodePtr(void * value)132     explicit MacroAssemblerCodePtr(void* value)
133 #if CPU(ARM_THUMB2)
134         // Decorate the pointer as a thumb code pointer.
135         : m_value(reinterpret_cast<char*>(value) + 1)
136 #else
137         : m_value(value)
138 #endif
139     {
140         ASSERT_VALID_CODE_POINTER(m_value);
141     }
142 
MacroAssemblerCodePtr(ReturnAddressPtr ra)143     explicit MacroAssemblerCodePtr(ReturnAddressPtr ra)
144         : m_value(ra.value())
145     {
146         ASSERT_VALID_CODE_POINTER(m_value);
147     }
148 
executableAddress()149     void* executableAddress() const { return m_value; }
150 #if CPU(ARM_THUMB2)
151     // To use this pointer as a data address remove the decoration.
dataLocation()152     void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return reinterpret_cast<char*>(m_value) - 1; }
153 #else
dataLocation()154     void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return m_value; }
155 #endif
156 
157     bool operator!()
158     {
159         return !m_value;
160     }
161 
162 private:
163     void* m_value;
164 };
165 
166 // MacroAssemblerCodeRef:
167 //
168 // A reference to a section of JIT generated code.  A CodeRef consists of a
169 // pointer to the code, and a ref pointer to the pool from within which it
170 // was allocated.
171 class MacroAssemblerCodeRef {
172 public:
MacroAssemblerCodeRef()173     MacroAssemblerCodeRef()
174         : m_size(0)
175     {
176     }
177 
MacroAssemblerCodeRef(void * code,PassRefPtr<ExecutablePool> executablePool,size_t size)178     MacroAssemblerCodeRef(void* code, PassRefPtr<ExecutablePool> executablePool, size_t size)
179         : m_code(code)
180         , m_executablePool(executablePool)
181         , m_size(size)
182     {
183     }
184 
185     MacroAssemblerCodePtr m_code;
186     RefPtr<ExecutablePool> m_executablePool;
187     size_t m_size;
188 };
189 
190 } // namespace JSC
191 
192 #endif // ENABLE(ASSEMBLER)
193 
194 #endif // MacroAssemblerCodeRef_h
195