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 |