--- /dev/null 2017-01-22 10:16:57.869617664 -0800 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/util/Util.java 2017-02-15 16:57:18.421215407 -0800 @@ -0,0 +1,215 @@ +/* + * 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 uncheckedCast(@SuppressWarnings("unused") Class type, Object object) { + return (T) object; + } + + /** + * Statically cast an object to an arbitrary Object type. Dynamically checked. + */ + @SuppressWarnings("unchecked") + public static 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 void atPutGrow(List 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)"; + } +}