OLD | NEW |
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 #include "platform/heap/StackFrameDepth.h" | 5 #include "platform/heap/StackFrameDepth.h" |
6 | 6 |
7 #include "public/platform/Platform.h" | 7 #include "public/platform/Platform.h" |
8 | 8 |
9 #if OS(WIN) | 9 #if OS(WIN) |
10 #include <stddef.h> | 10 #include <stddef.h> |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 return currentStackFrameBaseOnCallee(dummy); | 49 return currentStackFrameBaseOnCallee(dummy); |
50 } | 50 } |
51 | 51 |
52 void StackFrameDepth::enableStackLimit() | 52 void StackFrameDepth::enableStackLimit() |
53 { | 53 { |
54 #if ENABLE(ASSERT) | 54 #if ENABLE(ASSERT) |
55 s_isEnabled = true; | 55 s_isEnabled = true; |
56 s_isUsingFallbackStackSize = false; | 56 s_isUsingFallbackStackSize = false; |
57 #endif | 57 #endif |
58 | 58 |
59 // Windows and OSX platforms will always return a non-zero estimate. | 59 // All supported platforms will currently return a non-zero estimate, |
| 60 // except if ASan is enabled. |
60 size_t stackSize = getUnderestimatedStackSize(); | 61 size_t stackSize = getUnderestimatedStackSize(); |
61 if (!stackSize) { | 62 if (!stackSize) { |
62 s_stackFrameLimit = getFallbackStackLimit(); | 63 s_stackFrameLimit = getFallbackStackLimit(); |
63 return; | 64 return; |
64 } | 65 } |
65 | 66 |
66 static const int kStackRoomSize = 1024; | 67 static const int kStackRoomSize = 1024; |
67 | 68 |
68 Address stackBase = reinterpret_cast<Address>(getStackStart()); | 69 Address stackBase = reinterpret_cast<Address>(getStackStart()); |
69 RELEASE_ASSERT(stackSize > static_cast<const size_t>(kStackRoomSize)); | 70 RELEASE_ASSERT(stackSize > static_cast<const size_t>(kStackRoomSize)); |
70 size_t stackRoom = stackSize - kStackRoomSize; | 71 size_t stackRoom = stackSize - kStackRoomSize; |
71 RELEASE_ASSERT(stackBase > reinterpret_cast<Address>(stackRoom)); | 72 RELEASE_ASSERT(stackBase > reinterpret_cast<Address>(stackRoom)); |
72 s_stackFrameLimit = reinterpret_cast<uintptr_t>(stackBase - stackRoom); | 73 s_stackFrameLimit = reinterpret_cast<uintptr_t>(stackBase - stackRoom); |
73 } | 74 } |
74 | 75 |
75 size_t StackFrameDepth::getUnderestimatedStackSize() | 76 size_t StackFrameDepth::getUnderestimatedStackSize() |
76 { | 77 { |
77 // FIXME: ASAN bot uses a fake stack as a thread stack frame, | 78 // FIXME: ASAN bot uses a fake stack as a thread stack frame, |
78 // and its size is different from the value which APIs tells us. | 79 // and its size is different from the value which APIs tells us. |
79 #if defined(ADDRESS_SANITIZER) | 80 #if defined(ADDRESS_SANITIZER) |
80 return 0; | 81 return 0; |
81 #endif | 82 #endif |
82 | 83 |
83 // FIXME: On Mac OSX and Linux, this method cannot estimate stack size | 84 // FIXME: On Mac OSX and Linux, this method cannot estimate stack size |
84 // correctly for the main thread. | 85 // correctly for the main thread. |
85 | 86 |
86 #if defined(__GLIBC__) || OS(ANDROID) || OS(FREEBSD) | 87 #if defined(__GLIBC__) || OS(ANDROID) || OS(FREEBSD) |
87 // pthread_getattr_np() can fail if the thread is not invoked by | 88 // pthread_getattr_np() can fail if the thread is not invoked by |
88 // pthread_create() (e.g., the main thread of webkit_unit_tests). | 89 // pthread_create() (e.g., the main thread of webkit_unit_tests). |
89 // In this case, this method returns 0 and the caller must handle it. | 90 // If so, a conservative size estimate is returned. |
90 | 91 |
91 pthread_attr_t attr; | 92 pthread_attr_t attr; |
92 int error; | 93 int error; |
93 #if OS(FREEBSD) | 94 #if OS(FREEBSD) |
94 pthread_attr_init(&attr); | 95 pthread_attr_init(&attr); |
95 error = pthread_attr_get_np(pthread_self(), &attr); | 96 error = pthread_attr_get_np(pthread_self(), &attr); |
96 #else | 97 #else |
97 error = pthread_getattr_np(pthread_self(), &attr); | 98 error = pthread_getattr_np(pthread_self(), &attr); |
98 #endif | 99 #endif |
99 if (!error) { | 100 if (!error) { |
100 void* base; | 101 void* base; |
101 size_t size; | 102 size_t size; |
102 error = pthread_attr_getstack(&attr, &base, &size); | 103 error = pthread_attr_getstack(&attr, &base, &size); |
103 RELEASE_ASSERT(!error); | 104 RELEASE_ASSERT(!error); |
104 pthread_attr_destroy(&attr); | 105 pthread_attr_destroy(&attr); |
105 return size; | 106 return size; |
106 } | 107 } |
107 #if OS(FREEBSD) | 108 #if OS(FREEBSD) |
108 pthread_attr_destroy(&attr); | 109 pthread_attr_destroy(&attr); |
109 #endif | 110 #endif |
110 | 111 |
111 return 0; | 112 // Return a 512k stack size, (conservatively) assuming the following: |
| 113 // - that size is much lower than the pthreads default (x86 pthreads has a
2M default.) |
| 114 // - no one is running Blink with an RLIMIT_STACK override, let alone as |
| 115 // low as 512k. |
| 116 // |
| 117 return 512 * 1024; |
112 #elif OS(MACOSX) | 118 #elif OS(MACOSX) |
113 // pthread_get_stacksize_np() returns too low a value for the main thread on | 119 // pthread_get_stacksize_np() returns too low a value for the main thread on |
114 // OSX 10.9, http://mail.openjdk.java.net/pipermail/hotspot-dev/2013-October
/011369.html | 120 // OSX 10.9, http://mail.openjdk.java.net/pipermail/hotspot-dev/2013-October
/011369.html |
115 // | 121 // |
116 // Multiple workarounds possible, adopt the one made by https://github.com/r
obovm/robovm/issues/274 | 122 // Multiple workarounds possible, adopt the one made by https://github.com/r
obovm/robovm/issues/274 |
117 // (cf. https://developer.apple.com/library/mac/documentation/Cocoa/Conceptu
al/Multithreading/CreatingThreads/CreatingThreads.html | 123 // (cf. https://developer.apple.com/library/mac/documentation/Cocoa/Conceptu
al/Multithreading/CreatingThreads/CreatingThreads.html |
118 // on why hardcoding sizes is reasonable.) | 124 // on why hardcoding sizes is reasonable.) |
119 if (pthread_main_np()) { | 125 if (pthread_main_np()) { |
120 #if defined(IOS) | 126 #if defined(IOS) |
121 pthread_attr_t attr; | 127 pthread_attr_t attr; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 return reinterpret_cast<void*>(__readgsqword(offsetof(NT_TIB64, StackBase)))
; | 186 return reinterpret_cast<void*>(__readgsqword(offsetof(NT_TIB64, StackBase)))
; |
181 #else | 187 #else |
182 return reinterpret_cast<void*>(__readfsdword(offsetof(NT_TIB, StackBase))); | 188 return reinterpret_cast<void*>(__readfsdword(offsetof(NT_TIB, StackBase))); |
183 #endif | 189 #endif |
184 #else | 190 #else |
185 #error Unsupported getStackStart on this platform. | 191 #error Unsupported getStackStart on this platform. |
186 #endif | 192 #endif |
187 } | 193 } |
188 | 194 |
189 } // namespace blink | 195 } // namespace blink |
OLD | NEW |