Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / v8 / src / assert-scope.h
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 "src/allocation.h"
9 #include "src/base/platform/platform.h"
10 #include "src/utils.h"
11
12 namespace v8 {
13 namespace internal {
14
15 class Isolate;
16
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
24 };
25
26
27 enum PerIsolateAssertType {
28   JAVASCRIPT_EXECUTION_ASSERT,
29   JAVASCRIPT_EXECUTION_THROWS,
30   ALLOCATION_FAILURE_ASSERT,
31   DEOPTIMIZATION_ASSERT,
32   COMPILATION_ASSERT
33 };
34
35
36 class PerThreadAssertData {
37  public:
38   PerThreadAssertData() : nesting_level_(0) {
39     for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; i++) {
40       assert_states_[i] = true;
41     }
42   }
43
44   void set(PerThreadAssertType type, bool allow) {
45     assert_states_[type] = allow;
46   }
47
48   bool get(PerThreadAssertType type) const {
49     return assert_states_[type];
50   }
51
52   void increment_level() { ++nesting_level_; }
53   bool decrement_level() { return --nesting_level_ == 0; }
54
55  private:
56   bool assert_states_[LAST_PER_THREAD_ASSERT_TYPE];
57   int nesting_level_;
58
59   DISALLOW_COPY_AND_ASSIGN(PerThreadAssertData);
60 };
61
62
63 class PerThreadAssertScopeBase {
64  protected:
65   PerThreadAssertScopeBase() {
66     data_ = GetAssertData();
67     if (data_ == NULL) {
68       data_ = new PerThreadAssertData();
69       SetThreadLocalData(data_);
70     }
71     data_->increment_level();
72   }
73
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)));
78     }
79     delete data_;
80     SetThreadLocalData(NULL);
81   }
82
83   static PerThreadAssertData* GetAssertData() {
84     return reinterpret_cast<PerThreadAssertData*>(
85         base::Thread::GetThreadLocal(thread_local_key));
86   }
87
88   static base::Thread::LocalStorageKey thread_local_key;
89   PerThreadAssertData* data_;
90   friend class Isolate;
91
92  private:
93   static void SetThreadLocalData(PerThreadAssertData* data) {
94     base::Thread::SetThreadLocal(thread_local_key, data);
95   }
96 };
97
98
99 template <PerThreadAssertType type, bool allow>
100 class PerThreadAssertScope : public PerThreadAssertScopeBase {
101  public:
102   PerThreadAssertScope() {
103     old_state_ = data_->get(type);
104     data_->set(type, allow);
105   }
106
107   ~PerThreadAssertScope() { data_->set(type, old_state_); }
108
109   static bool IsAllowed() {
110     PerThreadAssertData* data = GetAssertData();
111     return data == NULL || data->get(type);
112   }
113
114  private:
115   bool old_state_;
116
117   DISALLOW_COPY_AND_ASSIGN(PerThreadAssertScope);
118 };
119
120
121 class PerIsolateAssertBase {
122  protected:
123   static uint32_t GetData(Isolate* isolate);
124   static void SetData(Isolate* isolate, uint32_t data);
125 };
126
127
128 template <PerIsolateAssertType type, bool allow>
129 class PerIsolateAssertScope : public PerIsolateAssertBase {
130  public:
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));
135   }
136
137   ~PerIsolateAssertScope() {
138     SetData(isolate_, old_data_);
139   }
140
141   static bool IsAllowed(Isolate* isolate) {
142     return DataBit::decode(GetData(isolate));
143   }
144
145  private:
146   typedef BitField<bool, type, 1> DataBit;
147
148   uint32_t old_data_;
149   Isolate* isolate_;
150
151   DISALLOW_COPY_AND_ASSIGN(PerIsolateAssertScope);
152 };
153
154
155 template <PerThreadAssertType type, bool allow>
156 #ifdef DEBUG
157 class PerThreadAssertScopeDebugOnly : public
158     PerThreadAssertScope<type, allow> {
159 #else
160 class PerThreadAssertScopeDebugOnly {
161  public:
162   PerThreadAssertScopeDebugOnly() { }
163 #endif
164 };
165
166
167 template <PerIsolateAssertType type, bool allow>
168 #ifdef DEBUG
169 class PerIsolateAssertScopeDebugOnly : public
170     PerIsolateAssertScope<type, allow> {
171  public:
172   explicit PerIsolateAssertScopeDebugOnly(Isolate* isolate)
173       : PerIsolateAssertScope<type, allow>(isolate) { }
174 #else
175 class PerIsolateAssertScopeDebugOnly {
176  public:
177   explicit PerIsolateAssertScopeDebugOnly(Isolate* isolate) { }
178 #endif
179 };
180
181 // Per-thread assert scopes.
182
183 // Scope to document where we do not expect handles to be created.
184 typedef PerThreadAssertScopeDebugOnly<HANDLE_ALLOCATION_ASSERT, false>
185     DisallowHandleAllocation;
186
187 // Scope to introduce an exception to DisallowHandleAllocation.
188 typedef PerThreadAssertScopeDebugOnly<HANDLE_ALLOCATION_ASSERT, true>
189     AllowHandleAllocation;
190
191 // Scope to document where we do not expect any allocation and GC.
192 typedef PerThreadAssertScopeDebugOnly<HEAP_ALLOCATION_ASSERT, false>
193     DisallowHeapAllocation;
194
195 // Scope to introduce an exception to DisallowHeapAllocation.
196 typedef PerThreadAssertScopeDebugOnly<HEAP_ALLOCATION_ASSERT, true>
197     AllowHeapAllocation;
198
199 // Scope to document where we do not expect any handle dereferences.
200 typedef PerThreadAssertScopeDebugOnly<HANDLE_DEREFERENCE_ASSERT, false>
201     DisallowHandleDereference;
202
203 // Scope to introduce an exception to DisallowHandleDereference.
204 typedef PerThreadAssertScopeDebugOnly<HANDLE_DEREFERENCE_ASSERT, true>
205     AllowHandleDereference;
206
207 // Scope to document where we do not expect deferred handles to be dereferenced.
208 typedef PerThreadAssertScopeDebugOnly<DEFERRED_HANDLE_DEREFERENCE_ASSERT, false>
209     DisallowDeferredHandleDereference;
210
211 // Scope to introduce an exception to DisallowDeferredHandleDereference.
212 typedef PerThreadAssertScopeDebugOnly<DEFERRED_HANDLE_DEREFERENCE_ASSERT, true>
213     AllowDeferredHandleDereference;
214
215 // Scope to document where we do not expect deferred handles to be dereferenced.
216 typedef PerThreadAssertScopeDebugOnly<CODE_DEPENDENCY_CHANGE_ASSERT, false>
217     DisallowCodeDependencyChange;
218
219 // Scope to introduce an exception to DisallowDeferredHandleDereference.
220 typedef PerThreadAssertScopeDebugOnly<CODE_DEPENDENCY_CHANGE_ASSERT, true>
221     AllowCodeDependencyChange;
222
223
224 // Per-isolate assert scopes.
225
226 // Scope to document where we do not expect javascript execution.
227 typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, false>
228     DisallowJavascriptExecution;
229
230 // Scope to introduce an exception to DisallowJavascriptExecution.
231 typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, true>
232     AllowJavascriptExecution;
233
234 // Scope in which javascript execution leads to exception being thrown.
235 typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, false>
236     ThrowOnJavascriptExecution;
237
238 // Scope to introduce an exception to ThrowOnJavascriptExecution.
239 typedef PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, true>
240     NoThrowOnJavascriptExecution;
241
242 // Scope to document where we do not expect an allocation failure.
243 typedef PerIsolateAssertScopeDebugOnly<ALLOCATION_FAILURE_ASSERT, false>
244     DisallowAllocationFailure;
245
246 // Scope to introduce an exception to DisallowAllocationFailure.
247 typedef PerIsolateAssertScopeDebugOnly<ALLOCATION_FAILURE_ASSERT, true>
248     AllowAllocationFailure;
249
250 // Scope to document where we do not expect deoptimization.
251 typedef PerIsolateAssertScopeDebugOnly<DEOPTIMIZATION_ASSERT, false>
252     DisallowDeoptimization;
253
254 // Scope to introduce an exception to DisallowDeoptimization.
255 typedef PerIsolateAssertScopeDebugOnly<DEOPTIMIZATION_ASSERT, true>
256     AllowDeoptimization;
257
258 // Scope to document where we do not expect deoptimization.
259 typedef PerIsolateAssertScopeDebugOnly<COMPILATION_ASSERT, false>
260     DisallowCompilation;
261
262 // Scope to introduce an exception to DisallowDeoptimization.
263 typedef PerIsolateAssertScopeDebugOnly<COMPILATION_ASSERT, true>
264     AllowCompilation;
265 } }  // namespace v8::internal
266
267 #endif  // V8_ASSERT_SCOPE_H_