Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||
---|---|---|---|---|---|---|---|---|
1 | /* | - | ||||||
2 | * Copyright (C) 2009, 2012 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 "Disassembler.h" | - | ||||||
30 | #include "ExecutableAllocator.h" | - | ||||||
31 | #include "LLIntData.h" | - | ||||||
32 | #include <wtf/DataLog.h> | - | ||||||
33 | #include <wtf/PassRefPtr.h> | - | ||||||
34 | #include <wtf/RefPtr.h> | - | ||||||
35 | #include <wtf/UnusedParam.h> | - | ||||||
36 | #include <qglobal.h> | - | ||||||
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 | #define ASSERT_VALID_CODE_OFFSET(offset) \ | - | ||||||
49 | ASSERT(!(offset & 1)) // Must be multiple of 2. | - | ||||||
50 | #else | - | ||||||
51 | #define ASSERT_VALID_CODE_POINTER(ptr) \ | - | ||||||
52 | ASSERT(ptr) | - | ||||||
53 | #define ASSERT_VALID_CODE_OFFSET(offset) // Anything goes! | - | ||||||
54 | #endif | - | ||||||
55 | - | |||||||
56 | #if CPU(X86) && OS(WINDOWS) | - | ||||||
57 | #define CALLING_CONVENTION_IS_STDCALL 1 | - | ||||||
58 | #ifndef CDECL | - | ||||||
59 | #if COMPILER(MSVC) | - | ||||||
60 | #define CDECL __cdecl | - | ||||||
61 | #else | - | ||||||
62 | #define CDECL __attribute__ ((__cdecl)) | - | ||||||
63 | #endif // COMPILER(MSVC) | - | ||||||
64 | #endif // CDECL | - | ||||||
65 | #else | - | ||||||
66 | #define CALLING_CONVENTION_IS_STDCALL 0 | - | ||||||
67 | #endif | - | ||||||
68 | - | |||||||
69 | #if CPU(X86) && !OS(INTEGRITY) | - | ||||||
70 | #define HAS_FASTCALL_CALLING_CONVENTION 1 | - | ||||||
71 | #ifndef FASTCALL | - | ||||||
72 | #if COMPILER(MSVC) | - | ||||||
73 | #define FASTCALL __fastcall | - | ||||||
74 | #else | - | ||||||
75 | #define FASTCALL __attribute__ ((fastcall)) | - | ||||||
76 | #endif // COMPILER(MSVC) | - | ||||||
77 | #endif // FASTCALL | - | ||||||
78 | #else | - | ||||||
79 | #define HAS_FASTCALL_CALLING_CONVENTION 0 | - | ||||||
80 | #endif // CPU(X86) | - | ||||||
81 | - | |||||||
82 | namespace JSC { | - | ||||||
83 | - | |||||||
84 | // FunctionPtr: | - | ||||||
85 | // | - | ||||||
86 | // FunctionPtr should be used to wrap pointers to C/C++ functions in JSC | - | ||||||
87 | // (particularly, the stub functions). | - | ||||||
88 | class FunctionPtr { | - | ||||||
89 | public: | - | ||||||
90 | FunctionPtr() | - | ||||||
91 | : m_value(0) | - | ||||||
92 | { | - | ||||||
93 | } never executed: end of block | 0 | ||||||
94 | - | |||||||
95 | template<typename returnType> | - | ||||||
96 | FunctionPtr(returnType(*value)()) | - | ||||||
97 | : m_value((void*)value) | - | ||||||
98 | { | - | ||||||
99 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
100 | } never executed: end of block | 0 | ||||||
101 | - | |||||||
102 | template<typename returnType, typename argType1> | - | ||||||
103 | FunctionPtr(returnType(*value)(argType1)) | - | ||||||
104 | : m_value((void*)value) | - | ||||||
105 | { | - | ||||||
106 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
107 | } never executed: end of block | 0 | ||||||
108 | - | |||||||
109 | template<typename returnType, typename argType1, typename argType2> | - | ||||||
110 | FunctionPtr(returnType(*value)(argType1, argType2)) | - | ||||||
111 | : m_value((void*)value) | - | ||||||
112 | { | - | ||||||
113 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
114 | } never executed: end of block | 0 | ||||||
115 | - | |||||||
116 | template<typename returnType, typename argType1, typename argType2, typename argType3> | - | ||||||
117 | FunctionPtr(returnType(*value)(argType1, argType2, argType3)) | - | ||||||
118 | : m_value((void*)value) | - | ||||||
119 | { | - | ||||||
120 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
121 | } never executed: end of block | 0 | ||||||
122 | - | |||||||
123 | template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4> | - | ||||||
124 | FunctionPtr(returnType(*value)(argType1, argType2, argType3, argType4)) | - | ||||||
125 | : m_value((void*)value) | - | ||||||
126 | { | - | ||||||
127 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
128 | } never executed: end of block | 0 | ||||||
129 | - | |||||||
130 | template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4, typename argType5> | - | ||||||
131 | FunctionPtr(returnType(*value)(argType1, argType2, argType3, argType4, argType5)) | - | ||||||
132 | : m_value((void*)value) | - | ||||||
133 | { | - | ||||||
134 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
135 | } never executed: end of block | 0 | ||||||
136 | - | |||||||
137 | template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4, typename argType5, typename argType6> | - | ||||||
138 | FunctionPtr(returnType(*value)(argType1, argType2, argType3, argType4, argType5, argType6)) | - | ||||||
139 | : m_value((void*)value) | - | ||||||
140 | { | - | ||||||
141 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
142 | } never executed: end of block | 0 | ||||||
143 | - | |||||||
144 | // MSVC doesn't seem to treat functions with different calling conventions as | - | ||||||
145 | // different types; these methods already defined for fastcall, below. | - | ||||||
146 | #if CALLING_CONVENTION_IS_STDCALL && !OS(WINDOWS) | - | ||||||
147 | - | |||||||
148 | template<typename returnType> | - | ||||||
149 | FunctionPtr(returnType (CDECL *value)()) | - | ||||||
150 | : m_value((void*)value) | - | ||||||
151 | { | - | ||||||
152 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
153 | } | - | ||||||
154 | - | |||||||
155 | template<typename returnType, typename argType1> | - | ||||||
156 | FunctionPtr(returnType (CDECL *value)(argType1)) | - | ||||||
157 | : m_value((void*)value) | - | ||||||
158 | { | - | ||||||
159 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
160 | } | - | ||||||
161 | - | |||||||
162 | template<typename returnType, typename argType1, typename argType2> | - | ||||||
163 | FunctionPtr(returnType (CDECL *value)(argType1, argType2)) | - | ||||||
164 | : m_value((void*)value) | - | ||||||
165 | { | - | ||||||
166 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
167 | } | - | ||||||
168 | - | |||||||
169 | template<typename returnType, typename argType1, typename argType2, typename argType3> | - | ||||||
170 | FunctionPtr(returnType (CDECL *value)(argType1, argType2, argType3)) | - | ||||||
171 | : m_value((void*)value) | - | ||||||
172 | { | - | ||||||
173 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
174 | } | - | ||||||
175 | - | |||||||
176 | template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4> | - | ||||||
177 | FunctionPtr(returnType (CDECL *value)(argType1, argType2, argType3, argType4)) | - | ||||||
178 | : m_value((void*)value) | - | ||||||
179 | { | - | ||||||
180 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
181 | } | - | ||||||
182 | #endif | - | ||||||
183 | - | |||||||
184 | #if HAS_FASTCALL_CALLING_CONVENTION | - | ||||||
185 | - | |||||||
186 | template<typename returnType> | - | ||||||
187 | FunctionPtr(returnType (FASTCALL *value)()) | - | ||||||
188 | : m_value((void*)value) | - | ||||||
189 | { | - | ||||||
190 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
191 | } | - | ||||||
192 | - | |||||||
193 | template<typename returnType, typename argType1> | - | ||||||
194 | FunctionPtr(returnType (FASTCALL *value)(argType1)) | - | ||||||
195 | : m_value((void*)value) | - | ||||||
196 | { | - | ||||||
197 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
198 | } | - | ||||||
199 | - | |||||||
200 | template<typename returnType, typename argType1, typename argType2> | - | ||||||
201 | FunctionPtr(returnType (FASTCALL *value)(argType1, argType2)) | - | ||||||
202 | : m_value((void*)value) | - | ||||||
203 | { | - | ||||||
204 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
205 | } | - | ||||||
206 | - | |||||||
207 | template<typename returnType, typename argType1, typename argType2, typename argType3> | - | ||||||
208 | FunctionPtr(returnType (FASTCALL *value)(argType1, argType2, argType3)) | - | ||||||
209 | : m_value((void*)value) | - | ||||||
210 | { | - | ||||||
211 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
212 | } | - | ||||||
213 | - | |||||||
214 | template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4> | - | ||||||
215 | FunctionPtr(returnType (FASTCALL *value)(argType1, argType2, argType3, argType4)) | - | ||||||
216 | : m_value((void*)value) | - | ||||||
217 | { | - | ||||||
218 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
219 | } | - | ||||||
220 | #endif | - | ||||||
221 | - | |||||||
222 | template<typename FunctionType> | - | ||||||
223 | explicit FunctionPtr(FunctionType* value) | - | ||||||
224 | // Using a C-ctyle cast here to avoid compiler error on RVTC: | - | ||||||
225 | // Error: #694: reinterpret_cast cannot cast away const or other type qualifiers | - | ||||||
226 | // (I guess on RVTC function pointers have a different constness to GCC/MSVC?) | - | ||||||
227 | : m_value((void*)value) | - | ||||||
228 | { | - | ||||||
229 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
230 | } never executed: end of block | 0 | ||||||
231 | - | |||||||
232 | void* value() const { return m_value; } never executed: return m_value; | 0 | ||||||
233 | void* executableAddress() const { return m_value; } never executed: return m_value; | 0 | ||||||
234 | - | |||||||
235 | - | |||||||
236 | private: | - | ||||||
237 | void* m_value; | - | ||||||
238 | }; | - | ||||||
239 | - | |||||||
240 | // ReturnAddressPtr: | - | ||||||
241 | // | - | ||||||
242 | // ReturnAddressPtr should be used to wrap return addresses generated by processor | - | ||||||
243 | // 'call' instructions exectued in JIT code. We use return addresses to look up | - | ||||||
244 | // exception and optimization information, and to repatch the call instruction | - | ||||||
245 | // that is the source of the return address. | - | ||||||
246 | class ReturnAddressPtr { | - | ||||||
247 | public: | - | ||||||
248 | ReturnAddressPtr() | - | ||||||
249 | : m_value(0) | - | ||||||
250 | { | - | ||||||
251 | } never executed: end of block | 0 | ||||||
252 | - | |||||||
253 | explicit ReturnAddressPtr(void* value) | - | ||||||
254 | : m_value(value) | - | ||||||
255 | { | - | ||||||
256 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
257 | } never executed: end of block | 0 | ||||||
258 | - | |||||||
259 | explicit ReturnAddressPtr(FunctionPtr function) | - | ||||||
260 | : m_value(function.value()) | - | ||||||
261 | { | - | ||||||
262 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
263 | } never executed: end of block | 0 | ||||||
264 | - | |||||||
265 | void* value() const { return m_value; } never executed: return m_value; | 0 | ||||||
266 | - | |||||||
267 | private: | - | ||||||
268 | void* m_value; | - | ||||||
269 | }; | - | ||||||
270 | - | |||||||
271 | // MacroAssemblerCodePtr: | - | ||||||
272 | // | - | ||||||
273 | // MacroAssemblerCodePtr should be used to wrap pointers to JIT generated code. | - | ||||||
274 | class MacroAssemblerCodePtr { | - | ||||||
275 | public: | - | ||||||
276 | MacroAssemblerCodePtr() | - | ||||||
277 | : m_value(0) | - | ||||||
278 | { | - | ||||||
279 | } executed 4614471 times by 153 tests: end of block Executed by:
| 4614471 | ||||||
280 | - | |||||||
281 | explicit MacroAssemblerCodePtr(void* value) | - | ||||||
282 | #if CPU(ARM_THUMB2) | - | ||||||
283 | // Decorate the pointer as a thumb code pointer. | - | ||||||
284 | : m_value(reinterpret_cast<char*>(value) + 1) | - | ||||||
285 | #else | - | ||||||
286 | : m_value(value) | - | ||||||
287 | #endif | - | ||||||
288 | { | - | ||||||
289 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
290 | } executed 1165202 times by 153 tests: end of block Executed by:
| 1165202 | ||||||
291 | - | |||||||
292 | static MacroAssemblerCodePtr createFromExecutableAddress(void* value) | - | ||||||
293 | { | - | ||||||
294 | ASSERT_VALID_CODE_POINTER(value); | - | ||||||
295 | MacroAssemblerCodePtr result; | - | ||||||
296 | result.m_value = value; | - | ||||||
297 | return result; never executed: return result; | 0 | ||||||
298 | } | - | ||||||
299 | - | |||||||
300 | #if ENABLE(LLINT) | - | ||||||
301 | static MacroAssemblerCodePtr createLLIntCodePtr(LLIntCode codeId) | - | ||||||
302 | { | - | ||||||
303 | return createFromExecutableAddress(LLInt::getCodePtr(codeId)); | - | ||||||
304 | } | - | ||||||
305 | #endif | - | ||||||
306 | - | |||||||
307 | explicit MacroAssemblerCodePtr(ReturnAddressPtr ra) | - | ||||||
308 | : m_value(ra.value()) | - | ||||||
309 | { | - | ||||||
310 | ASSERT_VALID_CODE_POINTER(m_value); | - | ||||||
311 | } never executed: end of block | 0 | ||||||
312 | - | |||||||
313 | void* executableAddress() const { return m_value; } executed 25023 times by 65 tests: return m_value; Executed by:
| 25023 | ||||||
314 | #if CPU(ARM_THUMB2) | - | ||||||
315 | // To use this pointer as a data address remove the decoration. | - | ||||||
316 | void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return reinterpret_cast<char*>(m_value) - 1; } | - | ||||||
317 | #else | - | ||||||
318 | void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return m_value; } never executed: return m_value; | 0 | ||||||
319 | #endif | - | ||||||
320 | - | |||||||
321 | bool operator!() const | - | ||||||
322 | { | - | ||||||
323 | return !m_value; executed 1164588 times by 153 tests: return !m_value; Executed by:
| 1164588 | ||||||
324 | } | - | ||||||
325 | - | |||||||
326 | private: | - | ||||||
327 | void* m_value; | - | ||||||
328 | }; | - | ||||||
329 | - | |||||||
330 | // MacroAssemblerCodeRef: | - | ||||||
331 | // | - | ||||||
332 | // A reference to a section of JIT generated code. A CodeRef consists of a | - | ||||||
333 | // pointer to the code, and a ref pointer to the pool from within which it | - | ||||||
334 | // was allocated. | - | ||||||
335 | class MacroAssemblerCodeRef { | - | ||||||
336 | private: | - | ||||||
337 | // This is private because it's dangerous enough that we want uses of it | - | ||||||
338 | // to be easy to find - hence the static create method below. | - | ||||||
339 | explicit MacroAssemblerCodeRef(MacroAssemblerCodePtr codePtr) | - | ||||||
340 | : m_codePtr(codePtr) | - | ||||||
341 | { | - | ||||||
342 | ASSERT(m_codePtr); | - | ||||||
343 | } never executed: end of block | 0 | ||||||
344 | - | |||||||
345 | public: | - | ||||||
346 | MacroAssemblerCodeRef() | - | ||||||
347 | { | - | ||||||
348 | } | - | ||||||
349 | - | |||||||
350 | MacroAssemblerCodeRef(PassRefPtr<ExecutableMemoryHandle> executableMemory) | - | ||||||
351 | : m_codePtr(executableMemory->start()) | - | ||||||
352 | , m_executableMemory(executableMemory) | - | ||||||
353 | { | - | ||||||
354 | ASSERT(m_executableMemory->isManaged()); | - | ||||||
355 | ASSERT(m_executableMemory->start()); | - | ||||||
356 | ASSERT(m_codePtr); | - | ||||||
357 | } executed 1164589 times by 153 tests: end of block Executed by:
| 1164589 | ||||||
358 | - | |||||||
359 | // Use this only when you know that the codePtr refers to code that is | - | ||||||
360 | // already being kept alive through some other means. Typically this means | - | ||||||
361 | // that codePtr is immortal. | - | ||||||
362 | static MacroAssemblerCodeRef createSelfManagedCodeRef(MacroAssemblerCodePtr codePtr) | - | ||||||
363 | { | - | ||||||
364 | return MacroAssemblerCodeRef(codePtr); never executed: return MacroAssemblerCodeRef(codePtr); | 0 | ||||||
365 | } | - | ||||||
366 | - | |||||||
367 | #if ENABLE(LLINT) | - | ||||||
368 | // Helper for creating self-managed code refs from LLInt. | - | ||||||
369 | static MacroAssemblerCodeRef createLLIntCodeRef(LLIntCode codeId) | - | ||||||
370 | { | - | ||||||
371 | return createSelfManagedCodeRef(MacroAssemblerCodePtr::createFromExecutableAddress(LLInt::getCodePtr(codeId))); | - | ||||||
372 | } | - | ||||||
373 | #endif | - | ||||||
374 | - | |||||||
375 | ExecutableMemoryHandle* executableMemory() const | - | ||||||
376 | { | - | ||||||
377 | return m_executableMemory.get(); never executed: return m_executableMemory.get(); | 0 | ||||||
378 | } | - | ||||||
379 | - | |||||||
380 | MacroAssemblerCodePtr code() const | - | ||||||
381 | { | - | ||||||
382 | return m_codePtr; executed 24410 times by 65 tests: return m_codePtr; Executed by:
| 24410 | ||||||
383 | } | - | ||||||
384 | - | |||||||
385 | size_t size() const | - | ||||||
386 | { | - | ||||||
387 | if (!m_executableMemory)
| 0-1173854 | ||||||
388 | return 0; never executed: return 0; | 0 | ||||||
389 | return m_executableMemory->sizeInBytes(); executed 1173855 times by 153 tests: return m_executableMemory->sizeInBytes(); Executed by:
| 1173855 | ||||||
390 | } | - | ||||||
391 | - | |||||||
392 | bool tryToDisassemble(const char* prefix) const | - | ||||||
393 | { | - | ||||||
394 | return JSC::tryToDisassemble(m_codePtr, size(), prefix, WTF::dataFile()); never executed: return JSC::tryToDisassemble(m_codePtr, size(), prefix, WTF::dataFile()); | 0 | ||||||
395 | } | - | ||||||
396 | - | |||||||
397 | bool operator!() const { return !m_codePtr; } never executed: return !m_codePtr; | 0 | ||||||
398 | - | |||||||
399 | private: | - | ||||||
400 | MacroAssemblerCodePtr m_codePtr; | - | ||||||
401 | RefPtr<ExecutableMemoryHandle> m_executableMemory; | - | ||||||
402 | }; | - | ||||||
403 | - | |||||||
404 | } // namespace JSC | - | ||||||
405 | - | |||||||
406 | #endif // MacroAssemblerCodeRef_h | - | ||||||
Source code | Switch to Preprocessed file |