V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
assert-scope.cc
1 // Copyright 2014 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 #include "src/assert-scope.h"
6 
7 #include "src/base/lazy-instance.h"
8 #include "src/base/platform/platform.h"
9 #include "src/isolate.h"
10 #include "src/utils.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 namespace {
16 
17 struct PerThreadAssertKeyConstructTrait final {
18  static void Construct(void* key_arg) {
19  auto key = reinterpret_cast<base::Thread::LocalStorageKey*>(key_arg);
20  *key = base::Thread::CreateThreadLocalKey();
21  }
22 };
23 
24 
25 typedef base::LazyStaticInstance<base::Thread::LocalStorageKey,
26  PerThreadAssertKeyConstructTrait>::type
27  PerThreadAssertKey;
28 
29 
30 PerThreadAssertKey kPerThreadAssertKey;
31 
32 } // namespace
33 
34 
35 class PerThreadAssertData final {
36  public:
37  PerThreadAssertData() : nesting_level_(0) {
38  for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; i++) {
39  assert_states_[i] = true;
40  }
41  }
42 
44  for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; ++i) {
45  DCHECK(assert_states_[i]);
46  }
47  }
48 
49  bool Get(PerThreadAssertType type) const { return assert_states_[type]; }
50  void Set(PerThreadAssertType type, bool x) { assert_states_[type] = x; }
51 
52  void IncrementLevel() { ++nesting_level_; }
53  bool DecrementLevel() { return --nesting_level_ == 0; }
54 
55  static PerThreadAssertData* GetCurrent() {
56  return reinterpret_cast<PerThreadAssertData*>(
57  base::Thread::GetThreadLocal(kPerThreadAssertKey.Get()));
58  }
59  static void SetCurrent(PerThreadAssertData* data) {
60  base::Thread::SetThreadLocal(kPerThreadAssertKey.Get(), data);
61  }
62 
63  private:
64  bool assert_states_[LAST_PER_THREAD_ASSERT_TYPE];
65  int nesting_level_;
66 
67  DISALLOW_COPY_AND_ASSIGN(PerThreadAssertData);
68 };
69 
70 template <PerThreadAssertType kType, bool kAllow>
72  PerThreadAssertData* current_data = PerThreadAssertData::GetCurrent();
73  if (current_data == nullptr) {
74  current_data = new PerThreadAssertData();
75  PerThreadAssertData::SetCurrent(current_data);
76  }
77  data_and_old_state_.update(current_data, current_data->Get(kType));
78  current_data->IncrementLevel();
79  current_data->Set(kType, kAllow);
80 }
81 
82 template <PerThreadAssertType kType, bool kAllow>
83 PerThreadAssertScope<kType, kAllow>::~PerThreadAssertScope() {
84  if (data() == nullptr) return;
85  Release();
86 }
87 
88 template <PerThreadAssertType kType, bool kAllow>
89 void PerThreadAssertScope<kType, kAllow>::Release() {
90  auto* current_data = data();
91  DCHECK_NOT_NULL(current_data);
92  current_data->Set(kType, old_state());
93  if (current_data->DecrementLevel()) {
94  PerThreadAssertData::SetCurrent(nullptr);
95  delete current_data;
96  }
97  set_data(nullptr);
98 }
99 
100 // static
101 template <PerThreadAssertType kType, bool kAllow>
102 bool PerThreadAssertScope<kType, kAllow>::IsAllowed() {
103  PerThreadAssertData* current_data = PerThreadAssertData::GetCurrent();
104  return current_data == nullptr || current_data->Get(kType);
105 }
106 
107 template <PerIsolateAssertType kType, bool kAllow>
108 class PerIsolateAssertScope<kType, kAllow>::DataBit
109  : public BitField<bool, kType, 1> {};
110 
111 
112 template <PerIsolateAssertType kType, bool kAllow>
114  : isolate_(isolate), old_data_(isolate->per_isolate_assert_data()) {
115  DCHECK_NOT_NULL(isolate);
116  STATIC_ASSERT(kType < 32);
117  isolate_->set_per_isolate_assert_data(DataBit::update(old_data_, kAllow));
118 }
119 
120 
121 template <PerIsolateAssertType kType, bool kAllow>
123  isolate_->set_per_isolate_assert_data(old_data_);
124 }
125 
126 
127 // static
128 template <PerIsolateAssertType kType, bool kAllow>
129 bool PerIsolateAssertScope<kType, kAllow>::IsAllowed(Isolate* isolate) {
130  return DataBit::decode(isolate->per_isolate_assert_data());
131 }
132 
133 
134 // -----------------------------------------------------------------------------
135 // Instantiations.
136 
137 template class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, false>;
138 template class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, true>;
139 template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, false>;
140 template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, true>;
141 template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, false>;
142 template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, true>;
143 template class PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, false>;
144 template class PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, true>;
145 template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, false>;
146 template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, true>;
147 
148 template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, false>;
149 template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, true>;
150 template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, false>;
151 template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, true>;
152 template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_DUMP, false>;
153 template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_DUMP, true>;
154 template class PerIsolateAssertScope<DEOPTIMIZATION_ASSERT, false>;
155 template class PerIsolateAssertScope<DEOPTIMIZATION_ASSERT, true>;
156 template class PerIsolateAssertScope<COMPILATION_ASSERT, false>;
157 template class PerIsolateAssertScope<COMPILATION_ASSERT, true>;
158 template class PerIsolateAssertScope<NO_EXCEPTION_ASSERT, false>;
159 template class PerIsolateAssertScope<NO_EXCEPTION_ASSERT, true>;
160 
161 } // namespace internal
162 } // namespace v8
Definition: libplatform.h:13
Definition: v8.h:3740