Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: third_party/WebKit/Source/platform/heap/StackFrameDepth.h

Issue 2304023003: StackFrameDepth should be managed per ThreadHeap (Closed)
Patch Set: fix Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef StackFrameDepth_h 5 #ifndef StackFrameDepth_h
6 #define StackFrameDepth_h 6 #define StackFrameDepth_h
7 7
8 #include "platform/PlatformExport.h" 8 #include "platform/PlatformExport.h"
9 #include "wtf/Allocator.h" 9 #include "wtf/Allocator.h"
10 #include "wtf/Assertions.h" 10 #include "wtf/Assertions.h"
11 #include <cstddef> 11 #include <cstddef>
12 #include <stdint.h> 12 #include <stdint.h>
13 13
14 namespace blink { 14 namespace blink {
15 15
16 // StackFrameDepth keeps track of current call stack frame depth. 16 // StackFrameDepth keeps track of current call stack frame depth.
17 // It is specifically used to control stack usage while tracing 17 // It is specifically used to control stack usage while tracing
18 // the object graph during a GC. 18 // the object graph during a GC.
19 // 19 //
20 // Use isSafeToRecurse() to determine if it is safe to consume 20 // Use isSafeToRecurse() to determine if it is safe to consume
21 // more stack by invoking another recursive call. 21 // more stack by invoking another recursive call.
22 class PLATFORM_EXPORT StackFrameDepth final { 22 class PLATFORM_EXPORT StackFrameDepth {
23 STATIC_ONLY(StackFrameDepth);
24 public: 23 public:
25 inline static bool isSafeToRecurse() 24 void enableStackLimit();
25 void disableStackLimit()
26 { 26 {
27 // Asssume that the stack grows towards lower addresses, which 27 m_stackFrameLimit = kMinimumStackLimit;
28 // all the ABIs currently supported do.
29 //
30 // A unit test checks that the assumption holds for a target
31 // (HeapTest.StackGrowthDirection.)
32 return currentStackFrame() > s_stackFrameLimit;
33 } 28 }
34 29
35 static void enableStackLimit(); 30 bool isEnabled() { return m_stackFrameLimit != kMinimumStackLimit; }
36 static void disableStackLimit() 31 bool isAcceptableStackUse()
37 {
38 s_stackFrameLimit = kMinimumStackLimit;
39 }
40
41 #if ENABLE(ASSERT)
42 inline static bool isEnabled() { return s_stackFrameLimit != kMinimumStackLi mit; }
43 inline static bool isAcceptableStackUse()
44 { 32 {
45 #if defined(ADDRESS_SANITIZER) 33 #if defined(ADDRESS_SANITIZER)
46 // ASan adds extra stack usage leading to too noisy asserts. 34 // ASan adds extra stack usage leading to too noisy asserts.
47 return true; 35 return true;
48 #else 36 #else
49 return !isEnabled() || isSafeToRecurse(); 37 return !isEnabled() || isSafeToRecurse();
50 #endif 38 #endif
51 } 39 }
52 #endif
53 40
54 static size_t getUnderestimatedStackSize(); 41 static size_t getUnderestimatedStackSize();
55 static void* getStackStart(); 42 static void* getStackStart();
56 43
57 #if COMPILER(MSVC) 44 #if COMPILER(MSVC)
58 // Ignore C4172: returning address of local variable or temporary: dummy. This 45 // Ignore C4172: returning address of local variable or temporary: dummy. This
59 // warning suppression has to go outside of the function to take effect. 46 // warning suppression has to go outside of the function to take effect.
60 #pragma warning(push) 47 #pragma warning(push)
61 #pragma warning(disable: 4172) 48 #pragma warning(disable: 4172)
62 #endif 49 #endif
63 static uintptr_t currentStackFrame(const char* dummy = nullptr) 50 static uintptr_t currentStackFrame(const char* dummy = nullptr)
64 { 51 {
65 #if COMPILER(GCC) 52 #if COMPILER(GCC)
66 return reinterpret_cast<uintptr_t>(__builtin_frame_address(0)); 53 return reinterpret_cast<uintptr_t>(__builtin_frame_address(0));
67 #elif COMPILER(MSVC) 54 #elif COMPILER(MSVC)
68 return reinterpret_cast<uintptr_t>(&dummy) - sizeof(void*); 55 return reinterpret_cast<uintptr_t>(&dummy) - sizeof(void*);
69 #else 56 #else
70 #error "Stack frame pointer estimation not supported on this platform." 57 #error "Stack frame pointer estimation not supported on this platform."
71 return 0; 58 return 0;
72 #endif 59 #endif
73 } 60 }
74 #if COMPILER(MSVC) 61 #if COMPILER(MSVC)
75 #pragma warning(pop) 62 #pragma warning(pop)
76 #endif 63 #endif
77 64
65 protected:
66 StackFrameDepth() : m_stackFrameLimit(kMinimumStackLimit) {}
67
78 private: 68 private:
69 bool isSafeToRecurse()
70 {
71 // Asssume that the stack grows towards lower addresses, which
72 // all the ABIs currently supported do.
73 //
74 // A unit test checks that the assumption holds for a target
75 // (HeapTest.StackGrowthDirection.)
76 return currentStackFrame() > m_stackFrameLimit;
77 }
78
79 // The maximum depth of eager, unrolled trace() calls that is 79 // The maximum depth of eager, unrolled trace() calls that is
80 // considered safe and allowed for targets with an unknown 80 // considered safe and allowed for targets with an unknown
81 // thread stack size. 81 // thread stack size.
82 static const int kSafeStackFrameSize = 32 * 1024; 82 static const int kSafeStackFrameSize = 32 * 1024;
83 83
84 // The stack pointer is assumed to grow towards lower addresses; 84 // The stack pointer is assumed to grow towards lower addresses;
85 // |kMinimumStackLimit| then being the limit that a stack 85 // |kMinimumStackLimit| then being the limit that a stack
86 // pointer will always exceed. 86 // pointer will always exceed.
87 static const uintptr_t kMinimumStackLimit = ~0ul; 87 static const uintptr_t kMinimumStackLimit = ~0ul;
88 88
89 static uintptr_t getFallbackStackLimit(); 89 static uintptr_t getFallbackStackLimit();
90 90
91 // The (pointer-valued) stack limit. 91 // The (pointer-valued) stack limit.
92 static uintptr_t s_stackFrameLimit; 92 uintptr_t m_stackFrameLimit;
93 }; 93 };
94 94
95 class StackFrameDepthScope { 95 class StackFrameDepthScope {
96 STACK_ALLOCATED(); 96 STACK_ALLOCATED();
97 WTF_MAKE_NONCOPYABLE(StackFrameDepthScope); 97 WTF_MAKE_NONCOPYABLE(StackFrameDepthScope);
98 public: 98 public:
99 StackFrameDepthScope() 99 explicit StackFrameDepthScope(StackFrameDepth* depth): m_depth(depth)
100 { 100 {
101 StackFrameDepth::enableStackLimit(); 101 m_depth->enableStackLimit();
102 // Enabled unless under stack pressure. 102 // Enabled unless under stack pressure.
103 ASSERT(StackFrameDepth::isSafeToRecurse() || !StackFrameDepth::isEnabled ()); 103 DCHECK(m_depth->isSafeToRecurse() || !m_depth->isEnabled());
104 } 104 }
105 105
106 ~StackFrameDepthScope() 106 ~StackFrameDepthScope()
107 { 107 {
108 StackFrameDepth::disableStackLimit(); 108 m_depth->disableStackLimit();
109 } 109 }
110
111 private:
112 StackFrameDepth* m_depth;
110 }; 113 };
111 114
112 } // namespace blink 115 } // namespace blink
113 116
114 #endif // StackFrameDepth_h 117 #endif // StackFrameDepth_h
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698