Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008, 2010 Apple Inc. All Rights Reserved. | 2 * Copyright (C) 2008, 2010 Apple Inc. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| 11 * documentation and/or other materials provided with the distribution. | 11 * documentation and/or other materials provided with the distribution. |
| 12 * | 12 * |
| 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
| 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
| 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 * | 24 * |
| 25 */ | 25 */ |
| 26 | 26 |
| 27 #include "wtf/WTFThreadData.h" | 27 #include "wtf/WTFThreadData.h" |
| 28 | 28 |
| 29 #include "wtf/PtrUtil.h" | |
| 30 #include "wtf/StackUtil.h" | |
| 29 #include "wtf/text/AtomicStringTable.h" | 31 #include "wtf/text/AtomicStringTable.h" |
| 30 #include "wtf/text/TextCodecICU.h" | 32 #include "wtf/text/TextCodecICU.h" |
| 31 | 33 |
| 32 namespace WTF { | 34 namespace WTF { |
| 33 | 35 |
| 36 uintptr_t WTFThreadData::s_mainThreadStackStart = 0; | |
| 37 uintptr_t WTFThreadData::s_mainThreadUnderestimatedStackSize = 0; | |
| 38 uint8_t WTFThreadData::s_mainThreadDataStorage[sizeof(WTFThreadData)]; | |
| 39 | |
| 34 ThreadSpecific<WTFThreadData>* WTFThreadData::staticData; | 40 ThreadSpecific<WTFThreadData>* WTFThreadData::staticData; |
| 35 | 41 |
| 36 WTFThreadData::WTFThreadData() | 42 WTFThreadData::WTFThreadData(ThreadType type) |
| 37 : m_atomicStringTable(new AtomicStringTable), | 43 : m_threadId(internal::currentThreadSyscall()) { |
| 38 m_cachedConverterICU(new ICUConverterWrapper), | 44 // Static globals must be initialized before the AtomicStringTable, but after |
| 39 m_threadId(internal::currentThreadSyscall()) {} | 45 // |this| is initialized. Note that we call threadStackSize() from |
| 46 // getUnderestimatedStackSize() on MSVC. | |
| 47 if (type == MainThread) { | |
| 48 s_mainThreadStackStart = | |
| 49 reinterpret_cast<uintptr_t>(WTF::getStackStart()) - sizeof(void*); | |
| 50 size_t underestimatedStackSize = getUnderestimatedStackSize(); | |
| 51 if (underestimatedStackSize > sizeof(void*)) { | |
| 52 s_mainThreadUnderestimatedStackSize = | |
| 53 underestimatedStackSize - sizeof(void*); | |
| 54 } | |
|
haraken
2017/01/16 04:42:30
Can we do this initialization in WTFThreadData::in
Charlie Harrison
2017/01/18 01:49:48
This is all gone.
| |
| 55 } | |
| 56 m_atomicStringTable = makeUnique<AtomicStringTable>(); | |
| 57 m_cachedConverterICU = makeUnique<ICUConverterWrapper>(); | |
| 58 } | |
| 40 | 59 |
| 41 WTFThreadData::~WTFThreadData() {} | 60 WTFThreadData::~WTFThreadData() {} |
| 42 | 61 |
| 62 #if OS(WIN) && COMPILER(MSVC) | |
| 63 size_t WTFThreadData::threadStackSize() { | |
|
haraken
2017/01/16 04:42:30
I want to put this method in the same file as getU
Charlie Harrison
2017/01/18 01:49:48
Done.
| |
| 64 if (m_threadStackSize) | |
| 65 return m_threadStackSize; | |
| 66 | |
| 67 // Notice that we cannot use the TIB's StackLimit for the stack end, as it | |
| 68 // tracks the end of the committed range. We're after the end of the reserved | |
| 69 // stack area (most of which will be uncommitted, most times.) | |
| 70 MEMORY_BASIC_INFORMATION stackInfo; | |
| 71 memset(&stackInfo, 0, sizeof(MEMORY_BASIC_INFORMATION)); | |
| 72 size_t resultSize = | |
| 73 VirtualQuery(&stackInfo, &stackInfo, sizeof(MEMORY_BASIC_INFORMATION)); | |
| 74 DCHECK_GE(resultSize, sizeof(MEMORY_BASIC_INFORMATION)); | |
| 75 uint8_t* stackEnd = reinterpret_cast<uint8_t*>(stackInfo.AllocationBase); | |
| 76 | |
| 77 uint8_t* stackStart = reinterpret_cast<uint8_t*>(WTF::getStackStart()); | |
| 78 RELEASE_ASSERT(stackStart && stackStart > stackEnd); | |
| 79 m_threadStackSize = static_cast<size_t>(stackStart - stackEnd); | |
| 80 // When the third last page of the reserved stack is accessed as a | |
| 81 // guard page, the second last page will be committed (along with removing | |
| 82 // the guard bit on the third last) _and_ a stack overflow exception | |
| 83 // is raised. | |
| 84 // | |
| 85 // We have zero interest in running into stack overflow exceptions while | |
| 86 // marking objects, so simply consider the last three pages + one above | |
| 87 // as off-limits and adjust the reported stack size accordingly. | |
| 88 // | |
| 89 // http://blogs.msdn.com/b/satyem/archive/2012/08/13/thread-s-stack-memory-man agement.aspx | |
| 90 // explains the details. | |
| 91 RELEASE_ASSERT(m_threadStackSize > 4 * 0x1000); | |
| 92 m_threadStackSize -= 4 * 0x1000; | |
| 93 return m_threadStackSize; | |
| 94 } | |
| 95 #endif | |
| 96 | |
| 97 void WTFThreadData::initialize() { | |
| 98 DCHECK(!WTFThreadData::staticData); | |
| 99 WTFThreadData::staticData = new ThreadSpecific<WTFThreadData>; | |
| 100 new (s_mainThreadDataStorage) WTFThreadData(MainThread); | |
| 101 } | |
| 102 | |
| 103 WTFThreadData& WTFThreadData::current() { | |
| 104 #if defined(__GLIBC__) || OS(ANDROID) || OS(FREEBSD) | |
| 105 return **WTFThreadData::staticData; | |
| 106 #else | |
| 107 // TLS lookup is slow. | |
| 108 if (LIKELY(stackBasedIsMainThread())) | |
| 109 return mainThreadData(); | |
| 110 return **WTFThreadData::staticData; | |
| 111 #endif | |
| 112 } | |
| 113 | |
| 114 bool WTFThreadData::isMainThread() { | |
| 115 return current() == mainThreadData(); | |
| 116 } | |
| 117 | |
| 118 WTFThreadData& WTFThreadData::mainThreadData() { | |
| 119 return *(reinterpret_cast<WTFThreadData*>(s_mainThreadDataStorage)); | |
| 120 } | |
| 121 | |
| 122 bool WTFThreadData::stackBasedIsMainThread() { | |
| 123 uintptr_t dummy; | |
| 124 uintptr_t addressDiff = | |
| 125 s_mainThreadStackStart - reinterpret_cast<uintptr_t>(&dummy); | |
| 126 // This is a fast way to judge if we are in the main thread. | |
| 127 // If |&dummy| is within |s_mainThreadUnderestimatedStackSize| byte from | |
| 128 // the stack start of the main thread, we judge that we are in | |
| 129 // the main thread. | |
| 130 return addressDiff < s_mainThreadUnderestimatedStackSize; | |
| 131 } | |
| 132 | |
| 133 bool operator==(const WTFThreadData& data1, const WTFThreadData& data2) { | |
| 134 return data1.threadId() == data2.threadId(); | |
| 135 } | |
| 136 | |
| 43 } // namespace WTF | 137 } // namespace WTF |
| OLD | NEW |