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