blob: 4e29d619daa7ec930f3918969d18ca819bf15a99 [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 static org.graalvm.compiler.core.common.GraalOptions.HotSpotPrintInlining;
import java.util.Collection;
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 {
private static int getJavaSpecificationVersion() {
String value = System.getProperty("java.specification.version");
if (value.startsWith("1.")) {
value = value.substring(2);
}
return Integer.parseInt(value);
}
/**
* The integer value corresponding to the value of the {@code java.specification.version} system
* property after any leading {@code "1."} has been stripped.
*/
public static final int JAVA_SPECIFICATION_VERSION = getJavaSpecificationVersion();
/**
* Determines if the Java runtime is version 8 or earlier.
*/
public static final boolean Java8OrEarlier = JAVA_SPECIFICATION_VERSION <= 8;
/**
* 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;
}
public interface Stringify {
String apply(Object o);
}
public static String join(Collection<?> c, String sep) {
return join(c, sep, "", "", null);
}
public static String join(Collection<?> c, String sep, String prefix, String suffix, Stringify stringify) {
StringBuilder buf = new StringBuilder(prefix);
boolean first = true;
for (Object e : c) {
if (!first) {
buf.append(sep);
} else {
first = false;
}
buf.append(stringify != null ? stringify.apply(e) : String.valueOf(e));
}
buf.append(suffix);
return buf.toString();
}
/**
* 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) {
if (HotSpotPrintInlining.getValue()) {
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)";
}
}