1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/assert-scope.h" 6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/base/lazy-instance.h" 8958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/base/platform/platform.h" 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/isolate.h" 10958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/utils.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 15958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace { 16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstruct PerThreadAssertKeyConstructTrait final { 18958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static void Construct(base::Thread::LocalStorageKey* key) { 19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier *key = base::Thread::CreateThreadLocalKey(); 20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertypedef base::LazyStaticInstance<base::Thread::LocalStorageKey, 25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PerThreadAssertKeyConstructTrait>::type 26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PerThreadAssertKey; 27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierPerThreadAssertKey kPerThreadAssertKey; 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace 32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass PerThreadAssertData final { 35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PerThreadAssertData() : nesting_level_(0) { 37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; i++) { 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier assert_states_[i] = true; 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ~PerThreadAssertData() { 43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; ++i) { 44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(assert_states_[i]); 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool Get(PerThreadAssertType type) const { return assert_states_[type]; } 49958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Set(PerThreadAssertType type, bool x) { assert_states_[type] = x; } 50958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void IncrementLevel() { ++nesting_level_; } 52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool DecrementLevel() { return --nesting_level_ == 0; } 53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 54958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static PerThreadAssertData* GetCurrent() { 55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return reinterpret_cast<PerThreadAssertData*>( 56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier base::Thread::GetThreadLocal(kPerThreadAssertKey.Get())); 57958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static void SetCurrent(PerThreadAssertData* data) { 59958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier base::Thread::SetThreadLocal(kPerThreadAssertKey.Get(), data); 60958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 61958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 62958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 63958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool assert_states_[LAST_PER_THREAD_ASSERT_TYPE]; 64958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int nesting_level_; 65958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 66958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DISALLOW_COPY_AND_ASSIGN(PerThreadAssertData); 67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 68958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 69958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate <PerThreadAssertType kType, bool kAllow> 71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierPerThreadAssertScope<kType, kAllow>::PerThreadAssertScope() 72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : data_(PerThreadAssertData::GetCurrent()) { 73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (data_ == NULL) { 74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier data_ = new PerThreadAssertData(); 75958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PerThreadAssertData::SetCurrent(data_); 76958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier data_->IncrementLevel(); 78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier old_state_ = data_->Get(kType); 79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier data_->Set(kType, kAllow); 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate <PerThreadAssertType kType, bool kAllow> 84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierPerThreadAssertScope<kType, kAllow>::~PerThreadAssertScope() { 8562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (data_ == nullptr) return; 8662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Release(); 8762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 8862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 8962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate <PerThreadAssertType kType, bool kAllow> 9062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid PerThreadAssertScope<kType, kAllow>::Release() { 91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_NOT_NULL(data_); 92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier data_->Set(kType, old_state_); 93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (data_->DecrementLevel()) { 94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PerThreadAssertData::SetCurrent(NULL); 95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier delete data_; 96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 9762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch data_ = nullptr; 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// static 101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate <PerThreadAssertType kType, bool kAllow> 102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool PerThreadAssertScope<kType, kAllow>::IsAllowed() { 103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PerThreadAssertData* data = PerThreadAssertData::GetCurrent(); 104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return data == NULL || data->Get(kType); 105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate <PerIsolateAssertType kType, bool kAllow> 109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass PerIsolateAssertScope<kType, kAllow>::DataBit 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : public BitField<bool, kType, 1> {}; 111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate <PerIsolateAssertType kType, bool kAllow> 114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierPerIsolateAssertScope<kType, kAllow>::PerIsolateAssertScope(Isolate* isolate) 115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : isolate_(isolate), old_data_(isolate->per_isolate_assert_data()) { 116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_NOT_NULL(isolate); 117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier STATIC_ASSERT(kType < 32); 118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate_->set_per_isolate_assert_data(DataBit::update(old_data_, kAllow)); 119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate <PerIsolateAssertType kType, bool kAllow> 123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierPerIsolateAssertScope<kType, kAllow>::~PerIsolateAssertScope() { 124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier isolate_->set_per_isolate_assert_data(old_data_); 125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// static 129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate <PerIsolateAssertType kType, bool kAllow> 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool PerIsolateAssertScope<kType, kAllow>::IsAllowed(Isolate* isolate) { 131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return DataBit::decode(isolate->per_isolate_assert_data()); 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// ----------------------------------------------------------------------------- 136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Instantiations. 137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, false>; 139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, true>; 140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, false>; 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, true>; 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, false>; 143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, true>; 144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, false>; 145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, true>; 146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, false>; 147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, true>; 148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, false>; 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, true>; 151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, false>; 152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, true>; 153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerIsolateAssertScope<DEOPTIMIZATION_ASSERT, false>; 154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerIsolateAssertScope<DEOPTIMIZATION_ASSERT, true>; 155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerIsolateAssertScope<COMPILATION_ASSERT, false>; 156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniertemplate class PerIsolateAssertScope<COMPILATION_ASSERT, true>; 15762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate class PerIsolateAssertScope<NO_EXCEPTION_ASSERT, false>; 15862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochtemplate class PerIsolateAssertScope<NO_EXCEPTION_ASSERT, true>; 159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace internal 161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace v8 162