| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. | 2 * Copyright (C) 2008 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 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 #include "wtf/Assertions.h" | 29 #include "wtf/Assertions.h" |
| 30 #include "wtf/CPU.h" | 30 #include "wtf/CPU.h" |
| 31 #include "wtf/CheckedArithmetic.h" | 31 #include "wtf/CheckedArithmetic.h" |
| 32 #include <cstddef> | 32 #include <cstddef> |
| 33 | 33 |
| 34 #if ENABLE(ASSERT) | 34 #if ENABLE(ASSERT) |
| 35 #include "wtf/Noncopyable.h" | 35 #include "wtf/Noncopyable.h" |
| 36 #include "wtf/Threading.h" | 36 #include "wtf/Threading.h" |
| 37 | 37 |
| 38 class WTF_EXPORT StaticLocalVerifier { | 38 class WTF_EXPORT StaticLocalVerifier { |
| 39 WTF_MAKE_NONCOPYABLE(StaticLocalVerifier); | 39 WTF_MAKE_NONCOPYABLE(StaticLocalVerifier); |
| 40 public: | |
| 41 StaticLocalVerifier() | |
| 42 : m_safelyInitialized(WTF::isBeforeThreadCreated()) | |
| 43 , m_thread(WTF::currentThread()) | |
| 44 { | |
| 45 } | |
| 46 | 40 |
| 47 bool isNotRacy() | 41 public: |
| 48 { | 42 StaticLocalVerifier() |
| 49 // Make sure that this 1) is safely initialized, 2) keeps being called | 43 : m_safelyInitialized(WTF::isBeforeThreadCreated()), m_thread(WTF::current
Thread()) { |
| 50 // on the same thread, or 3) is called within | 44 } |
| 51 // AtomicallyInitializedStatic (i.e. with a lock held). | |
| 52 return m_safelyInitialized || m_thread == WTF::currentThread() || WTF::i
sAtomicallyInitializedStaticMutexLockHeld(); | |
| 53 } | |
| 54 | 45 |
| 55 private: | 46 bool isNotRacy() { |
| 56 bool m_safelyInitialized; | 47 // Make sure that this 1) is safely initialized, 2) keeps being called |
| 57 ThreadIdentifier m_thread; | 48 // on the same thread, or 3) is called within |
| 49 // AtomicallyInitializedStatic (i.e. with a lock held). |
| 50 return m_safelyInitialized || m_thread == WTF::currentThread() || WTF::isAto
micallyInitializedStaticMutexLockHeld(); |
| 51 } |
| 52 |
| 53 private: |
| 54 bool m_safelyInitialized; |
| 55 ThreadIdentifier m_thread; |
| 58 }; | 56 }; |
| 59 #endif | 57 #endif |
| 60 | 58 |
| 61 // Use this to declare and define a static local variable (static T;) so that | 59 // Use this to declare and define a static local variable (static T;) so that |
| 62 // it is leaked so that its destructors are not called at exit. | 60 // it is leaked so that its destructors are not called at exit. |
| 63 #ifndef DEFINE_STATIC_LOCAL | 61 #ifndef DEFINE_STATIC_LOCAL |
| 64 | 62 |
| 65 #if ENABLE(ASSERT) | 63 #if ENABLE(ASSERT) |
| 66 #define DEFINE_STATIC_LOCAL(type, name, arguments) \ | 64 #define DEFINE_STATIC_LOCAL(type, name, arguments) \ |
| 67 static StaticLocalVerifier name##StaticLocalVerifier; \ | 65 static StaticLocalVerifier name##StaticLocalVerifier; \ |
| 68 ASSERT(name##StaticLocalVerifier.isNotRacy()); \ | 66 ASSERT(name##StaticLocalVerifier.isNotRacy()); \ |
| 69 static type& name = *new type arguments | 67 static type& name = *new type arguments |
| 70 #else | 68 #else |
| 71 #define DEFINE_STATIC_LOCAL(type, name, arguments) \ | 69 #define DEFINE_STATIC_LOCAL(type, name, arguments) \ |
| 72 static type& name = *new type arguments | 70 static type& name = *new type arguments |
| 73 #endif | 71 #endif |
| 74 | 72 |
| 75 #endif | 73 #endif |
| 76 | 74 |
| 77 | |
| 78 // Use this to declare and define a static local pointer to a ref-counted object
so that | 75 // Use this to declare and define a static local pointer to a ref-counted object
so that |
| 79 // it is leaked so that the object's destructors are not called at exit. | 76 // it is leaked so that the object's destructors are not called at exit. |
| 80 // This macro should be used with ref-counted objects rather than DEFINE_STATIC_
LOCAL macro, | 77 // This macro should be used with ref-counted objects rather than DEFINE_STATIC_
LOCAL macro, |
| 81 // as this macro does not lead to an extra memory allocation. | 78 // as this macro does not lead to an extra memory allocation. |
| 82 #ifndef DEFINE_STATIC_REF | 79 #ifndef DEFINE_STATIC_REF |
| 83 #define DEFINE_STATIC_REF(type, name, arguments) \ | 80 #define DEFINE_STATIC_REF(type, name, arguments) \ |
| 84 static type* name = PassRefPtr<type>(arguments).leakRef(); | 81 static type* name = PassRefPtr<type>(arguments).leakRef(); |
| 85 #endif | 82 #endif |
| 86 | 83 |
| 87 /* | 84 /* |
| 88 * The reinterpret_cast<Type1*>([pointer to Type2]) expressions - where | 85 * The reinterpret_cast<Type1*>([pointer to Type2]) expressions - where |
| 89 * sizeof(Type1) > sizeof(Type2) - cause the following warning on ARM with GCC: | 86 * sizeof(Type1) > sizeof(Type2) - cause the following warning on ARM with GCC: |
| 90 * increases required alignment of target type. | 87 * increases required alignment of target type. |
| 91 * | 88 * |
| 92 * An implicit or an extra static_cast<void*> bypasses the warning. | 89 * An implicit or an extra static_cast<void*> bypasses the warning. |
| 93 * For more info see the following bugzilla entries: | 90 * For more info see the following bugzilla entries: |
| 94 * - https://bugs.webkit.org/show_bug.cgi?id=38045 | 91 * - https://bugs.webkit.org/show_bug.cgi?id=38045 |
| 95 * - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43976 | 92 * - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43976 |
| 96 */ | 93 */ |
| 97 #if CPU(ARM) && COMPILER(GCC) | 94 #if CPU(ARM) && COMPILER(GCC) |
| 98 template<typename Type> | 95 template <typename Type> |
| 99 bool isPointerTypeAlignmentOkay(Type* ptr) | 96 bool isPointerTypeAlignmentOkay(Type* ptr) { |
| 100 { | 97 return !(reinterpret_cast<intptr_t>(ptr) % __alignof__(Type)); |
| 101 return !(reinterpret_cast<intptr_t>(ptr) % __alignof__(Type)); | |
| 102 } | 98 } |
| 103 | 99 |
| 104 template<typename TypePtr> | 100 template <typename TypePtr> |
| 105 TypePtr reinterpret_cast_ptr(void* ptr) | 101 TypePtr reinterpret_cast_ptr(void* ptr) { |
| 106 { | 102 ASSERT(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr))); |
| 107 ASSERT(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr))); | 103 return reinterpret_cast<TypePtr>(ptr); |
| 108 return reinterpret_cast<TypePtr>(ptr); | |
| 109 } | 104 } |
| 110 | 105 |
| 111 template<typename TypePtr> | 106 template <typename TypePtr> |
| 112 TypePtr reinterpret_cast_ptr(const void* ptr) | 107 TypePtr reinterpret_cast_ptr(const void* ptr) { |
| 113 { | 108 ASSERT(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr))); |
| 114 ASSERT(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr))); | 109 return reinterpret_cast<TypePtr>(ptr); |
| 115 return reinterpret_cast<TypePtr>(ptr); | |
| 116 } | 110 } |
| 117 #else | 111 #else |
| 118 template<typename Type> | 112 template <typename Type> |
| 119 bool isPointerTypeAlignmentOkay(Type*) | 113 bool isPointerTypeAlignmentOkay(Type*) { |
| 120 { | 114 return true; |
| 121 return true; | |
| 122 } | 115 } |
| 123 #define reinterpret_cast_ptr reinterpret_cast | 116 #define reinterpret_cast_ptr reinterpret_cast |
| 124 #endif | 117 #endif |
| 125 | 118 |
| 126 namespace WTF { | 119 namespace WTF { |
| 127 | 120 |
| 128 /* | 121 /* |
| 129 * C++'s idea of a reinterpret_cast lacks sufficient cojones. | 122 * C++'s idea of a reinterpret_cast lacks sufficient cojones. |
| 130 */ | 123 */ |
| 131 template<typename TO, typename FROM> | 124 template <typename TO, typename FROM> |
| 132 inline TO bitwise_cast(FROM from) | 125 inline TO bitwise_cast(FROM from) { |
| 133 { | 126 static_assert(sizeof(TO) == sizeof(FROM), "WTF::bitwise_cast sizeof casted typ
es should be equal"); |
| 134 static_assert(sizeof(TO) == sizeof(FROM), "WTF::bitwise_cast sizeof casted t
ypes should be equal"); | 127 union { |
| 135 union { | 128 FROM from; |
| 136 FROM from; | 129 TO to; |
| 137 TO to; | 130 } u; |
| 138 } u; | 131 u.from = from; |
| 139 u.from = from; | 132 return u.to; |
| 140 return u.to; | |
| 141 } | 133 } |
| 142 | 134 |
| 143 template<typename To, typename From> | 135 template <typename To, typename From> |
| 144 inline To safeCast(From value) | 136 inline To safeCast(From value) { |
| 145 { | 137 ASSERT(isInBounds<To>(value)); |
| 146 ASSERT(isInBounds<To>(value)); | 138 return static_cast<To>(value); |
| 147 return static_cast<To>(value); | |
| 148 } | 139 } |
| 149 | 140 |
| 150 // Macro that returns a compile time constant with the length of an array, but g
ives an error if passed a non-array. | 141 // Macro that returns a compile time constant with the length of an array, but g
ives an error if passed a non-array. |
| 151 template<typename T, size_t Size> char (&ArrayLengthHelperFunction(T (&)[Size]))
[Size]; | 142 template <typename T, size_t Size> |
| 143 char(&ArrayLengthHelperFunction(T(&)[Size]))[Size]; |
| 152 // GCC needs some help to deduce a 0 length array. | 144 // GCC needs some help to deduce a 0 length array. |
| 153 #if COMPILER(GCC) | 145 #if COMPILER(GCC) |
| 154 template<typename T> char (&ArrayLengthHelperFunction(T (&)[0]))[0]; | 146 template <typename T> |
| 147 char(&ArrayLengthHelperFunction(T(&)[0]))[0]; |
| 155 #endif | 148 #endif |
| 156 #define WTF_ARRAY_LENGTH(array) sizeof(::WTF::ArrayLengthHelperFunction(array)) | 149 #define WTF_ARRAY_LENGTH(array) sizeof(::WTF::ArrayLengthHelperFunction(array)) |
| 157 | 150 |
| 158 } // namespace WTF | 151 } // namespace WTF |
| 159 | 152 |
| 160 // This version of placement new omits a 0 check. | 153 // This version of placement new omits a 0 check. |
| 161 enum NotNullTag { NotNull }; | 154 enum NotNullTag { NotNull }; |
| 162 inline void* operator new(size_t, NotNullTag, void* location) | 155 inline void* operator new(size_t, NotNullTag, void* location) { |
| 163 { | 156 ASSERT(location); |
| 164 ASSERT(location); | 157 return location; |
| 165 return location; | |
| 166 } | 158 } |
| 167 | 159 |
| 168 using WTF::bitwise_cast; | 160 using WTF::bitwise_cast; |
| 169 using WTF::safeCast; | 161 using WTF::safeCast; |
| 170 | 162 |
| 171 #endif // WTF_StdLibExtras_h | 163 #endif // WTF_StdLibExtras_h |
| OLD | NEW |