src/Utility.h
author David Anderson <danderson@mozilla.com>
Wed Jul 25 01:32:49 2012 -0700 (2012-07-25)
changeset 93 23189d937087
parent 92 e3974e7360e9
child 105 35bacccdffcb
permissions -rw-r--r--
Fix opt clang build.
     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 <stddef.h>
    24 #include <stdint.h>
    25 #ifdef _MSC_VER
    26 # include <intrin.h>
    27 #endif
    28 
    29 #ifdef _MSC_VER
    30 # pragma warning(disable:4355)
    31 #endif
    32 
    33 namespace ke {
    34 
    35 static const size_t kMallocAlignment = sizeof(void *) * 2;
    36 
    37 typedef uint8_t uint8;
    38 typedef int32_t int32;
    39 typedef uint32_t uint32;
    40 
    41 typedef uint8 * Address;
    42 
    43 static const size_t kKB = 1024;
    44 static const size_t kMB = 1024 * kKB;
    45 static const size_t kGB = 1024 * kMB;
    46 
    47 template <typename T>
    48 class AutoVec
    49 {
    50     T *t_;
    51 
    52   public:
    53     AutoVec()
    54       : t_(NULL)
    55     {
    56     }
    57     AutoVec(T *t)
    58       : t_(t)
    59     {
    60     }
    61     ~AutoVec() {
    62         delete [] t_;
    63     }
    64     operator T *() {
    65         return t_;
    66     }
    67     void operator =(T *t) {
    68         if (t_)
    69             delete [] t_;
    70         t_ = t;
    71     }
    72 };
    73 
    74 // Bob Jenkin's one-at-a-time hash function[1].
    75 //
    76 // [1] http://burtleburtle.net/bob/hash/doobs.html
    77 class CharacterStreamHasher
    78 {
    79     uint32 hash;
    80 
    81   public:
    82     CharacterStreamHasher()
    83       : hash(0)
    84     { }
    85 
    86     void add(char c) {
    87         hash += c;
    88         hash += (hash << 10);
    89         hash ^= (hash >> 6);
    90     }
    91 
    92     void add(const char *s, size_t length) {
    93         for (size_t i = 0; i < length; i++)
    94             add(s[i]);
    95     }
    96 
    97     uint32 result() {
    98         hash += (hash << 3);
    99         hash ^= (hash >> 11);
   100         hash += (hash << 15);
   101         return hash;
   102     }
   103 };
   104 
   105 static inline uint32
   106 HashCharSequence(const char *s, size_t length)
   107 {
   108     CharacterStreamHasher hasher;
   109     hasher.add(s, length);
   110     return hasher.result();
   111 }
   112 
   113 static inline size_t
   114 Log2(size_t number)
   115 {
   116     assert(number != 0);
   117 
   118 #ifdef _MSC_VER
   119     unsigned long rval;
   120 # ifdef _M_IX86
   121     _BitScanReverse(&rval, number);
   122 # elif _M_X64
   123     _BitScanReverse64(&rval, number);
   124 # endif
   125     return rval;
   126 #else
   127 	size_t bit;
   128 	asm("bsr %1, %0\n"
   129 		: "=r" (bit)
   130 		: "rm" (number));
   131 	return bit;
   132 #endif
   133 }
   134 
   135 static inline size_t
   136 FindRightmostBit(size_t number)
   137 {
   138     assert(number != 0);
   139 
   140 #ifdef _MSC_VER
   141     unsigned long rval;
   142 # ifdef _M_IX86
   143     _BitScanForward(&rval, number);
   144 # elif _M_X64
   145     _BitScanForward64(&rval, number);
   146 # endif
   147     return rval;
   148 #else
   149 	size_t bit;
   150 	asm("bsf %1, %0\n"
   151 		: "=r" (bit)
   152 		: "rm" (number));
   153 	return bit;
   154 #endif
   155 }
   156 
   157 static inline bool
   158 IsPowerOfTwo(size_t value)
   159 {
   160     if (value == 0)
   161         return false;
   162     return !(value & (value - 1));
   163 }
   164 
   165 static inline size_t
   166 Align(size_t count, size_t alignment)
   167 {
   168     assert(IsPowerOfTwo(alignment));
   169     return count + (alignment - (count % alignment)) % alignment;
   170 }
   171 
   172 static inline bool
   173 IsUint32AddSafe(unsigned a, unsigned b)
   174 {
   175     if (!a || !b)
   176         return true;
   177     size_t log2_a = Log2(a);
   178     size_t log2_b = Log2(b);
   179     return (log2_a < sizeof(unsigned) * 8) &&
   180            (log2_b < sizeof(unsigned) * 8);
   181 }
   182 
   183 static inline bool
   184 IsUintPtrAddSafe(size_t a, size_t b)
   185 {
   186     if (!a || !b)
   187         return true;
   188     size_t log2_a = Log2(a);
   189     size_t log2_b = Log2(b);
   190     return (log2_a < sizeof(size_t) * 8) &&
   191            (log2_b < sizeof(size_t) * 8);
   192 }
   193 
   194 static inline bool
   195 IsUint32MultiplySafe(unsigned a, unsigned b)
   196 {
   197     if (a <= 1 || b <= 1)
   198         return true;
   199 
   200     size_t log2_a = Log2(a);
   201     size_t log2_b = Log2(b);
   202     return log2_a + log2_b <= sizeof(unsigned) * 8;
   203 }
   204 
   205 static inline bool
   206 IsUintPtrMultiplySafe(size_t a, size_t b)
   207 {
   208     if (a <= 1 || b <= 1)
   209         return true;
   210 
   211     size_t log2_a = Log2(a);
   212     size_t log2_b = Log2(b);
   213     return log2_a + log2_b <= sizeof(size_t) * 8;
   214 }
   215 
   216 #define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array[0]))
   217 #define STATIC_ASSERT(cond) extern int static_assert_f(int a[(cond) ? 1 : -1])
   218 
   219 #define IS_ALIGNED(addr, alignment)	(!(uintptr_t(addr) & ((alignment) - 1)))
   220 
   221 template <typename T>
   222 static inline bool
   223 IsAligned(T addr, size_t alignment)
   224 {
   225     assert(IsPowerOfTwo(alignment));
   226     return !(uintptr_t(addr) & (alignment - 1));
   227 }
   228 
   229 static inline Address
   230 AlignedBase(Address addr, size_t alignment)
   231 {
   232     assert(IsPowerOfTwo(alignment));
   233     return Address(uintptr_t(addr) & ~(alignment - 1));
   234 }
   235 
   236 template <typename T> static inline T
   237 Min(const T &t1, const T &t2)
   238 {
   239     return t1 < t2 ? t1 : t2;
   240 }
   241 
   242 #define OFFSETOF(Class, Member) reinterpret_cast<size_t>(&((Class *)NULL)->Member)
   243 
   244 }
   245 
   246 #endif // _include_jitcraft_utility_h_