Chromium Code Reviews| Index: src/assert-scope.h |
| diff --git a/src/assert-scope.h b/src/assert-scope.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e70836a3387f9fe5e670149f28e47e91e9db08ec |
| --- /dev/null |
| +++ b/src/assert-scope.h |
| @@ -0,0 +1,154 @@ |
| +// Copyright 2013 the V8 project authors. All rights reserved. |
| +// Redistribution and use in source and binary forms, with or without |
| +// modification, are permitted provided that the following conditions are |
| +// met: |
| +// |
| +// * Redistributions of source code must retain the above copyright |
| +// notice, this list of conditions and the following disclaimer. |
| +// * Redistributions in binary form must reproduce the above |
| +// copyright notice, this list of conditions and the following |
| +// disclaimer in the documentation and/or other materials provided |
| +// with the distribution. |
| +// * Neither the name of Google Inc. nor the names of its |
| +// contributors may be used to endorse or promote products derived |
| +// from this software without specific prior written permission. |
| +// |
| +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| + |
| +#ifndef V8_ASSERT_SCOPE_H_ |
| +#define V8_ASSERT_SCOPE_H_ |
| + |
| +#include "allocation.h" |
| +#include "platform.h" |
| + |
| +namespace v8 { |
| +namespace internal { |
| + |
| +class Isolate; |
| + |
| +enum PerThreadAssertType { |
| + HEAP_ALLOCATION_ASSERT, |
| + HANDLE_ALLOCATION_ASSERT, |
| + HANDLE_DEREFERENCE_ASSERT, |
| + DEFERRED_HANDLE_DEREFERENCE_ASSERT, |
| + LAST_PER_THREAD_ASSERT_TYPE |
| +}; |
| + |
| + |
| +#ifdef DEBUG |
| +class PerThreadAssertData { |
| + public: |
| + PerThreadAssertData() { |
| + for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; i++) { |
| + assert_states_[i] = true; |
| + } |
| + } |
| + |
| + void set(PerThreadAssertType type, bool allow) { |
| + assert_states_[type] = allow; |
| + } |
| + |
| + bool get(PerThreadAssertType type) { |
|
Sven Panne
2013/06/03 09:58:23
Missing const.
Yang
2013/06/03 13:37:15
Done.
|
| + return assert_states_[type]; |
| + } |
| + |
| + private: |
| + static Thread::LocalStorageKey thread_local_key; |
|
Sven Panne
2013/06/03 09:58:23
This is in the wrong class: It has nothing to do w
Yang
2013/06/03 13:37:15
Done.
|
| + bool assert_states_[LAST_PER_THREAD_ASSERT_TYPE]; |
| + |
| + friend class Isolate; |
| + template <PerThreadAssertType, bool> friend class PerThreadAssertScope; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(PerThreadAssertData); |
| +}; |
| +#endif // DEBUG |
| + |
| + |
| +template <PerThreadAssertType type, bool allow> |
| +class PerThreadAssertScope BASE_EMBEDDED { |
| + public: |
| +#ifndef DEBUG |
| + PerThreadAssertScope() { } |
| + static void SetIsAllowed(bool is_allowed) { } |
| +#else |
| + PerThreadAssertScope() { |
| + PerThreadAssertData* data = AssertData(); |
| + old_state_ = data->get(type); |
| + data->set(type, allow); |
| + } |
| + |
| + ~PerThreadAssertScope() { AssertData()->set(type, old_state_); } |
| + |
| + static bool IsAllowed() { return AssertData()->get(type); } |
| + |
| + // Set flag without resetting it at the end of the scope. |
| + static void SetIsAllowed(bool is_allowed) { |
|
Sven Panne
2013/06/03 09:58:23
This is a real wart, because it totally breaks the
Yang
2013/06/03 13:37:15
We use this in the deoptimizer and heap as well (f
|
| + AssertData()->set(type, is_allowed); |
| + } |
| + |
| + private: |
| + static PerThreadAssertData* AssertData() { |
| + PerThreadAssertData* data = reinterpret_cast<PerThreadAssertData*>( |
| + Thread::GetThreadLocal(PerThreadAssertData::thread_local_key)); |
| + if (data == NULL) { |
| + data = new PerThreadAssertData(); |
| + Thread::SetThreadLocal(PerThreadAssertData::thread_local_key, data); |
| + } |
| + return data; |
| + } |
| + |
| + bool old_state_; |
| +#endif |
| +}; |
| + |
| +// Scope to document where we do not expect handles to be created. |
| +typedef PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, false> |
| + DisallowHandleAllocation; |
| + |
| +// Scope to introduce an exception to DisallowHandleAllocation. |
| +typedef PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, true> |
| + AllowHandleAllocation; |
| + |
| +// Scope to document where we do not expect any allocation and GC. |
| +typedef PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, false> |
| + DisallowHeapAllocation; |
| + |
| +// Scope to introduce an exception to DisallowHeapAllocation. |
| +typedef PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, true> |
| + AllowHeapAllocation; |
| + |
| +// Scope to document where we do not expect any handle dereferences. |
| +typedef PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, false> |
| + DisallowHandleDereference; |
| + |
| +// Scope to introduce an exception to DisallowHandleDereference. |
| +typedef PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, true> |
| + AllowHandleDereference; |
| + |
| +// Scope to document where we do not expect deferred handles to be dereferenced. |
| +typedef PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, false> |
| + DisallowDeferredHandleDereference; |
| + |
| +// Scope to introduce an exception to DisallowDeferredHandleDereference. |
| +typedef PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, true> |
| + AllowDeferredHandleDereference; |
| + |
| +#ifdef DEBUG |
|
Sven Panne
2013/06/03 09:58:23
I don't think we need this #ifdef nor the macro be
Yang
2013/06/03 13:37:15
I'll just use the variable name to state its purpo
|
| +#define ALLOW_DEFERRED_HANDLE_DEREF(isolate, why_this_is_safe) \ |
| + AllowDeferredHandleDereference allow_deferred_deref; |
| +#else |
| +#define ALLOW_DEFERRED_HANDLE_DEREF(isolate, why_this_is_safe) |
| +#endif // DEBUG |
| +} } // namespace v8::internal |
| + |
| +#endif // V8_ASSERT_SCOPE_H_ |