Unreviewed, rolling out r220060.
[WebKit.git] / Source / WTF / wtf / WTFThreadData.h
1 /*
2  * Copyright (C) 2008-2017 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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. 
24  *
25  */
26
27 #ifndef WTFThreadData_h
28 #define WTFThreadData_h
29
30 #include <wtf/FastTLS.h>
31 #include <wtf/Noncopyable.h>
32 #include <wtf/StackBounds.h>
33 #include <wtf/StackStats.h>
34 #include <wtf/ThreadSpecific.h>
35
36 namespace WTF {
37
38 class AtomicStringTable;
39
40 typedef void (*AtomicStringTableDestructor)(AtomicStringTable*);
41
42 class WTFThreadData {
43     WTF_MAKE_NONCOPYABLE(WTFThreadData);
44 public:
45     WTF_EXPORT_PRIVATE WTFThreadData();
46     WTF_EXPORT_PRIVATE ~WTFThreadData();
47
48     AtomicStringTable* atomicStringTable()
49     {
50         return m_currentAtomicStringTable;
51     }
52
53     AtomicStringTable* setCurrentAtomicStringTable(AtomicStringTable* atomicStringTable)
54     {
55         AtomicStringTable* oldAtomicStringTable = m_currentAtomicStringTable;
56         m_currentAtomicStringTable = atomicStringTable;
57         return oldAtomicStringTable;
58     }
59
60     const StackBounds& stack()
61     {
62         return m_stackBounds;
63     }
64
65 #if ENABLE(STACK_STATS)
66     StackStats::PerThreadStats& stackStats()
67     {
68         return m_stackStats;
69     }
70 #endif
71
72     void* savedStackPointerAtVMEntry()
73     {
74         return m_savedStackPointerAtVMEntry;
75     }
76
77     void setSavedStackPointerAtVMEntry(void* stackPointerAtVMEntry)
78     {
79         m_savedStackPointerAtVMEntry = stackPointerAtVMEntry;
80     }
81
82     void* savedLastStackTop()
83     {
84         return m_savedLastStackTop;
85     }
86
87     void setSavedLastStackTop(void* lastStackTop)
88     {
89         m_savedLastStackTop = lastStackTop;
90     }
91
92     void* m_apiData { nullptr };
93
94 private:
95     AtomicStringTable* m_currentAtomicStringTable { nullptr };
96     AtomicStringTable* m_defaultAtomicStringTable { nullptr };
97     AtomicStringTableDestructor m_atomicStringTableDestructor { nullptr };
98
99     StackBounds m_stackBounds;
100 #if ENABLE(STACK_STATS)
101     StackStats::PerThreadStats m_stackStats;
102 #endif
103     void* m_savedStackPointerAtVMEntry { nullptr };
104     void* m_savedLastStackTop;
105
106 #if HAVE(FAST_TLS)
107     WTF_EXPORT_PRIVATE static WTFThreadData& createAndRegisterForGetspecificDirect();
108 #else
109     static WTF_EXPORTDATA ThreadSpecific<WTFThreadData>* staticData;
110 #endif
111
112     friend WTFThreadData& wtfThreadData();
113     friend class AtomicStringTable;
114 };
115
116 inline WTFThreadData& wtfThreadData()
117 {
118     // WRT WebCore:
119     //    WTFThreadData is used on main thread before it could possibly be used
120     //    on secondary ones, so there is no need for synchronization here.
121     // WRT JavaScriptCore:
122     //    wtfThreadData() is initially called from initializeThreading(), ensuring
123     //    this is initially called in a pthread_once locked context.
124 #if !HAVE(FAST_TLS)
125     if (!WTFThreadData::staticData)
126         WTFThreadData::staticData = new ThreadSpecific<WTFThreadData>;
127     return **WTFThreadData::staticData;
128 #else
129     if (WTFThreadData* data = static_cast<WTFThreadData*>(_pthread_getspecific_direct(WTF_THREAD_DATA_KEY)))
130         return *data;
131     return WTFThreadData::createAndRegisterForGetspecificDirect();
132 #endif
133 }
134
135 } // namespace WTF
136
137 using WTF::WTFThreadData;
138 using WTF::wtfThreadData;
139 using WTF::AtomicStringTable;
140
141 #endif // WTFThreadData_h