Line data Source code
1 : // Copyright 2013 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_ASSERT_SCOPE_H_
6 : #define V8_ASSERT_SCOPE_H_
7 :
8 : #include <stdint.h>
9 :
10 : #include "src/base/macros.h"
11 : #include "src/base/optional.h"
12 : #include "src/globals.h"
13 : #include "src/pointer-with-payload.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 :
18 : // Forward declarations.
19 : class Isolate;
20 : class PerThreadAssertData;
21 :
22 : template <>
23 : struct PointerWithPayloadTraits<PerThreadAssertData> {
24 : static constexpr int value = 1;
25 : };
26 :
27 : enum PerThreadAssertType {
28 : HEAP_ALLOCATION_ASSERT,
29 : HANDLE_ALLOCATION_ASSERT,
30 : HANDLE_DEREFERENCE_ASSERT,
31 : DEFERRED_HANDLE_DEREFERENCE_ASSERT,
32 : CODE_DEPENDENCY_CHANGE_ASSERT,
33 : LAST_PER_THREAD_ASSERT_TYPE
34 : };
35 :
36 : enum PerIsolateAssertType {
37 : JAVASCRIPT_EXECUTION_ASSERT,
38 : JAVASCRIPT_EXECUTION_THROWS,
39 : JAVASCRIPT_EXECUTION_DUMP,
40 : DEOPTIMIZATION_ASSERT,
41 : COMPILATION_ASSERT,
42 : NO_EXCEPTION_ASSERT
43 : };
44 :
45 : template <PerThreadAssertType kType, bool kAllow>
46 : class PerThreadAssertScope {
47 : public:
48 : V8_EXPORT_PRIVATE PerThreadAssertScope();
49 : V8_EXPORT_PRIVATE ~PerThreadAssertScope();
50 :
51 : V8_EXPORT_PRIVATE static bool IsAllowed();
52 :
53 : void Release();
54 :
55 : private:
56 : PointerWithPayload<PerThreadAssertData, bool, 1> data_and_old_state_;
57 :
58 0 : V8_INLINE void set_data(PerThreadAssertData* data) {
59 : data_and_old_state_.SetPointer(data);
60 0 : }
61 :
62 0 : V8_INLINE PerThreadAssertData* data() const {
63 0 : return data_and_old_state_.GetPointer();
64 : }
65 :
66 0 : V8_INLINE void set_old_state(bool old_state) {
67 0 : return data_and_old_state_.SetPayload(old_state);
68 : }
69 :
70 0 : V8_INLINE bool old_state() const { return data_and_old_state_.GetPayload(); }
71 :
72 : DISALLOW_COPY_AND_ASSIGN(PerThreadAssertScope);
73 : };
74 :
75 :
76 : template <PerIsolateAssertType type, bool allow>
77 : class PerIsolateAssertScope {
78 : public:
79 : V8_EXPORT_PRIVATE explicit PerIsolateAssertScope(Isolate* isolate);
80 : V8_EXPORT_PRIVATE ~PerIsolateAssertScope();
81 :
82 : static bool IsAllowed(Isolate* isolate);
83 :
84 : private:
85 : class DataBit;
86 :
87 : Isolate* isolate_;
88 : uint32_t old_data_;
89 :
90 : DISALLOW_COPY_AND_ASSIGN(PerIsolateAssertScope);
91 : };
92 :
93 :
94 : template <PerThreadAssertType type, bool allow>
95 : #ifdef DEBUG
96 : class PerThreadAssertScopeDebugOnly : public
97 : PerThreadAssertScope<type, allow> {
98 : #else
99 : class PerThreadAssertScopeDebugOnly {
100 : public:
101 : PerThreadAssertScopeDebugOnly() { // NOLINT (modernize-use-equals-default)
102 : // Define a constructor to avoid unused variable warnings.
103 : }
104 : void Release() {}
105 : #endif
106 : };
107 :
108 :
109 : template <PerIsolateAssertType type, bool allow>
110 : #ifdef DEBUG
111 : class PerIsolateAssertScopeDebugOnly : public
112 : PerIsolateAssertScope<type, allow> {
113 : public:
114 : explicit PerIsolateAssertScopeDebugOnly(Isolate* isolate)
115 : : PerIsolateAssertScope<type, allow>(isolate) { }
116 : #else
117 : class PerIsolateAssertScopeDebugOnly {
118 : public:
119 : explicit PerIsolateAssertScopeDebugOnly(Isolate* isolate) { }
120 : #endif
121 : };
122 :
123 : // Per-thread assert scopes.
124 :
125 : // Scope to document where we do not expect handles to be created.
126 : typedef PerThreadAssertScopeDebugOnly<HANDLE_ALLOCATION_ASSERT, false>
127 : DisallowHandleAllocation;
128 :
129 : // Scope to introduce an exception to DisallowHandleAllocation.
130 : typedef PerThreadAssertScopeDebugOnly<HANDLE_ALLOCATION_ASSERT, true>
131 : AllowHandleAllocation;
132 :
133 : // Scope to document where we do not expect any allocation and GC.
134 : typedef PerThreadAssertScopeDebugOnly<HEAP_ALLOCATION_ASSERT, false>
135 : DisallowHeapAllocation;
136 : #ifdef DEBUG
137 : #define DISALLOW_HEAP_ALLOCATION(name) DisallowHeapAllocation name;
138 : #else
139 : #define DISALLOW_HEAP_ALLOCATION(name)
140 : #endif
141 :
142 : // Scope to introduce an exception to DisallowHeapAllocation.
143 : typedef PerThreadAssertScopeDebugOnly<HEAP_ALLOCATION_ASSERT, true>
144 : AllowHeapAllocation;
145 :
146 : // Scope to document where we do not expect any handle dereferences.
147 : typedef PerThreadAssertScopeDebugOnly<HANDLE_DEREFERENCE_ASSERT, false>
148 : DisallowHandleDereference;
149 :
150 : // Scope to introduce an exception to DisallowHandleDereference.
151 : typedef PerThreadAssertScopeDebugOnly<HANDLE_DEREFERENCE_ASSERT, true>
152 : AllowHandleDereference;
153 :
154 : // Scope to document where we do not expect deferred handles to be dereferenced.
155 : typedef PerThreadAssertScopeDebugOnly<DEFERRED_HANDLE_DEREFERENCE_ASSERT, false>
156 : DisallowDeferredHandleDereference;
157 :
158 : // Scope to introduce an exception to DisallowDeferredHandleDereference.
159 : typedef PerThreadAssertScopeDebugOnly<DEFERRED_HANDLE_DEREFERENCE_ASSERT, true>
160 : AllowDeferredHandleDereference;
161 :
162 : // Scope to document where we do not expect deferred handles to be dereferenced.
163 : typedef PerThreadAssertScopeDebugOnly<CODE_DEPENDENCY_CHANGE_ASSERT, false>
164 : DisallowCodeDependencyChange;
165 :
166 : // Scope to introduce an exception to DisallowDeferredHandleDereference.
167 : typedef PerThreadAssertScopeDebugOnly<CODE_DEPENDENCY_CHANGE_ASSERT, true>
168 : AllowCodeDependencyChange;
169 :
170 : class DisallowHeapAccess {
171 : DisallowCodeDependencyChange no_dependency_change_;
172 : DisallowHandleAllocation no_handle_allocation_;
173 : DisallowHandleDereference no_handle_dereference_;
174 : DisallowHeapAllocation no_heap_allocation_;
175 : };
176 :
177 : class DisallowHeapAccessIf {
178 : public:
179 : explicit DisallowHeapAccessIf(bool condition) {
180 : if (condition) maybe_disallow_.emplace();
181 : }
182 :
183 : private:
184 : base::Optional<DisallowHeapAccess> maybe_disallow_;
185 : };
186 :
187 : // Per-isolate assert scopes.
188 :
189 : // Scope to document where we do not expect javascript execution.
190 : typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, false>
191 : DisallowJavascriptExecution;
192 :
193 : // Scope to introduce an exception to DisallowJavascriptExecution.
194 : typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, true>
195 : AllowJavascriptExecution;
196 :
197 : // Scope to document where we do not expect javascript execution (debug only)
198 : typedef PerIsolateAssertScopeDebugOnly<JAVASCRIPT_EXECUTION_ASSERT, false>
199 : DisallowJavascriptExecutionDebugOnly;
200 :
201 : // Scope to introduce an exception to DisallowJavascriptExecutionDebugOnly.
202 : typedef PerIsolateAssertScopeDebugOnly<JAVASCRIPT_EXECUTION_ASSERT, true>
203 : AllowJavascriptExecutionDebugOnly;
204 :
205 : // Scope in which javascript execution leads to exception being thrown.
206 : typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, false>
207 : ThrowOnJavascriptExecution;
208 :
209 : // Scope to introduce an exception to ThrowOnJavascriptExecution.
210 : typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, true>
211 : NoThrowOnJavascriptExecution;
212 :
213 : // Scope in which javascript execution causes dumps.
214 : typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_DUMP, false>
215 : DumpOnJavascriptExecution;
216 :
217 : // Scope in which javascript execution causes dumps.
218 : typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_DUMP, true>
219 : NoDumpOnJavascriptExecution;
220 :
221 : // Scope to document where we do not expect deoptimization.
222 : typedef PerIsolateAssertScopeDebugOnly<DEOPTIMIZATION_ASSERT, false>
223 : DisallowDeoptimization;
224 :
225 : // Scope to introduce an exception to DisallowDeoptimization.
226 : typedef PerIsolateAssertScopeDebugOnly<DEOPTIMIZATION_ASSERT, true>
227 : AllowDeoptimization;
228 :
229 : // Scope to document where we do not expect deoptimization.
230 : typedef PerIsolateAssertScopeDebugOnly<COMPILATION_ASSERT, false>
231 : DisallowCompilation;
232 :
233 : // Scope to introduce an exception to DisallowDeoptimization.
234 : typedef PerIsolateAssertScopeDebugOnly<COMPILATION_ASSERT, true>
235 : AllowCompilation;
236 :
237 : // Scope to document where we do not expect exceptions.
238 : typedef PerIsolateAssertScopeDebugOnly<NO_EXCEPTION_ASSERT, false>
239 : DisallowExceptions;
240 :
241 : // Scope to introduce an exception to DisallowExceptions.
242 : typedef PerIsolateAssertScopeDebugOnly<NO_EXCEPTION_ASSERT, true>
243 : AllowExceptions;
244 :
245 : // Explicit instantiation declarations.
246 : extern template class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, false>;
247 : extern template class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, true>;
248 : extern template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, false>;
249 : extern template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, true>;
250 : extern template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, false>;
251 : extern template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, true>;
252 : extern template class PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT,
253 : false>;
254 : extern template class PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT,
255 : true>;
256 : extern template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT,
257 : false>;
258 : extern template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, true>;
259 :
260 : extern template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, false>;
261 : extern template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, true>;
262 : extern template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, false>;
263 : extern template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, true>;
264 : extern template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_DUMP, false>;
265 : extern template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_DUMP, true>;
266 : extern template class PerIsolateAssertScope<DEOPTIMIZATION_ASSERT, false>;
267 : extern template class PerIsolateAssertScope<DEOPTIMIZATION_ASSERT, true>;
268 : extern template class PerIsolateAssertScope<COMPILATION_ASSERT, false>;
269 : extern template class PerIsolateAssertScope<COMPILATION_ASSERT, true>;
270 : extern template class PerIsolateAssertScope<NO_EXCEPTION_ASSERT, false>;
271 : extern template class PerIsolateAssertScope<NO_EXCEPTION_ASSERT, true>;
272 :
273 : } // namespace internal
274 : } // namespace v8
275 :
276 : #endif // V8_ASSERT_SCOPE_H_
|