1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/Utility.h Tue Jul 24 23:53:34 2012 -0700
1.3 @@ -0,0 +1,243 @@
1.4 +/* vim: set ts=4 sw=4 tw=99 et:
1.5 + *
1.6 + * Copyright (C) 2012 David Anderson
1.7 + *
1.8 + * This file is part of JITCraft.
1.9 + *
1.10 + * JITCraft is free software: you can redistribute it and/or modify it under
1.11 + * the terms of the GNU General Public License as published by the Free
1.12 + * Software Foundation, either version 3 of the License, or (at your option)
1.13 + * any later version.
1.14 + *
1.15 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
1.16 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License along with
1.20 + * JITCraft. If not, see http://www.gnu.org/licenses/.
1.21 + */
1.22 +#ifndef _include_jitcraft_utility_h_
1.23 +#define _include_jitcraft_utility_h_
1.24 +
1.25 +#include <assert.h>
1.26 +#include <stdint.h>
1.27 +#ifdef _MSC_VER
1.28 +# include <intrin.h>
1.29 +#endif
1.30 +
1.31 +#ifdef _MSC_VER
1.32 +# pragma warning(disable:4355)
1.33 +#endif
1.34 +
1.35 +namespace ke {
1.36 +
1.37 +static const size_t kMallocAlignment = sizeof(void *) * 2;
1.38 +
1.39 +typedef uint8_t uint8;
1.40 +typedef int32_t int32;
1.41 +typedef uint32_t uint32;
1.42 +
1.43 +typedef uint8 * Address;
1.44 +
1.45 +static const size_t kKB = 1024;
1.46 +static const size_t kMB = 1024 * kKB;
1.47 +static const size_t kGB = 1024 * kMB;
1.48 +
1.49 +template <typename T>
1.50 +class AutoVec
1.51 +{
1.52 + T *t_;
1.53 +
1.54 + public:
1.55 + AutoVec()
1.56 + : t_(NULL)
1.57 + {
1.58 + }
1.59 + AutoVec(T *t)
1.60 + : t_(t)
1.61 + {
1.62 + }
1.63 + ~AutoVec() {
1.64 + delete [] t_;
1.65 + }
1.66 + operator T *() {
1.67 + return t_;
1.68 + }
1.69 + void operator =(T *t) {
1.70 + if (t_)
1.71 + delete [] t_;
1.72 + t_ = t;
1.73 + }
1.74 +};
1.75 +
1.76 +// Bob Jenkin's one-at-a-time hash function[1].
1.77 +//
1.78 +// [1] http://burtleburtle.net/bob/hash/doobs.html
1.79 +class CharacterStreamHasher
1.80 +{
1.81 + uint32 hash;
1.82 +
1.83 + public:
1.84 + CharacterStreamHasher()
1.85 + : hash(0)
1.86 + { }
1.87 +
1.88 + void add(char c) {
1.89 + hash += c;
1.90 + hash += (hash << 10);
1.91 + hash ^= (hash >> 6);
1.92 + }
1.93 +
1.94 + void add(const char *s, size_t length) {
1.95 + for (size_t i = 0; i < length; i++)
1.96 + add(s[i]);
1.97 + }
1.98 +
1.99 + uint32 result() {
1.100 + hash += (hash << 3);
1.101 + hash ^= (hash >> 11);
1.102 + hash += (hash << 15);
1.103 + return hash;
1.104 + }
1.105 +};
1.106 +
1.107 +static inline uint32
1.108 +HashCharSequence(const char *s, size_t length)
1.109 +{
1.110 + CharacterStreamHasher hasher;
1.111 + hasher.add(s, length);
1.112 + return hasher.result();
1.113 +}
1.114 +
1.115 +static inline size_t
1.116 +Log2(size_t number)
1.117 +{
1.118 + assert(number != 0);
1.119 +
1.120 +#ifdef _MSC_VER
1.121 + unsigned long rval;
1.122 +# ifdef _M_IX86
1.123 + _BitScanReverse(&rval, number);
1.124 +# elif _M_X64
1.125 + _BitScanReverse64(&rval, number);
1.126 +# endif
1.127 + return rval;
1.128 +#else
1.129 + size_t bit;
1.130 + asm("bsr %1, %0\n"
1.131 + : "=r" (bit)
1.132 + : "rm" (number));
1.133 + return bit;
1.134 +#endif
1.135 +}
1.136 +
1.137 +static inline size_t
1.138 +FindRightmostBit(size_t number)
1.139 +{
1.140 + assert(number != 0);
1.141 +
1.142 +#ifdef _MSC_VER
1.143 + unsigned long rval;
1.144 +# ifdef _M_IX86
1.145 + _BitScanForward(&rval, number);
1.146 +# elif _M_X64
1.147 + _BitScanForward64(&rval, number);
1.148 +# endif
1.149 + return rval;
1.150 +#else
1.151 + size_t bit;
1.152 + asm("bsf %1, %0\n"
1.153 + : "=r" (bit)
1.154 + : "rm" (number));
1.155 + return bit;
1.156 +#endif
1.157 +}
1.158 +
1.159 +static inline bool
1.160 +IsPowerOfTwo(size_t value)
1.161 +{
1.162 + if (value == 0)
1.163 + return false;
1.164 + return !(value & (value - 1));
1.165 +}
1.166 +
1.167 +static inline size_t
1.168 +Align(size_t count, size_t alignment)
1.169 +{
1.170 + assert(IsPowerOfTwo(alignment));
1.171 + return count + (alignment - (count % alignment)) % alignment;
1.172 +}
1.173 +
1.174 +static inline bool
1.175 +IsUint32AddSafe(unsigned a, unsigned b)
1.176 +{
1.177 + if (!a || !b)
1.178 + return true;
1.179 + size_t log2_a = Log2(a);
1.180 + size_t log2_b = Log2(b);
1.181 + return (log2_a < sizeof(unsigned) * 8) &&
1.182 + (log2_b < sizeof(unsigned) * 8);
1.183 +}
1.184 +
1.185 +static inline bool
1.186 +IsUintPtrAddSafe(size_t a, size_t b)
1.187 +{
1.188 + if (!a || !b)
1.189 + return true;
1.190 + size_t log2_a = Log2(a);
1.191 + size_t log2_b = Log2(b);
1.192 + return (log2_a < sizeof(size_t) * 8) &&
1.193 + (log2_b < sizeof(size_t) * 8);
1.194 +}
1.195 +
1.196 +static inline bool
1.197 +IsUint32MultiplySafe(unsigned a, unsigned b)
1.198 +{
1.199 + if (a <= 1 || b <= 1)
1.200 + return true;
1.201 +
1.202 + size_t log2_a = Log2(a);
1.203 + size_t log2_b = Log2(b);
1.204 + return log2_a + log2_b <= sizeof(unsigned) * 8;
1.205 +}
1.206 +
1.207 +static inline bool
1.208 +IsUintPtrMultiplySafe(size_t a, size_t b)
1.209 +{
1.210 + if (a <= 1 || b <= 1)
1.211 + return true;
1.212 +
1.213 + size_t log2_a = Log2(a);
1.214 + size_t log2_b = Log2(b);
1.215 + return log2_a + log2_b <= sizeof(size_t) * 8;
1.216 +}
1.217 +
1.218 +#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array[0]))
1.219 +#define STATIC_ASSERT(cond) extern int static_assert_f(int a[(cond) ? 1 : -1])
1.220 +
1.221 +#define IS_ALIGNED(addr, alignment) (!(uintptr_t(addr) & ((alignment) - 1)))
1.222 +
1.223 +template <typename T>
1.224 +static inline bool
1.225 +IsAligned(T addr, size_t alignment)
1.226 +{
1.227 + assert(IsPowerOfTwo(alignment));
1.228 + return !(uintptr_t(addr) & (alignment - 1));
1.229 +}
1.230 +
1.231 +static inline Address
1.232 +AlignedBase(Address addr, size_t alignment)
1.233 +{
1.234 + assert(IsPowerOfTwo(alignment));
1.235 + return Address(uintptr_t(addr) & ~(alignment - 1));
1.236 +}
1.237 +
1.238 +template <typename T> static inline T
1.239 +Min(const T &t1, const T &t2)
1.240 +{
1.241 + return t1 < t2 ? t1 : t2;
1.242 +}
1.243 +
1.244 +}
1.245 +
1.246 +#endif // _include_jitcraft_utility_h_