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 #include "src/base/macros.h"
10 #include "src/globals.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 // Forward declarations.
16 class Isolate;
17 class PerThreadAssertData;
18 
19 
20 enum PerThreadAssertType {
21   HEAP_ALLOCATION_ASSERT,
22   HANDLE_ALLOCATION_ASSERT,
23   HANDLE_DEREFERENCE_ASSERT,
24   DEFERRED_HANDLE_DEREFERENCE_ASSERT,
25   CODE_DEPENDENCY_CHANGE_ASSERT,
26   LAST_PER_THREAD_ASSERT_TYPE
27 };
28 
29 enum PerIsolateAssertType {
30   JAVASCRIPT_EXECUTION_ASSERT,
31   JAVASCRIPT_EXECUTION_THROWS,
32   DEOPTIMIZATION_ASSERT,
33   COMPILATION_ASSERT,
34   NO_EXCEPTION_ASSERT
35 };
36 
37 template <PerThreadAssertType kType, bool kAllow>
38 class PerThreadAssertScope {
39  public:
40   V8_EXPORT_PRIVATE PerThreadAssertScope();
41   V8_EXPORT_PRIVATE ~PerThreadAssertScope();
42 
43   V8_EXPORT_PRIVATE static bool IsAllowed();
44 
45   void Release();
46 
47  private:
48   PerThreadAssertData* data_;
49   bool old_state_;
50 
51   DISALLOW_COPY_AND_ASSIGN(PerThreadAssertScope);
52 };
53 
54 
55 template <PerIsolateAssertType type, bool allow>
56 class PerIsolateAssertScope {
57  public:
58   explicit PerIsolateAssertScope(Isolate* isolate);
59   ~PerIsolateAssertScope();
60 
61   static bool IsAllowed(Isolate* isolate);
62 
63  private:
64   class DataBit;
65 
66   Isolate* isolate_;
67   uint32_t old_data_;
68 
69   DISALLOW_COPY_AND_ASSIGN(PerIsolateAssertScope);
70 };
71 
72 
73 template <PerThreadAssertType type, bool allow>
74 #ifdef DEBUG
75 class PerThreadAssertScopeDebugOnly : public
76     PerThreadAssertScope<type, allow> {
77 #else
78 class PerThreadAssertScopeDebugOnly {
79  public:
80   PerThreadAssertScopeDebugOnly() { }
81   void Release() {}
82 #endif
83 };
84 
85 
86 template <PerIsolateAssertType type, bool allow>
87 #ifdef DEBUG
88 class PerIsolateAssertScopeDebugOnly : public
89     PerIsolateAssertScope<type, allow> {
90  public:
PerIsolateAssertScopeDebugOnly(Isolate * isolate)91   explicit PerIsolateAssertScopeDebugOnly(Isolate* isolate)
92       : PerIsolateAssertScope<type, allow>(isolate) { }
93 #else
94 class PerIsolateAssertScopeDebugOnly {
95  public:
96   explicit PerIsolateAssertScopeDebugOnly(Isolate* isolate) { }
97 #endif
98 };
99 
100 // Per-thread assert scopes.
101 
102 // Scope to document where we do not expect handles to be created.
103 typedef PerThreadAssertScopeDebugOnly<HANDLE_ALLOCATION_ASSERT, false>
104     DisallowHandleAllocation;
105 
106 // Scope to introduce an exception to DisallowHandleAllocation.
107 typedef PerThreadAssertScopeDebugOnly<HANDLE_ALLOCATION_ASSERT, true>
108     AllowHandleAllocation;
109 
110 // Scope to document where we do not expect any allocation and GC.
111 typedef PerThreadAssertScopeDebugOnly<HEAP_ALLOCATION_ASSERT, false>
112     DisallowHeapAllocation;
113 
114 // Scope to introduce an exception to DisallowHeapAllocation.
115 typedef PerThreadAssertScopeDebugOnly<HEAP_ALLOCATION_ASSERT, true>
116     AllowHeapAllocation;
117 
118 // Scope to document where we do not expect any handle dereferences.
119 typedef PerThreadAssertScopeDebugOnly<HANDLE_DEREFERENCE_ASSERT, false>
120     DisallowHandleDereference;
121 
122 // Scope to introduce an exception to DisallowHandleDereference.
123 typedef PerThreadAssertScopeDebugOnly<HANDLE_DEREFERENCE_ASSERT, true>
124     AllowHandleDereference;
125 
126 // Scope to document where we do not expect deferred handles to be dereferenced.
127 typedef PerThreadAssertScopeDebugOnly<DEFERRED_HANDLE_DEREFERENCE_ASSERT, false>
128     DisallowDeferredHandleDereference;
129 
130 // Scope to introduce an exception to DisallowDeferredHandleDereference.
131 typedef PerThreadAssertScopeDebugOnly<DEFERRED_HANDLE_DEREFERENCE_ASSERT, true>
132     AllowDeferredHandleDereference;
133 
134 // Scope to document where we do not expect deferred handles to be dereferenced.
135 typedef PerThreadAssertScopeDebugOnly<CODE_DEPENDENCY_CHANGE_ASSERT, false>
136     DisallowCodeDependencyChange;
137 
138 // Scope to introduce an exception to DisallowDeferredHandleDereference.
139 typedef PerThreadAssertScopeDebugOnly<CODE_DEPENDENCY_CHANGE_ASSERT, true>
140     AllowCodeDependencyChange;
141 
142 
143 // Per-isolate assert scopes.
144 
145 // Scope to document where we do not expect javascript execution.
146 typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, false>
147     DisallowJavascriptExecution;
148 
149 // Scope to introduce an exception to DisallowJavascriptExecution.
150 typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, true>
151     AllowJavascriptExecution;
152 
153 // Scope to document where we do not expect javascript execution (debug only)
154 typedef PerIsolateAssertScopeDebugOnly<JAVASCRIPT_EXECUTION_ASSERT, false>
155     DisallowJavascriptExecutionDebugOnly;
156 
157 // Scope to introduce an exception to DisallowJavascriptExecutionDebugOnly.
158 typedef PerIsolateAssertScopeDebugOnly<JAVASCRIPT_EXECUTION_ASSERT, true>
159     AllowJavascriptExecutionDebugOnly;
160 
161 // Scope in which javascript execution leads to exception being thrown.
162 typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, false>
163     ThrowOnJavascriptExecution;
164 
165 // Scope to introduce an exception to ThrowOnJavascriptExecution.
166 typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, true>
167     NoThrowOnJavascriptExecution;
168 
169 // Scope to document where we do not expect deoptimization.
170 typedef PerIsolateAssertScopeDebugOnly<DEOPTIMIZATION_ASSERT, false>
171     DisallowDeoptimization;
172 
173 // Scope to introduce an exception to DisallowDeoptimization.
174 typedef PerIsolateAssertScopeDebugOnly<DEOPTIMIZATION_ASSERT, true>
175     AllowDeoptimization;
176 
177 // Scope to document where we do not expect deoptimization.
178 typedef PerIsolateAssertScopeDebugOnly<COMPILATION_ASSERT, false>
179     DisallowCompilation;
180 
181 // Scope to introduce an exception to DisallowDeoptimization.
182 typedef PerIsolateAssertScopeDebugOnly<COMPILATION_ASSERT, true>
183     AllowCompilation;
184 
185 // Scope to document where we do not expect exceptions.
186 typedef PerIsolateAssertScopeDebugOnly<NO_EXCEPTION_ASSERT, false>
187     DisallowExceptions;
188 
189 // Scope to introduce an exception to DisallowExceptions.
190 typedef PerIsolateAssertScopeDebugOnly<NO_EXCEPTION_ASSERT, true>
191     AllowExceptions;
192 }  // namespace internal
193 }  // namespace v8
194 
195 #endif  // V8_ASSERT_SCOPE_H_
196