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

Side by Side Diff: third_party/WebKit/Source/wtf/WTFThreadData.cpp

Issue 2623273007: Fast path for ThreadSpecific for main thread on TLS-slow platforms (Closed)
Patch Set: [WIP] Fast path for currentThread() for main thread on TLS-slow platforms Created 3 years, 11 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 /* 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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698