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 13namespace v8 { 14namespace internal { 15 16namespace { 17 18template <PerThreadAssertType kType> 19using PerThreadDataBit = base::BitField<bool, kType, 1>; 20 21// Thread-local storage for assert data. Default all asserts to "allow". 22thread_local uint32_t current_per_thread_assert_data(~0); 23 24} // namespace 25 26template <PerThreadAssertType kType, bool kAllow> 27PerThreadAssertScope<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 33template <PerThreadAssertType kType, bool kAllow> 34PerThreadAssertScope<kType, kAllow>::~PerThreadAssertScope() { 35 if (!old_data_.has_value()) return; 36 Release(); 37} 38 39template <PerThreadAssertType kType, bool kAllow> 40void PerThreadAssertScope<kType, kAllow>::Release() { 41 current_per_thread_assert_data = old_data_.value(); 42 old_data_.reset(); 43} 44 45// static 46template <PerThreadAssertType kType, bool kAllow> 47bool 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 84PER_ISOLATE_ASSERT_TYPE(PER_ISOLATE_ASSERT_ENABLE_SCOPE_DEFINITION, true) 85PER_ISOLATE_ASSERT_TYPE(PER_ISOLATE_ASSERT_DISABLE_SCOPE_DEFINITION, false) 86 87// ----------------------------------------------------------------------------- 88// Instantiations. 89 90template class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, false>; 91template class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, true>; 92template class PerThreadAssertScope<SAFEPOINTS_ASSERT, false>; 93template class PerThreadAssertScope<SAFEPOINTS_ASSERT, true>; 94template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, false>; 95template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, true>; 96template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, false>; 97template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, true>; 98template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, false>; 99template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, true>; 100template class PerThreadAssertScope<CODE_ALLOCATION_ASSERT, false>; 101template class PerThreadAssertScope<CODE_ALLOCATION_ASSERT, true>; 102template class PerThreadAssertScope<GC_MOLE, false>; 103 104} // namespace internal 105} // namespace v8 106