jitcraft/Utility.h
author David Anderson <dvander@alliedmods.net>
Mon Jul 23 01:19:44 2012 -0700 (2012-07-23)
changeset 85 06a0015b6a5c
parent 59 b7d61ddb3c8d
permissions -rw-r--r--
Added global variable support.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of JITCraft.
     6  *
     7  * JITCraft is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * JITCraft. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #ifndef _include_jitcraft_utility_h_
    20 #define _include_jitcraft_utility_h_
    21 
    22 #include <assert.h>
    23 #include <stdint.h>
    24 #ifdef _MSC_VER
    25 # include <intrin.h>
    26 #endif
    27 
    28 #ifdef _MSC_VER
    29 # pragma warning(disable:4355)
    30 #endif
    31 
    32 namespace ke {
    33 
    34 static const size_t kMallocAlignment = sizeof(void *) * 2;
    35 
    36 typedef uint8_t uint8;
    37 typedef int32_t int32;
    38 typedef uint32_t uint32;
    39 
    40 typedef uint8 * Address;
    41 
    42 static const size_t kKB = 1024;
    43 static const size_t kMB = 1024 * kKB;
    44 static const size_t kGB = 1024 * kMB;
    45 
    46 template <typename T>
    47 class AutoVec
    48 {
    49     T *t_;
    50 
    51   public:
    52     AutoVec()
    53       : t_(NULL)
    54     {
    55     }
    56     AutoVec(T *t)
    57       : t_(t)
    58     {
    59     }
    60     ~AutoVec() {
    61         delete [] t_;
    62     }
    63     operator T *() {
    64         return t_;
    65     }
    66     void operator =(T *t) {
    67         if (t_)
    68             delete [] t_;
    69         t_ = t;
    70     }
    71 };
    72 
    73 // Bob Jenkin's one-at-a-time hash function[1].
    74 //
    75 // [1] http://burtleburtle.net/bob/hash/doobs.html
    76 class CharacterStreamHasher
    77 {
    78     uint32 hash;
    79 
    80   public:
    81     CharacterStreamHasher()
    82       : hash(0)
    83     { }
    84 
    85     void add(char c) {
    86         hash += c;
    87         hash += (hash << 10);
    88         hash ^= (hash >> 6);
    89     }
    90 
    91     void add(const char *s, size_t length) {
    92         for (size_t i = 0; i < length; i++)
    93             add(s[i]);
    94     }
    95 
    96     uint32 result() {
    97         hash += (hash << 3);
    98         hash ^= (hash >> 11);
    99         hash += (hash << 15);
   100         return hash;
   101     }
   102 };
   103 
   104 static inline uint32
   105 HashCharSequence(const char *s, size_t length)
   106 {
   107     CharacterStreamHasher hasher;
   108     hasher.add(s, length);
   109     return hasher.result();
   110 }
   111 
   112 static inline size_t
   113 Log2(size_t number)
   114 {
   115     assert(number != 0);
   116 
   117 #ifdef _MSC_VER
   118     unsigned long rval;
   119     _BitScanReverse(&rval, number);
   120     return rval;
   121 #else
   122 	size_t bit;
   123 	asm("bsr %1, %0\n"
   124 		: "=r" (bit)
   125 		: "rm" (number));
   126 	return bit;
   127 #endif
   128 }
   129 
   130 static inline size_t
   131 FindRightmostBit(size_t number)
   132 {
   133     assert(number != 0);
   134 
   135 #ifdef _MSC_VER
   136     unsigned long rval;
   137     _BitScanForward(&rval, number);
   138     return rval;
   139 #else
   140 	size_t bit;
   141 	asm("bsf %1, %0\n"
   142 		: "=r" (bit)
   143 		: "rm" (number));
   144 	return bit;
   145 #endif
   146 }
   147 
   148 static inline bool
   149 IsPowerOfTwo(size_t value)
   150 {
   151     if (value == 0)
   152         return false;
   153     return !(value & (value - 1));
   154 }
   155 
   156 static inline size_t
   157 Align(size_t count, size_t alignment)
   158 {
   159     assert(IsPowerOfTwo(alignment));
   160     return count + (alignment - (count % alignment)) % alignment;
   161 }
   162 
   163 static inline bool
   164 IsUint32AddSafe(unsigned a, unsigned b)
   165 {
   166     if (!a || !b)
   167         return true;
   168     unsigned log2_a = Log2(a);
   169     unsigned log2_b = Log2(b);
   170     return (log2_a < sizeof(unsigned) * 8) &&
   171            (log2_b < sizeof(unsigned) * 8);
   172 }
   173 
   174 static inline bool
   175 IsUintPtrAddSafe(size_t a, size_t b)
   176 {
   177     if (!a || !b)
   178         return true;
   179     size_t log2_a = Log2(a);
   180     size_t log2_b = Log2(b);
   181     return (log2_a < sizeof(size_t) * 8) &&
   182            (log2_b < sizeof(size_t) * 8);
   183 }
   184 
   185 static inline bool
   186 IsUint32MultiplySafe(unsigned a, unsigned b)
   187 {
   188     if (a <= 1 || b <= 1)
   189         return true;
   190 
   191     unsigned log2_a = Log2(a);
   192     unsigned log2_b = Log2(b);
   193     return log2_a + log2_b <= sizeof(unsigned) * 8;
   194 }
   195 
   196 static inline bool
   197 IsUintPtrMultiplySafe(size_t a, size_t b)
   198 {
   199     if (a <= 1 || b <= 1)
   200         return true;
   201 
   202     size_t log2_a = Log2(a);
   203     size_t log2_b = Log2(b);
   204     return log2_a + log2_b <= sizeof(size_t) * 8;
   205 }
   206 
   207 #define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array[0]))
   208 #define STATIC_ASSERT(cond) extern int static_assert_f(int a[(cond) ? 1 : -1])
   209 
   210 #define IS_ALIGNED(addr, alignment)	(!(uintptr_t(addr) & ((alignment) - 1)))
   211 
   212 template <typename T>
   213 static inline bool
   214 IsAligned(T addr, size_t alignment)
   215 {
   216     assert(IsPowerOfTwo(alignment));
   217     return !(uintptr_t(addr) & (alignment - 1));
   218 }
   219 
   220 static inline Address
   221 AlignedBase(Address addr, size_t alignment)
   222 {
   223     assert(IsPowerOfTwo(alignment));
   224     return Address(uintptr_t(addr) & ~(alignment - 1));
   225 }
   226 
   227 template <typename T> static inline T
   228 Min(const T &t1, const T &t2)
   229 {
   230     return t1 < t2 ? t1 : t2;
   231 }
   232 
   233 }
   234 
   235 #endif // _include_jitcraft_utility_h_