2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef WTF_StdLibExtras_h
27 #define WTF_StdLibExtras_h
29 #include "wtf/Assertions.h"
31 #include "wtf/CheckedArithmetic.h"
34 #include "wtf/Noncopyable.h"
35 #include "wtf/Threading.h"
37 class WTF_EXPORT StaticLocalVerifier
{
38 WTF_MAKE_NONCOPYABLE(StaticLocalVerifier
);
41 : m_safelyInitialized(WTF::isBeforeThreadCreated())
42 , m_thread(WTF::currentThread())
48 // Make sure that this 1) is safely initialized, 2) keeps being called
49 // on the same thread, or 3) is called within
50 // AtomicallyInitializedStatic (i.e. with a lock held).
51 return m_safelyInitialized
|| m_thread
== WTF::currentThread() || WTF::isAtomicallyInitializedStaticMutexLockHeld();
55 bool m_safelyInitialized
;
56 ThreadIdentifier m_thread
;
60 // Use this to declare and define a static local variable (static T;) so that
61 // it is leaked so that its destructors are not called at exit.
62 #ifndef DEFINE_STATIC_LOCAL
65 #define DEFINE_STATIC_LOCAL(type, name, arguments) \
66 static StaticLocalVerifier name##StaticLocalVerifier; \
67 ASSERT(name##StaticLocalVerifier.isNotRacy()); \
68 static type& name = *new type arguments
70 #define DEFINE_STATIC_LOCAL(type, name, arguments) \
71 static type& name = *new type arguments
74 // Does the same as DEFINE_STATIC_LOCAL but without assertions.
75 // Use this when you are absolutely sure that it is safe but above
76 // assertions fail (e.g. called on multiple thread with a local lock).
77 #define DEFINE_STATIC_LOCAL_NOASSERT(type, name, arguments) \
78 static type& name = *new type arguments
82 // Use this to declare and define a static local pointer to a ref-counted object so that
83 // it is leaked so that the object's destructors are not called at exit.
84 // This macro should be used with ref-counted objects rather than DEFINE_STATIC_LOCAL macro,
85 // as this macro does not lead to an extra memory allocation.
86 #ifndef DEFINE_STATIC_REF
87 #define DEFINE_STATIC_REF(type, name, arguments) \
88 static type* name = PassRefPtr<type>(arguments).leakRef();
91 // Use this macro to declare and define a debug-only global variable that may have a
92 // non-trivial constructor and destructor. When building with clang, this will suppress
93 // warnings about global constructors and exit-time destructors.
96 #define DEFINE_DEBUG_ONLY_GLOBAL(type, name, arguments) \
97 _Pragma("clang diagnostic push") \
98 _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \
99 _Pragma("clang diagnostic ignored \"-Wexit-time-destructors\"") \
100 static type name arguments; \
101 _Pragma("clang diagnostic pop")
103 #define DEFINE_DEBUG_ONLY_GLOBAL(type, name, arguments) \
104 static type name arguments;
105 #endif // COMPILER(CLANG)
107 #define DEFINE_DEBUG_ONLY_GLOBAL(type, name, arguments)
111 * The reinterpret_cast<Type1*>([pointer to Type2]) expressions - where
112 * sizeof(Type1) > sizeof(Type2) - cause the following warning on ARM with GCC:
113 * increases required alignment of target type.
115 * An implicit or an extra static_cast<void*> bypasses the warning.
116 * For more info see the following bugzilla entries:
117 * - https://bugs.webkit.org/show_bug.cgi?id=38045
118 * - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43976
120 #if CPU(ARM) && COMPILER(GCC)
121 template<typename Type
>
122 bool isPointerTypeAlignmentOkay(Type
* ptr
)
124 return !(reinterpret_cast<intptr_t>(ptr
) % __alignof__(Type
));
127 template<typename TypePtr
>
128 TypePtr
reinterpret_cast_ptr(void* ptr
)
130 ASSERT(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr
>(ptr
)));
131 return reinterpret_cast<TypePtr
>(ptr
);
134 template<typename TypePtr
>
135 TypePtr
reinterpret_cast_ptr(const void* ptr
)
137 ASSERT(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr
>(ptr
)));
138 return reinterpret_cast<TypePtr
>(ptr
);
141 template<typename Type
>
142 bool isPointerTypeAlignmentOkay(Type
*)
146 #define reinterpret_cast_ptr reinterpret_cast
152 * C++'s idea of a reinterpret_cast lacks sufficient cojones.
154 template<typename TO
, typename FROM
>
155 inline TO
bitwise_cast(FROM from
)
157 static_assert(sizeof(TO
) == sizeof(FROM
), "WTF::bitwise_cast sizeof casted types should be equal");
166 template<typename To
, typename From
>
167 inline To
safeCast(From value
)
169 ASSERT(isInBounds
<To
>(value
));
170 return static_cast<To
>(value
);
173 // Macro that returns a compile time constant with the length of an array, but gives an error if passed a non-array.
174 template<typename T
, size_t Size
> char (&ArrayLengthHelperFunction(T (&)[Size
]))[Size
];
175 // GCC needs some help to deduce a 0 length array.
177 template<typename T
> char (&ArrayLengthHelperFunction(T (&)[0]))[0];
179 #define WTF_ARRAY_LENGTH(array) sizeof(::WTF::ArrayLengthHelperFunction(array))
183 // This version of placement new omits a 0 check.
184 enum NotNullTag
{ NotNull
};
185 inline void* operator new(size_t, NotNullTag
, void* location
)
191 using WTF::bitwise_cast
;
194 #endif // WTF_StdLibExtras_h