001/* 002 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.compiler.common.util; 024 025import java.util.*; 026 027import com.oracle.graal.debug.*; 028 029import jdk.internal.jvmci.code.*; 030 031/** 032 * The {@code Util} class contains a motley collection of utility methods used throughout the 033 * compiler. 034 */ 035public class Util { 036 037 public static final int PRINTING_LINE_WIDTH = 40; 038 public static final char SECTION_CHARACTER = '*'; 039 public static final char SUB_SECTION_CHARACTER = '='; 040 public static final char SEPERATOR_CHARACTER = '-'; 041 042 public static <T> boolean replaceInList(T a, T b, List<T> list) { 043 final int max = list.size(); 044 for (int i = 0; i < max; i++) { 045 if (list.get(i) == a) { 046 list.set(i, b); 047 return true; 048 } 049 } 050 return false; 051 } 052 053 /** 054 * Statically cast an object to an arbitrary Object type. Dynamically checked. 055 */ 056 @SuppressWarnings("unchecked") 057 public static <T> T uncheckedCast(@SuppressWarnings("unused") Class<T> type, Object object) { 058 return (T) object; 059 } 060 061 /** 062 * Statically cast an object to an arbitrary Object type. Dynamically checked. 063 */ 064 @SuppressWarnings("unchecked") 065 public static <T> T uncheckedCast(Object object) { 066 return (T) object; 067 } 068 069 /** 070 * Utility method to combine a base hash with the identity hash of one or more objects. 071 * 072 * @param hash the base hash 073 * @param x the object to add to the hash 074 * @return the combined hash 075 */ 076 public static int hash1(int hash, Object x) { 077 // always set at least one bit in case the hash wraps to zero 078 return 0x10000000 | (hash + 7 * System.identityHashCode(x)); 079 } 080 081 /** 082 * Utility method to combine a base hash with the identity hash of one or more objects. 083 * 084 * @param hash the base hash 085 * @param x the first object to add to the hash 086 * @param y the second object to add to the hash 087 * @return the combined hash 088 */ 089 public static int hash2(int hash, Object x, Object y) { 090 // always set at least one bit in case the hash wraps to zero 091 return 0x20000000 | (hash + 7 * System.identityHashCode(x) + 11 * System.identityHashCode(y)); 092 } 093 094 /** 095 * Utility method to combine a base hash with the identity hash of one or more objects. 096 * 097 * @param hash the base hash 098 * @param x the first object to add to the hash 099 * @param y the second object to add to the hash 100 * @param z the third object to add to the hash 101 * @return the combined hash 102 */ 103 public static int hash3(int hash, Object x, Object y, Object z) { 104 // always set at least one bit in case the hash wraps to zero 105 return 0x30000000 | (hash + 7 * System.identityHashCode(x) + 11 * System.identityHashCode(y) + 13 * System.identityHashCode(z)); 106 } 107 108 /** 109 * Utility method to combine a base hash with the identity hash of one or more objects. 110 * 111 * @param hash the base hash 112 * @param x the first object to add to the hash 113 * @param y the second object to add to the hash 114 * @param z the third object to add to the hash 115 * @param w the fourth object to add to the hash 116 * @return the combined hash 117 */ 118 public static int hash4(int hash, Object x, Object y, Object z, Object w) { 119 // always set at least one bit in case the hash wraps to zero 120 return 0x40000000 | (hash + 7 * System.identityHashCode(x) + 11 * System.identityHashCode(y) + 13 * System.identityHashCode(z) + 17 * System.identityHashCode(w)); 121 } 122 123 static { 124 assert CodeUtil.log2(2) == 1; 125 assert CodeUtil.log2(4) == 2; 126 assert CodeUtil.log2(8) == 3; 127 assert CodeUtil.log2(16) == 4; 128 assert CodeUtil.log2(32) == 5; 129 assert CodeUtil.log2(0x40000000) == 30; 130 131 assert CodeUtil.log2(2L) == 1; 132 assert CodeUtil.log2(4L) == 2; 133 assert CodeUtil.log2(8L) == 3; 134 assert CodeUtil.log2(16L) == 4; 135 assert CodeUtil.log2(32L) == 5; 136 assert CodeUtil.log2(0x4000000000000000L) == 62; 137 138 assert !CodeUtil.isPowerOf2(3); 139 assert !CodeUtil.isPowerOf2(5); 140 assert !CodeUtil.isPowerOf2(7); 141 assert !CodeUtil.isPowerOf2(-1); 142 143 assert CodeUtil.isPowerOf2(2); 144 assert CodeUtil.isPowerOf2(4); 145 assert CodeUtil.isPowerOf2(8); 146 assert CodeUtil.isPowerOf2(16); 147 assert CodeUtil.isPowerOf2(32); 148 assert CodeUtil.isPowerOf2(64); 149 } 150 151 /** 152 * Sets the element at a given position of a list and ensures that this position exists. If the 153 * list is current shorter than the position, intermediate positions are filled with a given 154 * value. 155 * 156 * @param list the list to put the element into 157 * @param pos the position at which to insert the element 158 * @param x the element that should be inserted 159 * @param filler the filler element that is used for the intermediate positions in case the list 160 * is shorter than pos 161 */ 162 public static <T> void atPutGrow(List<T> list, int pos, T x, T filler) { 163 if (list.size() < pos + 1) { 164 while (list.size() < pos + 1) { 165 list.add(filler); 166 } 167 assert list.size() == pos + 1; 168 } 169 170 assert list.size() >= pos + 1; 171 list.set(pos, x); 172 } 173 174 public static void breakpoint() { 175 // do nothing. 176 } 177 178 public static void guarantee(boolean b, String string) { 179 if (!b) { 180 throw new BailoutException(string); 181 } 182 } 183 184 public static void warning(String string) { 185 TTY.println("WARNING: " + string); 186 } 187 188 public static int safeToInt(long l) { 189 assert (int) l == l; 190 return (int) l; 191 } 192 193 public static int roundUp(int number, int mod) { 194 return ((number + mod - 1) / mod) * mod; 195 } 196 197 public static void printSection(String name, char sectionCharacter) { 198 199 String header = " " + name + " "; 200 int remainingCharacters = PRINTING_LINE_WIDTH - header.length(); 201 int leftPart = remainingCharacters / 2; 202 int rightPart = remainingCharacters - leftPart; 203 for (int i = 0; i < leftPart; i++) { 204 TTY.print(sectionCharacter); 205 } 206 207 TTY.print(header); 208 209 for (int i = 0; i < rightPart; i++) { 210 TTY.print(sectionCharacter); 211 } 212 213 TTY.println(); 214 } 215 216 /** 217 * Prints entries in a byte array as space separated hex values to {@link TTY}. 218 * 219 * @param address an address at which the bytes are located. This is used to print an address 220 * prefix per line of output. 221 * @param array the array containing all the bytes to print 222 * @param bytesPerLine the number of values to print per line of output 223 */ 224 public static void printBytes(long address, byte[] array, int bytesPerLine) { 225 printBytes(address, array, 0, array.length, bytesPerLine); 226 } 227 228 /** 229 * Prints entries in a byte array as space separated hex values to {@link TTY}. 230 * 231 * @param address an address at which the bytes are located. This is used to print an address 232 * prefix per line of output. 233 * @param array the array containing the bytes to print 234 * @param offset the offset in {@code array} of the values to print 235 * @param length the number of values from {@code array} print 236 * @param bytesPerLine the number of values to print per line of output 237 */ 238 public static void printBytes(long address, byte[] array, int offset, int length, int bytesPerLine) { 239 assert bytesPerLine > 0; 240 boolean newLine = true; 241 for (int i = 0; i < length; i++) { 242 if (newLine) { 243 TTY.print("%08x: ", address + i); 244 newLine = false; 245 } 246 TTY.print("%02x ", array[i]); 247 if (i % bytesPerLine == bytesPerLine - 1) { 248 TTY.println(); 249 newLine = true; 250 } 251 } 252 253 if (length % bytesPerLine != bytesPerLine) { 254 TTY.println(); 255 } 256 } 257 258 public static boolean isShiftCount(int x) { 259 return 0 <= x && x < 32; 260 } 261 262 /** 263 * Determines if a given {@code int} value is the range of unsigned byte values. 264 */ 265 public static boolean isUByte(int x) { 266 return (x & 0xff) == x; 267 } 268 269 /** 270 * Determines if a given {@code int} value is the range of signed byte values. 271 */ 272 public static boolean isByte(int x) { 273 return (byte) x == x; 274 } 275 276 /** 277 * Determines if a given {@code long} value is the range of unsigned byte values. 278 */ 279 public static boolean isUByte(long x) { 280 return (x & 0xffL) == x; 281 } 282 283 /** 284 * Determines if a given {@code long} value is the range of signed byte values. 285 */ 286 public static boolean isByte(long l) { 287 return (byte) l == l; 288 } 289 290 /** 291 * Determines if a given {@code long} value is the range of unsigned int values. 292 */ 293 public static boolean isUInt(long x) { 294 return (x & 0xffffffffL) == x; 295 } 296 297 /** 298 * Determines if a given {@code long} value is the range of signed int values. 299 */ 300 public static boolean isInt(long l) { 301 return (int) l == l; 302 } 303 304 /** 305 * Determines if a given {@code int} value is the range of signed short values. 306 */ 307 public static boolean isShort(int x) { 308 return (short) x == x; 309 } 310 311 public static boolean is32bit(long x) { 312 return -0x80000000L <= x && x < 0x80000000L; 313 } 314 315 public static short safeToShort(int v) { 316 assert isShort(v); 317 return (short) v; 318 } 319 320 /** 321 * Creates an array of integers of length "size", in which each number from 0 to (size - 1) 322 * occurs exactly once. The integers are sorted using the given comparator. This can be used to 323 * create a sorting for arrays that cannot be modified directly. 324 * 325 * @param size The size of the range to be sorted. 326 * @param comparator A comparator that is used to compare indexes. 327 * @return An array of integers that contains each number from 0 to (size - 1) exactly once, 328 * sorted using the comparator. 329 */ 330 public static Integer[] createSortedPermutation(int size, Comparator<Integer> comparator) { 331 Integer[] indexes = new Integer[size]; 332 for (int i = 0; i < size; i++) { 333 indexes[i] = i; 334 } 335 Arrays.sort(indexes, comparator); 336 return indexes; 337 } 338}