| Index: src/assert-scope.cc
|
| diff --git a/src/assert-scope.cc b/src/assert-scope.cc
|
| index c4aa9877d45773e748320a40cde69958aabefd16..4c10fddb91243a7fbf4d8cfc371ca2e88a28dba4 100644
|
| --- a/src/assert-scope.cc
|
| +++ b/src/assert-scope.cc
|
| @@ -2,20 +2,154 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -
|
| #include "src/assert-scope.h"
|
| -#include "src/v8.h"
|
| +
|
| +#include "src/base/lazy-instance.h"
|
| +#include "src/base/platform/platform.h"
|
| +#include "src/isolate-inl.h"
|
| +#include "src/utils.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
|
|
| -uint32_t PerIsolateAssertBase::GetData(Isolate* isolate) {
|
| - return isolate->per_isolate_assert_data();
|
| +namespace {
|
| +
|
| +struct PerThreadAssertKeyConstructTrait FINAL {
|
| + static void Construct(base::Thread::LocalStorageKey* key) {
|
| + *key = base::Thread::CreateThreadLocalKey();
|
| + }
|
| +};
|
| +
|
| +
|
| +typedef base::LazyStaticInstance<base::Thread::LocalStorageKey,
|
| + PerThreadAssertKeyConstructTrait>::type
|
| + PerThreadAssertKey;
|
| +
|
| +
|
| +PerThreadAssertKey kPerThreadAssertKey;
|
| +
|
| +} // namespace
|
| +
|
| +
|
| +class PerThreadAssertData FINAL {
|
| + public:
|
| + PerThreadAssertData() : nesting_level_(0) {
|
| + for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; i++) {
|
| + assert_states_[i] = true;
|
| + }
|
| + }
|
| +
|
| + ~PerThreadAssertData() {
|
| + for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; ++i) {
|
| + DCHECK(assert_states_[i]);
|
| + }
|
| + }
|
| +
|
| + bool Get(PerThreadAssertType type) const { return assert_states_[type]; }
|
| + void Set(PerThreadAssertType type, bool x) { assert_states_[type] = x; }
|
| +
|
| + void IncrementLevel() { ++nesting_level_; }
|
| + bool DecrementLevel() { return --nesting_level_ == 0; }
|
| +
|
| + static PerThreadAssertData* GetCurrent() {
|
| + return reinterpret_cast<PerThreadAssertData*>(
|
| + base::Thread::GetThreadLocal(kPerThreadAssertKey.Get()));
|
| + }
|
| + static void SetCurrent(PerThreadAssertData* data) {
|
| + base::Thread::SetThreadLocal(kPerThreadAssertKey.Get(), data);
|
| + }
|
| +
|
| + private:
|
| + bool assert_states_[LAST_PER_THREAD_ASSERT_TYPE];
|
| + int nesting_level_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PerThreadAssertData);
|
| +};
|
| +
|
| +
|
| +template <PerThreadAssertType kType, bool kAllow>
|
| +PerThreadAssertScope<kType, kAllow>::PerThreadAssertScope()
|
| + : data_(PerThreadAssertData::GetCurrent()) {
|
| + if (data_ == NULL) {
|
| + data_ = new PerThreadAssertData();
|
| + PerThreadAssertData::SetCurrent(data_);
|
| + }
|
| + data_->IncrementLevel();
|
| + old_state_ = data_->Get(kType);
|
| + data_->Set(kType, kAllow);
|
| }
|
|
|
|
|
| -void PerIsolateAssertBase::SetData(Isolate* isolate, uint32_t data) {
|
| - isolate->set_per_isolate_assert_data(data);
|
| +template <PerThreadAssertType kType, bool kAllow>
|
| +PerThreadAssertScope<kType, kAllow>::~PerThreadAssertScope() {
|
| + DCHECK_NOT_NULL(data_);
|
| + data_->Set(kType, old_state_);
|
| + if (data_->DecrementLevel()) {
|
| + PerThreadAssertData::SetCurrent(NULL);
|
| + delete data_;
|
| + }
|
| }
|
|
|
| -} } // namespace v8::internal
|
| +
|
| +// static
|
| +template <PerThreadAssertType kType, bool kAllow>
|
| +bool PerThreadAssertScope<kType, kAllow>::IsAllowed() {
|
| + PerThreadAssertData* data = PerThreadAssertData::GetCurrent();
|
| + return data == NULL || data->Get(kType);
|
| +}
|
| +
|
| +
|
| +template <PerIsolateAssertType kType, bool kAllow>
|
| +class PerIsolateAssertScope<kType, kAllow>::DataBit
|
| + : public BitField<bool, kType, 1> {};
|
| +
|
| +
|
| +template <PerIsolateAssertType kType, bool kAllow>
|
| +PerIsolateAssertScope<kType, kAllow>::PerIsolateAssertScope(Isolate* isolate)
|
| + : isolate_(isolate), old_data_(isolate->per_isolate_assert_data()) {
|
| + DCHECK_NOT_NULL(isolate);
|
| + STATIC_ASSERT(kType < 32);
|
| + isolate_->set_per_isolate_assert_data(DataBit::update(old_data_, kAllow));
|
| +}
|
| +
|
| +
|
| +template <PerIsolateAssertType kType, bool kAllow>
|
| +PerIsolateAssertScope<kType, kAllow>::~PerIsolateAssertScope() {
|
| + isolate_->set_per_isolate_assert_data(old_data_);
|
| +}
|
| +
|
| +
|
| +// static
|
| +template <PerIsolateAssertType kType, bool kAllow>
|
| +bool PerIsolateAssertScope<kType, kAllow>::IsAllowed(Isolate* isolate) {
|
| + return DataBit::decode(isolate->per_isolate_assert_data());
|
| +}
|
| +
|
| +
|
| +// -----------------------------------------------------------------------------
|
| +// Instantiations.
|
| +
|
| +template class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, false>;
|
| +template class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, true>;
|
| +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<DEFERRED_HANDLE_DEREFERENCE_ASSERT, false>;
|
| +template class PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, true>;
|
| +template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, false>;
|
| +template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, true>;
|
| +
|
| +template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, false>;
|
| +template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, true>;
|
| +template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, false>;
|
| +template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, true>;
|
| +template class PerIsolateAssertScope<ALLOCATION_FAILURE_ASSERT, false>;
|
| +template class PerIsolateAssertScope<ALLOCATION_FAILURE_ASSERT, true>;
|
| +template class PerIsolateAssertScope<DEOPTIMIZATION_ASSERT, false>;
|
| +template class PerIsolateAssertScope<DEOPTIMIZATION_ASSERT, true>;
|
| +template class PerIsolateAssertScope<COMPILATION_ASSERT, false>;
|
| +template class PerIsolateAssertScope<COMPILATION_ASSERT, true>;
|
| +
|
| +} // namespace internal
|
| +} // namespace v8
|
|
|