/work/obj-fuzz/dist/include/mozilla/ThreadLocal.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | /* Cross-platform lightweight thread local data wrappers. */ |
8 | | |
9 | | #ifndef mozilla_ThreadLocal_h |
10 | | #define mozilla_ThreadLocal_h |
11 | | |
12 | | #if !defined(XP_WIN) |
13 | | # include <pthread.h> |
14 | | #endif |
15 | | |
16 | | #include "mozilla/Assertions.h" |
17 | | #include "mozilla/Attributes.h" |
18 | | #include "mozilla/TypeTraits.h" |
19 | | |
20 | | namespace mozilla { |
21 | | |
22 | | namespace detail { |
23 | | |
24 | | #ifdef XP_MACOSX |
25 | | # if defined(__has_feature) |
26 | | # if __has_feature(cxx_thread_local) |
27 | | # define MACOSX_HAS_THREAD_LOCAL |
28 | | # endif |
29 | | # endif |
30 | | #endif |
31 | | |
32 | | /* |
33 | | * Thread Local Storage helpers. |
34 | | * |
35 | | * Usage: |
36 | | * |
37 | | * Do not directly instantiate this class. Instead, use the |
38 | | * MOZ_THREAD_LOCAL macro to declare or define instances. The macro |
39 | | * takes a type name as its argument. |
40 | | * |
41 | | * Declare like this: |
42 | | * extern MOZ_THREAD_LOCAL(int) tlsInt; |
43 | | * Define like this: |
44 | | * MOZ_THREAD_LOCAL(int) tlsInt; |
45 | | * or: |
46 | | * static MOZ_THREAD_LOCAL(int) tlsInt; |
47 | | * |
48 | | * Only static-storage-duration (e.g. global variables, or static class members) |
49 | | * objects of this class should be instantiated. This class relies on |
50 | | * zero-initialization, which is implicit for static-storage-duration objects. |
51 | | * It doesn't have a custom default constructor, to avoid static initializers. |
52 | | * |
53 | | * API usage: |
54 | | * |
55 | | * // Create a TLS item. |
56 | | * // |
57 | | * // Note that init() should be invoked before the first use of set() |
58 | | * // or get(). It is ok to call it multiple times. This must be |
59 | | * // called in a way that avoids possible races with other threads. |
60 | | * MOZ_THREAD_LOCAL(int) tlsKey; |
61 | | * if (!tlsKey.init()) { |
62 | | * // deal with the error |
63 | | * } |
64 | | * |
65 | | * // Set the TLS value |
66 | | * tlsKey.set(123); |
67 | | * |
68 | | * // Get the TLS value |
69 | | * int value = tlsKey.get(); |
70 | | */ |
71 | | |
72 | | // Integral types narrower than void* must be extended to avoid |
73 | | // warnings from valgrind on some platforms. This helper type |
74 | | // achieves that without penalizing the common case of ThreadLocals |
75 | | // instantiated using a pointer type. |
76 | | template<typename S> |
77 | | struct Helper |
78 | | { |
79 | | typedef uintptr_t Type; |
80 | | }; |
81 | | |
82 | | template<typename S> |
83 | | struct Helper<S *> |
84 | | { |
85 | | typedef S *Type; |
86 | | }; |
87 | | |
88 | | #if defined(XP_WIN) |
89 | | /* |
90 | | * ThreadLocalKeyStorage uses Thread Local APIs that are declared in |
91 | | * processthreadsapi.h. To use this class on Windows, include that file |
92 | | * (or windows.h) before including ThreadLocal.h. |
93 | | * |
94 | | * TLS_OUT_OF_INDEXES is a #define that is used to detect whether |
95 | | * an appropriate header has been included prior to this file |
96 | | */ |
97 | | #if defined(TLS_OUT_OF_INDEXES) |
98 | | /* Despite not being used for MOZ_THREAD_LOCAL, we expose an implementation for |
99 | | * Windows for cases where it's not desirable to use thread_local */ |
100 | | template<typename T> |
101 | | class ThreadLocalKeyStorage |
102 | | { |
103 | | public: |
104 | | ThreadLocalKeyStorage() |
105 | | : mKey(TLS_OUT_OF_INDEXES) |
106 | | {} |
107 | | |
108 | | inline bool initialized() const { |
109 | | return mKey != TLS_OUT_OF_INDEXES; |
110 | | } |
111 | | |
112 | | inline void init() { |
113 | | mKey = TlsAlloc(); |
114 | | } |
115 | | |
116 | | inline T get() const { |
117 | | void* h = TlsGetValue(mKey); |
118 | | return static_cast<T>(reinterpret_cast<typename Helper<T>::Type>(h)); |
119 | | } |
120 | | |
121 | | inline bool set(const T aValue) { |
122 | | void* h = reinterpret_cast<void*>(static_cast<typename Helper<T>::Type>(aValue)); |
123 | | return TlsSetValue(mKey, h); |
124 | | } |
125 | | |
126 | | private: |
127 | | unsigned long mKey; |
128 | | }; |
129 | | #endif |
130 | | #else |
131 | | template<typename T> |
132 | | class ThreadLocalKeyStorage |
133 | | { |
134 | | public: |
135 | | constexpr ThreadLocalKeyStorage() |
136 | | : mKey(0), mInited(false) |
137 | | {} |
138 | | |
139 | | inline bool initialized() const { |
140 | | return mInited; |
141 | | } |
142 | | |
143 | | inline void init() { |
144 | | mInited = !pthread_key_create(&mKey, nullptr); |
145 | | } |
146 | | |
147 | | inline T get() const { |
148 | | void* h = pthread_getspecific(mKey); |
149 | | return static_cast<T>(reinterpret_cast<typename Helper<T>::Type>(h)); |
150 | | } |
151 | | |
152 | | inline bool set(const T aValue) { |
153 | | void* h = reinterpret_cast<void*>(static_cast<typename Helper<T>::Type>(aValue)); |
154 | | return !pthread_setspecific(mKey, h); |
155 | | } |
156 | | |
157 | | private: |
158 | | pthread_key_t mKey; |
159 | | bool mInited; |
160 | | }; |
161 | | #endif |
162 | | |
163 | | template<typename T> |
164 | | class ThreadLocalNativeStorage |
165 | | { |
166 | | public: |
167 | | // __thread does not allow non-trivial constructors, but we can |
168 | | // instead rely on zero-initialization. |
169 | 3.18k | inline bool initialized() const { |
170 | 3.18k | return true; |
171 | 3.18k | } mozilla::detail::ThreadLocalNativeStorage<CollectorData*>::initialized() const Line | Count | Source | 169 | 6 | inline bool initialized() const { | 170 | 6 | return true; | 171 | 6 | } |
mozilla::detail::ThreadLocalNativeStorage<mozilla::AbstractThread*>::initialized() const Line | Count | Source | 169 | 12 | inline bool initialized() const { | 170 | 12 | return true; | 171 | 12 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<mozilla::CooperativeThreadPool::CooperativeThread*>::initialized() const mozilla::detail::ThreadLocalNativeStorage<mozilla::Scheduler::EventLoopActivation*>::initialized() const Line | Count | Source | 169 | 6 | inline bool initialized() const { | 170 | 6 | return true; | 171 | 6 | } |
mozilla::detail::ThreadLocalNativeStorage<bool>::initialized() const Line | Count | Source | 169 | 36 | inline bool initialized() const { | 170 | 36 | return true; | 171 | 36 | } |
mozilla::detail::ThreadLocalNativeStorage<PRThread*>::initialized() const Line | Count | Source | 169 | 124 | inline bool initialized() const { | 170 | 124 | return true; | 171 | 124 | } |
Unified_cpp_xpcom_build0.cpp:mozilla::detail::ThreadLocalNativeStorage<(anonymous namespace)::PerThreadData*>::initialized() const Line | Count | Source | 169 | 6 | inline bool initialized() const { | 170 | 6 | return true; | 171 | 6 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<nsCOMArray<nsIFile>*>::initialized() const mozilla::detail::ThreadLocalNativeStorage<XPCJSContext*>::initialized() const Line | Count | Source | 169 | 6 | inline bool initialized() const { | 170 | 6 | return true; | 171 | 6 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<unsigned long>::initialized() const mozilla::detail::ThreadLocalNativeStorage<mozilla::dom::ScriptSettingsStackEntry*>::initialized() const Line | Count | Source | 169 | 6 | inline bool initialized() const { | 170 | 6 | return true; | 171 | 6 | } |
mozilla::detail::ThreadLocalNativeStorage<RegisteredThread*>::initialized() const Line | Count | Source | 169 | 98 | inline bool initialized() const { | 170 | 98 | return true; | 171 | 98 | } |
mozilla::detail::ThreadLocalNativeStorage<ProfilingStack*>::initialized() const Line | Count | Source | 169 | 98 | inline bool initialized() const { | 170 | 98 | return true; | 171 | 98 | } |
mozilla::detail::ThreadLocalNativeStorage<mozilla::BackgroundHangThread*>::initialized() const Line | Count | Source | 169 | 6 | inline bool initialized() const { | 170 | 6 | return true; | 171 | 6 | } |
mozilla::detail::ThreadLocalNativeStorage<js::jit::JitContext*>::initialized() const Line | Count | Source | 169 | 2.77k | inline bool initialized() const { | 170 | 2.77k | return true; | 171 | 2.77k | } |
mozilla::detail::ThreadLocalNativeStorage<JSContext*>::initialized() const Line | Count | Source | 169 | 6 | inline bool initialized() const { | 170 | 6 | return true; | 171 | 6 | } |
|
172 | | |
173 | 0 | inline void init() { |
174 | 0 | } Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<CollectorData*>::init() Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<mozilla::AbstractThread*>::init() Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<mozilla::CooperativeThreadPool::CooperativeThread*>::init() Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<mozilla::Scheduler::EventLoopActivation*>::init() Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<bool>::init() Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<PRThread*>::init() Unexecuted instantiation: Unified_cpp_xpcom_build0.cpp:mozilla::detail::ThreadLocalNativeStorage<(anonymous namespace)::PerThreadData*>::init() Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<nsCOMArray<nsIFile>*>::init() Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<XPCJSContext*>::init() Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<unsigned long>::init() Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<mozilla::dom::ScriptSettingsStackEntry*>::init() Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<RegisteredThread*>::init() Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<ProfilingStack*>::init() Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<mozilla::BackgroundHangThread*>::init() Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<js::jit::JitContext*>::init() Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<JSContext*>::init() |
175 | | |
176 | 242M | inline T get() const { |
177 | 242M | return mValue; |
178 | 242M | } mozilla::detail::ThreadLocalNativeStorage<ProfilingStack*>::get() const Line | Count | Source | 176 | 1.62M | inline T get() const { | 177 | 1.62M | return mValue; | 178 | 1.62M | } |
mozilla::detail::ThreadLocalNativeStorage<bool>::get() const Line | Count | Source | 176 | 50.8M | inline T get() const { | 177 | 50.8M | return mValue; | 178 | 50.8M | } |
mozilla::detail::ThreadLocalNativeStorage<CollectorData*>::get() const Line | Count | Source | 176 | 75.7M | inline T get() const { | 177 | 75.7M | return mValue; | 178 | 75.7M | } |
mozilla::detail::ThreadLocalNativeStorage<mozilla::AbstractThread*>::get() const Line | Count | Source | 176 | 3 | inline T get() const { | 177 | 3 | return mValue; | 178 | 3 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<mozilla::CooperativeThreadPool::CooperativeThread*>::get() const Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<mozilla::Scheduler::EventLoopActivation*>::get() const mozilla::detail::ThreadLocalNativeStorage<PRThread*>::get() const Line | Count | Source | 176 | 118 | inline T get() const { | 177 | 118 | return mValue; | 178 | 118 | } |
Unified_cpp_xpcom_build0.cpp:mozilla::detail::ThreadLocalNativeStorage<(anonymous namespace)::PerThreadData*>::get() const Line | Count | Source | 176 | 108 | inline T get() const { | 177 | 108 | return mValue; | 178 | 108 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<nsCOMArray<nsIFile>*>::get() const mozilla::detail::ThreadLocalNativeStorage<XPCJSContext*>::get() const Line | Count | Source | 176 | 30.8M | inline T get() const { | 177 | 30.8M | return mValue; | 178 | 30.8M | } |
Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<unsigned long>::get() const mozilla::detail::ThreadLocalNativeStorage<mozilla::dom::ScriptSettingsStackEntry*>::get() const Line | Count | Source | 176 | 61.7M | inline T get() const { | 177 | 61.7M | return mValue; | 178 | 61.7M | } |
mozilla::detail::ThreadLocalNativeStorage<RegisteredThread*>::get() const Line | Count | Source | 176 | 413 | inline T get() const { | 177 | 413 | return mValue; | 178 | 413 | } |
mozilla::detail::ThreadLocalNativeStorage<mozilla::BackgroundHangThread*>::get() const Line | Count | Source | 176 | 3 | inline T get() const { | 177 | 3 | return mValue; | 178 | 3 | } |
mozilla::detail::ThreadLocalNativeStorage<JSContext*>::get() const Line | Count | Source | 176 | 21.3M | inline T get() const { | 177 | 21.3M | return mValue; | 178 | 21.3M | } |
mozilla::detail::ThreadLocalNativeStorage<js::jit::JitContext*>::get() const Line | Count | Source | 176 | 1.38k | inline T get() const { | 177 | 1.38k | return mValue; | 178 | 1.38k | } |
|
179 | | |
180 | 3.24M | inline bool set(const T aValue) { |
181 | 3.24M | mValue = aValue; |
182 | 3.24M | return true; |
183 | 3.24M | } mozilla::detail::ThreadLocalNativeStorage<CollectorData*>::set(CollectorData*) Line | Count | Source | 180 | 3 | inline bool set(const T aValue) { | 181 | 3 | mValue = aValue; | 182 | 3 | return true; | 183 | 3 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<mozilla::AbstractThread*>::set(mozilla::AbstractThread*) Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<mozilla::CooperativeThreadPool::CooperativeThread*>::set(mozilla::CooperativeThreadPool::CooperativeThread*) Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<mozilla::Scheduler::EventLoopActivation*>::set(mozilla::Scheduler::EventLoopActivation*) mozilla::detail::ThreadLocalNativeStorage<bool>::set(bool) Line | Count | Source | 180 | 12 | inline bool set(const T aValue) { | 181 | 12 | mValue = aValue; | 182 | 12 | return true; | 183 | 12 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<PRThread*>::set(PRThread*) Unified_cpp_xpcom_build0.cpp:mozilla::detail::ThreadLocalNativeStorage<(anonymous namespace)::PerThreadData*>::set((anonymous namespace)::PerThreadData*) Line | Count | Source | 180 | 19 | inline bool set(const T aValue) { | 181 | 19 | mValue = aValue; | 182 | 19 | return true; | 183 | 19 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<nsCOMArray<nsIFile>*>::set(nsCOMArray<nsIFile>*) mozilla::detail::ThreadLocalNativeStorage<XPCJSContext*>::set(XPCJSContext*) Line | Count | Source | 180 | 3 | inline bool set(const T aValue) { | 181 | 3 | mValue = aValue; | 182 | 3 | return true; | 183 | 3 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocalNativeStorage<unsigned long>::set(unsigned long) mozilla::detail::ThreadLocalNativeStorage<mozilla::dom::ScriptSettingsStackEntry*>::set(mozilla::dom::ScriptSettingsStackEntry*) Line | Count | Source | 180 | 3.24M | inline bool set(const T aValue) { | 181 | 3.24M | mValue = aValue; | 182 | 3.24M | return true; | 183 | 3.24M | } |
mozilla::detail::ThreadLocalNativeStorage<RegisteredThread*>::set(RegisteredThread*) Line | Count | Source | 180 | 49 | inline bool set(const T aValue) { | 181 | 49 | mValue = aValue; | 182 | 49 | return true; | 183 | 49 | } |
mozilla::detail::ThreadLocalNativeStorage<ProfilingStack*>::set(ProfilingStack*) Line | Count | Source | 180 | 49 | inline bool set(const T aValue) { | 181 | 49 | mValue = aValue; | 182 | 49 | return true; | 183 | 49 | } |
mozilla::detail::ThreadLocalNativeStorage<mozilla::BackgroundHangThread*>::set(mozilla::BackgroundHangThread*) Line | Count | Source | 180 | 3 | inline bool set(const T aValue) { | 181 | 3 | mValue = aValue; | 182 | 3 | return true; | 183 | 3 | } |
mozilla::detail::ThreadLocalNativeStorage<js::jit::JitContext*>::set(js::jit::JitContext*) Line | Count | Source | 180 | 338 | inline bool set(const T aValue) { | 181 | 338 | mValue = aValue; | 182 | 338 | return true; | 183 | 338 | } |
mozilla::detail::ThreadLocalNativeStorage<JSContext*>::set(JSContext*) Line | Count | Source | 180 | 27 | inline bool set(const T aValue) { | 181 | 27 | mValue = aValue; | 182 | 27 | return true; | 183 | 27 | } |
|
184 | | |
185 | | private: |
186 | | T mValue; |
187 | | }; |
188 | | |
189 | | template<typename T, template <typename U> class Storage> |
190 | | class ThreadLocal: public Storage<T> |
191 | | { |
192 | | public: |
193 | | MOZ_MUST_USE inline bool init(); |
194 | | |
195 | 9 | void infallibleInit() { |
196 | 9 | MOZ_RELEASE_ASSERT(init(), "Infallible TLS initialization failed"); |
197 | 9 | } Unexecuted instantiation: mozilla::detail::ThreadLocal<mozilla::CooperativeThreadPool::CooperativeThread*, mozilla::detail::ThreadLocalNativeStorage>::infallibleInit() mozilla::detail::ThreadLocal<mozilla::Scheduler::EventLoopActivation*, mozilla::detail::ThreadLocalNativeStorage>::infallibleInit() Line | Count | Source | 195 | 3 | void infallibleInit() { | 196 | 3 | MOZ_RELEASE_ASSERT(init(), "Infallible TLS initialization failed"); | 197 | 3 | } |
mozilla::detail::ThreadLocal<bool, mozilla::detail::ThreadLocalNativeStorage>::infallibleInit() Line | Count | Source | 195 | 6 | void infallibleInit() { | 196 | 6 | MOZ_RELEASE_ASSERT(init(), "Infallible TLS initialization failed"); | 197 | 6 | } |
|
198 | | |
199 | | inline T get() const; |
200 | | |
201 | | inline void set(const T aValue); |
202 | | }; |
203 | | |
204 | | template<typename T, template <typename U> class Storage> |
205 | | inline bool |
206 | | ThreadLocal<T, Storage>::init() |
207 | 1.53k | { |
208 | 1.53k | static_assert(mozilla::IsPointer<T>::value || mozilla::IsIntegral<T>::value, |
209 | 1.53k | "mozilla::ThreadLocal must be used with a pointer or " |
210 | 1.53k | "integral type"); |
211 | 1.53k | static_assert(sizeof(T) <= sizeof(void*), |
212 | 1.53k | "mozilla::ThreadLocal can't be used for types larger than " |
213 | 1.53k | "a pointer"); |
214 | 1.53k | |
215 | 1.53k | if (!Storage<T>::initialized()) { |
216 | 0 | Storage<T>::init(); |
217 | 0 | } |
218 | 1.53k | return Storage<T>::initialized(); |
219 | 1.53k | } mozilla::detail::ThreadLocal<CollectorData*, mozilla::detail::ThreadLocalNativeStorage>::init() Line | Count | Source | 207 | 3 | { | 208 | 3 | static_assert(mozilla::IsPointer<T>::value || mozilla::IsIntegral<T>::value, | 209 | 3 | "mozilla::ThreadLocal must be used with a pointer or " | 210 | 3 | "integral type"); | 211 | 3 | static_assert(sizeof(T) <= sizeof(void*), | 212 | 3 | "mozilla::ThreadLocal can't be used for types larger than " | 213 | 3 | "a pointer"); | 214 | 3 | | 215 | 3 | if (!Storage<T>::initialized()) { | 216 | 0 | Storage<T>::init(); | 217 | 0 | } | 218 | 3 | return Storage<T>::initialized(); | 219 | 3 | } |
mozilla::detail::ThreadLocal<mozilla::AbstractThread*, mozilla::detail::ThreadLocalNativeStorage>::init() Line | Count | Source | 207 | 6 | { | 208 | 6 | static_assert(mozilla::IsPointer<T>::value || mozilla::IsIntegral<T>::value, | 209 | 6 | "mozilla::ThreadLocal must be used with a pointer or " | 210 | 6 | "integral type"); | 211 | 6 | static_assert(sizeof(T) <= sizeof(void*), | 212 | 6 | "mozilla::ThreadLocal can't be used for types larger than " | 213 | 6 | "a pointer"); | 214 | 6 | | 215 | 6 | if (!Storage<T>::initialized()) { | 216 | 0 | Storage<T>::init(); | 217 | 0 | } | 218 | 6 | return Storage<T>::initialized(); | 219 | 6 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocal<mozilla::CooperativeThreadPool::CooperativeThread*, mozilla::detail::ThreadLocalNativeStorage>::init() mozilla::detail::ThreadLocal<mozilla::Scheduler::EventLoopActivation*, mozilla::detail::ThreadLocalNativeStorage>::init() Line | Count | Source | 207 | 3 | { | 208 | 3 | static_assert(mozilla::IsPointer<T>::value || mozilla::IsIntegral<T>::value, | 209 | 3 | "mozilla::ThreadLocal must be used with a pointer or " | 210 | 3 | "integral type"); | 211 | 3 | static_assert(sizeof(T) <= sizeof(void*), | 212 | 3 | "mozilla::ThreadLocal can't be used for types larger than " | 213 | 3 | "a pointer"); | 214 | 3 | | 215 | 3 | if (!Storage<T>::initialized()) { | 216 | 0 | Storage<T>::init(); | 217 | 0 | } | 218 | 3 | return Storage<T>::initialized(); | 219 | 3 | } |
mozilla::detail::ThreadLocal<bool, mozilla::detail::ThreadLocalNativeStorage>::init() Line | Count | Source | 207 | 18 | { | 208 | 18 | static_assert(mozilla::IsPointer<T>::value || mozilla::IsIntegral<T>::value, | 209 | 18 | "mozilla::ThreadLocal must be used with a pointer or " | 210 | 18 | "integral type"); | 211 | 18 | static_assert(sizeof(T) <= sizeof(void*), | 212 | 18 | "mozilla::ThreadLocal can't be used for types larger than " | 213 | 18 | "a pointer"); | 214 | 18 | | 215 | 18 | if (!Storage<T>::initialized()) { | 216 | 0 | Storage<T>::init(); | 217 | 0 | } | 218 | 18 | return Storage<T>::initialized(); | 219 | 18 | } |
mozilla::detail::ThreadLocal<PRThread*, mozilla::detail::ThreadLocalNativeStorage>::init() Line | Count | Source | 207 | 3 | { | 208 | 3 | static_assert(mozilla::IsPointer<T>::value || mozilla::IsIntegral<T>::value, | 209 | 3 | "mozilla::ThreadLocal must be used with a pointer or " | 210 | 3 | "integral type"); | 211 | 3 | static_assert(sizeof(T) <= sizeof(void*), | 212 | 3 | "mozilla::ThreadLocal can't be used for types larger than " | 213 | 3 | "a pointer"); | 214 | 3 | | 215 | 3 | if (!Storage<T>::initialized()) { | 216 | 0 | Storage<T>::init(); | 217 | 0 | } | 218 | 3 | return Storage<T>::initialized(); | 219 | 3 | } |
Unified_cpp_xpcom_build0.cpp:mozilla::detail::ThreadLocal<(anonymous namespace)::PerThreadData*, mozilla::detail::ThreadLocalNativeStorage>::init() Line | Count | Source | 207 | 3 | { | 208 | 3 | static_assert(mozilla::IsPointer<T>::value || mozilla::IsIntegral<T>::value, | 209 | 3 | "mozilla::ThreadLocal must be used with a pointer or " | 210 | 3 | "integral type"); | 211 | 3 | static_assert(sizeof(T) <= sizeof(void*), | 212 | 3 | "mozilla::ThreadLocal can't be used for types larger than " | 213 | 3 | "a pointer"); | 214 | 3 | | 215 | 3 | if (!Storage<T>::initialized()) { | 216 | 0 | Storage<T>::init(); | 217 | 0 | } | 218 | 3 | return Storage<T>::initialized(); | 219 | 3 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocal<nsCOMArray<nsIFile>*, mozilla::detail::ThreadLocalNativeStorage>::init() mozilla::detail::ThreadLocal<XPCJSContext*, mozilla::detail::ThreadLocalNativeStorage>::init() Line | Count | Source | 207 | 3 | { | 208 | 3 | static_assert(mozilla::IsPointer<T>::value || mozilla::IsIntegral<T>::value, | 209 | 3 | "mozilla::ThreadLocal must be used with a pointer or " | 210 | 3 | "integral type"); | 211 | 3 | static_assert(sizeof(T) <= sizeof(void*), | 212 | 3 | "mozilla::ThreadLocal can't be used for types larger than " | 213 | 3 | "a pointer"); | 214 | 3 | | 215 | 3 | if (!Storage<T>::initialized()) { | 216 | 0 | Storage<T>::init(); | 217 | 0 | } | 218 | 3 | return Storage<T>::initialized(); | 219 | 3 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocal<unsigned long, mozilla::detail::ThreadLocalNativeStorage>::init() mozilla::detail::ThreadLocal<mozilla::dom::ScriptSettingsStackEntry*, mozilla::detail::ThreadLocalNativeStorage>::init() Line | Count | Source | 207 | 3 | { | 208 | 3 | static_assert(mozilla::IsPointer<T>::value || mozilla::IsIntegral<T>::value, | 209 | 3 | "mozilla::ThreadLocal must be used with a pointer or " | 210 | 3 | "integral type"); | 211 | 3 | static_assert(sizeof(T) <= sizeof(void*), | 212 | 3 | "mozilla::ThreadLocal can't be used for types larger than " | 213 | 3 | "a pointer"); | 214 | 3 | | 215 | 3 | if (!Storage<T>::initialized()) { | 216 | 0 | Storage<T>::init(); | 217 | 0 | } | 218 | 3 | return Storage<T>::initialized(); | 219 | 3 | } |
mozilla::detail::ThreadLocal<RegisteredThread*, mozilla::detail::ThreadLocalNativeStorage>::init() Line | Count | Source | 207 | 49 | { | 208 | 49 | static_assert(mozilla::IsPointer<T>::value || mozilla::IsIntegral<T>::value, | 209 | 49 | "mozilla::ThreadLocal must be used with a pointer or " | 210 | 49 | "integral type"); | 211 | 49 | static_assert(sizeof(T) <= sizeof(void*), | 212 | 49 | "mozilla::ThreadLocal can't be used for types larger than " | 213 | 49 | "a pointer"); | 214 | 49 | | 215 | 49 | if (!Storage<T>::initialized()) { | 216 | 0 | Storage<T>::init(); | 217 | 0 | } | 218 | 49 | return Storage<T>::initialized(); | 219 | 49 | } |
mozilla::detail::ThreadLocal<ProfilingStack*, mozilla::detail::ThreadLocalNativeStorage>::init() Line | Count | Source | 207 | 49 | { | 208 | 49 | static_assert(mozilla::IsPointer<T>::value || mozilla::IsIntegral<T>::value, | 209 | 49 | "mozilla::ThreadLocal must be used with a pointer or " | 210 | 49 | "integral type"); | 211 | 49 | static_assert(sizeof(T) <= sizeof(void*), | 212 | 49 | "mozilla::ThreadLocal can't be used for types larger than " | 213 | 49 | "a pointer"); | 214 | 49 | | 215 | 49 | if (!Storage<T>::initialized()) { | 216 | 0 | Storage<T>::init(); | 217 | 0 | } | 218 | 49 | return Storage<T>::initialized(); | 219 | 49 | } |
mozilla::detail::ThreadLocal<mozilla::BackgroundHangThread*, mozilla::detail::ThreadLocalNativeStorage>::init() Line | Count | Source | 207 | 3 | { | 208 | 3 | static_assert(mozilla::IsPointer<T>::value || mozilla::IsIntegral<T>::value, | 209 | 3 | "mozilla::ThreadLocal must be used with a pointer or " | 210 | 3 | "integral type"); | 211 | 3 | static_assert(sizeof(T) <= sizeof(void*), | 212 | 3 | "mozilla::ThreadLocal can't be used for types larger than " | 213 | 3 | "a pointer"); | 214 | 3 | | 215 | 3 | if (!Storage<T>::initialized()) { | 216 | 0 | Storage<T>::init(); | 217 | 0 | } | 218 | 3 | return Storage<T>::initialized(); | 219 | 3 | } |
mozilla::detail::ThreadLocal<js::jit::JitContext*, mozilla::detail::ThreadLocalNativeStorage>::init() Line | Count | Source | 207 | 1.38k | { | 208 | 1.38k | static_assert(mozilla::IsPointer<T>::value || mozilla::IsIntegral<T>::value, | 209 | 1.38k | "mozilla::ThreadLocal must be used with a pointer or " | 210 | 1.38k | "integral type"); | 211 | 1.38k | static_assert(sizeof(T) <= sizeof(void*), | 212 | 1.38k | "mozilla::ThreadLocal can't be used for types larger than " | 213 | 1.38k | "a pointer"); | 214 | 1.38k | | 215 | 1.38k | if (!Storage<T>::initialized()) { | 216 | 0 | Storage<T>::init(); | 217 | 0 | } | 218 | 1.38k | return Storage<T>::initialized(); | 219 | 1.38k | } |
mozilla::detail::ThreadLocal<JSContext*, mozilla::detail::ThreadLocalNativeStorage>::init() Line | Count | Source | 207 | 3 | { | 208 | 3 | static_assert(mozilla::IsPointer<T>::value || mozilla::IsIntegral<T>::value, | 209 | 3 | "mozilla::ThreadLocal must be used with a pointer or " | 210 | 3 | "integral type"); | 211 | 3 | static_assert(sizeof(T) <= sizeof(void*), | 212 | 3 | "mozilla::ThreadLocal can't be used for types larger than " | 213 | 3 | "a pointer"); | 214 | 3 | | 215 | 3 | if (!Storage<T>::initialized()) { | 216 | 0 | Storage<T>::init(); | 217 | 0 | } | 218 | 3 | return Storage<T>::initialized(); | 219 | 3 | } |
|
220 | | |
221 | | template<typename T, template <typename U> class Storage> |
222 | | inline T |
223 | | ThreadLocal<T, Storage>::get() const |
224 | 242M | { |
225 | 242M | MOZ_ASSERT(Storage<T>::initialized()); |
226 | 242M | return Storage<T>::get(); |
227 | 242M | } mozilla::detail::ThreadLocal<ProfilingStack*, mozilla::detail::ThreadLocalNativeStorage>::get() const Line | Count | Source | 224 | 1.62M | { | 225 | 1.62M | MOZ_ASSERT(Storage<T>::initialized()); | 226 | 1.62M | return Storage<T>::get(); | 227 | 1.62M | } |
mozilla::detail::ThreadLocal<bool, mozilla::detail::ThreadLocalNativeStorage>::get() const Line | Count | Source | 224 | 50.8M | { | 225 | 50.8M | MOZ_ASSERT(Storage<T>::initialized()); | 226 | 50.8M | return Storage<T>::get(); | 227 | 50.8M | } |
mozilla::detail::ThreadLocal<CollectorData*, mozilla::detail::ThreadLocalNativeStorage>::get() const Line | Count | Source | 224 | 75.7M | { | 225 | 75.7M | MOZ_ASSERT(Storage<T>::initialized()); | 226 | 75.7M | return Storage<T>::get(); | 227 | 75.7M | } |
mozilla::detail::ThreadLocal<mozilla::AbstractThread*, mozilla::detail::ThreadLocalNativeStorage>::get() const Line | Count | Source | 224 | 3 | { | 225 | 3 | MOZ_ASSERT(Storage<T>::initialized()); | 226 | 3 | return Storage<T>::get(); | 227 | 3 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocal<mozilla::CooperativeThreadPool::CooperativeThread*, mozilla::detail::ThreadLocalNativeStorage>::get() const Unexecuted instantiation: mozilla::detail::ThreadLocal<mozilla::Scheduler::EventLoopActivation*, mozilla::detail::ThreadLocalNativeStorage>::get() const mozilla::detail::ThreadLocal<PRThread*, mozilla::detail::ThreadLocalNativeStorage>::get() const Line | Count | Source | 224 | 118 | { | 225 | 118 | MOZ_ASSERT(Storage<T>::initialized()); | 226 | 118 | return Storage<T>::get(); | 227 | 118 | } |
Unified_cpp_xpcom_build0.cpp:mozilla::detail::ThreadLocal<(anonymous namespace)::PerThreadData*, mozilla::detail::ThreadLocalNativeStorage>::get() const Line | Count | Source | 224 | 108 | { | 225 | 108 | MOZ_ASSERT(Storage<T>::initialized()); | 226 | 108 | return Storage<T>::get(); | 227 | 108 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocal<nsCOMArray<nsIFile>*, mozilla::detail::ThreadLocalNativeStorage>::get() const mozilla::detail::ThreadLocal<XPCJSContext*, mozilla::detail::ThreadLocalNativeStorage>::get() const Line | Count | Source | 224 | 30.8M | { | 225 | 30.8M | MOZ_ASSERT(Storage<T>::initialized()); | 226 | 30.8M | return Storage<T>::get(); | 227 | 30.8M | } |
Unexecuted instantiation: mozilla::detail::ThreadLocal<unsigned long, mozilla::detail::ThreadLocalNativeStorage>::get() const mozilla::detail::ThreadLocal<mozilla::dom::ScriptSettingsStackEntry*, mozilla::detail::ThreadLocalNativeStorage>::get() const Line | Count | Source | 224 | 61.7M | { | 225 | 61.7M | MOZ_ASSERT(Storage<T>::initialized()); | 226 | 61.7M | return Storage<T>::get(); | 227 | 61.7M | } |
mozilla::detail::ThreadLocal<RegisteredThread*, mozilla::detail::ThreadLocalNativeStorage>::get() const Line | Count | Source | 224 | 413 | { | 225 | 413 | MOZ_ASSERT(Storage<T>::initialized()); | 226 | 413 | return Storage<T>::get(); | 227 | 413 | } |
mozilla::detail::ThreadLocal<mozilla::BackgroundHangThread*, mozilla::detail::ThreadLocalNativeStorage>::get() const Line | Count | Source | 224 | 3 | { | 225 | 3 | MOZ_ASSERT(Storage<T>::initialized()); | 226 | 3 | return Storage<T>::get(); | 227 | 3 | } |
mozilla::detail::ThreadLocal<JSContext*, mozilla::detail::ThreadLocalNativeStorage>::get() const Line | Count | Source | 224 | 21.3M | { | 225 | 21.3M | MOZ_ASSERT(Storage<T>::initialized()); | 226 | 21.3M | return Storage<T>::get(); | 227 | 21.3M | } |
mozilla::detail::ThreadLocal<js::jit::JitContext*, mozilla::detail::ThreadLocalNativeStorage>::get() const Line | Count | Source | 224 | 1.38k | { | 225 | 1.38k | MOZ_ASSERT(Storage<T>::initialized()); | 226 | 1.38k | return Storage<T>::get(); | 227 | 1.38k | } |
|
228 | | |
229 | | template<typename T, template <typename U> class Storage> |
230 | | inline void |
231 | | ThreadLocal<T, Storage>::set(const T aValue) |
232 | 3.24M | { |
233 | 3.24M | MOZ_ASSERT(Storage<T>::initialized()); |
234 | 3.24M | bool succeeded = Storage<T>::set(aValue); |
235 | 3.24M | if (!succeeded) { |
236 | 0 | MOZ_CRASH(); |
237 | 0 | } |
238 | 3.24M | } mozilla::detail::ThreadLocal<CollectorData*, mozilla::detail::ThreadLocalNativeStorage>::set(CollectorData*) Line | Count | Source | 232 | 3 | { | 233 | 3 | MOZ_ASSERT(Storage<T>::initialized()); | 234 | 3 | bool succeeded = Storage<T>::set(aValue); | 235 | 3 | if (!succeeded) { | 236 | 0 | MOZ_CRASH(); | 237 | 0 | } | 238 | 3 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocal<mozilla::AbstractThread*, mozilla::detail::ThreadLocalNativeStorage>::set(mozilla::AbstractThread*) Unexecuted instantiation: mozilla::detail::ThreadLocal<mozilla::CooperativeThreadPool::CooperativeThread*, mozilla::detail::ThreadLocalNativeStorage>::set(mozilla::CooperativeThreadPool::CooperativeThread*) Unexecuted instantiation: mozilla::detail::ThreadLocal<mozilla::Scheduler::EventLoopActivation*, mozilla::detail::ThreadLocalNativeStorage>::set(mozilla::Scheduler::EventLoopActivation*) mozilla::detail::ThreadLocal<bool, mozilla::detail::ThreadLocalNativeStorage>::set(bool) Line | Count | Source | 232 | 12 | { | 233 | 12 | MOZ_ASSERT(Storage<T>::initialized()); | 234 | 12 | bool succeeded = Storage<T>::set(aValue); | 235 | 12 | if (!succeeded) { | 236 | 0 | MOZ_CRASH(); | 237 | 0 | } | 238 | 12 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocal<PRThread*, mozilla::detail::ThreadLocalNativeStorage>::set(PRThread*) Unified_cpp_xpcom_build0.cpp:mozilla::detail::ThreadLocal<(anonymous namespace)::PerThreadData*, mozilla::detail::ThreadLocalNativeStorage>::set((anonymous namespace)::PerThreadData*) Line | Count | Source | 232 | 19 | { | 233 | 19 | MOZ_ASSERT(Storage<T>::initialized()); | 234 | 19 | bool succeeded = Storage<T>::set(aValue); | 235 | 19 | if (!succeeded) { | 236 | 0 | MOZ_CRASH(); | 237 | 0 | } | 238 | 19 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocal<nsCOMArray<nsIFile>*, mozilla::detail::ThreadLocalNativeStorage>::set(nsCOMArray<nsIFile>*) mozilla::detail::ThreadLocal<XPCJSContext*, mozilla::detail::ThreadLocalNativeStorage>::set(XPCJSContext*) Line | Count | Source | 232 | 3 | { | 233 | 3 | MOZ_ASSERT(Storage<T>::initialized()); | 234 | 3 | bool succeeded = Storage<T>::set(aValue); | 235 | 3 | if (!succeeded) { | 236 | 0 | MOZ_CRASH(); | 237 | 0 | } | 238 | 3 | } |
Unexecuted instantiation: mozilla::detail::ThreadLocal<unsigned long, mozilla::detail::ThreadLocalNativeStorage>::set(unsigned long) mozilla::detail::ThreadLocal<mozilla::dom::ScriptSettingsStackEntry*, mozilla::detail::ThreadLocalNativeStorage>::set(mozilla::dom::ScriptSettingsStackEntry*) Line | Count | Source | 232 | 3.24M | { | 233 | 3.24M | MOZ_ASSERT(Storage<T>::initialized()); | 234 | 3.24M | bool succeeded = Storage<T>::set(aValue); | 235 | 3.24M | if (!succeeded) { | 236 | 0 | MOZ_CRASH(); | 237 | 0 | } | 238 | 3.24M | } |
mozilla::detail::ThreadLocal<RegisteredThread*, mozilla::detail::ThreadLocalNativeStorage>::set(RegisteredThread*) Line | Count | Source | 232 | 49 | { | 233 | 49 | MOZ_ASSERT(Storage<T>::initialized()); | 234 | 49 | bool succeeded = Storage<T>::set(aValue); | 235 | 49 | if (!succeeded) { | 236 | 0 | MOZ_CRASH(); | 237 | 0 | } | 238 | 49 | } |
mozilla::detail::ThreadLocal<ProfilingStack*, mozilla::detail::ThreadLocalNativeStorage>::set(ProfilingStack*) Line | Count | Source | 232 | 49 | { | 233 | 49 | MOZ_ASSERT(Storage<T>::initialized()); | 234 | 49 | bool succeeded = Storage<T>::set(aValue); | 235 | 49 | if (!succeeded) { | 236 | 0 | MOZ_CRASH(); | 237 | 0 | } | 238 | 49 | } |
mozilla::detail::ThreadLocal<mozilla::BackgroundHangThread*, mozilla::detail::ThreadLocalNativeStorage>::set(mozilla::BackgroundHangThread*) Line | Count | Source | 232 | 3 | { | 233 | 3 | MOZ_ASSERT(Storage<T>::initialized()); | 234 | 3 | bool succeeded = Storage<T>::set(aValue); | 235 | 3 | if (!succeeded) { | 236 | 0 | MOZ_CRASH(); | 237 | 0 | } | 238 | 3 | } |
mozilla::detail::ThreadLocal<js::jit::JitContext*, mozilla::detail::ThreadLocalNativeStorage>::set(js::jit::JitContext*) Line | Count | Source | 232 | 338 | { | 233 | 338 | MOZ_ASSERT(Storage<T>::initialized()); | 234 | 338 | bool succeeded = Storage<T>::set(aValue); | 235 | 338 | if (!succeeded) { | 236 | 0 | MOZ_CRASH(); | 237 | 0 | } | 238 | 338 | } |
mozilla::detail::ThreadLocal<JSContext*, mozilla::detail::ThreadLocalNativeStorage>::set(JSContext*) Line | Count | Source | 232 | 27 | { | 233 | 27 | MOZ_ASSERT(Storage<T>::initialized()); | 234 | 27 | bool succeeded = Storage<T>::set(aValue); | 235 | 27 | if (!succeeded) { | 236 | 0 | MOZ_CRASH(); | 237 | 0 | } | 238 | 27 | } |
|
239 | | |
240 | | #if (defined(XP_WIN) || defined(MACOSX_HAS_THREAD_LOCAL)) && !defined(__MINGW32__) |
241 | | #define MOZ_THREAD_LOCAL(TYPE) thread_local mozilla::detail::ThreadLocal<TYPE, mozilla::detail::ThreadLocalNativeStorage> |
242 | | #elif defined(HAVE_THREAD_TLS_KEYWORD) |
243 | | #define MOZ_THREAD_LOCAL(TYPE) __thread mozilla::detail::ThreadLocal<TYPE, mozilla::detail::ThreadLocalNativeStorage> |
244 | | #else |
245 | | #define MOZ_THREAD_LOCAL(TYPE) mozilla::detail::ThreadLocal<TYPE, mozilla::detail::ThreadLocalKeyStorage> |
246 | | #endif |
247 | | |
248 | | } // namespace detail |
249 | | } // namespace mozilla |
250 | | |
251 | | #endif /* mozilla_ThreadLocal_h */ |