LCOV - code coverage report
Current view: top level - src/base - macros.h (source / functions) Hit Total Coverage
Test: app.info Lines: 11 11 100.0 %
Date: 2019-04-17 Functions: 4 4 100.0 %

          Line data    Source code
       1             : // Copyright 2014 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_BASE_MACROS_H_
       6             : #define V8_BASE_MACROS_H_
       7             : 
       8             : #include <limits>
       9             : 
      10             : #include "src/base/compiler-specific.h"
      11             : #include "src/base/format-macros.h"
      12             : #include "src/base/logging.h"
      13             : 
      14             : // No-op macro which is used to work around MSVC's funky VA_ARGS support.
      15             : #define EXPAND(x) x
      16             : 
      17             : // This macro does nothing. That's all.
      18             : #define NOTHING(...)
      19             : 
      20             : // TODO(all) Replace all uses of this macro with C++'s offsetof. To do that, we
      21             : // have to make sure that only standard-layout types and simple field
      22             : // designators are used.
      23             : #define OFFSET_OF(type, field) \
      24             :   (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(16)->field)) - 16)
      25             : 
      26             : 
      27             : // The arraysize(arr) macro returns the # of elements in an array arr.
      28             : // The expression is a compile-time constant, and therefore can be
      29             : // used in defining new arrays, for example.  If you use arraysize on
      30             : // a pointer by mistake, you will get a compile-time error.
      31             : #define arraysize(array) (sizeof(ArraySizeHelper(array)))
      32             : 
      33             : 
      34             : // This template function declaration is used in defining arraysize.
      35             : // Note that the function doesn't need an implementation, as we only
      36             : // use its type.
      37             : template <typename T, size_t N>
      38             : char (&ArraySizeHelper(T (&array)[N]))[N];
      39             : 
      40             : 
      41             : #if !V8_CC_MSVC
      42             : // That gcc wants both of these prototypes seems mysterious. VC, for
      43             : // its part, can't decide which to use (another mystery). Matching of
      44             : // template overloads: the final frontier.
      45             : template <typename T, size_t N>
      46             : char (&ArraySizeHelper(const T (&array)[N]))[N];
      47             : #endif
      48             : 
      49             : // bit_cast<Dest,Source> is a template function that implements the
      50             : // equivalent of "*reinterpret_cast<Dest*>(&source)".  We need this in
      51             : // very low-level functions like the protobuf library and fast math
      52             : // support.
      53             : //
      54             : //   float f = 3.14159265358979;
      55             : //   int i = bit_cast<int32>(f);
      56             : //   // i = 0x40490fdb
      57             : //
      58             : // The classical address-casting method is:
      59             : //
      60             : //   // WRONG
      61             : //   float f = 3.14159265358979;            // WRONG
      62             : //   int i = * reinterpret_cast<int*>(&f);  // WRONG
      63             : //
      64             : // The address-casting method actually produces undefined behavior
      65             : // according to ISO C++ specification section 3.10 -15 -.  Roughly, this
      66             : // section says: if an object in memory has one type, and a program
      67             : // accesses it with a different type, then the result is undefined
      68             : // behavior for most values of "different type".
      69             : //
      70             : // This is true for any cast syntax, either *(int*)&f or
      71             : // *reinterpret_cast<int*>(&f).  And it is particularly true for
      72             : // conversions between integral lvalues and floating-point lvalues.
      73             : //
      74             : // The purpose of 3.10 -15- is to allow optimizing compilers to assume
      75             : // that expressions with different types refer to different memory.  gcc
      76             : // 4.0.1 has an optimizer that takes advantage of this.  So a
      77             : // non-conforming program quietly produces wildly incorrect output.
      78             : //
      79             : // The problem is not the use of reinterpret_cast.  The problem is type
      80             : // punning: holding an object in memory of one type and reading its bits
      81             : // back using a different type.
      82             : //
      83             : // The C++ standard is more subtle and complex than this, but that
      84             : // is the basic idea.
      85             : //
      86             : // Anyways ...
      87             : //
      88             : // bit_cast<> calls memcpy() which is blessed by the standard,
      89             : // especially by the example in section 3.9 .  Also, of course,
      90             : // bit_cast<> wraps up the nasty logic in one place.
      91             : //
      92             : // Fortunately memcpy() is very fast.  In optimized mode, with a
      93             : // constant size, gcc 2.95.3, gcc 4.0.1, and msvc 7.1 produce inline
      94             : // code with the minimal amount of data movement.  On a 32-bit system,
      95             : // memcpy(d,s,4) compiles to one load and one store, and memcpy(d,s,8)
      96             : // compiles to two loads and two stores.
      97             : //
      98             : // I tested this code with gcc 2.95.3, gcc 4.0.1, icc 8.1, and msvc 7.1.
      99             : //
     100             : // WARNING: if Dest or Source is a non-POD type, the result of the memcpy
     101             : // is likely to surprise you.
     102             : template <class Dest, class Source>
     103             : V8_INLINE Dest bit_cast(Source const& source) {
     104             :   static_assert(sizeof(Dest) == sizeof(Source),
     105             :                 "source and dest must be same size");
     106     6433214 :   Dest dest;
     107             :   memcpy(&dest, &source, sizeof(dest));
     108             :   return dest;
     109             : }
     110             : 
     111             : // Explicitly declare the assignment operator as deleted.
     112             : #define DISALLOW_ASSIGN(TypeName) TypeName& operator=(const TypeName&) = delete
     113             : 
     114             : // Explicitly declare the copy constructor and assignment operator as deleted.
     115             : // This also deletes the implicit move constructor and implicit move assignment
     116             : // operator, but still allows to manually define them.
     117             : #define DISALLOW_COPY_AND_ASSIGN(TypeName) \
     118             :   TypeName(const TypeName&) = delete;      \
     119             :   DISALLOW_ASSIGN(TypeName)
     120             : 
     121             : // Explicitly declare all implicit constructors as deleted, namely the
     122             : // default constructor, copy constructor and operator= functions.
     123             : // This is especially useful for classes containing only static methods.
     124             : #define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
     125             :   TypeName() = delete;                           \
     126             :   DISALLOW_COPY_AND_ASSIGN(TypeName)
     127             : 
     128             : // Disallow copying a type, but provide default construction, move construction
     129             : // and move assignment. Especially useful for move-only structs.
     130             : #define MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(TypeName) \
     131             :   TypeName() = default;                               \
     132             :   MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(TypeName)
     133             : 
     134             : // Disallow copying a type, and only provide move construction and move
     135             : // assignment. Especially useful for move-only structs.
     136             : #define MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(TypeName)       \
     137             :   TypeName(TypeName&&) V8_NOEXCEPT = default;            \
     138             :   TypeName& operator=(TypeName&&) V8_NOEXCEPT = default; \
     139             :   DISALLOW_COPY_AND_ASSIGN(TypeName)
     140             : 
     141             : // A macro to disallow the dynamic allocation.
     142             : // This should be used in the private: declarations for a class
     143             : // Declaring operator new and delete as deleted is not spec compliant.
     144             : // Extract from 3.2.2 of C++11 spec:
     145             : //  [...] A non-placement deallocation function for a class is
     146             : //  odr-used by the definition of the destructor of that class, [...]
     147             : #define DISALLOW_NEW_AND_DELETE()                            \
     148             :   void* operator new(size_t) { base::OS::Abort(); }          \
     149             :   void* operator new[](size_t) { base::OS::Abort(); }        \
     150             :   void operator delete(void*, size_t) { base::OS::Abort(); } \
     151             :   void operator delete[](void*, size_t) { base::OS::Abort(); }
     152             : 
     153             : // Define V8_USE_ADDRESS_SANITIZER macro.
     154             : #if defined(__has_feature)
     155             : #if __has_feature(address_sanitizer)
     156             : #define V8_USE_ADDRESS_SANITIZER 1
     157             : #endif
     158             : #endif
     159             : 
     160             : // Define DISABLE_ASAN macro.
     161             : #ifdef V8_USE_ADDRESS_SANITIZER
     162             : #define DISABLE_ASAN __attribute__((no_sanitize_address))
     163             : #else
     164             : #define DISABLE_ASAN
     165             : #endif
     166             : 
     167             : // Define V8_USE_MEMORY_SANITIZER macro.
     168             : #if defined(__has_feature)
     169             : #if __has_feature(memory_sanitizer)
     170             : #define V8_USE_MEMORY_SANITIZER 1
     171             : #endif
     172             : #endif
     173             : 
     174             : // Helper macro to define no_sanitize attributes only with clang.
     175             : #if defined(__clang__) && defined(__has_attribute)
     176             : #if __has_attribute(no_sanitize)
     177             : #define CLANG_NO_SANITIZE(what) __attribute__((no_sanitize(what)))
     178             : #endif
     179             : #endif
     180             : #if !defined(CLANG_NO_SANITIZE)
     181             : #define CLANG_NO_SANITIZE(what)
     182             : #endif
     183             : 
     184             : // DISABLE_CFI_PERF -- Disable Control Flow Integrity checks for Perf reasons.
     185             : #define DISABLE_CFI_PERF CLANG_NO_SANITIZE("cfi")
     186             : 
     187             : // DISABLE_CFI_ICALL -- Disable Control Flow Integrity indirect call checks,
     188             : // useful because calls into JITed code can not be CFI verified.
     189             : #define DISABLE_CFI_ICALL CLANG_NO_SANITIZE("cfi-icall")
     190             : 
     191             : #if V8_CC_GNU
     192             : #define V8_IMMEDIATE_CRASH() __builtin_trap()
     193             : #else
     194             : #define V8_IMMEDIATE_CRASH() ((void(*)())0)()
     195             : #endif
     196             : 
     197             : // A convenience wrapper around static_assert without a string message argument.
     198             : // Once C++17 becomes the default, this macro can be removed in favor of the
     199             : // new static_assert(condition) overload.
     200             : #define STATIC_ASSERT(test) static_assert(test, #test)
     201             : 
     202             : namespace v8 {
     203             : namespace base {
     204             : 
     205             : // Note that some implementations of std::is_trivially_copyable mandate that at
     206             : // least one of the copy constructor, move constructor, copy assignment or move
     207             : // assignment is non-deleted, while others do not. Be aware that also
     208             : // base::is_trivially_copyable will differ for these cases.
     209             : template <typename T>
     210             : struct is_trivially_copyable {
     211             : #if V8_CC_MSVC
     212             :   // Unfortunately, MSVC 2015 is broken in that std::is_trivially_copyable can
     213             :   // be false even though it should be true according to the standard.
     214             :   // (status at 2018-02-26, observed on the msvc waterfall bot).
     215             :   // Interestingly, the lower-level primitives used below are working as
     216             :   // intended, so we reimplement this according to the standard.
     217             :   // See also https://developercommunity.visualstudio.com/content/problem/
     218             :   //          170883/msvc-type-traits-stdis-trivial-is-bugged.html.
     219             :   static constexpr bool value =
     220             :       // Copy constructor is trivial or deleted.
     221             :       (std::is_trivially_copy_constructible<T>::value ||
     222             :        !std::is_copy_constructible<T>::value) &&
     223             :       // Copy assignment operator is trivial or deleted.
     224             :       (std::is_trivially_copy_assignable<T>::value ||
     225             :        !std::is_copy_assignable<T>::value) &&
     226             :       // Move constructor is trivial or deleted.
     227             :       (std::is_trivially_move_constructible<T>::value ||
     228             :        !std::is_move_constructible<T>::value) &&
     229             :       // Move assignment operator is trivial or deleted.
     230             :       (std::is_trivially_move_assignable<T>::value ||
     231             :        !std::is_move_assignable<T>::value) &&
     232             :       // (Some implementations mandate that one of the above is non-deleted, but
     233             :       // the standard does not, so let's skip this check.)
     234             :       // Trivial non-deleted destructor.
     235             :       std::is_trivially_destructible<T>::value;
     236             : 
     237             : #elif defined(__GNUC__) && __GNUC__ < 5
     238             :   // WARNING:
     239             :   // On older libstdc++ versions, there is no way to correctly implement
     240             :   // is_trivially_copyable. The workaround below is an approximation (neither
     241             :   // over- nor underapproximation). E.g. it wrongly returns true if the move
     242             :   // constructor is non-trivial, and it wrongly returns false if the copy
     243             :   // constructor is deleted, but copy assignment is trivial.
     244             :   // TODO(rongjie) Remove this workaround once we require gcc >= 5.0
     245             :   static constexpr bool value =
     246             :       __has_trivial_copy(T) && __has_trivial_destructor(T);
     247             : 
     248             : #else
     249             :   static constexpr bool value = std::is_trivially_copyable<T>::value;
     250             : #endif
     251             : };
     252             : #if defined(__GNUC__) && __GNUC__ < 5
     253             : // On older libstdc++ versions, base::is_trivially_copyable<T>::value is only an
     254             : // approximation (see above), so make ASSERT_{NOT_,}TRIVIALLY_COPYABLE a noop.
     255             : #define ASSERT_TRIVIALLY_COPYABLE(T) static_assert(true, "check disabled")
     256             : #define ASSERT_NOT_TRIVIALLY_COPYABLE(T) static_assert(true, "check disabled")
     257             : #else
     258             : #define ASSERT_TRIVIALLY_COPYABLE(T)                         \
     259             :   static_assert(::v8::base::is_trivially_copyable<T>::value, \
     260             :                 #T " should be trivially copyable")
     261             : #define ASSERT_NOT_TRIVIALLY_COPYABLE(T)                      \
     262             :   static_assert(!::v8::base::is_trivially_copyable<T>::value, \
     263             :                 #T " should not be trivially copyable")
     264             : #endif
     265             : 
     266             : // The USE(x, ...) template is used to silence C++ compiler warnings
     267             : // issued for (yet) unused variables (typically parameters).
     268             : // The arguments are guaranteed to be evaluated from left to right.
     269             : struct Use {
     270             :   template <typename T>
     271   496417650 :   Use(T&&) {}  // NOLINT(runtime/explicit)
     272             : };
     273             : #define USE(...)                                                   \
     274             :   do {                                                             \
     275             :     ::v8::base::Use unused_tmp_array_for_use_macro[]{__VA_ARGS__}; \
     276             :     (void)unused_tmp_array_for_use_macro;                          \
     277             :   } while (false)
     278             : 
     279             : // Evaluate the instantiations of an expression with parameter packs.
     280             : // Since USE has left-to-right evaluation order of it's arguments,
     281             : // the parameter pack is iterated from left to right and side effects
     282             : // have defined behavior.
     283             : #define ITERATE_PACK(...) USE(0, ((__VA_ARGS__), 0)...)
     284             : 
     285             : }  // namespace base
     286             : }  // namespace v8
     287             : 
     288             : // implicit_cast<A>(x) triggers an implicit cast from {x} to type {A}. This is
     289             : // useful in situations where static_cast<A>(x) would do too much.
     290             : // Only use this for cheap-to-copy types, or use move semantics explicitly.
     291             : template <class A>
     292             : V8_INLINE A implicit_cast(A x) {
     293             :   return x;
     294             : }
     295             : 
     296             : // Define our own macros for writing 64-bit constants.  This is less fragile
     297             : // than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it
     298             : // works on compilers that don't have it (like MSVC).
     299             : #if V8_CC_MSVC
     300             : # if V8_HOST_ARCH_64_BIT
     301             : #  define V8_PTR_PREFIX   "ll"
     302             : # else
     303             : #  define V8_PTR_PREFIX   ""
     304             : # endif  // V8_HOST_ARCH_64_BIT
     305             : #elif V8_CC_MINGW64
     306             : # define V8_PTR_PREFIX    "I64"
     307             : #elif V8_HOST_ARCH_64_BIT
     308             : # define V8_PTR_PREFIX    "l"
     309             : #else
     310             : #if V8_OS_AIX
     311             : #define V8_PTR_PREFIX "l"
     312             : #else
     313             : # define V8_PTR_PREFIX    ""
     314             : #endif
     315             : #endif
     316             : 
     317             : #define V8PRIxPTR V8_PTR_PREFIX "x"
     318             : #define V8PRIdPTR V8_PTR_PREFIX "d"
     319             : #define V8PRIuPTR V8_PTR_PREFIX "u"
     320             : 
     321             : #if V8_TARGET_ARCH_64_BIT
     322             : #define V8_PTR_HEX_DIGITS 12
     323             : #define V8PRIxPTR_FMT "0x%012" V8PRIxPTR
     324             : #else
     325             : #define V8_PTR_HEX_DIGITS 8
     326             : #define V8PRIxPTR_FMT "0x%08" V8PRIxPTR
     327             : #endif
     328             : 
     329             : // ptrdiff_t is 't' according to the standard, but MSVC uses 'I'.
     330             : #if V8_CC_MSVC
     331             : #define V8PRIxPTRDIFF "Ix"
     332             : #define V8PRIdPTRDIFF "Id"
     333             : #define V8PRIuPTRDIFF "Iu"
     334             : #else
     335             : #define V8PRIxPTRDIFF "tx"
     336             : #define V8PRIdPTRDIFF "td"
     337             : #define V8PRIuPTRDIFF "tu"
     338             : #endif
     339             : 
     340             : // Fix for Mac OS X defining uintptr_t as "unsigned long":
     341             : #if V8_OS_MACOSX
     342             : #undef V8PRIxPTR
     343             : #define V8PRIxPTR "lx"
     344             : #undef V8PRIdPTR
     345             : #define V8PRIdPTR "ld"
     346             : #undef V8PRIuPTR
     347             : #define V8PRIuPTR "lxu"
     348             : #endif
     349             : 
     350             : // The following macro works on both 32 and 64-bit platforms.
     351             : // Usage: instead of writing 0x1234567890123456
     352             : //      write V8_2PART_UINT64_C(0x12345678,90123456);
     353             : #define V8_2PART_UINT64_C(a, b) (((static_cast<uint64_t>(a) << 32) + 0x##b##u))
     354             : 
     355             : // Return the largest multiple of m which is <= x.
     356             : template <typename T>
     357             : inline T RoundDown(T x, intptr_t m) {
     358             :   STATIC_ASSERT(std::is_integral<T>::value);
     359             :   // m must be a power of two.
     360             :   DCHECK(m != 0 && ((m & (m - 1)) == 0));
     361  4359672627 :   return x & -m;
     362             : }
     363             : template <intptr_t m, typename T>
     364             : constexpr inline T RoundDown(T x) {
     365             :   STATIC_ASSERT(std::is_integral<T>::value);
     366             :   // m must be a power of two.
     367             :   STATIC_ASSERT(m != 0 && ((m & (m - 1)) == 0));
     368    15527460 :   return x & -m;
     369             : }
     370             : 
     371             : // Return the smallest multiple of m which is >= x.
     372             : template <typename T>
     373         310 : inline T RoundUp(T x, intptr_t m) {
     374             :   STATIC_ASSERT(std::is_integral<T>::value);
     375  4336469002 :   return RoundDown<T>(static_cast<T>(x + m - 1), m);
     376             : }
     377             : template <intptr_t m, typename T>
     378             : constexpr inline T RoundUp(T x) {
     379             :   STATIC_ASSERT(std::is_integral<T>::value);
     380    15527460 :   return RoundDown<m, T>(static_cast<T>(x + (m - 1)));
     381             : }
     382             : 
     383             : template <typename T, typename U>
     384             : constexpr inline bool IsAligned(T value, U alignment) {
     385    40035222 :   return (value & (alignment - 1)) == 0;
     386             : }
     387             : 
     388             : inline void* AlignedAddress(void* address, size_t alignment) {
     389             :   // The alignment must be a power of two.
     390             :   DCHECK_EQ(alignment & (alignment - 1), 0u);
     391     3313726 :   return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(address) &
     392     3313726 :                                  ~static_cast<uintptr_t>(alignment - 1));
     393             : }
     394             : 
     395             : // Bounds checks for float to integer conversions, which does truncation. Hence,
     396             : // the range of legal values is (min - 1, max + 1).
     397             : template <typename int_t, typename float_t, typename biggest_int_t = int64_t>
     398             : bool is_inbounds(float_t v) {
     399             :   static_assert(sizeof(int_t) < sizeof(biggest_int_t),
     400             :                 "int_t can't be bounds checked by the compiler");
     401             :   constexpr float_t kLowerBound =
     402             :       static_cast<float_t>(std::numeric_limits<int_t>::min()) - 1;
     403             :   constexpr float_t kUpperBound =
     404             :       static_cast<float_t>(std::numeric_limits<int_t>::max()) + 1;
     405             :   constexpr bool kLowerBoundIsMin =
     406             :       static_cast<biggest_int_t>(kLowerBound) ==
     407             :       static_cast<biggest_int_t>(std::numeric_limits<int_t>::min());
     408             :   constexpr bool kUpperBoundIsMax =
     409             :       static_cast<biggest_int_t>(kUpperBound) ==
     410             :       static_cast<biggest_int_t>(std::numeric_limits<int_t>::max());
     411             :   return (kLowerBoundIsMin ? (kLowerBound <= v) : (kLowerBound < v)) &&
     412       10648 :          (kUpperBoundIsMax ? (v <= kUpperBound) : (v < kUpperBound));
     413             : }
     414             : 
     415             : #ifdef V8_OS_WIN
     416             : 
     417             : // Setup for Windows shared library export.
     418             : #ifdef BUILDING_V8_SHARED
     419             : #define V8_EXPORT_PRIVATE __declspec(dllexport)
     420             : #elif USING_V8_SHARED
     421             : #define V8_EXPORT_PRIVATE __declspec(dllimport)
     422             : #else
     423             : #define V8_EXPORT_PRIVATE
     424             : #endif  // BUILDING_V8_SHARED
     425             : 
     426             : #else  // V8_OS_WIN
     427             : 
     428             : // Setup for Linux shared library export.
     429             : #if V8_HAS_ATTRIBUTE_VISIBILITY
     430             : #ifdef BUILDING_V8_SHARED
     431             : #define V8_EXPORT_PRIVATE __attribute__((visibility("default")))
     432             : #else
     433             : #define V8_EXPORT_PRIVATE
     434             : #endif
     435             : #else
     436             : #define V8_EXPORT_PRIVATE
     437             : #endif
     438             : 
     439             : #endif  // V8_OS_WIN
     440             : 
     441             : #endif  // V8_BASE_MACROS_H_

Generated by: LCOV version 1.10