blob: ea51d1e2ec2ab72e7980218207151a5518bb2ab7 [file] [log] [blame]
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3#ifndef ART_SRC_UTILS_H_
4#define ART_SRC_UTILS_H_
5
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07006#include "globals.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -07007#include "logging.h"
Elliott Hughes11e45072011-08-16 17:40:46 -07008#include "stringpiece.h"
Elliott Hughesc7ac37f2011-08-12 12:21:58 -07009#include "stringprintf.h"
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070010
Carl Shapiro6b6b5f02011-06-21 15:05:09 -070011namespace art {
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070012
Elliott Hughes11e45072011-08-16 17:40:46 -070013class Object;
14
Carl Shapiroa2e18e12011-06-21 18:57:55 -070015template<typename T>
16static inline bool IsPowerOfTwo(T x) {
17 return (x & (x - 1)) == 0;
18}
19
Carl Shapiroa2e18e12011-06-21 18:57:55 -070020template<typename T>
21static inline bool IsAligned(T x, int n) {
22 CHECK(IsPowerOfTwo(n));
23 return (x & (n - 1)) == 0;
24}
25
Carl Shapiroa2e18e12011-06-21 18:57:55 -070026template<typename T>
27static inline bool IsAligned(T* x, int n) {
28 return IsAligned(reinterpret_cast<uintptr_t>(x), n);
29}
30
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070031// Check whether an N-bit two's-complement representation can hold value.
32static inline bool IsInt(int N, word value) {
33 CHECK_LT(0, N);
34 CHECK_LT(N, kBitsPerWord);
35 word limit = static_cast<word>(1) << (N - 1);
36 return (-limit <= value) && (value < limit);
37}
38
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070039static inline bool IsUint(int N, word value) {
40 CHECK_LT(0, N);
41 CHECK_LT(N, kBitsPerWord);
42 word limit = static_cast<word>(1) << N;
43 return (0 <= value) && (value < limit);
44}
45
Carl Shapiroa2e18e12011-06-21 18:57:55 -070046static inline bool IsAbsoluteUint(int N, word value) {
47 CHECK_LT(0, N);
48 CHECK_LT(N, kBitsPerWord);
49 if (value < 0) value = -value;
50 return IsUint(N, value);
51}
52
Ian Rogersb033c752011-07-20 12:22:35 -070053static inline int32_t Low16Bits(int32_t value) {
54 return static_cast<int32_t>(value & 0xffff);
55}
56
57static inline int32_t High16Bits(int32_t value) {
58 return static_cast<int32_t>(value >> 16);
59}
Carl Shapiroa2e18e12011-06-21 18:57:55 -070060
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070061static inline int32_t Low32Bits(int64_t value) {
62 return static_cast<int32_t>(value);
63}
64
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -070065static inline int32_t High32Bits(int64_t value) {
66 return static_cast<int32_t>(value >> 32);
67}
68
Carl Shapiro61e019d2011-07-14 16:53:09 -070069template<typename T>
70static inline T RoundDown(T x, int n) {
71 CHECK(IsPowerOfTwo(n));
72 return (x & -n);
73}
74
75template<typename T>
76static inline T RoundUp(T x, int n) {
77 return RoundDown(x + n - 1, n);
78}
79
Carl Shapiroa2e18e12011-06-21 18:57:55 -070080// Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
Carl Shapiro1fb86202011-06-27 17:43:13 -070081// figure 3-3, page 48, where the function is called clp2.
82static inline uint32_t RoundUpToPowerOfTwo(uint32_t x) {
83 x = x - 1;
84 x = x | (x >> 1);
85 x = x | (x >> 2);
86 x = x | (x >> 4);
87 x = x | (x >> 8);
88 x = x | (x >> 16);
89 return x + 1;
90}
91
92// Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
Carl Shapiroa2e18e12011-06-21 18:57:55 -070093// figure 5-2, page 66, where the function is called pop.
94static inline int CountOneBits(uint32_t x) {
95 x = x - ((x >> 1) & 0x55555555);
96 x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
97 x = (x + (x >> 4)) & 0x0F0F0F0F;
98 x = x + (x >> 8);
99 x = x + (x >> 16);
100 return static_cast<int>(x & 0x0000003F);
101}
102
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700103#define CLZ(x) __builtin_clz(x)
104
Elliott Hughes46b92ba2011-08-12 17:57:34 -0700105static inline bool NeedsEscaping(uint16_t ch) {
106 return (ch < ' ' || ch > '~');
107}
108
Elliott Hughesc7ac37f2011-08-12 12:21:58 -0700109static inline std::string PrintableChar(uint16_t ch) {
110 std::string result;
Elliott Hughes46b92ba2011-08-12 17:57:34 -0700111 result += '\'';
112 if (NeedsEscaping(ch)) {
113 StringAppendF(&result, "\\u%04x", ch);
114 } else {
Elliott Hughesc7ac37f2011-08-12 12:21:58 -0700115 result += ch;
Elliott Hughesc7ac37f2011-08-12 12:21:58 -0700116 }
Elliott Hughes46b92ba2011-08-12 17:57:34 -0700117 result += '\'';
Elliott Hughesc7ac37f2011-08-12 12:21:58 -0700118 return result;
119}
120
Elliott Hughes46b92ba2011-08-12 17:57:34 -0700121// TODO: assume the content is UTF-8, and show code point escapes?
Elliott Hughesc7ac37f2011-08-12 12:21:58 -0700122template<typename StringT>
123static inline std::string PrintableString(const StringT& s) {
124 std::string result;
125 result += '"';
126 for (typename StringT::iterator it = s.begin(); it != s.end(); ++it) {
127 char ch = *it;
Elliott Hughes46b92ba2011-08-12 17:57:34 -0700128 if (NeedsEscaping(ch)) {
Elliott Hughesc7ac37f2011-08-12 12:21:58 -0700129 StringAppendF(&result, "\\x%02x", ch & 0xff);
Elliott Hughes46b92ba2011-08-12 17:57:34 -0700130 } else {
131 result += ch;
Elliott Hughesc7ac37f2011-08-12 12:21:58 -0700132 }
133 }
134 result += '"';
135 return result;
136}
137
Elliott Hughes11e45072011-08-16 17:40:46 -0700138// Return a newly-allocated string containing a human-readable equivalent
139// of 'descriptor'. So "I" would be "int", "[[I" would be "int[][]",
140// "[Ljava/lang/String;" would be "java.lang.String[]", and so forth.
141std::string PrettyDescriptor(const StringPiece& descriptor);
142
143// Returns a human-readable string form of the name of the class of
144// the given object. So given a java.lang.String, the output would
145// be "java.lang.String". Given an array of int, the output would be "int[]".
146// Given String.class, the output would be "java.lang.Class<java.lang.String>".
147std::string PrettyType(const Object* obj);
148
Carl Shapiro6b6b5f02011-06-21 15:05:09 -0700149} // namespace art
Carl Shapiroa5d5cfd2011-06-21 12:46:59 -0700150
151#endif // ART_SRC_UTILS_H_