assert-scope.cc 4.75 KB
Newer Older
1 2 3 4
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5
#include "src/common/assert-scope.h"
6

7
#include "src/base/bit-field.h"
8 9
#include "src/base/lazy-instance.h"
#include "src/base/platform/platform.h"
10
#include "src/execution/isolate.h"
11
#include "src/utils/utils.h"
12 13 14 15

namespace v8 {
namespace internal {

16 17
namespace {

18 19
template <PerThreadAssertType kType>
using PerThreadDataBit = base::BitField<bool, kType, 1>;
20

21 22
// Thread-local storage for assert data. Default all asserts to "allow".
thread_local uint32_t current_per_thread_assert_data(~0);
23

24
}  // namespace
25 26

template <PerThreadAssertType kType, bool kAllow>
27 28 29 30
PerThreadAssertScope<kType, kAllow>::PerThreadAssertScope()
    : old_data_(current_per_thread_assert_data) {
  current_per_thread_assert_data =
      PerThreadDataBit<kType>::update(old_data_.value(), kAllow);
31 32
}

33 34
template <PerThreadAssertType kType, bool kAllow>
PerThreadAssertScope<kType, kAllow>::~PerThreadAssertScope() {
35
  if (!old_data_.has_value()) return;
36 37 38 39 40
  Release();
}

template <PerThreadAssertType kType, bool kAllow>
void PerThreadAssertScope<kType, kAllow>::Release() {
41 42
  current_per_thread_assert_data = old_data_.value();
  old_data_.reset();
43 44
}

45 46 47
// static
template <PerThreadAssertType kType, bool kAllow>
bool PerThreadAssertScope<kType, kAllow>::IsAllowed() {
48
  return PerThreadDataBit<kType>::decode(current_per_thread_assert_data);
49 50
}

51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
#define PER_ISOLATE_ASSERT_SCOPE_DEFINITION(ScopeType, field, enable)      \
  ScopeType::ScopeType(Isolate* isolate)                                   \
      : isolate_(isolate), old_data_(isolate->field()) {                   \
    DCHECK_NOT_NULL(isolate);                                              \
    isolate_->set_##field(enable);                                         \
  }                                                                        \
                                                                           \
  ScopeType::~ScopeType() { isolate_->set_##field(old_data_); }            \
                                                                           \
  /* static */                                                             \
  bool ScopeType::IsAllowed(Isolate* isolate) { return isolate->field(); } \
                                                                           \
  /* static */                                                             \
  void ScopeType::Open(Isolate* isolate, bool* was_execution_allowed) {    \
    DCHECK_NOT_NULL(isolate);                                              \
    DCHECK_NOT_NULL(was_execution_allowed);                                \
    *was_execution_allowed = isolate->field();                             \
    isolate->set_##field(enable);                                          \
  }                                                                        \
  /* static */                                                             \
  void ScopeType::Close(Isolate* isolate, bool was_execution_allowed) {    \
    DCHECK_NOT_NULL(isolate);                                              \
    isolate->set_##field(was_execution_allowed);                           \
  }

#define PER_ISOLATE_ASSERT_ENABLE_SCOPE_DEFINITION(EnableType, _, field, \
                                                   enable)               \
  PER_ISOLATE_ASSERT_SCOPE_DEFINITION(EnableType, field, enable)

#define PER_ISOLATE_ASSERT_DISABLE_SCOPE_DEFINITION(_, DisableType, field, \
                                                    enable)                \
  PER_ISOLATE_ASSERT_SCOPE_DEFINITION(DisableType, field, enable)

PER_ISOLATE_ASSERT_TYPE(PER_ISOLATE_ASSERT_ENABLE_SCOPE_DEFINITION, true)
PER_ISOLATE_ASSERT_TYPE(PER_ISOLATE_ASSERT_DISABLE_SCOPE_DEFINITION, false)
86

87 88 89 90 91
// -----------------------------------------------------------------------------
// Instantiations.

template class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, false>;
template class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, true>;
92 93
template class PerThreadAssertScope<SAFEPOINTS_ASSERT, false>;
template class PerThreadAssertScope<SAFEPOINTS_ASSERT, true>;
94 95 96 97 98 99
template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, false>;
template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, true>;
template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, false>;
template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, true>;
template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, false>;
template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, true>;
100 101
template class PerThreadAssertScope<CODE_ALLOCATION_ASSERT, false>;
template class PerThreadAssertScope<CODE_ALLOCATION_ASSERT, true>;
102
template class PerThreadAssertScope<GC_MOLE, false>;
103 104 105

}  // namespace internal
}  // namespace v8