Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
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 ***** */
30 #ifndef assembler_assembler_MacroAssemblerCodeRef_h
31 #define assembler_assembler_MacroAssemblerCodeRef_h
33 #include "assembler/wtf/Assertions.h"
34 #include "assembler/wtf/Platform.h"
35 #include "assembler/jit/ExecutableAllocator.h"
37 #if ENABLE_ASSEMBLER
39 #include "jsutil.h"
41 // ASSERT_VALID_CODE_POINTER checks that ptr is a non-null pointer, and that it is a valid
42 // instruction address on the platform (for example, check any alignment requirements).
43 #if WTF_CPU_ARM_THUMB2
44 // ARM/thumb instructions must be 16-bit aligned, but all code pointers to be loaded
45 // into the processor are decorated with the bottom bit set, indicating that this is
46 // thumb code (as oposed to 32-bit traditional ARM). The first test checks for both
47 // decorated and undectorated null, and the second test ensures that the pointer is
48 // decorated.
49 #define ASSERT_VALID_CODE_POINTER(ptr) \
50 ASSERT(reinterpret_cast<intptr_t>(ptr) & ~1); \
51 ASSERT(reinterpret_cast<intptr_t>(ptr) & 1)
52 #define ASSERT_VALID_CODE_OFFSET(offset) \
53 ASSERT(!(offset & 1)) // Must be multiple of 2.
54 #else
55 #define ASSERT_VALID_CODE_POINTER(ptr) \
56 ASSERT(ptr)
57 #define ASSERT_VALID_CODE_OFFSET(offset) // Anything goes!
58 #endif
60 namespace JSC {
62 // FunctionPtr:
63 //
64 // FunctionPtr should be used to wrap pointers to C/C++ functions in JSC
65 // (particularly, the stub functions).
66 class FunctionPtr {
67 public:
68 FunctionPtr()
69 : m_value(0)
70 {
71 }
73 template<typename FunctionType>
74 explicit FunctionPtr(FunctionType* value)
75 #if WTF_COMPILER_RVCT
76 // RVTC compiler needs C-style cast as it fails with the following error
77 // Error: #694: reinterpret_cast cannot cast away const or other type qualifiers
78 : m_value((void*)(value))
79 #else
80 : m_value(reinterpret_cast<void*>(value))
81 #endif
82 {
83 ASSERT_VALID_CODE_POINTER(m_value);
84 }
86 void* value() const { return m_value; }
87 void* executableAddress() const { return m_value; }
90 private:
91 void* m_value;
92 };
94 // ReturnAddressPtr:
95 //
96 // ReturnAddressPtr should be used to wrap return addresses generated by processor
97 // 'call' instructions exectued in JIT code. We use return addresses to look up
98 // exception and optimization information, and to repatch the call instruction
99 // that is the source of the return address.
100 class ReturnAddressPtr {
101 public:
102 ReturnAddressPtr()
103 : m_value(0)
104 {
105 }
107 explicit ReturnAddressPtr(void* value)
108 : m_value(value)
109 {
110 ASSERT_VALID_CODE_POINTER(m_value);
111 }
113 explicit ReturnAddressPtr(FunctionPtr function)
114 : m_value(function.value())
115 {
116 ASSERT_VALID_CODE_POINTER(m_value);
117 }
119 void* value() const { return m_value; }
121 private:
122 void* m_value;
123 };
125 // MacroAssemblerCodePtr:
126 //
127 // MacroAssemblerCodePtr should be used to wrap pointers to JIT generated code.
128 class MacroAssemblerCodePtr {
129 public:
130 MacroAssemblerCodePtr()
131 : m_value(0)
132 {
133 }
135 explicit MacroAssemblerCodePtr(void* value)
136 #if WTF_CPU_ARM_THUMB2
137 // Decorate the pointer as a thumb code pointer.
138 : m_value(reinterpret_cast<char*>(value) + 1)
139 #else
140 : m_value(value)
141 #endif
142 {
143 ASSERT_VALID_CODE_POINTER(m_value);
144 }
146 explicit MacroAssemblerCodePtr(ReturnAddressPtr ra)
147 : m_value(ra.value())
148 {
149 ASSERT_VALID_CODE_POINTER(m_value);
150 }
152 void* executableAddress() const {
153 return m_value;
154 }
155 #if WTF_CPU_ARM_THUMB2
156 // To use this pointer as a data address remove the decoration.
157 void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return reinterpret_cast<char*>(m_value) - 1; }
158 #else
159 void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return m_value; }
160 #endif
162 bool operator!() const
163 {
164 return !m_value;
165 }
167 ptrdiff_t operator -(const MacroAssemblerCodePtr &other) const
168 {
169 JS_ASSERT(m_value);
170 return reinterpret_cast<uint8_t *>(m_value) -
171 reinterpret_cast<uint8_t *>(other.m_value);
172 }
174 private:
175 void* m_value;
176 };
178 // MacroAssemblerCodeRef:
179 //
180 // A reference to a section of JIT generated code. A CodeRef consists of a
181 // pointer to the code, and a ref pointer to the pool from within which it
182 // was allocated.
183 class MacroAssemblerCodeRef {
184 public:
185 MacroAssemblerCodeRef()
186 : m_executablePool(NULL),
187 m_allocSize(0)
188 {
189 }
191 MacroAssemblerCodeRef(void* code, ExecutablePool* executablePool, size_t allocSize)
192 : m_code(code)
193 , m_executablePool(executablePool)
194 , m_allocSize(allocSize)
195 {
196 }
198 // Release the code memory in this code ref.
199 void release()
200 {
201 if (!m_executablePool)
202 return;
204 JS_POISON(m_code.executableAddress(), JS_SWEPT_CODE_PATTERN, m_allocSize);
206 m_code = MacroAssemblerCodePtr();
208 // MacroAssemblerCodeRef is only used by Yarr.
209 m_executablePool->release(m_allocSize, REGEXP_CODE);
210 m_executablePool = nullptr;
211 }
213 MacroAssemblerCodePtr code() const {
214 return m_code;
215 }
216 size_t allocSize() const {
217 return m_allocSize;
218 }
220 MacroAssemblerCodePtr m_code;
221 ExecutablePool* m_executablePool;
222 size_t m_allocSize;
223 };
225 } // namespace JSC
227 #endif // ENABLE(ASSEMBLER)
229 #endif /* assembler_assembler_MacroAssemblerCodeRef_h */