1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sw=4 et tw=79:
3 : *
4 : * ***** BEGIN LICENSE BLOCK *****
5 : * Copyright (C) 2009 Apple Inc. All rights reserved.
6 : *
7 : * Redistribution and use in source and binary forms, with or without
8 : * modification, are permitted provided that the following conditions
9 : * are met:
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * 2. Redistributions in binary form must reproduce the above copyright
13 : * notice, this list of conditions and the following disclaimer in the
14 : * documentation and/or other materials provided with the distribution.
15 : *
16 : * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
17 : * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
20 : * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 : * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 : * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24 : * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 : *
28 : * ***** END LICENSE BLOCK ***** */
29 :
30 : #ifndef MacroAssemblerCodeRef_h
31 : #define MacroAssemblerCodeRef_h
32 :
33 : #include "assembler/wtf/Platform.h"
34 : #include "assembler/jit/ExecutableAllocator.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 WTF_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:
65 : FunctionPtr()
66 : : m_value(0)
67 : {
68 : }
69 :
70 : template<typename FunctionType>
71 4972081 : explicit FunctionPtr(FunctionType* value)
72 : #if WTF_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 4972081 : : m_value(reinterpret_cast<void*>(value))
78 : #endif
79 : {
80 4972081 : ASSERT_VALID_CODE_POINTER(m_value);
81 4972081 : }
82 :
83 4905105 : void* value() const { return m_value; }
84 66466 : 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:
99 : ReturnAddressPtr()
100 : : m_value(0)
101 : {
102 : }
103 :
104 : explicit ReturnAddressPtr(void* value)
105 : : m_value(value)
106 : {
107 : ASSERT_VALID_CODE_POINTER(m_value);
108 : }
109 :
110 : explicit ReturnAddressPtr(FunctionPtr function)
111 : : m_value(function.value())
112 : {
113 : ASSERT_VALID_CODE_POINTER(m_value);
114 : }
115 :
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:
127 3805799 : MacroAssemblerCodePtr()
128 3805799 : : m_value(0)
129 : {
130 3805799 : }
131 :
132 21304096 : explicit MacroAssemblerCodePtr(void* value)
133 : #if WTF_CPU_ARM_THUMB2
134 : // Decorate the pointer as a thumb code pointer.
135 : : m_value(reinterpret_cast<char*>(value) + 1)
136 : #else
137 21304096 : : m_value(value)
138 : #endif
139 : {
140 21304096 : ASSERT_VALID_CODE_POINTER(m_value);
141 21304096 : }
142 :
143 : explicit MacroAssemblerCodePtr(ReturnAddressPtr ra)
144 : : m_value(ra.value())
145 : {
146 : ASSERT_VALID_CODE_POINTER(m_value);
147 : }
148 :
149 10901957 : void* executableAddress() const {
150 10901957 : return m_value;
151 : }
152 : #if WTF_CPU_ARM_THUMB2
153 : // To use this pointer as a data address remove the decoration.
154 : void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return reinterpret_cast<char*>(m_value) - 1; }
155 : #else
156 13864731 : void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return m_value; }
157 : #endif
158 :
159 : bool operator!()
160 : {
161 : return !m_value;
162 : }
163 :
164 1975904 : ptrdiff_t operator -(const MacroAssemblerCodePtr &other) const
165 : {
166 1975904 : JS_ASSERT(m_value);
167 : return reinterpret_cast<uint8_t *>(m_value) -
168 1975904 : reinterpret_cast<uint8_t *>(other.m_value);
169 : }
170 :
171 : private:
172 : void* m_value;
173 : };
174 :
175 : // MacroAssemblerCodeRef:
176 : //
177 : // A reference to a section of JIT generated code. A CodeRef consists of a
178 : // pointer to the code, and a ref pointer to the pool from within which it
179 : // was allocated.
180 : class MacroAssemblerCodeRef {
181 : public:
182 187071 : MacroAssemblerCodeRef()
183 : : m_executablePool(NULL),
184 187071 : m_size(0)
185 : {
186 187071 : }
187 :
188 184096 : MacroAssemblerCodeRef(void* code, ExecutablePool* executablePool, size_t size)
189 : : m_code(code)
190 : , m_executablePool(executablePool)
191 184096 : , m_size(size)
192 : {
193 184096 : }
194 :
195 : // Release the code memory in this code ref.
196 187071 : void release()
197 : {
198 187071 : if (!m_executablePool)
199 2975 : return;
200 :
201 : #if defined DEBUG && (defined WTF_CPU_X86 || defined WTF_CPU_X86_64)
202 184096 : void *addr = m_code.executableAddress();
203 184096 : memset(addr, 0xcc, m_size);
204 : #endif
205 184096 : m_executablePool->release();
206 184096 : m_executablePool = NULL;
207 : }
208 :
209 : MacroAssemblerCodePtr m_code;
210 : ExecutablePool* m_executablePool;
211 : size_t m_size;
212 : };
213 :
214 : } // namespace JSC
215 :
216 : #endif // ENABLE(ASSEMBLER)
217 :
218 : #endif // MacroAssemblerCodeRef_h
|