OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_ASSERT_SCOPE_H_ | 5 #ifndef V8_ASSERT_SCOPE_H_ |
6 #define V8_ASSERT_SCOPE_H_ | 6 #define V8_ASSERT_SCOPE_H_ |
7 | 7 |
8 #include "src/allocation.h" | 8 #include "include/v8stdint.h" |
9 #include "src/base/platform/platform.h" | 9 #include "src/base/macros.h" |
10 #include "src/utils.h" | |
11 | 10 |
12 namespace v8 { | 11 namespace v8 { |
13 namespace internal { | 12 namespace internal { |
14 | 13 |
| 14 // Forward declarations. |
15 class Isolate; | 15 class Isolate; |
| 16 class PerThreadAssertData; |
| 17 |
16 | 18 |
17 enum PerThreadAssertType { | 19 enum PerThreadAssertType { |
18 HEAP_ALLOCATION_ASSERT, | 20 HEAP_ALLOCATION_ASSERT, |
19 HANDLE_ALLOCATION_ASSERT, | 21 HANDLE_ALLOCATION_ASSERT, |
20 HANDLE_DEREFERENCE_ASSERT, | 22 HANDLE_DEREFERENCE_ASSERT, |
21 DEFERRED_HANDLE_DEREFERENCE_ASSERT, | 23 DEFERRED_HANDLE_DEREFERENCE_ASSERT, |
22 CODE_DEPENDENCY_CHANGE_ASSERT, | 24 CODE_DEPENDENCY_CHANGE_ASSERT, |
23 LAST_PER_THREAD_ASSERT_TYPE | 25 LAST_PER_THREAD_ASSERT_TYPE |
24 }; | 26 }; |
25 | 27 |
26 | 28 |
27 enum PerIsolateAssertType { | 29 enum PerIsolateAssertType { |
28 JAVASCRIPT_EXECUTION_ASSERT, | 30 JAVASCRIPT_EXECUTION_ASSERT, |
29 JAVASCRIPT_EXECUTION_THROWS, | 31 JAVASCRIPT_EXECUTION_THROWS, |
30 ALLOCATION_FAILURE_ASSERT, | 32 ALLOCATION_FAILURE_ASSERT, |
31 DEOPTIMIZATION_ASSERT, | 33 DEOPTIMIZATION_ASSERT, |
32 COMPILATION_ASSERT | 34 COMPILATION_ASSERT |
33 }; | 35 }; |
34 | 36 |
35 | 37 |
36 class PerThreadAssertData { | 38 template <PerThreadAssertType kType, bool kAllow> |
| 39 class PerThreadAssertScope { |
37 public: | 40 public: |
38 PerThreadAssertData() : nesting_level_(0) { | 41 PerThreadAssertScope(); |
39 for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; i++) { | 42 ~PerThreadAssertScope(); |
40 assert_states_[i] = true; | |
41 } | |
42 } | |
43 | 43 |
44 void set(PerThreadAssertType type, bool allow) { | 44 static bool IsAllowed(); |
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 | 45 |
55 private: | 46 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_; | 47 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_; | 48 bool old_state_; |
116 | 49 |
117 DISALLOW_COPY_AND_ASSIGN(PerThreadAssertScope); | 50 DISALLOW_COPY_AND_ASSIGN(PerThreadAssertScope); |
118 }; | 51 }; |
119 | 52 |
120 | 53 |
121 class PerIsolateAssertBase { | 54 template <PerIsolateAssertType type, bool allow> |
122 protected: | 55 class PerIsolateAssertScope { |
123 static uint32_t GetData(Isolate* isolate); | 56 public: |
124 static void SetData(Isolate* isolate, uint32_t data); | 57 explicit PerIsolateAssertScope(Isolate* isolate); |
125 }; | 58 ~PerIsolateAssertScope(); |
126 | 59 |
127 | 60 static bool IsAllowed(Isolate* isolate); |
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 | 61 |
145 private: | 62 private: |
146 typedef BitField<bool, type, 1> DataBit; | 63 class DataBit; |
147 | 64 |
| 65 Isolate* isolate_; |
148 uint32_t old_data_; | 66 uint32_t old_data_; |
149 Isolate* isolate_; | |
150 | 67 |
151 DISALLOW_COPY_AND_ASSIGN(PerIsolateAssertScope); | 68 DISALLOW_COPY_AND_ASSIGN(PerIsolateAssertScope); |
152 }; | 69 }; |
153 | 70 |
154 | 71 |
155 template <PerThreadAssertType type, bool allow> | 72 template <PerThreadAssertType type, bool allow> |
156 #ifdef DEBUG | 73 #ifdef DEBUG |
157 class PerThreadAssertScopeDebugOnly : public | 74 class PerThreadAssertScopeDebugOnly : public |
158 PerThreadAssertScope<type, allow> { | 75 PerThreadAssertScope<type, allow> { |
159 #else | 76 #else |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 // Scope to document where we do not expect deoptimization. | 175 // Scope to document where we do not expect deoptimization. |
259 typedef PerIsolateAssertScopeDebugOnly<COMPILATION_ASSERT, false> | 176 typedef PerIsolateAssertScopeDebugOnly<COMPILATION_ASSERT, false> |
260 DisallowCompilation; | 177 DisallowCompilation; |
261 | 178 |
262 // Scope to introduce an exception to DisallowDeoptimization. | 179 // Scope to introduce an exception to DisallowDeoptimization. |
263 typedef PerIsolateAssertScopeDebugOnly<COMPILATION_ASSERT, true> | 180 typedef PerIsolateAssertScopeDebugOnly<COMPILATION_ASSERT, true> |
264 AllowCompilation; | 181 AllowCompilation; |
265 } } // namespace v8::internal | 182 } } // namespace v8::internal |
266 | 183 |
267 #endif // V8_ASSERT_SCOPE_H_ | 184 #endif // V8_ASSERT_SCOPE_H_ |
OLD | NEW |