1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_RUNTIME_BASE_MACROS_H_ 18 #define ART_RUNTIME_BASE_MACROS_H_ 19 20 #include <stddef.h> // for size_t 21 22 #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) 23 24 // The COMPILE_ASSERT macro can be used to verify that a compile time 25 // expression is true. For example, you could use it to verify the 26 // size of a static array: 27 // 28 // COMPILE_ASSERT(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, 29 // content_type_names_incorrect_size); 30 // 31 // or to make sure a struct is smaller than a certain size: 32 // 33 // COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large); 34 // 35 // The second argument to the macro is the name of the variable. If 36 // the expression is false, most compilers will issue a warning/error 37 // containing the name of the variable. 38 39 template <bool> 40 struct CompileAssert { 41 }; 42 43 #define COMPILE_ASSERT(expr, msg) \ 44 typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] // NOLINT 45 46 // DISALLOW_COPY_AND_ASSIGN disallows the copy and operator= functions. 47 // It goes in the private: declarations in a class. 48 #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ 49 TypeName(const TypeName&); \ 50 void operator=(const TypeName&) 51 52 // A macro to disallow all the implicit constructors, namely the 53 // default constructor, copy constructor and operator= functions. 54 // 55 // This should be used in the private: declarations for a class 56 // that wants to prevent anyone from instantiating it. This is 57 // especially useful for classes containing only static methods. 58 #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ 59 TypeName(); \ 60 DISALLOW_COPY_AND_ASSIGN(TypeName) 61 62 // The arraysize(arr) macro returns the # of elements in an array arr. 63 // The expression is a compile-time constant, and therefore can be 64 // used in defining new arrays, for example. If you use arraysize on 65 // a pointer by mistake, you will get a compile-time error. 66 // 67 // One caveat is that arraysize() doesn't accept any array of an 68 // anonymous type or a type defined inside a function. In these rare 69 // cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below. This is 70 // due to a limitation in C++'s template system. The limitation might 71 // eventually be removed, but it hasn't happened yet. 72 73 // This template function declaration is used in defining arraysize. 74 // Note that the function doesn't need an implementation, as we only 75 // use its type. 76 template <typename T, size_t N> 77 char (&ArraySizeHelper(T (&array)[N]))[N]; 78 79 #define arraysize(array) (sizeof(ArraySizeHelper(array))) 80 81 // ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize, 82 // but can be used on anonymous types or types defined inside 83 // functions. It's less safe than arraysize as it accepts some 84 // (although not all) pointers. Therefore, you should use arraysize 85 // whenever possible. 86 // 87 // The expression ARRAYSIZE_UNSAFE(a) is a compile-time constant of type 88 // size_t. 89 // 90 // ARRAYSIZE_UNSAFE catches a few type errors. If you see a compiler error 91 // 92 // "warning: division by zero in ..." 93 // 94 // when using ARRAYSIZE_UNSAFE, you are (wrongfully) giving it a pointer. 95 // You should only use ARRAYSIZE_UNSAFE on statically allocated arrays. 96 // 97 // The following comments are on the implementation details, and can 98 // be ignored by the users. 99 // 100 // ARRAYSIZE_UNSAFE(arr) works by inspecting sizeof(arr) (the # of bytes in 101 // the array) and sizeof(*(arr)) (the # of bytes in one array 102 // element). If the former is divisible by the latter, perhaps arr is 103 // indeed an array, in which case the division result is the # of 104 // elements in the array. Otherwise, arr cannot possibly be an array, 105 // and we generate a compiler error to prevent the code from 106 // compiling. 107 // 108 // Since the size of bool is implementation-defined, we need to cast 109 // !(sizeof(a) & sizeof(*(a))) to size_t in order to ensure the final 110 // result has type size_t. 111 // 112 // This macro is not perfect as it wrongfully accepts certain 113 // pointers, namely where the pointer size is divisible by the pointee 114 // size. Since all our code has to go through a 32-bit compiler, 115 // where a pointer is 4 bytes, this means all pointers to a type whose 116 // size is 3 or greater than 4 will be (righteously) rejected. 117 #define ARRAYSIZE_UNSAFE(a) \ 118 ((sizeof(a) / sizeof(*(a))) / static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))) 119 120 #define SIZEOF_MEMBER(t, f) sizeof((reinterpret_cast<t*>(4096))->f) 121 122 #define OFFSETOF_MEMBER(t, f) \ 123 (reinterpret_cast<const char*>(&reinterpret_cast<t*>(16)->f) - reinterpret_cast<const char*>(16)) // NOLINT 124 125 #define OFFSETOF_VOLATILE_MEMBER(t, f) \ 126 (reinterpret_cast<volatile char*>(&reinterpret_cast<t*>(16)->f) - reinterpret_cast<volatile char*>(16)) // NOLINT 127 128 #define PACKED(x) __attribute__ ((__aligned__(x), __packed__)) 129 130 #define LIKELY(x) __builtin_expect((x), true) 131 #define UNLIKELY(x) __builtin_expect((x), false) 132 133 #ifndef NDEBUG 134 #define ALWAYS_INLINE 135 #else 136 #define ALWAYS_INLINE __attribute__ ((always_inline)) 137 #endif 138 139 #if defined (__APPLE__) 140 #define HOT_ATTR 141 #else 142 #define HOT_ATTR __attribute__ ((hot)) 143 #endif 144 145 #define PURE __attribute__ ((__pure__)) 146 147 // bionic and glibc both have TEMP_FAILURE_RETRY, but Mac OS' libc doesn't. 148 #ifndef TEMP_FAILURE_RETRY 149 #define TEMP_FAILURE_RETRY(exp) ({ \ 150 typeof(exp) _rc; \ 151 do { \ 152 _rc = (exp); \ 153 } while (_rc == -1 && errno == EINTR); \ 154 _rc; }) 155 #endif 156 157 template<typename T> void UNUSED(const T&) {} 158 159 #if defined(__SUPPORT_TS_ANNOTATION__) 160 161 #define ACQUIRED_AFTER(...) __attribute__ ((acquired_after(__VA_ARGS__))) 162 #define ACQUIRED_BEFORE(...) __attribute__ ((acquired_before(__VA_ARGS__))) 163 #define EXCLUSIVE_LOCK_FUNCTION(...) __attribute__ ((exclusive_lock(__VA_ARGS__))) 164 #define EXCLUSIVE_LOCKS_REQUIRED(...) __attribute__ ((exclusive_locks_required(__VA_ARGS__))) 165 #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__ ((exclusive_trylock(__VA_ARGS__))) 166 #define GUARDED_BY(x) __attribute__ ((guarded_by(x))) 167 #define GUARDED_VAR __attribute__ ((guarded)) 168 #define LOCKABLE __attribute__ ((lockable)) 169 #define LOCK_RETURNED(x) __attribute__ ((lock_returned(x))) 170 #define LOCKS_EXCLUDED(...) __attribute__ ((locks_excluded(__VA_ARGS__))) 171 #define NO_THREAD_SAFETY_ANALYSIS __attribute__ ((no_thread_safety_analysis)) 172 #define PT_GUARDED_BY(x) __attribute__ ((point_to_guarded_by(x))) 173 #define PT_GUARDED_VAR __attribute__ ((point_to_guarded)) 174 #define SCOPED_LOCKABLE __attribute__ ((scoped_lockable)) 175 #define SHARED_LOCK_FUNCTION(...) __attribute__ ((shared_lock(__VA_ARGS__))) 176 #define SHARED_LOCKS_REQUIRED(...) __attribute__ ((shared_locks_required(__VA_ARGS__))) 177 #define SHARED_TRYLOCK_FUNCTION(...) __attribute__ ((shared_trylock(__VA_ARGS__))) 178 #define UNLOCK_FUNCTION(...) __attribute__ ((unlock(__VA_ARGS__))) 179 180 #else 181 182 #define ACQUIRED_AFTER(...) 183 #define ACQUIRED_BEFORE(...) 184 #define EXCLUSIVE_LOCK_FUNCTION(...) 185 #define EXCLUSIVE_LOCKS_REQUIRED(...) 186 #define EXCLUSIVE_TRYLOCK_FUNCTION(...) 187 #define GUARDED_BY(x) 188 #define GUARDED_VAR 189 #define LOCKABLE 190 #define LOCK_RETURNED(x) 191 #define LOCKS_EXCLUDED(...) 192 #define NO_THREAD_SAFETY_ANALYSIS 193 #define PT_GUARDED_BY(x) 194 #define PT_GUARDED_VAR 195 #define SCOPED_LOCKABLE 196 #define SHARED_LOCK_FUNCTION(...) 197 #define SHARED_LOCKS_REQUIRED(...) 198 #define SHARED_TRYLOCK_FUNCTION(...) 199 #define UNLOCK_FUNCTION(...) 200 201 #endif // defined(__SUPPORT_TS_ANNOTATION__) 202 203 #endif // ART_RUNTIME_BASE_MACROS_H_ 204