• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/common/assert-scope.h"
6 
7 #include "src/base/bit-field.h"
8 #include "src/base/lazy-instance.h"
9 #include "src/base/platform/platform.h"
10 #include "src/execution/isolate.h"
11 #include "src/utils/utils.h"
12 
13 namespace v8 {
14 namespace internal {
15 
16 namespace {
17 
18 template <PerThreadAssertType kType>
19 using PerThreadDataBit = base::BitField<bool, kType, 1>;
20 
21 // Thread-local storage for assert data. Default all asserts to "allow".
22 thread_local uint32_t current_per_thread_assert_data(~0);
23 
24 }  // namespace
25 
26 template <PerThreadAssertType kType, bool kAllow>
PerThreadAssertScope()27 PerThreadAssertScope<kType, kAllow>::PerThreadAssertScope()
28     : old_data_(current_per_thread_assert_data) {
29   current_per_thread_assert_data =
30       PerThreadDataBit<kType>::update(old_data_.value(), kAllow);
31 }
32 
33 template <PerThreadAssertType kType, bool kAllow>
~PerThreadAssertScope()34 PerThreadAssertScope<kType, kAllow>::~PerThreadAssertScope() {
35   if (!old_data_.has_value()) return;
36   Release();
37 }
38 
39 template <PerThreadAssertType kType, bool kAllow>
Release()40 void PerThreadAssertScope<kType, kAllow>::Release() {
41   current_per_thread_assert_data = old_data_.value();
42   old_data_.reset();
43 }
44 
45 // static
46 template <PerThreadAssertType kType, bool kAllow>
IsAllowed()47 bool PerThreadAssertScope<kType, kAllow>::IsAllowed() {
48   return PerThreadDataBit<kType>::decode(current_per_thread_assert_data);
49 }
50 
51 #define PER_ISOLATE_ASSERT_SCOPE_DEFINITION(ScopeType, field, enable)      \
52   ScopeType::ScopeType(Isolate* isolate)                                   \
53       : isolate_(isolate), old_data_(isolate->field()) {                   \
54     DCHECK_NOT_NULL(isolate);                                              \
55     isolate_->set_##field(enable);                                         \
56   }                                                                        \
57                                                                            \
58   ScopeType::~ScopeType() { isolate_->set_##field(old_data_); }            \
59                                                                            \
60   /* static */                                                             \
61   bool ScopeType::IsAllowed(Isolate* isolate) { return isolate->field(); } \
62                                                                            \
63   /* static */                                                             \
64   void ScopeType::Open(Isolate* isolate, bool* was_execution_allowed) {    \
65     DCHECK_NOT_NULL(isolate);                                              \
66     DCHECK_NOT_NULL(was_execution_allowed);                                \
67     *was_execution_allowed = isolate->field();                             \
68     isolate->set_##field(enable);                                          \
69   }                                                                        \
70   /* static */                                                             \
71   void ScopeType::Close(Isolate* isolate, bool was_execution_allowed) {    \
72     DCHECK_NOT_NULL(isolate);                                              \
73     isolate->set_##field(was_execution_allowed);                           \
74   }
75 
76 #define PER_ISOLATE_ASSERT_ENABLE_SCOPE_DEFINITION(EnableType, _, field, \
77                                                    enable)               \
78   PER_ISOLATE_ASSERT_SCOPE_DEFINITION(EnableType, field, enable)
79 
80 #define PER_ISOLATE_ASSERT_DISABLE_SCOPE_DEFINITION(_, DisableType, field, \
81                                                     enable)                \
82   PER_ISOLATE_ASSERT_SCOPE_DEFINITION(DisableType, field, enable)
83 
84 PER_ISOLATE_ASSERT_TYPE(PER_ISOLATE_ASSERT_ENABLE_SCOPE_DEFINITION, true)
85 PER_ISOLATE_ASSERT_TYPE(PER_ISOLATE_ASSERT_DISABLE_SCOPE_DEFINITION, false)
86 
87 // -----------------------------------------------------------------------------
88 // Instantiations.
89 
90 template class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, false>;
91 template class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, true>;
92 template class PerThreadAssertScope<SAFEPOINTS_ASSERT, false>;
93 template class PerThreadAssertScope<SAFEPOINTS_ASSERT, true>;
94 template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, false>;
95 template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, true>;
96 template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, false>;
97 template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, true>;
98 template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, false>;
99 template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, true>;
100 template class PerThreadAssertScope<CODE_ALLOCATION_ASSERT, false>;
101 template class PerThreadAssertScope<CODE_ALLOCATION_ASSERT, true>;
102 template class PerThreadAssertScope<GC_MOLE, false>;
103 
104 }  // namespace internal
105 }  // namespace v8
106