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