v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
assert-scope.h
Go to the documentation of this file.
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_COMMON_ASSERT_SCOPE_H_
6#define V8_COMMON_ASSERT_SCOPE_H_
7
8#include <stdint.h>
9
10#include <optional>
11
12#include "src/base/macros.h"
14#include "src/common/globals.h"
15
16namespace v8 {
17namespace internal {
18
19// Forward declarations.
20class Isolate;
21
23 // Dummy type for indicating a valid PerThreadAsserts data. This is
24 // represented by an always-on bit, and is cleared when a scope's saved data
25 // is zeroed -- it should never be set or cleared on the actual per-thread
26 // data by a scope.
28
36 // Dummy type for disabling GC mole.
39};
40
42
43// Empty assert scope, used for debug-only scopes in release mode so that
44// the release-enabled PerThreadAssertScope is always an alias for, or a
45// subclass of PerThreadAssertScopeDebugOnly, and can be used in place of it.
46// This class is also templated so that it still has distinct instances for each
47// debug scope -- this is necessary for GCMole to be able to recognise
48// DisableGCMole scopes as distinct from other assert scopes.
49template <bool kAllow, PerThreadAssertType... kTypes>
51 public:
52 // Define a constructor to avoid unused variable warnings.
53 // NOLINTNEXTLINE
55 void Release() {}
56};
57
58template <bool kAllow, PerThreadAssertType... kTypes>
60 : public PerThreadAssertScopeEmpty<kAllow, kTypes...> {
61 public:
64
67
68 V8_EXPORT_PRIVATE static bool IsAllowed();
69
70 void Release();
71
72 private:
74};
75
76// Per-isolate assert scopes.
77
78#define PER_ISOLATE_DCHECK_TYPE(V, enable) \
79 /* Scope to document where we do not expect javascript execution. */ \
80 /* Scope to introduce an exception to DisallowJavascriptExecution. */ \
81 V(AllowJavascriptExecution, DisallowJavascriptExecution, \
82 javascript_execution_assert, enable) \
83 /* Scope to document where we do not expect deoptimization. */ \
84 /* Scope to introduce an exception to DisallowDeoptimization. */ \
85 V(AllowDeoptimization, DisallowDeoptimization, deoptimization_assert, \
86 enable) \
87 /* Scope to document where we do not expect deoptimization. */ \
88 /* Scope to introduce an exception to DisallowDeoptimization. */ \
89 V(AllowCompilation, DisallowCompilation, compilation_assert, enable) \
90 /* Scope to document where we do not expect exceptions. */ \
91 /* Scope to introduce an exception to DisallowExceptions. */ \
92 V(AllowExceptions, DisallowExceptions, no_exception_assert, enable)
93
94#define PER_ISOLATE_CHECK_TYPE(V, enable) \
95 /* Scope in which javascript execution leads to exception being thrown. */ \
96 /* Scope to introduce an exception to ThrowOnJavascriptExecution. */ \
97 V(NoThrowOnJavascriptExecution, ThrowOnJavascriptExecution, \
98 javascript_execution_throws, enable) \
99 /* Scope in which javascript execution causes dumps. */ \
100 /* Scope in which javascript execution doesn't cause dumps. */ \
101 V(NoDumpOnJavascriptExecution, DumpOnJavascriptExecution, \
102 javascript_execution_dump, enable)
103
104#define PER_ISOLATE_ASSERT_SCOPE_DECLARATION(ScopeType) \
105 class V8_NODISCARD ScopeType { \
106 public: \
107 V8_EXPORT_PRIVATE explicit ScopeType(Isolate* isolate); \
108 ScopeType(const ScopeType&) = delete; \
109 ScopeType& operator=(const ScopeType&) = delete; \
110 V8_EXPORT_PRIVATE ~ScopeType(); \
111 \
112 static bool IsAllowed(Isolate* isolate); \
113 \
114 V8_EXPORT_PRIVATE static void Open(Isolate* isolate, \
115 bool* was_execution_allowed); \
116 V8_EXPORT_PRIVATE static void Close(Isolate* isolate, \
117 bool was_execution_allowed); \
118 \
119 private: \
120 Isolate* isolate_; \
121 bool old_data_; \
122 };
123
124#define PER_ISOLATE_ASSERT_ENABLE_SCOPE(EnableType, _1, _2, _3) \
125 PER_ISOLATE_ASSERT_SCOPE_DECLARATION(EnableType)
126
127#define PER_ISOLATE_ASSERT_DISABLE_SCOPE(_1, DisableType, _2, _3) \
128 PER_ISOLATE_ASSERT_SCOPE_DECLARATION(DisableType)
129
134
135#ifdef DEBUG
136#define PER_ISOLATE_DCHECK_ENABLE_SCOPE(EnableType, DisableType, field, _) \
137 class EnableType##DebugOnly : public EnableType { \
138 public: \
139 explicit EnableType##DebugOnly(Isolate* isolate) : EnableType(isolate) {} \
140 };
141#else
142#define PER_ISOLATE_DCHECK_ENABLE_SCOPE(EnableType, DisableType, field, _) \
143 class V8_NODISCARD EnableType##DebugOnly { \
144 public: \
145 explicit EnableType##DebugOnly(Isolate* isolate) {} \
146 };
147#endif
148
149#ifdef DEBUG
150#define PER_ISOLATE_DCHECK_DISABLE_SCOPE(EnableType, DisableType, field, _) \
151 class DisableType##DebugOnly : public DisableType { \
152 public: \
153 explicit DisableType##DebugOnly(Isolate* isolate) \
154 : DisableType(isolate) {} \
155 };
156#else
157#define PER_ISOLATE_DCHECK_DISABLE_SCOPE(EnableType, DisableType, field, _) \
158 class V8_NODISCARD DisableType##DebugOnly { \
159 public: \
160 explicit DisableType##DebugOnly(Isolate* isolate) {} \
161 };
162#endif
163
166
167#ifdef DEBUG
168template <bool kAllow, PerThreadAssertType... kTypes>
169using PerThreadAssertScopeDebugOnly = PerThreadAssertScope<kAllow, kTypes...>;
170#else
171template <bool kAllow, PerThreadAssertType... kTypes>
174#endif
175
176// Per-thread assert scopes.
177
178// Scope to document where we do not expect handles to be created.
181
182// Scope to introduce an exception to DisallowHandleAllocation.
185
186// Scope to document where we do not expect safepoints to be entered.
189
190// Scope to introduce an exception to DisallowSafepoints.
192
193// Scope to document where we do not expect any allocation.
196
197// Scope to introduce an exception to DisallowHeapAllocation.
200
201// Like AllowHeapAllocation, but enabled in release builds.
204
205// Scope to document where we do not expect any handle dereferences.
208
209// Scope to introduce an exception to DisallowHandleDereference.
212
213// Explicitly allow handle dereference and creation for all threads/isolates on
214// one particular thread.
217
218// Scope to document where we do not expect code dependencies to change.
221
222// Scope to introduce an exception to DisallowCodeDependencyChange.
225
226// Scope to document where we do not expect code to be allocated.
229
230// Scope to introduce an exception to DisallowCodeAllocation.
233
234// Scope to document where we do not expect garbage collections. It differs from
235// DisallowHeapAllocation by also forbidding safepoints.
239
240// Like DisallowGarbageCollection, but enabled in release builds.
243
244// Scope to skip gc mole verification in places where we do tricky raw
245// work.
247
248// Scope to ensure slow path for obtaining position info is not called
251
252// Scope to add an exception to disallowing position info slow path
255
256// The DISALLOW_GARBAGE_COLLECTION macro can be used to define a
257// DisallowGarbageCollection field in classes that isn't present in release
258// builds.
259#ifdef DEBUG
260#define DISALLOW_GARBAGE_COLLECTION(name) DisallowGarbageCollection name;
261#else
262#define DISALLOW_GARBAGE_COLLECTION(name)
263#endif
264
265// Scope to introduce an exception to DisallowGarbageCollection.
269
270// Like AllowGarbageCollection, but enabled in release builds.
273
274// Scope to document where we do not expect any access to the heap.
278
279// Scope to introduce an exception to DisallowHeapAccess.
283
285 public:
287 if (condition) maybe_disallow_.emplace();
288 }
289
290 private:
291 std::optional<DisallowHeapAccess> maybe_disallow_;
292};
293
294// Like MutexGuard but also asserts that no garbage collection happens while
295// we're holding the mutex.
297 public:
299 : guard_(mutex), mutex_(mutex), no_gc_(std::in_place) {}
300
301 void Unlock() {
302 mutex_->Unlock();
303 no_gc_.reset();
304 }
305 void Lock() {
306 mutex_->Lock();
307 no_gc_.emplace();
308 }
309
310 private:
313 std::optional<DisallowGarbageCollection> no_gc_;
314};
315
316// Explicit instantiation declarations.
325extern template class PerThreadAssertScope<false,
330extern template class PerThreadAssertScope<false, GC_MOLE>;
333extern template class PerThreadAssertScope<false, SAFEPOINTS_ASSERT,
335extern template class PerThreadAssertScope<true, SAFEPOINTS_ASSERT,
337extern template class PerThreadAssertScope<
340extern template class PerThreadAssertScope<
343
344} // namespace internal
345} // namespace v8
346
347#endif // V8_COMMON_ASSERT_SCOPE_H_
#define PER_ISOLATE_ASSERT_DISABLE_SCOPE(_1, DisableType, _2, _3)
#define PER_ISOLATE_DCHECK_TYPE(V, enable)
#define PER_ISOLATE_ASSERT_ENABLE_SCOPE(EnableType, _1, _2, _3)
#define PER_ISOLATE_DCHECK_ENABLE_SCOPE(EnableType, DisableType, field, _)
#define PER_ISOLATE_DCHECK_DISABLE_SCOPE(EnableType, DisableType, field, _)
#define PER_ISOLATE_CHECK_TYPE(V, enable)
std::optional< DisallowHeapAccess > maybe_disallow_
std::optional< DisallowGarbageCollection > no_gc_
PerThreadAssertScope & operator=(const PerThreadAssertScope &)=delete
PerThreadAssertScope(const PerThreadAssertScope &)=delete
base::Mutex & mutex_
DisallowGarbageCollection no_gc_
base::Mutex mutex
STL namespace.
PerThreadAssertScopeEmpty< kAllow, kTypes... > PerThreadAssertScopeDebugOnly
@ CODE_DEPENDENCY_CHANGE_ASSERT
@ HANDLE_USAGE_ON_ALL_THREADS_ASSERT
@ POSITION_INFO_SLOW_ASSERT
@ ASSERT_TYPE_IS_VALID_MARKER
@ HANDLE_ALLOCATION_ASSERT
@ HANDLE_DEREFERENCE_ASSERT
#define V8_EXPORT_PRIVATE
Definition macros.h:460
#define V8_NODISCARD
Definition v8config.h:693