| 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 |