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

Side by Side Diff: third_party/WebKit/Source/wtf/StdLibExtras.h

Issue 2764833002: Move files in wtf/ to platform/wtf/ (Part 7). (Closed)
Patch Set: Rebase. Created 3 years, 9 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 // Copyright 2017 The Chromium Authors. All rights reserved.
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. 2 // Use of this source code is governed by a BSD-style license that can be
3 * 3 // found in the LICENSE file.
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 4
26 #ifndef WTF_StdLibExtras_h 5 #include "platform/wtf/StdLibExtras.h"
27 #define WTF_StdLibExtras_h
28 6
29 #include <cstddef> 7 // The contents of this header was moved to platform/wtf as part of
30 #include "base/numerics/safe_conversions.h" 8 // WTF migration project. See the following post for details:
31 #include "wtf/Assertions.h" 9 // https://groups.google.com/a/chromium.org/d/msg/blink-dev/tLdAZCTlcAA/bYXVT8gY CAAJ
32 #include "wtf/CPU.h"
33 #include "wtf/LeakAnnotations.h"
34 #include "wtf/Noncopyable.h"
35 #include "wtf/TypeTraits.h"
36
37 #if DCHECK_IS_ON()
38 #include "wtf/Threading.h"
39 #endif
40
41 // Use |DEFINE_STATIC_LOCAL()| to declare and define a static local variable
42 // (|static T;|) so that it is leaked and its destructors are not called at
43 // exit. T may also be a Blink garbage collected object, in which case it is
44 // wrapped up by an off-heap |Persistent<T>| reference to the object, keeping
45 // it alive across GCs.
46 //
47 // A |DEFINE_STATIC_LOCAL()| static should only be used on the thread it was
48 // created on.
49 //
50 #define DEFINE_STATIC_LOCAL(Type, Name, Arguments) \
51 static WTF::StaticSingleton<Type> s_##Name( \
52 new WTF::StaticSingleton<Type>::WrapperType Arguments); \
53 Type& Name = s_##Name.get(false)
54
55 // |DEFINE_THREAD_SAFE_STATIC_LOCAL()| is the cross-thread accessible variant
56 // of |DEFINE_STATIC_LOCAL()|; use it if the singleton can be accessed by
57 // multiple threads.
58 //
59 // TODO: rename as DEFINE_CROSS_THREAD_STATIC_LOCAL() ?
60 #define DEFINE_THREAD_SAFE_STATIC_LOCAL(Type, Name, Initializer) \
61 static WTF::StaticSingleton<Type> s_##Name(Initializer); \
62 Type& Name = s_##Name.get(true)
63
64 namespace blink {
65 template <typename T>
66 class Persistent;
67
68 } // namespace blink
69
70 namespace WTF {
71
72 template <typename Type>
73 class StaticSingleton final {
74 WTF_MAKE_NONCOPYABLE(StaticSingleton);
75
76 public:
77 template <typename T,
78 bool = WTF::IsGarbageCollectedType<T>::value &&
79 !WTF::IsPersistentReferenceType<T>::value>
80 struct Wrapper {
81 using type = T;
82
83 static T& unwrap(T* singleton) { return *singleton; }
84 };
85
86 template <typename T>
87 struct Wrapper<T, true> {
88 using type = blink::Persistent<T>;
89
90 static T& unwrap(blink::Persistent<T>* singleton) {
91 DCHECK(singleton);
92 // If this assert triggers, you're supplying an empty ("()") 'Arguments'
93 // argument to DEFINE_STATIC_LOCAL() - it must be the heap object you wish
94 // to create as a static singleton and wrapped up with a Persistent
95 // reference.
96 DCHECK(*singleton);
97 return **singleton;
98 }
99 };
100
101 using WrapperType = typename Wrapper<Type>::type;
102
103 // To cooperate with leak detection(LSan) for Blink garbage collected objects,
104 // the objects owned by persistent local statics will in some cases have to be
105 // finalized prior to leak checking. This only applies to static references to
106 // Blink heap objects and what they transitively hold on to. Hence the
107 // LEAK_SANITIZER_REGISTER_STATIC_LOCAL() use, it taking care of the grungy
108 // details.
109
110 explicit StaticSingleton(WrapperType* instance)
111 : m_instance(LEAK_SANITIZER_REGISTER_STATIC_LOCAL(WrapperType, instance))
112 #if DCHECK_IS_ON()
113 ,
114 m_safelyInitialized(WTF::isBeforeThreadCreated()),
115 m_thread(WTF::internal::currentThreadSyscall())
116 #endif
117 {
118 }
119
120 Type& get(bool allowCrossThreadUse) const {
121 #if DCHECK_IS_ON()
122 DCHECK(isNotRacy(allowCrossThreadUse));
123 #endif
124 ALLOW_UNUSED_LOCAL(allowCrossThreadUse);
125 return Wrapper<Type>::unwrap(m_instance);
126 }
127
128 operator Type&() { return get(); }
129
130 private:
131 #if DCHECK_IS_ON()
132
133 bool isNotRacy(bool allowCrossThreadUse) const {
134 // Make sure that singleton is safely initialized, or
135 // keeps being called on the same thread if cross-thread
136 // use is not permitted.
137 return allowCrossThreadUse || m_safelyInitialized ||
138 m_thread == WTF::internal::currentThreadSyscall();
139 }
140 #endif
141
142 WrapperType* m_instance;
143 #if DCHECK_IS_ON()
144 bool m_safelyInitialized;
145 ThreadIdentifier m_thread;
146 #endif
147 };
148
149 } // namespace WTF
150
151 // Use this to declare and define a static local pointer to a ref-counted object
152 // so that it is leaked so that the object's destructors are not called at
153 // exit. This macro should be used with ref-counted objects rather than
154 // DEFINE_STATIC_LOCAL macro, as this macro does not lead to an extra memory
155 // allocation.
156 #define DEFINE_STATIC_REF(type, name, arguments) \
157 static type* name = PassRefPtr<type>(arguments).leakRef();
158
159 /*
160 * The reinterpret_cast<Type1*>([pointer to Type2]) expressions - where
161 * sizeof(Type1) > sizeof(Type2) - cause the following warning on ARM with GCC:
162 * increases required alignment of target type.
163 *
164 * An implicit or an extra static_cast<void*> bypasses the warning.
165 * For more info see the following bugzilla entries:
166 * - https://bugs.webkit.org/show_bug.cgi?id=38045
167 * - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43976
168 */
169 #if CPU(ARM) && COMPILER(GCC)
170 template <typename Type>
171 bool isPointerTypeAlignmentOkay(Type* ptr) {
172 return !(reinterpret_cast<intptr_t>(ptr) % __alignof__(Type));
173 }
174
175 template <typename TypePtr>
176 TypePtr reinterpret_cast_ptr(void* ptr) {
177 DCHECK(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr)));
178 return reinterpret_cast<TypePtr>(ptr);
179 }
180
181 template <typename TypePtr>
182 TypePtr reinterpret_cast_ptr(const void* ptr) {
183 DCHECK(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr)));
184 return reinterpret_cast<TypePtr>(ptr);
185 }
186 #else
187 template <typename Type>
188 bool isPointerTypeAlignmentOkay(Type*) {
189 return true;
190 }
191 #define reinterpret_cast_ptr reinterpret_cast
192 #endif
193
194 namespace WTF {
195
196 /*
197 * C++'s idea of a reinterpret_cast lacks sufficient cojones.
198 */
199 template <typename TO, typename FROM>
200 inline TO bitwiseCast(FROM from) {
201 static_assert(sizeof(TO) == sizeof(FROM),
202 "WTF::bitwiseCast sizeof casted types should be equal");
203 union {
204 FROM from;
205 TO to;
206 } u;
207 u.from = from;
208 return u.to;
209 }
210
211 template <typename To, typename From>
212 inline To safeCast(From value) {
213 return base::checked_cast<To>(value);
214 }
215
216 // Use the following macros to prevent errors caused by accidental
217 // implicit casting of function arguments. For example, this can
218 // be used to prevent overflows from non-promoting conversions.
219 //
220 // Example:
221 //
222 // HAS_STRICTLY_TYPED_ARG
223 // void sendData(void* data, STRICTLY_TYPED_ARG(size))
224 // {
225 // ALLOW_NUMERIC_ARG_TYPES_PROMOTABLE_TO(size_t);
226 // ...
227 // }
228 //
229 // The previous example will prevent callers from passing, for example, an
230 // 'int'. On a 32-bit build, it will prevent use of an 'unsigned long long'.
231 #define HAS_STRICTLY_TYPED_ARG template <typename ActualArgType>
232 #define STRICTLY_TYPED_ARG(argName) ActualArgType argName
233 #define STRICT_ARG_TYPE(ExpectedArgType) \
234 static_assert(std::is_same<ActualArgType, ExpectedArgType>::value, \
235 "Strictly typed argument must be of type '" #ExpectedArgType \
236 "'.")
237 #define ALLOW_NUMERIC_ARG_TYPES_PROMOTABLE_TO(ExpectedArgType) \
238 static_assert( \
239 std::numeric_limits<ExpectedArgType>::is_integer == \
240 std::numeric_limits<ActualArgType>::is_integer, \
241 "Conversion between integer and non-integer types not allowed."); \
242 static_assert(sizeof(ExpectedArgType) >= sizeof(ActualArgType), \
243 "Truncating conversions not allowed."); \
244 static_assert(!std::numeric_limits<ActualArgType>::is_signed || \
245 std::numeric_limits<ExpectedArgType>::is_signed, \
246 "Signed to unsigned conversion not allowed."); \
247 static_assert((sizeof(ExpectedArgType) != sizeof(ActualArgType)) || \
248 (std::numeric_limits<ActualArgType>::is_signed == \
249 std::numeric_limits<ExpectedArgType>::is_signed), \
250 "Unsigned to signed conversion not allowed for types with " \
251 "identical size (could overflow).");
252
253 // Macro that returns a compile time constant with the length of an array, but
254 // gives an error if passed a non-array.
255 template <typename T, size_t Size>
256 char (&ArrayLengthHelperFunction(T (&)[Size]))[Size];
257 // GCC needs some help to deduce a 0 length array.
258 #if COMPILER(GCC)
259 template <typename T>
260 char (&ArrayLengthHelperFunction(T (&)[0]))[0];
261 #endif
262 #define WTF_ARRAY_LENGTH(array) sizeof(::WTF::ArrayLengthHelperFunction(array))
263
264 } // namespace WTF
265
266 using WTF::bitwiseCast;
267 using WTF::safeCast;
268
269 #endif // WTF_StdLibExtras_h
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/StackUtil.h ('k') | third_party/WebKit/Source/wtf/ThreadRestrictionVerifier.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698