jitcraft/Utility.h
author David Anderson <dvander@alliedmods.net>
Mon Jul 02 23:37:12 2012 -0700 (2012-07-02)
changeset 28 a9665857cfd5
parent 11 a350c2cc736a
child 49 a92afa7484fd
permissions -rw-r--r--
Added MacOS, gcc, and clang support. Preliminary crappy autoconf scripts of course.
     1 /*
     2  * Copyright (C) 2012 David Anderson
     3  *
     4  * This file is part of JITCraft.
     5  *
     6  * JITCraft is free software: you can redistribute it and/or modify it under
     7  * the terms of the GNU General Public License as published by the Free
     8  * Software Foundation, either version 3 of the License, or (at your option)
     9  * any later version.
    10  * 
    11  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License along with
    16  * JITCraft. If not, see http://www.gnu.org/licenses/.
    17  */
    18 #ifndef _include_jitcraft_utility_h_
    19 #define _include_jitcraft_utility_h_
    20 
    21 #include <assert.h>
    22 #include <stdint.h>
    23 #ifdef _MSC_VER
    24 # include <intrin.h>
    25 #endif
    26 
    27 #ifdef _MSC_VER
    28 # pragma warning(disable:4355)
    29 #endif
    30 
    31 namespace jc {
    32 
    33 static const size_t kMallocAlignment = sizeof(void *) * 2;
    34 
    35 typedef uint8_t uint8;
    36 typedef int32_t int32;
    37 typedef uint32_t uint32;
    38 
    39 typedef uint8 * Address;
    40 
    41 static const size_t kKB = 1024;
    42 static const size_t kMB = 1024 * kKB;
    43 static const size_t kGB = 1024 * kMB;
    44 
    45 template <typename T>
    46 class AutoVec
    47 {
    48     T *t_;
    49 
    50   public:
    51     AutoVec()
    52       : t_(NULL)
    53     {
    54     }
    55     AutoVec(T *t)
    56       : t_(t)
    57     {
    58     }
    59     ~AutoVec() {
    60         delete [] t_;
    61     }
    62     operator T *() {
    63         return t_;
    64     }
    65     void operator =(T *t) {
    66         if (t_)
    67             delete [] t_;
    68         t_ = t;
    69     }
    70 };
    71 
    72 static inline size_t
    73 Log2(size_t number)
    74 {
    75     assert(number != 0);
    76 
    77 #ifdef MSC_VER
    78     unsigned long rval;
    79     _BitScanReverse(&rval, number);
    80     return rval;
    81 #else
    82 	size_t bit;
    83 	asm("bsr %1, %0\n"
    84 		: "=r" (bit)
    85 		: "rm" (number));
    86 	return bit;
    87 #endif
    88 }
    89 
    90 static inline bool
    91 IsPowerOfTwo(size_t value)
    92 {
    93     if (value == 0)
    94         return false;
    95     return !(value & (value - 1));
    96 }
    97 
    98 static inline size_t
    99 Align(size_t count, size_t alignment)
   100 {
   101     assert(IsPowerOfTwo(alignment));
   102     return count + (alignment - (count % alignment)) % alignment;
   103 }
   104 
   105 static inline bool
   106 IsUint32AddSafe(unsigned a, unsigned b)
   107 {
   108     unsigned log2_a = Log2(a);
   109     unsigned log2_b = Log2(b);
   110     return (log2_a < sizeof(unsigned) * 8) &&
   111            (log2_b < sizeof(unsigned) * 8);
   112 }
   113 
   114 static inline bool
   115 IsUint32MultiplySafe(unsigned a, unsigned b)
   116 {
   117     if (a <= 1 || b <= 1)
   118         return true;
   119 
   120     unsigned log2_a = Log2(a);
   121     unsigned log2_b = Log2(b);
   122     return log2_a + log2_b <= sizeof(unsigned) * 8;
   123 }
   124 
   125 #define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array[0]))
   126 #define STATIC_ASSERT(cond) extern int static_assert_f(int a[(cond) ? 1 : -1])
   127 
   128 template <typename T>
   129 static inline bool
   130 IsAligned(T addr, size_t alignment)
   131 {
   132     assert(IsPowerOfTwo(alignment));
   133     return !(uintptr_t(addr) & (alignment - 1));
   134 }
   135 
   136 static inline Address
   137 AlignedBase(Address addr, size_t alignment)
   138 {
   139     assert(IsPowerOfTwo(alignment));
   140     return Address(uintptr_t(addr) & ~(alignment - 1));
   141 }
   142 
   143 template <typename T> static inline T
   144 Min(const T &t1, const T &t2)
   145 {
   146     return t1 < t2 ? t1 : t2;
   147 }
   148 
   149 }
   150 
   151 #endif // _include_jitcraft_utility_h_