blob: 5814a50d23d149bbfbec452d634d840ab5b13e4b [file] [log] [blame]
/*
* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.core.common.util;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.util.List;
import org.graalvm.compiler.debug.TTY;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* The {@code Util} class contains a motley collection of utility methods used throughout the
* compiler.
*/
public class Util {
/**
* Statically cast an object to an arbitrary Object type. Dynamically checked.
*/
@SuppressWarnings("unchecked")
public static <T> T uncheckedCast(@SuppressWarnings("unused") Class<T> type, Object object) {
return (T) object;
}
/**
* Statically cast an object to an arbitrary Object type. Dynamically checked.
*/
@SuppressWarnings("unchecked")
public static <T> T uncheckedCast(Object object) {
return (T) object;
}
/**
* Sets the element at a given position of a list and ensures that this position exists. If the
* list is current shorter than the position, intermediate positions are filled with a given
* value.
*
* @param list the list to put the element into
* @param pos the position at which to insert the element
* @param x the element that should be inserted
* @param filler the filler element that is used for the intermediate positions in case the list
* is shorter than pos
*/
public static <T> void atPutGrow(List<T> list, int pos, T x, T filler) {
if (list.size() < pos + 1) {
while (list.size() < pos + 1) {
list.add(filler);
}
assert list.size() == pos + 1;
}
assert list.size() >= pos + 1;
list.set(pos, x);
}
/**
* Prepends the String {@code indentation} to every line in String {@code lines}, including a
* possibly non-empty line following the final newline.
*/
public static String indent(String lines, String indentation) {
if (lines.length() == 0) {
return lines;
}
final String newLine = "\n";
if (lines.endsWith(newLine)) {
return indentation + (lines.substring(0, lines.length() - 1)).replace(newLine, newLine + indentation) + newLine;
}
return indentation + lines.replace(newLine, newLine + indentation);
}
/**
* Returns the zero value for a given numeric kind.
*/
public static JavaConstant zero(JavaKind kind) {
switch (kind) {
case Boolean:
return JavaConstant.FALSE;
case Byte:
return JavaConstant.forByte((byte) 0);
case Char:
return JavaConstant.forChar((char) 0);
case Double:
return JavaConstant.DOUBLE_0;
case Float:
return JavaConstant.FLOAT_0;
case Int:
return JavaConstant.INT_0;
case Long:
return JavaConstant.LONG_0;
case Short:
return JavaConstant.forShort((short) 0);
default:
throw new IllegalArgumentException(kind.toString());
}
}
/**
* Returns the one value for a given numeric kind.
*/
public static JavaConstant one(JavaKind kind) {
switch (kind) {
case Boolean:
return JavaConstant.TRUE;
case Byte:
return JavaConstant.forByte((byte) 1);
case Char:
return JavaConstant.forChar((char) 1);
case Double:
return JavaConstant.DOUBLE_1;
case Float:
return JavaConstant.FLOAT_1;
case Int:
return JavaConstant.INT_1;
case Long:
return JavaConstant.LONG_1;
case Short:
return JavaConstant.forShort((short) 1);
default:
throw new IllegalArgumentException(kind.toString());
}
}
/**
* Print a HotSpot-style inlining message to the console.
*/
public static void printInlining(final ResolvedJavaMethod method, final int bci, final int inliningDepth, final boolean success, final String msg, final Object... args) {
StringBuilder sb = new StringBuilder();
// 1234567
sb.append(" "); // print timestamp
// 1234
sb.append(" "); // print compilation number
// % s ! b n
sb.append(String.format("%c%c%c%c%c ", ' ', method.isSynchronized() ? 's' : ' ', ' ', ' ', method.isNative() ? 'n' : ' '));
sb.append(" "); // more indent
sb.append(" "); // initial inlining indent
for (int i = 0; i < inliningDepth; i++) {
sb.append(" ");
}
sb.append(String.format("@ %d %s %s%s", bci, methodName(method), success ? "" : "not inlining ", String.format(msg, args)));
TTY.println(sb.toString());
}
private static String methodName(ResolvedJavaMethod method) {
return method.format("%H.%n(%p):%r") + " (" + method.getCodeSize() + " bytes)";
}
/**
* Calls {@link AccessibleObject#setAccessible(boolean)} on {@code field} with the value
* {@code flag}.
*/
public static void setAccessible(Field field, boolean flag) {
field.setAccessible(flag);
}
/**
* Calls {@link AccessibleObject#setAccessible(boolean)} on {@code executable} with the value
* {@code flag}.
*/
public static void setAccessible(Executable executable, boolean flag) {
executable.setAccessible(flag);
}
}