| 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 |