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 39template <bool> 40struct 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. 76template <typename T, size_t N> 77char (&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 157template<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