Chromium Code Reviews| Index: Source/platform/heap/StackFrameDepth.h |
| diff --git a/Source/platform/heap/StackFrameDepth.h b/Source/platform/heap/StackFrameDepth.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ba720bfaca6f443597828884a7c264b4ec1ca34b |
| --- /dev/null |
| +++ b/Source/platform/heap/StackFrameDepth.h |
| @@ -0,0 +1,89 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef StackFrameDepth_h |
| +#define StackFrameDepth_h |
| + |
| +#include "wtf/Assertions.h" |
| +#include <stdint.h> |
| + |
| +namespace blink { |
| + |
| +// Enable estimation of stackframe pointer on supported platforms. |
| +#define ENABLE_STACKFRAME_POINTER_ESTIMATION 1 |
| + |
| +// StackFrameDepth keeps track of current call stack frame depth. |
| +// Use isSafeToRecurse() to query if there is a room in current |
| +// call stack for more recursive call. |
| +class StackFrameDepth final { |
| +public: |
| + static bool isEstimationSupported() |
| + { |
| +#if ENABLE(STACKFRAME_POINTER_ESTIMATION) && (COMPILER(GCC) || COMPILER(MSVC)) |
| + return true; |
| +#else |
| + return false; |
| +#endif |
| + } |
| + |
| + inline bool isSafeToRecurse() |
| + { |
| + if (isEstimationSupported()) { |
| + ASSERT(m_safeStackFrame); |
| + |
| + // Below comparison assumes callstack to glow downward, |
| + // which is true for all ABI Blink currently supports. |
| + return estimateCurrentStackFrame() < m_safeStackFrame; |
| + } |
| + |
| + return m_depth < kMaxDepth; |
| + } |
| + |
| + inline void increment() |
| + { |
| + if (isEstimationSupported()) |
| + return; |
| + |
| + ++m_depth; |
| + } |
| + |
| + inline void decrement() |
| + { |
| + if (isEstimationSupported()) |
| + return; |
| + |
| + ASSERT(m_depth > 0); |
| + --m_depth; |
| + } |
| + |
| + void configureLimit(); |
| + |
| +private: |
| + // The maximum depth of eager, unrolled trace() calls that is |
| + // considered safe and allowed. |
| + const int kMaxDepth = 100; |
| + |
| + static uintptr_t estimateCurrentStackFrame(const char* dummy = nullptr) |
| + { |
| + ASSERT(isEstimationSupported()); |
| +#if COMPILER(GCC) |
| + return reinterpret_cast<uintptr_t>(__builtin_frame_address(0)); |
| +#elif COMPILER(MSVC) |
| + return reinterpret_cast<uintptr_t>(&dummy); |
|
haraken
2015/01/07 05:04:44
Why can't we always use &dummy? If we can use &dum
kouhei (in TOK)
2015/01/07 05:06:39
Ideally, we want to have this compile to just "mov
haraken
2015/01/07 05:09:51
Makes sense.
Then why do you need m_depth? In a p
|
| +#else |
| + // Stack frame pointer estimation not supported on this platform. |
| + ASSERT_NOT_REACHED(); |
| + return 0; |
| +#endif |
| + } |
| + |
| + union { |
| + int m_depth; |
| + uintptr_t m_safeStackFrame; |
| + }; |
| +}; |
| + |
| +} // namespace blink |
| + |
| +#endif |