LCOV - code coverage report
Current view: top level - src - assert-scope.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 8 43 18.6 %
Date: 2017-10-20 Functions: 10 72 13.9 %

          Line data    Source code
       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           0 :     *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           0 :   PerThreadAssertData() : nesting_level_(0) {
      38           0 :     for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; i++) {
      39           0 :       assert_states_[i] = true;
      40             :     }
      41             :   }
      42             : 
      43             :   ~PerThreadAssertData() {
      44             :     for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; ++i) {
      45             :       DCHECK(assert_states_[i]);
      46             :     }
      47             :   }
      48             : 
      49           0 :   bool Get(PerThreadAssertType type) const { return assert_states_[type]; }
      50           0 :   void Set(PerThreadAssertType type, bool x) { assert_states_[type] = x; }
      51             : 
      52           0 :   void IncrementLevel() { ++nesting_level_; }
      53           0 :   bool DecrementLevel() { return --nesting_level_ == 0; }
      54             : 
      55           0 :   static PerThreadAssertData* GetCurrent() {
      56             :     return reinterpret_cast<PerThreadAssertData*>(
      57           0 :         base::Thread::GetThreadLocal(kPerThreadAssertKey.Get()));
      58             :   }
      59           0 :   static void SetCurrent(PerThreadAssertData* data) {
      60           0 :     base::Thread::SetThreadLocal(kPerThreadAssertKey.Get(), data);
      61           0 :   }
      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             : 
      71             : template <PerThreadAssertType kType, bool kAllow>
      72           0 : PerThreadAssertScope<kType, kAllow>::PerThreadAssertScope()
      73           0 :     : data_(PerThreadAssertData::GetCurrent()) {
      74           0 :   if (data_ == nullptr) {
      75           0 :     data_ = new PerThreadAssertData();
      76           0 :     PerThreadAssertData::SetCurrent(data_);
      77             :   }
      78           0 :   data_->IncrementLevel();
      79           0 :   old_state_ = data_->Get(kType);
      80             :   data_->Set(kType, kAllow);
      81           0 : }
      82             : 
      83             : 
      84             : template <PerThreadAssertType kType, bool kAllow>
      85           0 : PerThreadAssertScope<kType, kAllow>::~PerThreadAssertScope() {
      86           0 :   if (data_ == nullptr) return;
      87           0 :   Release();
      88           0 : }
      89             : 
      90             : template <PerThreadAssertType kType, bool kAllow>
      91           0 : void PerThreadAssertScope<kType, kAllow>::Release() {
      92             :   DCHECK_NOT_NULL(data_);
      93           0 :   data_->Set(kType, old_state_);
      94           0 :   if (data_->DecrementLevel()) {
      95           0 :     PerThreadAssertData::SetCurrent(nullptr);
      96           0 :     delete data_;
      97             :   }
      98           0 :   data_ = nullptr;
      99           0 : }
     100             : 
     101             : // static
     102             : template <PerThreadAssertType kType, bool kAllow>
     103           0 : bool PerThreadAssertScope<kType, kAllow>::IsAllowed() {
     104           0 :   PerThreadAssertData* data = PerThreadAssertData::GetCurrent();
     105           0 :   return data == nullptr || data->Get(kType);
     106             : }
     107             : 
     108             : 
     109             : template <PerIsolateAssertType kType, bool kAllow>
     110             : class PerIsolateAssertScope<kType, kAllow>::DataBit
     111             :     : public BitField<bool, kType, 1> {};
     112             : 
     113             : 
     114             : template <PerIsolateAssertType kType, bool kAllow>
     115    26807498 : PerIsolateAssertScope<kType, kAllow>::PerIsolateAssertScope(Isolate* isolate)
     116    26807498 :     : isolate_(isolate), old_data_(isolate->per_isolate_assert_data()) {
     117             :   DCHECK_NOT_NULL(isolate);
     118             :   STATIC_ASSERT(kType < 32);
     119             :   isolate_->set_per_isolate_assert_data(DataBit::update(old_data_, kAllow));
     120    13403749 : }
     121             : 
     122             : 
     123             : template <PerIsolateAssertType kType, bool kAllow>
     124    13403752 : PerIsolateAssertScope<kType, kAllow>::~PerIsolateAssertScope() {
     125    13403752 :   isolate_->set_per_isolate_assert_data(old_data_);
     126    13403752 : }
     127             : 
     128             : 
     129             : // static
     130             : template <PerIsolateAssertType kType, bool kAllow>
     131    46085148 : bool PerIsolateAssertScope<kType, kAllow>::IsAllowed(Isolate* isolate) {
     132    46085148 :   return DataBit::decode(isolate->per_isolate_assert_data());
     133             : }
     134             : 
     135             : 
     136             : // -----------------------------------------------------------------------------
     137             : // Instantiations.
     138             : 
     139             : template class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, false>;
     140             : template class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, true>;
     141             : template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, false>;
     142             : template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, true>;
     143             : template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, false>;
     144             : template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, true>;
     145             : template class PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, false>;
     146             : template class PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, true>;
     147             : template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, false>;
     148             : template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, true>;
     149             : 
     150             : template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, false>;
     151             : template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, true>;
     152             : template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, false>;
     153             : template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, 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

Generated by: LCOV version 1.10