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.
5 #ifndef V8_ASSERT_SCOPE_H_
6 #define V8_ASSERT_SCOPE_H_
8 #include "src/allocation.h"
9 #include "src/base/platform/platform.h"
10 #include "src/utils.h"
17 enum PerThreadAssertType {
18 HEAP_ALLOCATION_ASSERT,
19 HANDLE_ALLOCATION_ASSERT,
20 HANDLE_DEREFERENCE_ASSERT,
21 DEFERRED_HANDLE_DEREFERENCE_ASSERT,
22 CODE_DEPENDENCY_CHANGE_ASSERT,
23 LAST_PER_THREAD_ASSERT_TYPE
27 enum PerIsolateAssertType {
28 JAVASCRIPT_EXECUTION_ASSERT,
29 JAVASCRIPT_EXECUTION_THROWS,
30 ALLOCATION_FAILURE_ASSERT,
31 DEOPTIMIZATION_ASSERT,
36 class PerThreadAssertData {
38 PerThreadAssertData() : nesting_level_(0) {
39 for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; i++) {
40 assert_states_[i] = true;
44 void set(PerThreadAssertType type, bool allow) {
45 assert_states_[type] = allow;
48 bool get(PerThreadAssertType type) const {
49 return assert_states_[type];
52 void increment_level() { ++nesting_level_; }
53 bool decrement_level() { return --nesting_level_ == 0; }
56 bool assert_states_[LAST_PER_THREAD_ASSERT_TYPE];
59 DISALLOW_COPY_AND_ASSIGN(PerThreadAssertData);
63 class PerThreadAssertScopeBase {
65 PerThreadAssertScopeBase() {
66 data_ = GetAssertData();
68 data_ = new PerThreadAssertData();
69 SetThreadLocalData(data_);
71 data_->increment_level();
74 ~PerThreadAssertScopeBase() {
75 if (!data_->decrement_level()) return;
76 for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; i++) {
77 DCHECK(data_->get(static_cast<PerThreadAssertType>(i)));
80 SetThreadLocalData(NULL);
83 static PerThreadAssertData* GetAssertData() {
84 return reinterpret_cast<PerThreadAssertData*>(
85 base::Thread::GetThreadLocal(thread_local_key));
88 static base::Thread::LocalStorageKey thread_local_key;
89 PerThreadAssertData* data_;
93 static void SetThreadLocalData(PerThreadAssertData* data) {
94 base::Thread::SetThreadLocal(thread_local_key, data);
99 template <PerThreadAssertType type, bool allow>
100 class PerThreadAssertScope : public PerThreadAssertScopeBase {
102 PerThreadAssertScope() {
103 old_state_ = data_->get(type);
104 data_->set(type, allow);
107 ~PerThreadAssertScope() { data_->set(type, old_state_); }
109 static bool IsAllowed() {
110 PerThreadAssertData* data = GetAssertData();
111 return data == NULL || data->get(type);
117 DISALLOW_COPY_AND_ASSIGN(PerThreadAssertScope);
121 class PerIsolateAssertBase {
123 static uint32_t GetData(Isolate* isolate);
124 static void SetData(Isolate* isolate, uint32_t data);
128 template <PerIsolateAssertType type, bool allow>
129 class PerIsolateAssertScope : public PerIsolateAssertBase {
131 explicit PerIsolateAssertScope(Isolate* isolate) : isolate_(isolate) {
132 STATIC_ASSERT(type < 32);
133 old_data_ = GetData(isolate_);
134 SetData(isolate_, DataBit::update(old_data_, allow));
137 ~PerIsolateAssertScope() {
138 SetData(isolate_, old_data_);
141 static bool IsAllowed(Isolate* isolate) {
142 return DataBit::decode(GetData(isolate));
146 typedef BitField<bool, type, 1> DataBit;
151 DISALLOW_COPY_AND_ASSIGN(PerIsolateAssertScope);
155 template <PerThreadAssertType type, bool allow>
157 class PerThreadAssertScopeDebugOnly : public
158 PerThreadAssertScope<type, allow> {
160 class PerThreadAssertScopeDebugOnly {
162 PerThreadAssertScopeDebugOnly() { }
167 template <PerIsolateAssertType type, bool allow>
169 class PerIsolateAssertScopeDebugOnly : public
170 PerIsolateAssertScope<type, allow> {
172 explicit PerIsolateAssertScopeDebugOnly(Isolate* isolate)
173 : PerIsolateAssertScope<type, allow>(isolate) { }
175 class PerIsolateAssertScopeDebugOnly {
177 explicit PerIsolateAssertScopeDebugOnly(Isolate* isolate) { }
181 // Per-thread assert scopes.
183 // Scope to document where we do not expect handles to be created.
184 typedef PerThreadAssertScopeDebugOnly<HANDLE_ALLOCATION_ASSERT, false>
185 DisallowHandleAllocation;
187 // Scope to introduce an exception to DisallowHandleAllocation.
188 typedef PerThreadAssertScopeDebugOnly<HANDLE_ALLOCATION_ASSERT, true>
189 AllowHandleAllocation;
191 // Scope to document where we do not expect any allocation and GC.
192 typedef PerThreadAssertScopeDebugOnly<HEAP_ALLOCATION_ASSERT, false>
193 DisallowHeapAllocation;
195 // Scope to introduce an exception to DisallowHeapAllocation.
196 typedef PerThreadAssertScopeDebugOnly<HEAP_ALLOCATION_ASSERT, true>
199 // Scope to document where we do not expect any handle dereferences.
200 typedef PerThreadAssertScopeDebugOnly<HANDLE_DEREFERENCE_ASSERT, false>
201 DisallowHandleDereference;
203 // Scope to introduce an exception to DisallowHandleDereference.
204 typedef PerThreadAssertScopeDebugOnly<HANDLE_DEREFERENCE_ASSERT, true>
205 AllowHandleDereference;
207 // Scope to document where we do not expect deferred handles to be dereferenced.
208 typedef PerThreadAssertScopeDebugOnly<DEFERRED_HANDLE_DEREFERENCE_ASSERT, false>
209 DisallowDeferredHandleDereference;
211 // Scope to introduce an exception to DisallowDeferredHandleDereference.
212 typedef PerThreadAssertScopeDebugOnly<DEFERRED_HANDLE_DEREFERENCE_ASSERT, true>
213 AllowDeferredHandleDereference;
215 // Scope to document where we do not expect deferred handles to be dereferenced.
216 typedef PerThreadAssertScopeDebugOnly<CODE_DEPENDENCY_CHANGE_ASSERT, false>
217 DisallowCodeDependencyChange;
219 // Scope to introduce an exception to DisallowDeferredHandleDereference.
220 typedef PerThreadAssertScopeDebugOnly<CODE_DEPENDENCY_CHANGE_ASSERT, true>
221 AllowCodeDependencyChange;
224 // Per-isolate assert scopes.
226 // Scope to document where we do not expect javascript execution.
227 typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, false>
228 DisallowJavascriptExecution;
230 // Scope to introduce an exception to DisallowJavascriptExecution.
231 typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, true>
232 AllowJavascriptExecution;
234 // Scope in which javascript execution leads to exception being thrown.
235 typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, false>
236 ThrowOnJavascriptExecution;
238 // Scope to introduce an exception to ThrowOnJavascriptExecution.
239 typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, true>
240 NoThrowOnJavascriptExecution;
242 // Scope to document where we do not expect an allocation failure.
243 typedef PerIsolateAssertScopeDebugOnly<ALLOCATION_FAILURE_ASSERT, false>
244 DisallowAllocationFailure;
246 // Scope to introduce an exception to DisallowAllocationFailure.
247 typedef PerIsolateAssertScopeDebugOnly<ALLOCATION_FAILURE_ASSERT, true>
248 AllowAllocationFailure;
250 // Scope to document where we do not expect deoptimization.
251 typedef PerIsolateAssertScopeDebugOnly<DEOPTIMIZATION_ASSERT, false>
252 DisallowDeoptimization;
254 // Scope to introduce an exception to DisallowDeoptimization.
255 typedef PerIsolateAssertScopeDebugOnly<DEOPTIMIZATION_ASSERT, true>
258 // Scope to document where we do not expect deoptimization.
259 typedef PerIsolateAssertScopeDebugOnly<COMPILATION_ASSERT, false>
262 // Scope to introduce an exception to DisallowDeoptimization.
263 typedef PerIsolateAssertScopeDebugOnly<COMPILATION_ASSERT, true>
265 } } // namespace v8::internal
267 #endif // V8_ASSERT_SCOPE_H_