# HG changeset patch # User Andreas Woess # Date 1405013787 -7200 # Node ID 352de9bd8fd52516d2aeb78632d42172081fcee6 # Parent cec5a97ba1e4dab7dae843076772fd1a986d92cf# Parent efbf9195dfcb6f730f612b0912d32a432a5bf709 Merge diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Local.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Local.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Local.java Thu Jul 10 19:36:27 2014 +0200 @@ -32,5 +32,5 @@ String getName(); - ResolvedJavaType getType(); + JavaType getType(); } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java --- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java Thu Jul 10 19:36:27 2014 +0200 @@ -609,7 +609,7 @@ append(new BinaryRegReg(IDIV, result, a, loadNonConst(b))); break; case Long: - append(new BinaryRegReg(LDIV, result, a, loadNonConst(b))); + append(new BinaryRegReg(LDIV, result, a, loadNonConst(b), state)); break; case Float: append(new Op2Stack(FDIV, result, a, loadNonConst(b))); @@ -825,13 +825,21 @@ conversionInstruction = F2I; break; case I2D: - return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Double), I2D, input); + // Implemented in two steps, as this consists of sign extension and then move the + // bits over to the double register and then convert to double, in fact this does + // not generate any overhead in generated code + { + AllocatableValue tmp = emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Long), I2L, input); + return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Double), L2D, tmp); + } case I2F: return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Float), I2F, input); case L2D: return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Double), L2D, input); - case L2F: - return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Float), L2F, input); + case L2F: { + AllocatableValue tmp = emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Double), L2D, input); + return emitConvert2Op(LIRKind.derive(inputVal).changeType(Kind.Float), D2F, tmp); + } default: throw GraalInternalError.shouldNotReachHere(); } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSenReduTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSenReduTest.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSenReduTest.java Thu Jul 10 19:36:27 2014 +0200 @@ -384,7 +384,7 @@ public StructuredGraph visualize(StructuredGraph graph, String title) { DebugConfig debugConfig = DebugScope.getConfig(); - DebugConfig fixedConfig = Debug.fixedConfig(false, true, false, false, false, false, debugConfig.dumpHandlers(), debugConfig.verifyHandlers(), debugConfig.output()); + DebugConfig fixedConfig = Debug.fixedConfig(0, Debug.DEFAULT_LOG_LEVEL, false, false, false, false, debugConfig.dumpHandlers(), debugConfig.verifyHandlers(), debugConfig.output()); try (DebugConfigScope s = Debug.setConfig(fixedConfig)) { Debug.dump(graph, title); diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Thu Jul 10 19:36:27 2014 +0200 @@ -464,28 +464,7 @@ assertReadAndWriteInSameBlock(schedule, false); } - /* - * read of field a should be in first block, read of field b in loop begin block - */ - public static void testProxy1Snippet() { - while (container.a < container.b) { - container.b--; - } - container.b++; - } - - @Test - public void testProxy1() { - SchedulePhase schedule = getFinalSchedule("testProxy1Snippet", TestMode.WITHOUT_FRAMESTATES); - assertReadWithinStartBlock(schedule, true); // read of container.a should be in start block - /* - * read of container.b for increment operation should be in return block. TODO: not sure - * though, could be replaced by read of container.b of the loop header... - */ - assertReadWithinAllReturnBlocks(schedule, true); - } - - public static void testProxy2Snippet() { + public static void testProxySnippet() { while (container.a < container.b) { List list = new ArrayList<>(containerList); while (container.c < list.size()) { @@ -501,8 +480,8 @@ } @Test - public void testProxy2() { - SchedulePhase schedule = getFinalSchedule("testProxy2Snippet", TestMode.WITHOUT_FRAMESTATES); + public void testProxy() { + SchedulePhase schedule = getFinalSchedule("testProxySnippet", TestMode.WITHOUT_FRAMESTATES); assertReadWithinStartBlock(schedule, false); assertReadWithinAllReturnBlocks(schedule, false); } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java Thu Jul 10 19:36:27 2014 +0200 @@ -35,52 +35,52 @@ *

* These options enable the associated debug facility if their filter matches the * {@linkplain DebugScope#getQualifiedName() name} of the {@linkplain Debug#currentScope() current - * scope}. + * scope}. For the {@link GraalDebugConfig#Dump} and {@link GraalDebugConfig#Log} options, the log + * or dump level is set. The {@link GraalDebugConfig#Meter} and {@link GraalDebugConfig#Time} + * options don't have a level, for them {@code level = 0} means disabled and a {@code level > 0} + * means enabled. *

- * A filter is a list of comma-separated terms. Each term is interpreted as a glob pattern if it - * contains a "*" or "?" character. Otherwise, it is interpreted as a substring. If a term starts - * with "~", then it is an positive term. An input is matched by a filter if any of its positive - * terms match the input (or it has no positive terms) AND none of its negative terms match the - * input (or it has no negative terms). + * A filter is a list of comma-separated terms of the form {@code [:]}. + * {@code } is interpreted as a glob pattern if it contains a "*" or "?" character. + * Otherwise, it is interpreted as a substring. If {@code } is empty, it matches every + * scope. If {@code :} is omitted, it defaults to {@link Debug#DEFAULT_LOG_LEVEL}. The term + * {@code ~} is a shorthand for {@code :0} to disable a debug facility for a + * pattern. *

- * Examples of filters include: - *

+ * The resulting log level of a scope is determined by the last matching term. If no term + * matches, the log level is 0 (disabled). A filter with no terms matches every scope with a log + * level of {@link Debug#DEFAULT_LOG_LEVEL}. + * + *

Examples of filters

+ * * */ class DebugFilter { @@ -92,69 +92,76 @@ return new DebugFilter(spec.split(",")); } - final Term[] positive; - final Term[] negative; + private final Term[] terms; + + private DebugFilter(String[] terms) { + if (terms.length == 0) { + this.terms = null; + } else { + this.terms = new Term[terms.length]; + for (int i = 0; i < terms.length; i++) { + String t = terms[i]; + int idx = t.indexOf(':'); - DebugFilter(String[] terms) { - List pos = new ArrayList<>(terms.length); - List neg = new ArrayList<>(terms.length); - for (int i = 0; i < terms.length; i++) { - String t = terms[i]; - if (t.startsWith("~")) { - neg.add(new Term(t.substring(1))); - } else { - pos.add(new Term(t)); + String pattern; + int level; + if (idx < 0) { + if (t.startsWith("~")) { + pattern = t.substring(1); + level = 0; + } else { + pattern = t; + level = Debug.DEFAULT_LOG_LEVEL; + } + } else { + pattern = t.substring(0, idx); + if (idx + 1 < t.length()) { + level = Integer.parseInt(t.substring(idx + 1)); + } else { + level = Debug.DEFAULT_LOG_LEVEL; + } + } + + this.terms[i] = new Term(pattern, level); } } - this.positive = pos.isEmpty() ? null : pos.toArray(new Term[pos.size()]); - this.negative = neg.isEmpty() ? null : neg.toArray(new Term[neg.size()]); } /** - * Determines if a given input is matched by this filter. + * Check whether a given input is matched by this filter, and determine the log level. */ - public boolean matches(String input) { - boolean match = true; - if (positive != null) { - match = false; - for (Term t : positive) { + public int matchLevel(String input) { + if (terms == null) { + return Debug.DEFAULT_LOG_LEVEL; + } else { + int level = 0; + for (Term t : terms) { if (t.matches(input)) { - match = true; - break; + level = t.level; } } + return level; } - if (match && negative != null) { - for (Term t : negative) { - if (t.matches(input)) { - match = false; - break; - } - } - } - return match; } @Override public String toString() { - StringBuilder buf = new StringBuilder("DebugFilter["); - String sep = ""; - if (positive != null) { - buf.append(sep).append("pos=").append(Arrays.toString(positive)); - sep = ", "; + StringBuilder buf = new StringBuilder("DebugFilter"); + if (terms != null) { + buf.append(Arrays.toString(terms)); + } else { + buf.append("[]"); } - if (negative != null) { - buf.append(sep).append("neg=").append(Arrays.toString(negative)); - sep = ", "; - } - return buf.append("]").toString(); + return buf.toString(); } - static class Term { + private static class Term { - final Pattern pattern; + private final Pattern pattern; + public final int level; - public Term(String filter) { + public Term(String filter, int level) { + this.level = level; if (filter.isEmpty()) { this.pattern = null; } else if (filter.contains("*") || filter.contains("?")) { @@ -173,7 +180,7 @@ @Override public String toString() { - return pattern == null ? ".*" : pattern.toString(); + return (pattern == null ? ".*" : pattern.toString()) + ":" + level; } } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Thu Jul 10 19:36:27 2014 +0200 @@ -121,8 +121,8 @@ this.output = output; } - public boolean isLogEnabled() { - return isEnabled(logFilter); + public int getLogLevel() { + return getLevel(logFilter); } public boolean isLogEnabledForMethod() { @@ -137,8 +137,8 @@ return isEnabled(trackMemUseFilter); } - public boolean isDumpEnabled() { - return isEnabled(dumpFilter); + public int getDumpLevel() { + return getLevel(dumpFilter); } public boolean isDumpEnabledForMethod() { @@ -162,15 +162,27 @@ } private boolean isEnabled(DebugFilter filter) { - return checkDebugFilter(Debug.currentScope(), filter) && checkMethodFilter(); + return getLevel(filter) > 0; + } + + private int getLevel(DebugFilter filter) { + int level = checkDebugFilter(Debug.currentScope(), filter); + if (level > 0 && !checkMethodFilter()) { + level = 0; + } + return level; } private boolean isEnabledForMethod(DebugFilter filter) { return filter != null && checkMethodFilter(); } - private static boolean checkDebugFilter(String currentScope, DebugFilter filter) { - return filter != null && filter.matches(currentScope); + private static int checkDebugFilter(String currentScope, DebugFilter filter) { + if (filter == null) { + return 0; + } else { + return filter.matchLevel(currentScope); + } } /** @@ -241,7 +253,7 @@ if (e instanceof BailoutException) { return null; } - Debug.setConfig(Debug.fixedConfig(true, true, false, false, false, false, dumpHandlers, verifyHandlers, output)); + Debug.setConfig(Debug.fixedConfig(Debug.DEFAULT_LOG_LEVEL, Debug.DEFAULT_LOG_LEVEL, false, false, false, false, dumpHandlers, verifyHandlers, output)); Debug.log(String.format("Exception occurred in scope: %s", Debug.currentScope())); for (Object o : Debug.context()) { if (o instanceof Graph) { diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Thu Jul 10 19:36:27 2014 +0200 @@ -82,8 +82,14 @@ return config.isDumpEnabledForMethod(); } + public static final int DEFAULT_LOG_LEVEL = 2; + public static boolean isDumpEnabled() { - return ENABLED && DebugScope.getInstance().isDumpEnabled(); + return isDumpEnabled(DEFAULT_LOG_LEVEL); + } + + public static boolean isDumpEnabled(int dumpLevel) { + return ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel); } /** @@ -137,7 +143,11 @@ } public static boolean isLogEnabled() { - return ENABLED && DebugScope.getInstance().isLogEnabled(); + return isLogEnabled(DEFAULT_LOG_LEVEL); + } + + public static boolean isLogEnabled(int logLevel) { + return ENABLED && DebugScope.getInstance().isLogEnabled(logLevel); } @SuppressWarnings("unused") @@ -352,74 +362,106 @@ } } + public static void log(String msg) { + log(DEFAULT_LOG_LEVEL, msg); + } + /** * Prints a message to the current debug scope's logging stream if logging is enabled. * * @param msg the message to log */ - public static void log(String msg) { + public static void log(int logLevel, String msg) { if (ENABLED) { - DebugScope.getInstance().log(msg); + DebugScope.getInstance().log(logLevel, msg); } } + public static void log(String format, Object arg) { + log(DEFAULT_LOG_LEVEL, format, arg); + } + /** * Prints a message to the current debug scope's logging stream if logging is enabled. * * @param format a format string * @param arg the argument referenced by the format specifiers in {@code format} */ - public static void log(String format, Object arg) { + public static void log(int logLevel, String format, Object arg) { if (ENABLED) { - DebugScope.getInstance().log(format, arg); + DebugScope.getInstance().log(logLevel, format, arg); } } + public static void log(String format, Object arg1, Object arg2) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + /** - * @see #log(String, Object) + * @see #log(int, String, Object) */ - public static void log(String format, Object arg1, Object arg2) { + public static void log(int logLevel, String format, Object arg1, Object arg2) { if (ENABLED) { - DebugScope.getInstance().log(format, arg1, arg2); + DebugScope.getInstance().log(logLevel, format, arg1, arg2); } } + public static void log(String format, Object arg1, Object arg2, Object arg3) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); + } + /** - * @see #log(String, Object) + * @see #log(int, String, Object) */ - public static void log(String format, Object arg1, Object arg2, Object arg3) { + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3) { if (ENABLED) { - DebugScope.getInstance().log(format, arg1, arg2, arg3); + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3); } } + public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4); + } + /** - * @see #log(String, Object) + * @see #log(int, String, Object) */ - public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4) { + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4) { if (ENABLED) { - DebugScope.getInstance().log(format, arg1, arg2, arg3, arg4); + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4); } } + public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5); + } + /** - * @see #log(String, Object) + * @see #log(int, String, Object) */ - public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { if (ENABLED) { - DebugScope.getInstance().log(format, arg1, arg2, arg3, arg4, arg5); + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5); } } + public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5, arg6); + } + /** - * @see #log(String, Object) + * @see #log(int, String, Object) */ - public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { if (ENABLED) { - DebugScope.getInstance().log(format, arg1, arg2, arg3, arg4, arg5, arg6); + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5, arg6); } } + public static void logv(String format, Object... args) { + logv(DEFAULT_LOG_LEVEL, format, args); + } + /** * Prints a message to the current debug scope's logging stream. This method must only be called * if debugging is {@linkplain Debug#isEnabled() enabled} as it incurs allocation at the call @@ -429,11 +471,11 @@ * @param format a format string * @param args the arguments referenced by the format specifiers in {@code format} */ - public static void logv(String format, Object... args) { + public static void logv(int logLevel, String format, Object... args) { if (!ENABLED) { throw new InternalError("Use of Debug.logv() must be guarded by a test of Debug.isEnabled()"); } - DebugScope.getInstance().log(format, args); + DebugScope.getInstance().log(logLevel, format, args); } /** @@ -445,30 +487,58 @@ @Deprecated public static void log(String format, Object[] args) { assert false : "shouldn't use this"; - logv(format, args); + log(DEFAULT_LOG_LEVEL, format, args); + } + + /** + * This override exists to catch cases when {@link #log(int, String, Object)} is called with one + * argument bound to a varargs method parameter. It will bind to this method instead of the + * single arg variant and produce a deprecation warning instead of silently wrapping the + * Object[] inside of another Object[]. + */ + @Deprecated + public static void log(int logLevel, String format, Object[] args) { + assert false : "shouldn't use this"; + logv(logLevel, format, args); } public static void dump(Object object, String msg) { - if (ENABLED && DebugScope.getInstance().isDumpEnabled()) { - DebugScope.getInstance().dump(object, msg); + dump(DEFAULT_LOG_LEVEL, object, msg); + } + + public static void dump(int dumpLevel, Object object, String msg) { + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, msg); } } public static void dump(Object object, String format, Object arg) { - if (ENABLED && DebugScope.getInstance().isDumpEnabled()) { - DebugScope.getInstance().dump(object, format, arg); + dump(DEFAULT_LOG_LEVEL, object, format, arg); + } + + public static void dump(int dumpLevel, Object object, String format, Object arg) { + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, format, arg); } } public static void dump(Object object, String format, Object arg1, Object arg2) { - if (ENABLED && DebugScope.getInstance().isDumpEnabled()) { - DebugScope.getInstance().dump(object, format, arg1, arg2); + dump(DEFAULT_LOG_LEVEL, object, format, arg1, arg2); + } + + public static void dump(int dumpLevel, Object object, String format, Object arg1, Object arg2) { + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, format, arg1, arg2); } } public static void dump(Object object, String format, Object arg1, Object arg2, Object arg3) { - if (ENABLED && DebugScope.getInstance().isDumpEnabled()) { - DebugScope.getInstance().dump(object, format, arg1, arg2, arg3); + dump(DEFAULT_LOG_LEVEL, object, format, arg1, arg2, arg3); + } + + public static void dump(int dumpLevel, Object object, String format, Object arg1, Object arg2, Object arg3) { + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, format, arg1, arg2, arg3); } } @@ -481,8 +551,20 @@ @Deprecated public static void dump(Object object, String format, Object[] args) { assert false : "shouldn't use this"; - if (ENABLED && DebugScope.getInstance().isDumpEnabled()) { - DebugScope.getInstance().dump(object, format, args); + dump(DEFAULT_LOG_LEVEL, object, format, args); + } + + /** + * This override exists to catch cases when {@link #dump(int, Object, String, Object)} is called + * with one argument bound to a varargs method parameter. It will bind to this method instead of + * the single arg variant and produce a deprecation warning instead of silently wrapping the + * Object[] inside of another Object[]. + */ + @Deprecated + public static void dump(int dumpLevel, Object object, String format, Object[] args) { + assert false : "shouldn't use this"; + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, format, args); } } @@ -537,8 +619,8 @@ * * @return an object that reverts to the current indentation level when * {@linkplain Indent#close() closed} or null if debugging is disabled - * @see #logAndIndent(String) - * @see #logAndIndent(String, Object) + * @see #logAndIndent(int, String) + * @see #logAndIndent(int, String, Object) */ public static Indent indent() { if (ENABLED) { @@ -548,6 +630,10 @@ return null; } + public static Indent logAndIndent(String msg) { + return logAndIndent(DEFAULT_LOG_LEVEL, msg); + } + /** * A convenience function which combines {@link #log(String)} and {@link #indent()}. * @@ -555,13 +641,17 @@ * @return an object that reverts to the current indentation level when * {@linkplain Indent#close() closed} or null if debugging is disabled */ - public static Indent logAndIndent(String msg) { + public static Indent logAndIndent(int logLevel, String msg) { if (ENABLED) { - return logvAndIndent(msg); + return logvAndIndent(logLevel, msg); } return null; } + public static Indent logAndIndent(String format, Object arg) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg); + } + /** * A convenience function which combines {@link #log(String, Object)} and {@link #indent()}. * @@ -570,45 +660,54 @@ * @return an object that reverts to the current indentation level when * {@linkplain Indent#close() closed} or null if debugging is disabled */ - public static Indent logAndIndent(String format, Object arg) { + public static Indent logAndIndent(int logLevel, String format, Object arg) { + if (ENABLED) { + return logvAndIndent(logLevel, format, arg); + } + return null; + } + + public static Indent logAndIndent(String format, Object arg1, Object arg2) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2) { if (ENABLED) { - return logvAndIndent(format, arg); + return logvAndIndent(logLevel, format, arg1, arg2); + } + return null; + } + + public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2, Object arg3) { + if (ENABLED) { + return logvAndIndent(logLevel, format, arg1, arg2, arg3); } return null; } /** - * @see #logAndIndent(String, Object) - */ - public static Indent logAndIndent(String format, Object arg1, Object arg2) { - if (ENABLED) { - return logvAndIndent(format, arg1, arg2); - } - return null; - } - - /** - * @see #logAndIndent(String, Object) - */ - public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3) { - if (ENABLED) { - return logvAndIndent(format, arg1, arg2, arg3); - } - return null; - } - - /** - * A convenience function which combines {@link #logv(String, Object...)} and {@link #indent()}. + * A convenience function which combines {@link #logv(int, String, Object...)} and + * {@link #indent()}. * * @param format a format string * @param args the arguments referenced by the format specifiers in {@code format} * @return an object that reverts to the current indentation level when * {@linkplain Indent#close() closed} or null if debugging is disabled */ - public static Indent logvAndIndent(String format, Object... args) { + public static Indent logvAndIndent(int logLevel, String format, Object... args) { if (ENABLED) { DebugScope scope = DebugScope.getInstance(); - scope.log(format, args); + scope.log(logLevel, format, args); return scope.pushIndentLogger(); } throw new InternalError("Use of Debug.logvAndIndent() must be guarded by a test of Debug.isEnabled()"); @@ -623,7 +722,19 @@ @Deprecated public static void logAndIndent(String format, Object[] args) { assert false : "shouldn't use this"; - logvAndIndent(format, args); + logAndIndent(DEFAULT_LOG_LEVEL, format, args); + } + + /** + * This override exists to catch cases when {@link #logAndIndent(int, String, Object)} is called + * with one argument bound to a varargs method parameter. It will bind to this method instead of + * the single arg variant and produce a deprecation warning instead of silently wrapping the + * Object[] inside of another Object[]. + */ + @Deprecated + public static void logAndIndent(int logLevel, String format, Object[] args) { + assert false : "shouldn't use this"; + logvAndIndent(logLevel, format, args); } public static Iterable context() { @@ -845,20 +956,20 @@ } public static DebugConfig silentConfig() { - return fixedConfig(false, false, false, false, false, false, Collections. emptyList(), Collections. emptyList(), null); + return fixedConfig(0, 0, false, false, false, false, Collections. emptyList(), Collections. emptyList(), null); } - public static DebugConfig fixedConfig(final boolean isLogEnabled, final boolean isDumpEnabled, final boolean isMeterEnabled, final boolean isMemUseTrackingEnabled, final boolean isTimerEnabled, + public static DebugConfig fixedConfig(final int logLevel, final int dumpLevel, final boolean isMeterEnabled, final boolean isMemUseTrackingEnabled, final boolean isTimerEnabled, final boolean isVerifyEnabled, final Collection dumpHandlers, final Collection verifyHandlers, final PrintStream output) { return new DebugConfig() { @Override - public boolean isLogEnabled() { - return isLogEnabled; + public int getLogLevel() { + return logLevel; } public boolean isLogEnabledForMethod() { - return isLogEnabled; + return logLevel > 0; } @Override @@ -872,12 +983,12 @@ } @Override - public boolean isDumpEnabled() { - return isDumpEnabled; + public int getDumpLevel() { + return dumpLevel; } public boolean isDumpEnabledForMethod() { - return isDumpEnabled; + return dumpLevel > 0; } @Override diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java Thu Jul 10 19:36:27 2014 +0200 @@ -28,9 +28,16 @@ public interface DebugConfig { /** - * Determines if logging is on in the {@linkplain Debug#currentScope() current debug scope} . + * Determines the current log level in the {@linkplain Debug#currentScope() current debug scope} + * . */ - boolean isLogEnabled(); + int getLogLevel(); + + /** + * Determines the current dump level in the {@linkplain Debug#currentScope() current debug + * scope}. + */ + int getDumpLevel(); /** * Determines if logging can be enabled in the current method, regardless of the @@ -55,14 +62,6 @@ boolean isMemUseTrackingEnabled(); /** - * Determines if dumping is enabled in the {@linkplain Debug#currentScope() current debug scope} - * . - * - * @see Debug#dump(Object, String) - */ - boolean isDumpEnabled(); - - /** * Determines if dumping can be enabled in the current method, regardless of the * {@linkplain Debug#currentScope() current debug scope}. */ diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java Thu Jul 10 19:36:27 2014 +0200 @@ -83,6 +83,18 @@ private final Map featureState = new EnumMap<>(Feature.class); /** + * The debug levels of a {@link DelegatingDebugConfig} than can be + * {@linkplain DelegatingDebugConfig#override(Level, int) overridden} or + * {@linkplain DelegatingDebugConfig#delegate(Level) delegated}. + */ + public enum Level { + LOG, + DUMP + } + + private final Map levelState = new EnumMap<>(Level.class); + + /** * Creates a config that delegates to the {@link DebugScope#getConfig() current config}. */ public DelegatingDebugConfig() { @@ -106,18 +118,28 @@ return this; } + public DelegatingDebugConfig override(Level level, int newLevel) { + levelState.put(level, newLevel); + return this; + } + public DelegatingDebugConfig delegate(Feature feature) { featureState.put(feature, null); return this; } + public DelegatingDebugConfig delegate(Level level) { + levelState.put(level, null); + return this; + } + @Override - public boolean isLogEnabled() { - Boolean fs = featureState.get(Feature.LOG); - if (fs == null) { - return delegate.isLogEnabled(); + public int getLogLevel() { + Integer ls = levelState.get(Level.LOG); + if (ls == null) { + return delegate.getLogLevel(); } - return fs.booleanValue(); + return ls.intValue(); } public boolean isLogEnabledForMethod() { @@ -146,12 +168,12 @@ } @Override - public boolean isDumpEnabled() { - Boolean fs = featureState.get(Feature.DUMP); - if (fs == null) { - return delegate.isDumpEnabled(); + public int getDumpLevel() { + Integer ls = levelState.get(Level.DUMP); + if (ls == null) { + return delegate.getDumpLevel(); } - return fs.booleanValue(); + return ls.intValue(); } public boolean isDumpEnabledForMethod() { diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java Thu Jul 10 19:36:27 2014 +0200 @@ -52,8 +52,8 @@ } } - public void log(String msg, Object... args) { - if (isLogEnabled()) { + public void log(int logLevel, String msg, Object... args) { + if (isLogEnabled(logLevel)) { StringBuilder str = new StringBuilder(); printScopeName(str); str.append(indent); @@ -102,9 +102,10 @@ private boolean meterEnabled; private boolean timeEnabled; private boolean memUseTrackingEnabled; - private boolean dumpEnabled; private boolean verifyEnabled; - private boolean logEnabled; + + private int currentDumpLevel; + private int currentLogLevel; private PrintStream output; @@ -163,16 +164,18 @@ lastClosedTL.set(this); } - public boolean isDumpEnabled() { - return dumpEnabled; + public boolean isDumpEnabled(int dumpLevel) { + assert dumpLevel > 0; + return currentDumpLevel >= dumpLevel; } public boolean isVerifyEnabled() { return verifyEnabled; } - public boolean isLogEnabled() { - return logEnabled; + public boolean isLogEnabled(int logLevel) { + assert logLevel > 0; + return currentLogLevel >= logLevel; } public boolean isMeterEnabled() { @@ -187,12 +190,12 @@ return memUseTrackingEnabled; } - public void log(String msg, Object... args) { - lastUsedIndent.log(msg, args); + public void log(int logLevel, String msg, Object... args) { + lastUsedIndent.log(logLevel, msg, args); } - public void dump(Object object, String formatString, Object... args) { - if (isDumpEnabled()) { + public void dump(int dumpLevel, Object object, String formatString, Object... args) { + if (isDumpEnabled(dumpLevel)) { DebugConfig config = getConfig(); if (config != null) { String message = String.format(formatString, args); @@ -289,9 +292,10 @@ meterEnabled = false; memUseTrackingEnabled = false; timeEnabled = false; - dumpEnabled = false; verifyEnabled = false; + currentDumpLevel = 0; + // Be pragmatic: provide a default log stream to prevent a crash if the stream is not // set while logging output = TTY.cachedOut; @@ -299,10 +303,10 @@ meterEnabled = config.isMeterEnabled(); memUseTrackingEnabled = config.isMemUseTrackingEnabled(); timeEnabled = config.isTimeEnabled(); - dumpEnabled = config.isDumpEnabled(); verifyEnabled = config.isVerifyEnabled(); - logEnabled = config.isLogEnabled(); output = config.output(); + currentDumpLevel = config.getDumpLevel(); + currentLogLevel = config.getLogLevel(); } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.hotspot.loader/src/com/oracle/graal/hotspot/loader/Factory.java --- a/graal/com.oracle.graal.hotspot.loader/src/com/oracle/graal/hotspot/loader/Factory.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.loader/src/com/oracle/graal/hotspot/loader/Factory.java Thu Jul 10 19:36:27 2014 +0200 @@ -32,8 +32,11 @@ /** * Creates a new class loader for loading classes in {@code graal.jar}. + * + * Called from the VM. */ - public static ClassLoader newClassLoader() throws MalformedURLException { + @SuppressWarnings("unused") + private static ClassLoader newClassLoader() throws MalformedURLException { URL[] urls = {getGraalJarUrl()}; return URLClassLoader.newInstance(urls); } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.hotspot.sourcegen/src/com/oracle/graal/hotspot/sourcegen/GenGraalRuntimeInlineHpp.java --- a/graal/com.oracle.graal.hotspot.sourcegen/src/com/oracle/graal/hotspot/sourcegen/GenGraalRuntimeInlineHpp.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.sourcegen/src/com/oracle/graal/hotspot/sourcegen/GenGraalRuntimeInlineHpp.java Thu Jul 10 19:36:27 2014 +0200 @@ -166,7 +166,7 @@ out.printf(" if (strncmp(name, \"PrintFlags\", %d) == 0) {%n", len); out.println(" if (value[0] == '+') {"); out.println(" if (check_only) {"); - out.println(" TempNewSymbol name = SymbolTable::new_symbol(\"Lcom/oracle/graal/hotspot/HotSpotOptions;\", THREAD);"); + out.println(" TempNewSymbol name = SymbolTable::new_symbol(\"Lcom/oracle/graal/hotspot/HotSpotOptions;\", CHECK_(true));"); out.println(" hotSpotOptionsClass = SystemDictionary::resolve_or_fail(name, true, CHECK_(true));"); out.println(" }"); out.println(" set_option_helper(hotSpotOptionsClass, name, name_len, Handle(), '?', Handle(), 0L);"); diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Thu Jul 10 19:36:27 2014 +0200 @@ -692,7 +692,7 @@ }; DebugConfig debugConfig = DebugScope.getConfig(); - DebugConfig fixedConfig = Debug.fixedConfig(false, false, false, false, false, false, debugConfig.dumpHandlers(), debugConfig.verifyHandlers(), debugConfig.output()); + DebugConfig fixedConfig = Debug.fixedConfig(0, 0, false, false, false, false, debugConfig.dumpHandlers(), debugConfig.verifyHandlers(), debugConfig.output()); try (DebugConfigScope s = Debug.setConfig(fixedConfig)) { ReentrantNodeIterator.apply(closure, graph.start(), false); new WriteBarrierVerificationPhase().apply(graph); diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/LocalImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/LocalImpl.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/LocalImpl.java Thu Jul 10 19:36:27 2014 +0200 @@ -33,19 +33,14 @@ private final int startBci; private final int endBci; private final int slot; - private final ResolvedJavaType resolvedType; + private final JavaType type; public LocalImpl(String name, String type, HotSpotResolvedObjectType holder, int startBci, int endBci, int slot) { this.name = name; this.startBci = startBci; this.endBci = endBci; this.slot = slot; - JavaType t = runtime().lookupType(type, holder, true); - if (t instanceof ResolvedJavaType) { - this.resolvedType = (ResolvedJavaType) runtime().lookupType(type, holder, false); - } else { - throw new AssertionError(t.getClass() + " is not a ResolvedJavaType"); - } + this.type = runtime().lookupType(type, holder, false); } @Override @@ -64,8 +59,8 @@ } @Override - public ResolvedJavaType getType() { - return resolvedType; + public JavaType getType() { + return type; } @Override @@ -79,7 +74,7 @@ return false; } LocalImpl that = (LocalImpl) obj; - return this.name.equals(that.name) && this.startBci == that.startBci && this.endBci == that.endBci && this.slot == that.slot && this.resolvedType.equals(that.resolvedType); + return this.name.equals(that.name) && this.startBci == that.startBci && this.endBci == that.endBci && this.slot == that.slot && this.type.equals(that.type); } @Override @@ -89,6 +84,6 @@ @Override public String toString() { - return "LocalImpl"; + return "LocalImpl"; } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -67,12 +67,4 @@ @NodeIntrinsic public static native Word fetchUnrollInfo(long registerSaver); - - public MemoryCheckpoint asMemoryCheckpoint() { - return null; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -96,12 +96,4 @@ */ @NodeIntrinsic public static native Word compareAndSwap(Object object, long offset, Word expectedValue, Word newValue, @ConstantNodeParameter LocationIdentity locationIdentity); - - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SaveAllRegistersNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SaveAllRegistersNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SaveAllRegistersNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -24,15 +24,18 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.lir.StandardOp.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; /** * Saves all allocatable registers. */ -public class SaveAllRegistersNode extends FixedWithNextNode implements LIRLowerable { +@NodeInfo(allowedUsageTypes = {InputType.Memory}) +public class SaveAllRegistersNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Single { private SaveRegistersOp saveRegistersOp; @@ -59,4 +62,8 @@ */ @NodeIntrinsic public static native long saveAllRegisters(); + + public LocationIdentity getLocationIdentity() { + return LocationIdentity.ANY_LOCATION; + } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -22,10 +22,13 @@ */ package com.oracle.graal.hotspot.nodes; +import java.util.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; @@ -54,7 +57,10 @@ @Override public LocationIdentity[] getLocationIdentities() { - return foreignCalls.getKilledLocations(descriptor); + LocationIdentity[] killedLocations = foreignCalls.getKilledLocations(descriptor); + killedLocations = Arrays.copyOf(killedLocations, killedLocations.length + 1); + killedLocations[killedLocations.length - 1] = HotSpotReplacementsUtil.PENDING_EXCEPTION_LOCATION; + return killedLocations; } protected Value[] operands(NodeLIRBuilderTool gen) { @@ -83,12 +89,4 @@ } return super.toString(verbosity); } - - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/UncommonTrapCallNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/UncommonTrapCallNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/UncommonTrapCallNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -70,12 +70,4 @@ @NodeIntrinsic public static native Word uncommonTrap(long registerSaver, int trapRequest); - - public MemoryCheckpoint asMemoryCheckpoint() { - return null; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Thu Jul 10 19:36:27 2014 +0200 @@ -24,6 +24,7 @@ import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.HeapAccess.BarrierType; @@ -90,74 +91,66 @@ private void addWriteNodeBarriers(WriteNode node, StructuredGraph graph) { BarrierType barrierType = node.getBarrierType(); - if (barrierType == BarrierType.PRECISE) { - if (useG1GC()) { - if (!node.isInitialization()) { - addG1PreWriteBarrier(node, node.object(), null, node.location(), true, node.getNullCheck(), graph); + switch (barrierType) { + case NONE: + // nothing to do + break; + case IMPRECISE: + case PRECISE: + boolean precise = barrierType == BarrierType.PRECISE; + if (useG1GC()) { + if (!node.isInitialization()) { + addG1PreWriteBarrier(node, node.object(), null, node.location(), true, node.getNullCheck(), graph); + } + addG1PostWriteBarrier(node, node.object(), node.value(), node.location(), precise, graph); + } else { + addSerialPostWriteBarrier(node, node.object(), node.value(), node.location(), precise, graph); } - addG1PostWriteBarrier(node, node.object(), node.value(), node.location(), true, graph); - } else { - addSerialPostWriteBarrier(node, node.object(), node.value(), node.location(), true, graph); - } - } else if (barrierType == BarrierType.IMPRECISE) { - if (useG1GC()) { - if (!node.isInitialization()) { - addG1PreWriteBarrier(node, node.object(), null, node.location(), true, node.getNullCheck(), graph); - } - addG1PostWriteBarrier(node, node.object(), node.value(), node.location(), false, graph); - } else { - addSerialPostWriteBarrier(node, node.object(), node.value(), node.location(), false, graph); - } - } else { - assert barrierType == BarrierType.NONE; + break; + default: + throw new GraalInternalError("unexpected barrier type: " + barrierType); } } - private void addAtomicReadWriteNodeBarriers(LoweredAtomicReadAndWriteNode loweredAtomicReadAndWriteNode, StructuredGraph graph) { - BarrierType barrierType = loweredAtomicReadAndWriteNode.getBarrierType(); - if (barrierType == BarrierType.PRECISE) { - if (useG1GC()) { - addG1PreWriteBarrier(loweredAtomicReadAndWriteNode, loweredAtomicReadAndWriteNode.object(), null, loweredAtomicReadAndWriteNode.location(), true, - loweredAtomicReadAndWriteNode.getNullCheck(), graph); - addG1PostWriteBarrier(loweredAtomicReadAndWriteNode, loweredAtomicReadAndWriteNode.object(), loweredAtomicReadAndWriteNode.getNewValue(), loweredAtomicReadAndWriteNode.location(), - true, graph); - } else { - addSerialPostWriteBarrier(loweredAtomicReadAndWriteNode, loweredAtomicReadAndWriteNode.object(), loweredAtomicReadAndWriteNode.getNewValue(), loweredAtomicReadAndWriteNode.location(), - true, graph); - } - } else if (barrierType == BarrierType.IMPRECISE) { - if (useG1GC()) { - addG1PreWriteBarrier(loweredAtomicReadAndWriteNode, loweredAtomicReadAndWriteNode.object(), null, loweredAtomicReadAndWriteNode.location(), true, - loweredAtomicReadAndWriteNode.getNullCheck(), graph); - addG1PostWriteBarrier(loweredAtomicReadAndWriteNode, loweredAtomicReadAndWriteNode.object(), loweredAtomicReadAndWriteNode.getNewValue(), loweredAtomicReadAndWriteNode.location(), - false, graph); - } else { - addSerialPostWriteBarrier(loweredAtomicReadAndWriteNode, loweredAtomicReadAndWriteNode.object(), loweredAtomicReadAndWriteNode.getNewValue(), loweredAtomicReadAndWriteNode.location(), - false, graph); - } - } else { - assert barrierType == BarrierType.NONE; + private void addAtomicReadWriteNodeBarriers(LoweredAtomicReadAndWriteNode node, StructuredGraph graph) { + BarrierType barrierType = node.getBarrierType(); + switch (barrierType) { + case NONE: + // nothing to do + break; + case IMPRECISE: + case PRECISE: + boolean precise = barrierType == BarrierType.PRECISE; + if (useG1GC()) { + addG1PreWriteBarrier(node, node.object(), null, node.location(), true, node.getNullCheck(), graph); + addG1PostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), precise, graph); + } else { + addSerialPostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), precise, graph); + } + break; + default: + throw new GraalInternalError("unexpected barrier type: " + barrierType); } } private void addCASBarriers(LoweredCompareAndSwapNode node, StructuredGraph graph) { BarrierType barrierType = node.getBarrierType(); - if (barrierType == BarrierType.PRECISE) { - if (useG1GC()) { - addG1PreWriteBarrier(node, node.object(), node.getExpectedValue(), node.location(), false, false, graph); - addG1PostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), true, graph); - } else { - addSerialPostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), true, graph); - } - } else if (barrierType == BarrierType.IMPRECISE) { - if (useG1GC()) { - addG1PreWriteBarrier(node, node.object(), node.getExpectedValue(), node.location(), false, false, graph); - addG1PostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), false, graph); - } else { - addSerialPostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), false, graph); - } - } else { - assert barrierType == BarrierType.NONE; + switch (barrierType) { + case NONE: + // nothing to do + break; + case IMPRECISE: + case PRECISE: + boolean precise = barrierType == BarrierType.PRECISE; + if (useG1GC()) { + addG1PreWriteBarrier(node, node.object(), node.getExpectedValue(), node.location(), false, false, graph); + addG1PostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), precise, graph); + } else { + addSerialPostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), precise, graph); + } + break; + default: + throw new GraalInternalError("unexpected barrier type: " + barrierType); } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AssertionSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AssertionSnippets.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AssertionSnippets.java Thu Jul 10 19:36:27 2014 +0200 @@ -67,9 +67,6 @@ @NodeIntrinsic(ForeignCallNode.class) private static native void vmMessageC(@ConstantNodeParameter ForeignCallDescriptor stubPrintfC, boolean vmError, Word format, long v1, long v2, long v3); - @NodeIntrinsic(StubForeignCallNode.class) - private static native void stubVmMessageC(@ConstantNodeParameter ForeignCallDescriptor stubPrintfC, boolean vmError, Word format, long v1, long v2, long v3); - public static class Templates extends AbstractTemplates { private final SnippetInfo assertion = snippet(AssertionSnippets.class, "assertion"); diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java Thu Jul 10 19:36:27 2014 +0200 @@ -135,7 +135,7 @@ * Stack bang to make sure there's enough room for the interpreter frames. Bang stack for * total size of the interpreter frames plus shadow page size. Bang one page at a time * because large sizes can bang beyond yellow and red zones. - * + * * @deprecated This code should go away as soon as JDK-8032410 hits the Graal repository. */ final int totalFrameSizes = unrollBlock.readInt(deoptimizationUnrollBlockTotalFrameSizesOffset()); @@ -143,7 +143,7 @@ Word stackPointer = readRegister(stackPointerRegister); for (int i = 1; i < bangPages; i++) { - stackPointer.writeInt((-i * pageSize()) + stackBias(), 0); + stackPointer.writeInt((-i * pageSize()) + stackBias(), 0, UncommonTrapStub.STACK_BANG_LOCATION); } // Load number of interpreter frames. diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Thu Jul 10 19:36:27 2014 +0200 @@ -43,6 +43,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.phases.tiers.*; //JaCoCo Exclude @@ -160,8 +161,10 @@ compResult = new CompilationResult(toString()); try (Scope s0 = Debug.scope("StubCompilation", graph, providers.getCodeCache())) { Assumptions assumptions = new Assumptions(OptAssumptions.getValue()); + Suites defaultSuites = providers.getSuites().getDefaultSuites(); + Suites suites = new Suites(new PhaseSuite<>(), defaultSuites.getMidTier(), defaultSuites.getLowTier()); SchedulePhase schedule = emitFrontEnd(providers, target, graph, assumptions, null, providers.getSuites().getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, - getProfilingInfo(graph), null, providers.getSuites().getDefaultSuites()); + getProfilingInfo(graph), null, suites); emitBackEnd(graph, Stub.this, incomingCc, getInstalledCodeOwner(), backend, target, compResult, CompilationResultBuilderFactory.Default, assumptions, schedule, getRegisterConfig()); } catch (Throwable e) { throw Debug.handle(e); diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java Thu Jul 10 19:36:27 2014 +0200 @@ -77,6 +77,8 @@ */ public class UncommonTrapStub extends SnippetStub { + public static final LocationIdentity STACK_BANG_LOCATION = new NamedLocationIdentity("stack bang"); + private final TargetDescription target; public UncommonTrapStub(HotSpotProviders providers, TargetDescription target, HotSpotForeignCallLinkage linkage) { @@ -152,7 +154,7 @@ Word stackPointer = readRegister(stackPointerRegister); for (int i = 1; i < bangPages; i++) { - stackPointer.writeInt((-i * pageSize()) + stackBias(), 0); + stackPointer.writeInt((-i * pageSize()) + stackBias(), 0, STACK_BANG_LOCATION); } // Load number of interpreter frames. diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_l2f.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_l2f.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_l2f.java Thu Jul 10 19:36:27 2014 +0200 @@ -49,4 +49,14 @@ runTest("test", -74652389L); } + @Test + public void run3() throws Throwable { + runTest("test", Long.MAX_VALUE); + } + + @Test + public void run4() throws Throwable { + runTest("test", Long.MIN_VALUE); + } + } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Thu Jul 10 19:36:27 2014 +0200 @@ -332,7 +332,7 @@ * VirtualState nodes contained in the old exit's state may be shared by other * dominated VirtualStates. Those dominated virtual states need to see the * proxy->phi update that are applied below. - * + * * We now update the original fragment's nodes accordingly: */ originalExitState.applyToVirtual(node -> original.nodes.clearAndGrow(node)); @@ -357,8 +357,6 @@ phi = graph.addWithoutUnique(new ValuePhiNode(vpn.stamp(), merge)); } else if (vpn instanceof GuardProxyNode) { phi = graph.addWithoutUnique(new GuardPhiNode(merge)); - } else if (vpn instanceof MemoryProxyNode) { - phi = graph.addWithoutUnique(new MemoryPhiNode(merge, ((MemoryProxyNode) vpn).getLocationIdentity())); } else { throw GraalInternalError.shouldNotReachHere(); } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java --- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/IntegerStampTest.java Thu Jul 10 19:36:27 2014 +0200 @@ -299,4 +299,16 @@ assertFalse(new IntegerStamp(32, 0, 0xff00, 0, 0xff00).join(new IntegerStamp(32, 1, 0xff, 0x00, 0xff)).isLegal()); assertFalse(new IntegerStamp(32, 0x100, 0xff00, 0, 0xff00).join(new IntegerStamp(32, 0, 0xff, 0x00, 0xff)).isLegal()); } + + @Test + public void testShiftLeft() { + assertEquals(new IntegerStamp(32, 0, 0x1ff, 0, 0x1ff), StampTool.leftShift(new IntegerStamp(32, 0, 0xff, 0, 0xff), new IntegerStamp(32, 0, 1, 0, 1))); + assertEquals(new IntegerStamp(32, 0, 0x1fe0, 0, 0x1fe0), StampTool.leftShift(new IntegerStamp(32, 0, 0xff, 0, 0xff), new IntegerStamp(32, 5, 5, 5, 5))); + assertEquals(new IntegerStamp(32, 0x1e0, 0x1fe0, 0, 0x1fe0), StampTool.leftShift(new IntegerStamp(32, 0xf, 0xff, 0, 0xff), new IntegerStamp(32, 5, 5, 5, 5))); + + assertEquals(new IntegerStamp(64, 0, 0x1ff, 0, 0x1ff), StampTool.leftShift(new IntegerStamp(64, 0, 0xff, 0, 0xff), new IntegerStamp(32, 0, 1, 0, 1))); + assertEquals(new IntegerStamp(64, 0, 0x1fe0, 0, 0x1fe0), StampTool.leftShift(new IntegerStamp(64, 0, 0xff, 0, 0xff), new IntegerStamp(32, 5, 5, 5, 5))); + assertEquals(new IntegerStamp(64, 0x1e0, 0x1fe0, 0, 0x1fe0), StampTool.leftShift(new IntegerStamp(64, 0xf, 0xff, 0, 0xff), new IntegerStamp(32, 5, 5, 5, 5))); + + } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMemoryCheckpoint.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMemoryCheckpoint.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractMemoryCheckpoint.java Thu Jul 10 19:36:27 2014 +0200 @@ -37,12 +37,4 @@ protected AbstractMemoryCheckpoint(Stamp stamp, FrameState stateAfter) { super(stamp, stateAfter); } - - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -224,9 +224,7 @@ if (nodeClass.inputsEqual(trueNext, falseNext) && nodeClass.valueEqual(trueNext, falseNext)) { falseNext.replaceAtUsages(trueNext); graph().removeFixed(falseNext); - FixedNode next = trueNext.next(); - trueNext.setNext(null); - trueNext.replaceAtPredecessor(next); + GraphUtil.unlinkFixedNode(trueNext); graph().addBeforeFixed(this, trueNext); for (Node usage : trueNext.usages().snapshot()) { if (usage.isAlive()) { @@ -246,7 +244,8 @@ } } } - } while (false); + break; + } while (true); } /** diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -232,12 +232,4 @@ updateUsagesInterface(this.guard, guard); this.guard = guard; } - - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -48,12 +48,4 @@ public LocationIdentity getLocationIdentity() { return locationIdentity; } - - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryPhiNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -45,14 +45,6 @@ return locationIdentity; } - public MemoryCheckpoint asMemoryCheckpoint() { - return null; - } - - public MemoryPhiNode asMemoryPhi() { - return this; - } - @Override public NodeInputList values() { return values; diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryProxyNode.java Tue Jul 08 20:19:34 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2012, 2014, 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 com.oracle.graal.nodes; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; - -@NodeInfo(allowedUsageTypes = {InputType.Memory}) -public class MemoryProxyNode extends ProxyNode implements MemoryProxy, LIRLowerable { - - @Input(InputType.Memory) private MemoryNode value; - private final LocationIdentity identity; - - public MemoryProxyNode(MemoryNode value, BeginNode exit, LocationIdentity identity) { - super(StampFactory.forVoid(), exit); - this.value = value; - this.identity = identity; - } - - @Override - public ValueNode value() { - return value.asNode(); - } - - public LocationIdentity getLocationIdentity() { - return identity; - } - - @Override - public void generate(NodeLIRBuilderTool generator) { - } - - @Override - public boolean verify() { - assert value() instanceof MemoryNode : this + " " + value(); - return super.verify(); - } - - public MemoryNode getOriginalMemoryNode() { - return (MemoryNode) value(); - } - - public MemoryCheckpoint asMemoryCheckpoint() { - return getOriginalMemoryNode().asMemoryCheckpoint(); - } - - public MemoryPhiNode asMemoryPhi() { - return getOriginalMemoryNode().asMemoryPhi(); - } - - public Node getOriginalNode() { - return value.asNode(); - } -} diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.nodes; -import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.ValueNumberable; @@ -57,10 +56,6 @@ return super.verify(); } - public static MemoryProxyNode forMemory(MemoryNode value, BeginNode exit, LocationIdentity location, StructuredGraph graph) { - return graph.unique(new MemoryProxyNode(value, exit, location)); - } - public static ValueProxyNode forValue(ValueNode value, BeginNode exit, StructuredGraph graph) { return graph.unique(new ValueProxyNode(value, exit)); } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StartNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -36,12 +36,4 @@ public LocationIdentity getLocationIdentity() { return LocationIdentity.ANY_LOCATION; } - - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Thu Jul 10 19:36:27 2014 +0200 @@ -259,9 +259,7 @@ ((BeginNode) node).prepareDelete(); } assert node.usages().isEmpty() : node + " " + node.usages(); - FixedNode next = node.next(); - node.setNext(null); - node.replaceAtPredecessor(next); + GraphUtil.unlinkFixedNode(node); node.safeDelete(); } @@ -288,9 +286,7 @@ public void replaceFixedWithFloating(FixedWithNextNode node, FloatingNode replacement) { assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement; - FixedNode next = node.next(); - node.setNext(null); - node.replaceAtPredecessor(next); + GraphUtil.unlinkFixedNode(node); node.replaceAtUsages(replacement); node.safeDelete(); } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -92,12 +92,4 @@ updateUsages(lastLocationAccess, newLla); lastLocationAccess = newLla; } - - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -30,6 +30,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; /** * Location node that is the sum of two other location nodes. Can represent locations in the form of @@ -112,6 +113,11 @@ return getY().generateAddress(builder, gen, xAddr); } + @Override + public IntegerStamp getDisplacementStamp() { + return StampTool.add(getX().getDisplacementStamp(), getY().getDisplacementStamp()); + } + @NodeIntrinsic public static native Location addLocation(Location x, Location y); } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -73,4 +73,9 @@ public Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base) { return gen.emitAddress(base, getDisplacement(), Value.ILLEGAL, 0); } + + @Override + public IntegerStamp getDisplacementStamp() { + return StampFactory.forInteger(64, displacement, displacement); + } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -82,7 +82,8 @@ @Override public boolean verify() { MemoryNode lla = getLastLocationAccess(); - assert lla == null || lla.asMemoryCheckpoint() != null || lla.asMemoryPhi() != null : "lastLocationAccess of " + this + " should be a MemoryCheckpoint, but is " + lla; + assert lla == null || lla instanceof MemoryCheckpoint || lla instanceof MemoryProxy || lla instanceof MemoryPhiNode : "lastLocationAccess of " + this + + " should be a MemoryCheckpoint, but is " + lla; return super.verify(); } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.extended; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; @@ -29,6 +30,7 @@ import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; /** * Location node that has a displacement and a scaled index. Can represent locations in the form of @@ -101,6 +103,14 @@ } @Override + public IntegerStamp getDisplacementStamp() { + assert indexScaling > 0 && CodeUtil.isPowerOf2(indexScaling); + int scale = CodeUtil.log2(indexScaling); + return (IntegerStamp) StampTool.add(StampFactory.forInteger(64, displacement, displacement), + StampTool.signExtend(StampTool.leftShift(index.stamp(), StampFactory.forInteger(64, scale, scale)), 64)); + } + + @Override public Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base) { return gen.emitAddress(base, displacement, builder.operand(getIndex()), getIndexScaling()); } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -64,4 +64,9 @@ } public abstract Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base); + + /** + * @return the range of the displacement as a 64-bit integer stamp + */ + public abstract IntegerStamp getDisplacementStamp(); } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MembarNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -62,14 +62,6 @@ generator.getLIRGeneratorTool().emitMembar(barriers); } - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } - @SuppressWarnings("unused") @NodeIntrinsic public static void memoryBarrier(@ConstantNodeParameter int barriers) { diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/MemoryNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -31,8 +31,4 @@ public interface MemoryNode extends NodeInterface { ValueNode asNode(); - - MemoryCheckpoint asMemoryCheckpoint(); - - MemoryPhiNode asMemoryPhi(); } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -120,14 +120,6 @@ return stateAfter; } - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } - // specialized on value type until boxing/unboxing is sorted out in intrinsification @SuppressWarnings("unused") diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -70,12 +70,4 @@ assertTrue(stateAfter() != null, "an exception handler needs a frame state"); return super.verify(); } - - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -69,14 +69,6 @@ gen.setResult(this, result); } - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } - public boolean canNullCheck() { return false; } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -84,12 +84,4 @@ Value result = gen.getLIRGeneratorTool().emitCompareAndSwap(address, gen.operand(getExpectedValue()), gen.operand(getNewValue()), Constant.INT_1, Constant.INT_0); gen.setResult(this, result); } - - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -47,6 +47,10 @@ this.escapedReturnValue = escapedReturnValue; } + public ValueNode getEscapedReturnValue() { + return escapedReturnValue; + } + public void setEscapedReturnValue(ValueNode x) { updateUsages(escapedReturnValue, x); this.escapedReturnValue = x; diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java Thu Jul 10 19:36:27 2014 +0200 @@ -298,6 +298,18 @@ } int shiftBits = bits > 32 ? 6 : 5; long shiftMask = bits > 32 ? 0x3FL : 0x1FL; + if (shift.lowerBound() == shift.upperBound()) { + int shiftAmount = (int) (shift.lowerBound() & shiftMask); + if (shiftAmount == 0) { + return value; + } + // the mask of bits that will be lost or shifted into the sign bit + long removedBits = -1L << (bits - shiftAmount - 1); + if ((value.lowerBound() & removedBits) == 0 && (value.upperBound() & removedBits) == 0) { + // use a better stamp if neither lower nor upper bound can lose bits + return new IntegerStamp(bits, value.lowerBound() << shiftAmount, value.upperBound() << shiftAmount, value.downMask() << shiftAmount, value.upMask() << shiftAmount); + } + } if ((shift.lowerBound() >>> shiftBits) == (shift.upperBound() >>> shiftBits)) { long downMask = defaultMask; long upMask = 0; diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Thu Jul 10 19:36:27 2014 +0200 @@ -157,10 +157,15 @@ killWithUnusedFloatingInputs(stateAfter); } } + unlinkFixedNode(fixed); + killWithUnusedFloatingInputs(fixed); + } + + public static void unlinkFixedNode(FixedWithNextNode fixed) { + assert fixed.next() != null && fixed.predecessor() != null && fixed.isAlive(); FixedNode next = fixed.next(); fixed.setNext(null); fixed.replaceAtPredecessor(next); - killWithUnusedFloatingInputs(fixed); } public static void checkRedundantPhi(PhiNode phiNode) { diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConvertDeoptimizeToGuardPhase.java Thu Jul 10 19:36:27 2014 +0200 @@ -54,6 +54,7 @@ @Override protected void run(final StructuredGraph graph) { + assert graph.hasValueProxies() : "ConvertDeoptimizeToGuardPhase always creates proxies"; if (graph.getNodes(DeoptimizeNode.class).isEmpty()) { return; } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Thu Jul 10 19:36:27 2014 +0200 @@ -43,10 +43,9 @@ public class FloatingReadPhase extends Phase { - public enum ExecutionMode { - ANALYSIS_ONLY, - CREATE_FLOATING_READS - } + private boolean createFloatingReads; + private boolean createMemoryMapNodes; + private boolean updateExistingPhis; public static class MemoryMapImpl implements MemoryMap { @@ -90,14 +89,23 @@ } } - private final ExecutionMode execmode; - public FloatingReadPhase() { - this(ExecutionMode.CREATE_FLOATING_READS); + this(true, false, false); } - public FloatingReadPhase(ExecutionMode execmode) { - this.execmode = execmode; + /** + * @param createFloatingReads specifies whether {@link FloatableAccessNode}s like + * {@link ReadNode} should be converted into floating nodes (e.g., + * {@link FloatingReadNode}s) where possible + * @param createMemoryMapNodes a {@link MemoryMapNode} will be created for each return if this + * is true + * @param updateExistingPhis if true, then existing {@link MemoryPhiNode}s in the graph will be + * updated + */ + public FloatingReadPhase(boolean createFloatingReads, boolean createMemoryMapNodes, boolean updateExistingPhis) { + this.createFloatingReads = createFloatingReads; + this.createMemoryMapNodes = createMemoryMapNodes; + this.updateExistingPhis = updateExistingPhis; } /** @@ -127,7 +135,7 @@ ReentrantNodeIterator.apply(new CollectMemoryCheckpointsClosure(modifiedInLoops), graph.start(), new HashSet()); HashSetNodeEventListener listener = new HashSetNodeEventListener(EnumSet.of(NODE_ADDED, ZERO_USAGES)); try (NodeEventScope nes = graph.trackNodeEvents(listener)) { - ReentrantNodeIterator.apply(new FloatingReadClosure(modifiedInLoops, execmode), graph.start(), new MemoryMapImpl(graph.start())); + ReentrantNodeIterator.apply(new FloatingReadClosure(modifiedInLoops, createFloatingReads, createMemoryMapNodes, updateExistingPhis), graph.start(), new MemoryMapImpl(graph.start())); } for (Node n : removeExternallyUsedNodes(listener.getNodes())) { @@ -136,13 +144,13 @@ GraphUtil.killWithUnusedFloatingInputs(n); } } - if (execmode == ExecutionMode.CREATE_FLOATING_READS) { + if (createFloatingReads) { assert !graph.isAfterFloatingReadPhase(); graph.setAfterFloatingReadPhase(true); } } - public static MemoryMapImpl mergeMemoryMaps(MergeNode merge, List states) { + public static MemoryMapImpl mergeMemoryMaps(MergeNode merge, List states, boolean updateExistingPhis) { MemoryMapImpl newState = new MemoryMapImpl(); Set keys = new HashSet<>(); @@ -151,6 +159,17 @@ } assert !keys.contains(FINAL_LOCATION); + Map existingPhis = null; + if (updateExistingPhis) { + for (MemoryPhiNode phi : merge.phis().filter(MemoryPhiNode.class)) { + if (existingPhis == null) { + existingPhis = newIdentityMap(); + } + phi.values().clear(); + existingPhis.put(phi.getLocationIdentity(), phi); + } + } + for (LocationIdentity key : keys) { int mergedStatesCount = 0; boolean isPhi = false; @@ -158,14 +177,17 @@ for (MemoryMap state : states) { MemoryNode last = state.getLastLocationAccess(key); if (isPhi) { - merged.asMemoryPhi().addInput(ValueNodeUtil.asNode(last)); + ((MemoryPhiNode) merged).addInput(ValueNodeUtil.asNode(last)); } else { if (merged == last) { // nothing to do } else if (merged == null) { merged = last; } else { - MemoryPhiNode phi = merge.graph().addWithoutUnique(new MemoryPhiNode(merge, key)); + MemoryPhiNode phi = null; + if (existingPhis == null || (phi = existingPhis.remove(key)) == null) { + phi = merge.graph().addWithoutUnique(new MemoryPhiNode(merge, key)); + } for (int j = 0; j < mergedStatesCount; j++) { phi.addInput(ValueNodeUtil.asNode(merged)); } @@ -178,6 +200,11 @@ } newState.lastMemorySnapshot.put(key, merged); } + if (existingPhis != null) { + for (Map.Entry entry : existingPhis.entrySet()) { + entry.getValue().replaceAndDelete(newState.getLastLocationAccess(entry.getKey()).asNode()); + } + } return newState; } @@ -237,11 +264,15 @@ private static class FloatingReadClosure extends NodeIteratorClosure { private final Map> modifiedInLoops; - private final ExecutionMode execmode; + private boolean createFloatingReads; + private boolean createMemoryMapNodes; + private boolean updateExistingPhis; - public FloatingReadClosure(Map> modifiedInLoops, ExecutionMode execmode) { + public FloatingReadClosure(Map> modifiedInLoops, boolean createFloatingReads, boolean createMemoryMapNodes, boolean updateExistingPhis) { this.modifiedInLoops = modifiedInLoops; - this.execmode = execmode; + this.createFloatingReads = createFloatingReads; + this.createMemoryMapNodes = createMemoryMapNodes; + this.updateExistingPhis = updateExistingPhis; } @Override @@ -250,7 +281,7 @@ processAccess((MemoryAccess) node, state); } - if (node instanceof FloatableAccessNode && execmode == ExecutionMode.CREATE_FLOATING_READS) { + if (createFloatingReads & node instanceof FloatableAccessNode) { processFloatable((FloatableAccessNode) node, state); } else if (node instanceof MemoryCheckpoint.Single) { processCheckpoint((MemoryCheckpoint.Single) node, state); @@ -259,7 +290,7 @@ } assert MemoryCheckpoint.TypeAssertion.correctType(node) : node; - if (execmode == ExecutionMode.ANALYSIS_ONLY && node instanceof ReturnNode) { + if (createMemoryMapNodes && node instanceof ReturnNode) { ((ReturnNode) node).setMemoryMap(node.graph().unique(new MemoryMapNode(state.lastMemorySnapshot))); } return state; @@ -309,7 +340,7 @@ @Override protected MemoryMapImpl merge(MergeNode merge, List states) { - return mergeMemoryMaps(merge, states); + return mergeMemoryMaps(merge, states, updateExistingPhis); } @Override @@ -339,10 +370,25 @@ } Map phis = new HashMap<>(); + + if (updateExistingPhis) { + for (MemoryPhiNode phi : loop.phis().filter(MemoryPhiNode.class)) { + if (modifiedLocations.contains(phi.getLocationIdentity())) { + phi.values().clear(); + phi.addInput(ValueNodeUtil.asNode(initialState.getLastLocationAccess(phi.getLocationIdentity()))); + phis.put(phi.getLocationIdentity(), phi); + } else { + phi.replaceAndDelete(initialState.getLastLocationAccess(phi.getLocationIdentity()).asNode()); + } + } + } + for (LocationIdentity location : modifiedLocations) { - MemoryPhiNode phi = loop.graph().addWithoutUnique(new MemoryPhiNode(loop, location)); - phi.addInput(ValueNodeUtil.asNode(initialState.getLastLocationAccess(location))); - phis.put(location, phi); + if (!updateExistingPhis || !phis.containsKey(location)) { + MemoryPhiNode phi = loop.graph().addWithoutUnique(new MemoryPhiNode(loop, location)); + phi.addInput(ValueNodeUtil.asNode(initialState.getLastLocationAccess(location))); + phis.put(location, phi); + } } for (Map.Entry entry : phis.entrySet()) { initialState.lastMemorySnapshot.put(entry.getKey(), entry.getValue()); @@ -358,16 +404,6 @@ phi.initializeValueAt(endIndex, ValueNodeUtil.asNode(entry.getValue().getLastLocationAccess(key))); } } - for (Map.Entry entry : loopInfo.exitStates.entrySet()) { - LoopExitNode exit = entry.getKey(); - MemoryMapImpl state = entry.getValue(); - for (LocationIdentity location : modifiedLocations) { - MemoryNode lastAccessAtExit = state.lastMemorySnapshot.get(location); - if (lastAccessAtExit != null) { - state.lastMemorySnapshot.put(location, MemoryProxyNode.forMemory(lastAccessAtExit, exit, location, loop.graph())); - } - } - } return loopInfo.exitStates; } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Thu Jul 10 19:36:27 2014 +0200 @@ -38,6 +38,8 @@ */ public abstract class BasePhase { + public static final int PHASE_DUMP_LEVEL = 1; + private CharSequence name; /** @@ -97,8 +99,8 @@ this.run(graph, context); executionCount.increment(); inputNodesCount.add(graph.getNodeCount()); - if (dumpGraph && Debug.isDumpEnabled()) { - Debug.dump(graph, "After phase %s", getName()); + if (dumpGraph && Debug.isDumpEnabled(PHASE_DUMP_LEVEL)) { + Debug.dump(PHASE_DUMP_LEVEL, graph, "After phase %s", getName()); } if (Debug.isVerifyEnabled()) { Debug.verify(graph, "After phase %s", getName()); diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Thu Jul 10 19:36:27 2014 +0200 @@ -1050,7 +1050,7 @@ LocationIdentity readLocation = frn.location().getLocationIdentity(); assert readLocation != FINAL_LOCATION; if (frn.getLastLocationAccess() == node) { - assert identity == ANY_LOCATION || readLocation == identity : "location doesn't match: " + readLocation + ", " + identity; + assert identity == ANY_LOCATION || readLocation == identity || node instanceof MemoryCheckpoint.Multi : "location doesn't match: " + readLocation + ", " + identity; state.clearBeforeLastLocation(frn); } else if (!state.isBeforeLastLocation(frn) && (readLocation == identity || (node != getCFG().graph.start() && ANY_LOCATION == identity))) { state.removeRead(frn); diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java Thu Jul 10 19:36:27 2014 +0200 @@ -107,6 +107,12 @@ } } + public Suites(PhaseSuite highTier, PhaseSuite midTier, PhaseSuite lowTier) { + this.highTier = highTier; + this.midTier = midTier; + this.lowTier = lowTier; + } + private Suites(CompilerConfiguration config) { highTier = config.createHighTier(); midTier = config.createMidTier(); diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java Thu Jul 10 19:36:27 2014 +0200 @@ -347,9 +347,7 @@ for (Node checkCastUsage : checkCastNode.usages().snapshot()) { checkCheckCastUsage(graph, newInstance, checkCastNode, checkCastUsage); } - FixedNode next = checkCastNode.next(); - checkCastNode.setNext(null); - checkCastNode.replaceAtPredecessor(next); + GraphUtil.unlinkFixedNode(checkCastNode); GraphUtil.killCFG(checkCastNode); } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Thu Jul 10 19:36:27 2014 +0200 @@ -669,7 +669,7 @@ assert checkAllVarargPlaceholdersAreDeleted(parameterCount, placeholders); - new FloatingReadPhase(FloatingReadPhase.ExecutionMode.ANALYSIS_ONLY).apply(snippetCopy); + new FloatingReadPhase(false, true, false).apply(snippetCopy); MemoryAnchorNode memoryAnchor = snippetCopy.add(new MemoryAnchorNode()); snippetCopy.start().replaceAtUsages(InputType.Memory, memoryAnchor); @@ -694,7 +694,7 @@ List memMaps = returnNodes.stream().map(n -> n.getMemoryMap()).collect(Collectors.toList()); ValueNode returnValue = InliningUtil.mergeReturns(merge, returnNodes, null); this.returnNode = snippet.add(new ReturnNode(returnValue)); - MemoryMapImpl mmap = FloatingReadPhase.mergeMemoryMaps(merge, memMaps); + MemoryMapImpl mmap = FloatingReadPhase.mergeMemoryMaps(merge, memMaps, false); MemoryMapNode memoryMap = snippet.unique(new MemoryMapNode(mmap.getMap())); this.returnNode.setMemoryMap(memoryMap); for (MemoryMapNode mm : memMaps) { diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; @@ -127,6 +128,9 @@ */ protected StructuredGraph lowerReplacement(final StructuredGraph replacementGraph, LoweringTool tool) { final PhaseContext c = new PhaseContext(tool.getMetaAccess(), tool.getConstantReflection(), tool.getLowerer(), tool.getReplacements(), tool.assumptions()); + if (!graph().hasValueProxies()) { + new RemoveValueProxyPhase().apply(replacementGraph); + } GuardsStage guardsStage = graph().getGuardsStage(); if (guardsStage.ordinal() >= GuardsStage.FIXED_DEOPTS.ordinal()) { new GuardLoweringPhase().apply(replacementGraph, null); @@ -164,7 +168,9 @@ InliningUtil.inline(invoke, replacementGraph, false, null); Debug.dump(graph(), "After inlining replacement %s", replacementGraph); } else { - assert stateAfter() != null : "cannot lower to invoke without state: " + this; + if (stateAfter() == null) { + throw new GraalInternalError("cannot lower to invoke without state: %s", this); + } invoke.lower(tool); } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroStateSplitNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroStateSplitNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroStateSplitNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -62,14 +62,6 @@ return LocationIdentity.ANY_LOCATION; } - public MemoryCheckpoint asMemoryCheckpoint() { - return this; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } - protected void replaceSnippetInvokes(StructuredGraph snippetGraph) { for (MethodCallTargetNode call : snippetGraph.getNodes(MethodCallTargetNode.class)) { Invoke invoke = call.invoke(); diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MemoryAnchorNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MemoryAnchorNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MemoryAnchorNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -44,12 +44,4 @@ public Node canonical(CanonicalizerTool tool) { return usages().isEmpty() ? null : this; } - - public MemoryCheckpoint asMemoryCheckpoint() { - return null; - } - - public MemoryPhiNode asMemoryPhi() { - return null; - } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Thu Jul 10 19:36:27 2014 +0200 @@ -202,7 +202,7 @@ } StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod()); - if (inlineGraph == null && !methodCallTargetNode.targetMethod().isNative() && methodCallTargetNode.targetMethod().canBeInlined()) { + if (inlineGraph == null && canBeInlined(methodCallTargetNode)) { inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions, phaseContext, false); } @@ -242,6 +242,10 @@ } } + private static boolean canBeInlined(MethodCallTargetNode methodCallTargetNode) { + return !methodCallTargetNode.targetMethod().isNative() && methodCallTargetNode.targetMethod().getAnnotation(TruffleCallBoundary.class) == null; + } + private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList arguments, final Assumptions assumptions, final PhaseContext phaseContext, boolean ignoreSlowPath) { diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCacheImpl.java Thu Jul 10 19:36:27 2014 +0200 @@ -67,7 +67,7 @@ private final ResolvedJavaType stringBuilderClass; private final ResolvedJavaType runtimeExceptionClass; - private final ResolvedJavaType assertionErrorClass; + private final ResolvedJavaType errorClass; private final ResolvedJavaType controlFlowExceptionClass; private final ResolvedJavaMethod callBoundaryMethod; @@ -81,7 +81,7 @@ this.stringBuilderClass = providers.getMetaAccess().lookupJavaType(StringBuilder.class); this.runtimeExceptionClass = providers.getMetaAccess().lookupJavaType(RuntimeException.class); - this.assertionErrorClass = providers.getMetaAccess().lookupJavaType(AssertionError.class); + this.errorClass = providers.getMetaAccess().lookupJavaType(Error.class); this.controlFlowExceptionClass = providers.getMetaAccess().lookupJavaType(ControlFlowException.class); try { @@ -192,7 +192,7 @@ if (macroSubstitution != null) { InliningUtil.inlineMacroNode(methodCallTargetNode.invoke(), methodCallTargetNode.targetMethod(), macroSubstitution); } else { - tryCutOffRuntimeExceptions(methodCallTargetNode); + tryCutOffRuntimeExceptionsAndErrors(methodCallTargetNode); } } } @@ -257,14 +257,14 @@ InliningUtil.inline(invoke, inlineGraph, true, null); } - private boolean tryCutOffRuntimeExceptions(MethodCallTargetNode methodCallTargetNode) { + private boolean tryCutOffRuntimeExceptionsAndErrors(MethodCallTargetNode methodCallTargetNode) { if (methodCallTargetNode.targetMethod().isConstructor()) { ResolvedJavaType declaringClass = methodCallTargetNode.targetMethod().getDeclaringClass(); ResolvedJavaType exceptionType = Objects.requireNonNull(StampTool.typeOrNull(methodCallTargetNode.receiver().stamp())); - boolean removeAllocation = runtimeExceptionClass.isAssignableFrom(declaringClass) || assertionErrorClass.isAssignableFrom(declaringClass); - boolean isCFGException = controlFlowExceptionClass.isAssignableFrom(exceptionType); - if (removeAllocation && !isCFGException) { + boolean removeAllocation = runtimeExceptionClass.isAssignableFrom(declaringClass) || errorClass.isAssignableFrom(declaringClass); + boolean isControlFlowException = controlFlowExceptionClass.isAssignableFrom(exceptionType); + if (removeAllocation && !isControlFlowException) { DeoptimizeNode deoptNode = methodCallTargetNode.graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.UnreachedCode)); FixedNode invokeNode = methodCallTargetNode.invoke().asNode(); invokeNode.replaceAtPredecessor(deoptNode); diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -24,6 +24,8 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.util.*; import com.oracle.graal.replacements.nodes.*; public class NeverPartOfCompilationNode extends MacroNode implements IterableNodeType { @@ -40,6 +42,11 @@ } public final String getMessage() { - return message; + return message + " " + arguments.toString(); + } + + @Override + public void lower(LoweringTool tool) { + throw GraphUtil.approxSourceException(this, new VerificationError(getMessage())); } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java Thu Jul 10 19:36:27 2014 +0200 @@ -25,6 +25,8 @@ import java.lang.reflect.*; import java.util.*; +import com.oracle.graal.compiler.common.*; +import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -34,47 +36,27 @@ */ public class EffectList implements Iterable { - public abstract static class Effect { - - public boolean isVisible() { + public interface Effect { + default boolean isVisible() { return true; } - @Override - public String toString() { - StringBuilder str = new StringBuilder(); - for (Field field : getClass().getDeclaredFields()) { - String name = field.getName(); - if (name.contains("$")) { - name = name.substring(name.indexOf('$') + 1); - } - if (!Modifier.isStatic(field.getModifiers()) && !name.equals("0")) { - try { - field.setAccessible(true); - str.append(str.length() > 0 ? ", " : "").append(name).append("=").append(format(field.get(this))); - } catch (SecurityException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - } - return name() + " [" + str + "]"; + void apply(StructuredGraph graph, ArrayList obsoleteNodes); + } + + public interface SimpleEffect extends Effect { + default void apply(StructuredGraph graph, ArrayList obsoleteNodes) { + apply(graph); } - private static String format(Object object) { - if (object != null && Object[].class.isAssignableFrom(object.getClass())) { - return Arrays.toString((Object[]) object); - } - return "" + object; - } - - public abstract String name(); - - public abstract void apply(StructuredGraph graph, ArrayList obsoleteNodes); + void apply(StructuredGraph graph); } private static final Effect[] EMPTY_ARRAY = new Effect[0]; + private static final String[] EMPTY_STRING_ARRAY = new String[0]; private Effect[] effects = EMPTY_ARRAY; + private String[] names = EMPTY_STRING_ARRAY; private int size; private void enlarge(int elements) { @@ -84,26 +66,31 @@ length = Math.max(length * 2, 4); } effects = Arrays.copyOf(effects, length); + if (Debug.isEnabled()) { + names = Arrays.copyOf(names, length); + } } } - public void add(Effect effect) { - assert effect != null; - enlarge(1); - effects[size++] = effect; + public void add(String name, SimpleEffect effect) { + add(name, (Effect) effect); } - public void addAll(Collection list) { - enlarge(list.size()); - for (Effect effect : list) { - assert effect != null; - effects[size++] = effect; + public void add(String name, Effect effect) { + assert effect != null; + enlarge(1); + if (Debug.isEnabled()) { + names[size] = name; } + effects[size++] = effect; } public void addAll(EffectList list) { enlarge(list.size); System.arraycopy(list.effects, 0, effects, size, list.size); + if (Debug.isEnabled()) { + System.arraycopy(list.names, 0, names, size, list.size); + } size += list.size; } @@ -112,6 +99,10 @@ enlarge(list.size); System.arraycopy(effects, position, effects, position + list.size, size - position); System.arraycopy(list.effects, 0, effects, position, list.size); + if (Debug.isEnabled()) { + System.arraycopy(names, position, names, position + list.size, size - position); + System.arraycopy(list.names, 0, names, position, list.size); + } size += list.size; } @@ -167,15 +158,65 @@ return size == 0; } + public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { + for (int i = 0; i < size(); i++) { + Effect effect = effects[i]; + try { + effect.apply(graph, obsoleteNodes); + } catch (Throwable t) { + StringBuilder str = new StringBuilder(); + toString(str, i); + throw new GraalInternalError(t).addContext("effect", str); + } + if (effect.isVisible() && Debug.isLogEnabled()) { + StringBuilder str = new StringBuilder(); + toString(str, i); + Debug.log(" %s", str); + } + } + } + + private void toString(StringBuilder str, int i) { + Effect effect = effects[i]; + str.append(getName(i)).append(" ["); + boolean first = true; + for (Field field : effect.getClass().getDeclaredFields()) { + try { + field.setAccessible(true); + str.append(first ? "" : ", ").append(format(field.get(effect))); + first = false; + } catch (SecurityException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + str.append(']'); + } + + private static String format(Object object) { + if (object != null && Object[].class.isAssignableFrom(object.getClass())) { + return Arrays.toString((Object[]) object); + } + return "" + object; + } + @Override public String toString() { StringBuilder str = new StringBuilder(); for (int i = 0; i < size(); i++) { Effect effect = get(i); if (effect.isVisible()) { - str.append(effect).append('\n'); + toString(str, i); + str.append('\n'); } } return str.toString(); } + + private String getName(int i) { + if (Debug.isEnabled()) { + return names[i]; + } else { + return ""; + } + } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Thu Jul 10 19:36:27 2014 +0200 @@ -38,12 +38,11 @@ import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure; import com.oracle.graal.phases.graph.ReentrantBlockIterator.LoopInfo; import com.oracle.graal.phases.schedule.*; -import com.oracle.graal.virtual.phases.ea.EffectList.Effect; public abstract class EffectsClosure> extends EffectsPhase.Closure { - private final ControlFlowGraph cfg; - private final SchedulePhase schedule; + protected final ControlFlowGraph cfg; + protected final SchedulePhase schedule; protected final NodeMap aliases; protected final BlockMap blockEffects; @@ -81,12 +80,7 @@ private void apply(GraphEffectList effects, Object context) { if (!effects.isEmpty()) { Debug.log(" ==== effects for %s", context); - for (Effect effect : effects) { - effect.apply(graph, obsoleteNodes); - if (effect.isVisible()) { - Debug.log(" %s", effect); - } - } + effects.apply(graph, obsoleteNodes); if (TraceEscapeAnalysis.getValue()) { Debug.dump(graph, EffectsClosure.this.getClass().getSimpleName() + " - after processing %s", context); } @@ -228,6 +222,11 @@ @SuppressWarnings("unused") protected void commitEnds(List states) { } + + @Override + public String toString() { + return "MergeProcessor@" + merge; + } } public void addScalarAlias(ValueNode node, ValueNode alias) { diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java Thu Jul 10 19:36:27 2014 +0200 @@ -26,44 +26,23 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.debug.*; -import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.util.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.common.*; public class GraphEffectList extends EffectList { public void addCounterBefore(final String group, final String name, final int increment, final boolean addContext, final FixedNode position) { - add(new Effect() { - - @Override - public String name() { - return "addCounterBefore"; - } + add("add counter", graph -> DynamicCounterNode.addCounterBefore(group, name, increment, addContext, position)); + } - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - assert position.isAlive(); - DynamicCounterNode.addCounterBefore(group, name, increment, addContext, position); - } - }); + public void addCounterAfter(final String group, final String name, final int increment, final boolean addContext, final FixedWithNextNode position) { + add("add counter after", graph -> DynamicCounterNode.addCounterBefore(group, name, increment, addContext, position.next())); } public void addWeakCounterCounterBefore(final String group, final String name, final int increment, final boolean addContext, final ValueNode checkedValue, final FixedNode position) { - add(new Effect() { - - @Override - public String name() { - return "addWeakCounterBefore"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - assert position.isAlive(); - WeakCounterNode.addCounterBefore(group, name, increment, addContext, checkedValue, position); - } - }); + add("add weak counter", graph -> WeakCounterNode.addCounterBefore(group, name, increment, addContext, checkedValue, position)); } /** @@ -74,18 +53,9 @@ * @param position The fixed node before which the node should be added. */ public void addFixedNodeBefore(final FixedWithNextNode node, final FixedNode position) { - add(new Effect() { - - @Override - public String name() { - return "addFixedNodeBefore"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - assert !node.isAlive() && !node.isDeleted() && position.isAlive(); - graph.addBeforeFixed(position, graph.add(node)); - } + add("add fixed node", graph -> { + assert !node.isAlive() && !node.isDeleted() && position.isAlive(); + graph.addBeforeFixed(position, graph.add(node)); }); } @@ -94,20 +64,8 @@ * * @param node The floating node to be added. */ - public void addFloatingNode(final ValueNode node, final String cause) { - add(new Effect() { - - @Override - public String name() { - return "addFloatingNode " + cause; - } - - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - assert !node.isAlive() && !node.isDeleted() : node + " " + cause; - graph.addWithoutUnique(node); - } - }); + public void addFloatingNode(final ValueNode node, @SuppressWarnings("unused") final String cause) { + add("add floating node", graph -> graph.addWithoutUnique(node)); } /** @@ -117,18 +75,9 @@ * @param value The value that will be added to the phi node. */ public void addPhiInput(final PhiNode node, final ValueNode value) { - add(new Effect() { - - @Override - public String name() { - return "addPhiInput"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - assert node.isAlive() && value.isAlive() : node + " " + value; - node.addInput(value); - } + add("add phi input", graph -> { + assert node.isAlive() && value.isAlive() : node + " " + value; + node.addInput(value); }); } @@ -141,18 +90,9 @@ * @param value The new value for the phi input. */ public void initializePhiInput(final PhiNode node, final int index, final ValueNode value) { - add(new Effect() { - - @Override - public String name() { - return "setPhiInput"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - assert node.isAlive() && value.isAlive() && index >= 0; - node.initializeValueAt(index, value); - } + add("set phi input", (graph, obsoleteNodes) -> { + assert node.isAlive() && value.isAlive() && index >= 0; + node.initializeValueAt(index, value); }); } @@ -164,13 +104,7 @@ * @param state The virtual object state to add. */ public void addVirtualMapping(final FrameState node, final EscapeObjectState state) { - add(new Effect() { - - @Override - public String name() { - return "addVirtualMapping"; - } - + add("add virtual mapping", new Effect() { @Override public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { assert node.isAlive() && !state.isAlive() && !state.isDeleted(); @@ -196,22 +130,19 @@ * @param node The fixed node that should be deleted. */ public void deleteFixedNode(final FixedWithNextNode node) { - add(new Effect() { - - @Override - public String name() { - return "deleteFixedNode"; - } + add("delete fixed node", (graph, obsoleteNodes) -> { + GraphUtil.unlinkFixedNode(node); + assert obsoleteNodes.add(node); + }); + } - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - assert node.isAlive(); - FixedNode next = node.next(); - node.setNext(null); - node.replaceAtPredecessor(next); - assert obsoleteNodes.add(node); - } - }); + /** + * Removes the given fixed node from the control flow. + * + * @param node The fixed node that should be deleted. + */ + public void unlinkFixedNode(final FixedWithNextNode node) { + add("unlink fixed node", graph -> GraphUtil.unlinkFixedNode(node)); } /** @@ -225,27 +156,18 @@ * */ public void replaceAtUsages(final ValueNode node, final ValueNode replacement) { - add(new Effect() { - - @Override - public String name() { - return "replaceAtUsages"; + add("replace at usages", (graph, obsoleteNodes) -> { + assert node.isAlive() && replacement.isAlive(); + if (replacement instanceof FixedWithNextNode && ((FixedWithNextNode) replacement).next() == null) { + assert node instanceof FixedNode; + graph.addBeforeFixed((FixedNode) node, (FixedWithNextNode) replacement); } - - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - assert node.isAlive() && replacement.isAlive(); - if (replacement instanceof FixedWithNextNode && ((FixedWithNextNode) replacement).next() == null) { - assert node instanceof FixedNode; - graph.addBeforeFixed((FixedNode) node, (FixedWithNextNode) replacement); - } - node.replaceAtUsages(replacement); - if (node instanceof FixedWithNextNode) { - FixedNode next = ((FixedWithNextNode) node).next(); - ((FixedWithNextNode) node).setNext(null); - node.replaceAtPredecessor(next); - assert obsoleteNodes.add(node); - } + node.replaceAtUsages(replacement); + if (node instanceof FixedWithNextNode) { + FixedNode next = ((FixedWithNextNode) node).next(); + ((FixedWithNextNode) node).setNext(null); + node.replaceAtPredecessor(next); + assert obsoleteNodes.add(node); } }); } @@ -258,13 +180,7 @@ * @param newInput The value to replace with. */ public void replaceFirstInput(final Node node, final Node oldInput, final Node newInput) { - add(new Effect() { - - @Override - public String name() { - return "replaceFirstInput"; - } - + add("replace first input", new Effect() { @Override public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { assert node.isAlive() && oldInput.isAlive() && newInput.isAlive(); @@ -284,83 +200,6 @@ * @param action The action that should be performed when the effects are applied. */ public void customAction(final Runnable action) { - add(new Effect() { - - @Override - public String name() { - return "customAction"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - action.run(); - } - }); - } - - /** - * Add the materialization node to the graph's control flow at the given position, and then sets - * its values. - * - * @param position The fixed node before which the materialization node should be added. - * @param objects The allocated objects. - * @param locks The lock depths for each object. - * @param values The values (field, elements) of all objects. - * @param otherAllocations A list of allocations that need to be added before the rest (used for - * boxing allocations). - */ - public void addMaterializationBefore(final FixedNode position, final List objects, final List> locks, final List values, - final List otherAllocations) { - add(new Effect() { - - @Override - public String name() { - return "addMaterializationBefore"; - } - - @Override - public void apply(StructuredGraph graph, ArrayList obsoleteNodes) { - for (ValueNode otherAllocation : otherAllocations) { - graph.addWithoutUnique(otherAllocation); - if (otherAllocation instanceof FixedWithNextNode) { - graph.addBeforeFixed(position, (FixedWithNextNode) otherAllocation); - } else { - assert otherAllocation instanceof FloatingNode; - } - } - if (!objects.isEmpty()) { - CommitAllocationNode commit; - if (position.predecessor() instanceof CommitAllocationNode) { - commit = (CommitAllocationNode) position.predecessor(); - } else { - commit = graph.add(new CommitAllocationNode()); - graph.addBeforeFixed(position, commit); - } - for (AllocatedObjectNode obj : objects) { - graph.addWithoutUnique(obj); - commit.getVirtualObjects().add(obj.getVirtualObject()); - obj.setCommit(commit); - } - commit.getValues().addAll(values); - for (List monitorIds : locks) { - commit.addLocks(monitorIds); - } - - assert commit.usages().filter(AllocatedObjectNode.class).count() == commit.usages().count(); - List materializedValues = commit.usages().filter(AllocatedObjectNode.class).snapshot(); - for (int i = 0; i < commit.getValues().size(); i++) { - if (materializedValues.contains(commit.getValues().get(i))) { - commit.getValues().set(i, ((AllocatedObjectNode) commit.getValues().get(i)).getVirtualObject()); - } - } - - } - } - - @Override - public boolean isVisible() { - return true; - } - }); + add("customAction", graph -> action.run()); } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Thu Jul 10 19:36:27 2014 +0200 @@ -120,13 +120,15 @@ protected void processLoopExit(LoopExitNode exitNode, PEReadEliminationBlockState initialState, PEReadEliminationBlockState exitState, GraphEffectList effects) { super.processLoopExit(exitNode, initialState, exitState, effects); - for (Map.Entry entry : exitState.getReadCache().entrySet()) { - if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) { - ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity, this); - if (!(value instanceof ProxyNode) || ((ProxyNode) value).proxyPoint() != exitNode) { - ProxyNode proxy = new ValueProxyNode(value, exitNode); - effects.addFloatingNode(proxy, "readCacheProxy"); - entry.setValue(proxy); + if (exitNode.graph().hasValueProxies()) { + for (Map.Entry entry : exitState.getReadCache().entrySet()) { + if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) { + ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity, this); + if (!(value instanceof ProxyNode) || ((ProxyNode) value).proxyPoint() != exitNode) { + ProxyNode proxy = new ValueProxyNode(value, exitNode); + effects.addFloatingNode(proxy, "readCacheProxy"); + entry.setValue(proxy); + } } } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java Thu Jul 10 19:36:27 2014 +0200 @@ -27,6 +27,7 @@ import java.util.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.Virtualizable.EscapeState; import com.oracle.graal.nodes.virtual.*; @@ -75,7 +76,42 @@ List otherAllocations = new ArrayList<>(2); materializeWithCommit(fixed, virtual, objects, locks, values, otherAllocations, state); - materializeEffects.addMaterializationBefore(fixed, objects, locks, values, otherAllocations); + materializeEffects.add("materializeBefore", (graph, obsoleteNodes) -> { + for (ValueNode otherAllocation : otherAllocations) { + graph.addWithoutUnique(otherAllocation); + if (otherAllocation instanceof FixedWithNextNode) { + graph.addBeforeFixed(fixed, (FixedWithNextNode) otherAllocation); + } else { + assert otherAllocation instanceof FloatingNode; + } + } + if (!objects.isEmpty()) { + CommitAllocationNode commit; + if (fixed.predecessor() instanceof CommitAllocationNode) { + commit = (CommitAllocationNode) fixed.predecessor(); + } else { + commit = graph.add(new CommitAllocationNode()); + graph.addBeforeFixed(fixed, commit); + } + for (AllocatedObjectNode obj : objects) { + graph.addWithoutUnique(obj); + commit.getVirtualObjects().add(obj.getVirtualObject()); + obj.setCommit(commit); + } + commit.getValues().addAll(values); + for (List monitorIds : locks) { + commit.addLocks(monitorIds); + } + + assert commit.usages().filter(AllocatedObjectNode.class).count() == commit.usages().count(); + List materializedValues = commit.usages().filter(AllocatedObjectNode.class).snapshot(); + for (int i = 0; i < commit.getValues().size(); i++) { + if (materializedValues.contains(commit.getValues().get(i))) { + commit.getValues().set(i, ((AllocatedObjectNode) commit.getValues().get(i)).getVirtualObject()); + } + } + } + }); } private void materializeWithCommit(FixedNode fixed, VirtualObjectNode virtual, List objects, List> locks, List values, diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Thu Jul 10 19:36:27 2014 +0200 @@ -229,33 +229,35 @@ proxies.put(obj.virtual, proxy); } } - for (ObjectState obj : exitState.getStates()) { - ObjectState initialObj = initialState.getObjectStateOptional(obj.virtual); - if (obj.isVirtual()) { - for (int i = 0; i < obj.getEntries().length; i++) { - ValueNode value = obj.getEntry(i); - if (!(value instanceof VirtualObjectNode || value.isConstant())) { - if (exitNode.loopBegin().isPhiAtMerge(value) || initialObj == null || !initialObj.isVirtual() || initialObj.getEntry(i) != value) { - ProxyNode proxy = new ValueProxyNode(value, exitNode); - obj.setEntry(i, proxy); - effects.addFloatingNode(proxy, "virtualProxy"); + if (exitNode.graph().hasValueProxies()) { + for (ObjectState obj : exitState.getStates()) { + ObjectState initialObj = initialState.getObjectStateOptional(obj.virtual); + if (obj.isVirtual()) { + for (int i = 0; i < obj.getEntries().length; i++) { + ValueNode value = obj.getEntry(i); + if (!(value instanceof VirtualObjectNode || value.isConstant())) { + if (exitNode.loopBegin().isPhiAtMerge(value) || initialObj == null || !initialObj.isVirtual() || initialObj.getEntry(i) != value) { + ProxyNode proxy = new ValueProxyNode(value, exitNode); + obj.setEntry(i, proxy); + effects.addFloatingNode(proxy, "virtualProxy"); + } } } - } - } else { - if (initialObj == null || initialObj.isVirtual()) { - ProxyNode proxy = proxies.get(obj.virtual); - if (proxy == null) { - proxy = new ValueProxyNode(obj.getMaterializedValue(), exitNode); - effects.addFloatingNode(proxy, "proxy"); + } else { + if (initialObj == null || initialObj.isVirtual()) { + ProxyNode proxy = proxies.get(obj.virtual); + if (proxy == null) { + proxy = new ValueProxyNode(obj.getMaterializedValue(), exitNode); + effects.addFloatingNode(proxy, "proxy"); + } else { + effects.replaceFirstInput(proxy, proxy.value(), obj.getMaterializedValue()); + // nothing to do - will be handled in processNode + } + obj.updateMaterializedValue(proxy); } else { - effects.replaceFirstInput(proxy, proxy.value(), obj.getMaterializedValue()); - // nothing to do - will be handled in processNode - } - obj.updateMaterializedValue(proxy); - } else { - if (initialObj.getMaterializedValue() == obj.getMaterializedValue()) { - Debug.log("materialized value changes within loop: %s vs. %s at %s", initialObj.getMaterializedValue(), obj.getMaterializedValue(), exitNode); + if (initialObj.getMaterializedValue() == obj.getMaterializedValue()) { + Debug.log("materialized value changes within loop: %s vs. %s at %s", initialObj.getMaterializedValue(), obj.getMaterializedValue(), exitNode); + } } } } @@ -457,6 +459,9 @@ phis[valueIndex] = new ValuePhiNode(values[valueIndex].stamp().unrestricted(), merge); } } + if (phis[valueIndex] != null && !phis[valueIndex].stamp().isCompatible(values[valueIndex].stamp())) { + phis[valueIndex] = new ValuePhiNode(values[valueIndex].stamp().unrestricted(), merge); + } if (twoSlotKinds != null && twoSlotKinds[valueIndex] != null) { // skip an entry after a long/double value that occupies two int slots valueIndex++; diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Thu Jul 10 19:36:27 2014 +0200 @@ -171,11 +171,13 @@ @Override protected void processLoopExit(LoopExitNode exitNode, ReadEliminationBlockState initialState, ReadEliminationBlockState exitState, GraphEffectList effects) { - for (Map.Entry, ValueNode> entry : exitState.getReadCache().entrySet()) { - if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) { - ProxyNode proxy = new ValueProxyNode(exitState.getCacheEntry(entry.getKey()), exitNode); - effects.addFloatingNode(proxy, "readCacheProxy"); - entry.setValue(proxy); + if (exitNode.graph().hasValueProxies()) { + for (Map.Entry, ValueNode> entry : exitState.getReadCache().entrySet()) { + if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) { + ProxyNode proxy = new ValueProxyNode(exitState.getCacheEntry(entry.getKey()), exitNode); + effects.addFloatingNode(proxy, "readCacheProxy"); + entry.setValue(proxy); + } } } } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java Thu Jul 10 19:36:27 2014 +0200 @@ -113,6 +113,11 @@ throw new GraalInternalError("locationIdentity must be a constant so that this node can be canonicalized: " + locationIdentity); } + @Override + public IntegerStamp getDisplacementStamp() { + throw GraalInternalError.shouldNotReachHere(); + } + @NodeIntrinsic public static native Location constantLocation(LocationIdentity identity, Kind kind, long displacement); diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Thu Jul 10 19:36:27 2014 +0200 @@ -24,7 +24,6 @@ */ package com.oracle.truffle.api.nodes; -import java.io.*; import java.lang.annotation.*; import java.util.*; import java.util.concurrent.*; @@ -280,9 +279,6 @@ this.parent.adoptUnadoptedHelper(newNode); } reportReplace(this, newNode, reason); - if (TruffleOptions.TraceASTJSON) { - JSONHelper.dumpReplaceChild(this, newNode, reason); - } onReplace(newNode, reason); } @@ -310,6 +306,12 @@ ((ReplaceObserver) target).nodeReplaced(oldNode, newNode, reason); } } + if (TruffleOptions.TraceRewrites) { + NodeUtil.traceRewrite(this, newNode, reason); + } + if (TruffleOptions.TraceASTJSON) { + JSONHelper.dumpReplaceChild(this, newNode, reason); + } } /** @@ -320,36 +322,7 @@ * @param reason the reason the replace supplied */ protected void onReplace(Node newNode, CharSequence reason) { - if (TruffleOptions.TraceRewrites) { - traceRewrite(newNode, reason); - } - } - - private void traceRewrite(Node newNode, CharSequence reason) { - if (TruffleOptions.TraceRewritesFilterFromCost != null) { - if (filterByKind(this, TruffleOptions.TraceRewritesFilterFromCost)) { - return; - } - } - - if (TruffleOptions.TraceRewritesFilterToCost != null) { - if (filterByKind(newNode, TruffleOptions.TraceRewritesFilterToCost)) { - return; - } - } - - String filter = TruffleOptions.TraceRewritesFilterClass; - Class from = getClass(); - Class to = newNode.getClass(); - if (filter != null && (filterByContainsClassName(from, filter) || filterByContainsClassName(to, filter))) { - return; - } - - final SourceSection reportedSourceSection = getEncapsulatingSourceSection(); - - PrintStream out = System.out; - out.printf("[truffle] rewrite %-50s |From %-40s |To %-40s |Reason %s%s%n", this.toString(), formatNodeInfo(this), formatNodeInfo(newNode), reason != null && reason.length() > 0 ? reason - : "unknown", reportedSourceSection != null ? " at " + reportedSourceSection.getShortDescription() : ""); + // empty default } /** @@ -362,43 +335,6 @@ // empty default } - private static String formatNodeInfo(Node node) { - String cost = "?"; - switch (node.getCost()) { - case NONE: - cost = "G"; - break; - case MONOMORPHIC: - cost = "M"; - break; - case POLYMORPHIC: - cost = "P"; - break; - case MEGAMORPHIC: - cost = "G"; - break; - default: - cost = "?"; - break; - } - return cost + " " + node.getClass().getSimpleName(); - } - - private static boolean filterByKind(Node node, NodeCost cost) { - return node.getCost() == cost; - } - - private static boolean filterByContainsClassName(Class from, String filter) { - Class currentFrom = from; - while (currentFrom != null) { - if (currentFrom.getName().contains(filter)) { - return false; - } - currentFrom = currentFrom.getSuperclass(); - } - return true; - } - /** * Invokes the {@link NodeVisitor#visit(Node)} method for this node and recursively also for all * child nodes. @@ -421,11 +357,9 @@ * @return the iterator */ public final Iterable getChildren() { - final Node node = this; return new Iterable() { - public Iterator iterator() { - return new NodeUtil.NodeIterator(node); + return NodeUtil.makeIterator(Node.this); } }; } diff -r efbf9195dfcb -r 352de9bd8fd5 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Tue Jul 08 20:19:34 2014 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Thu Jul 10 19:36:27 2014 +0200 @@ -157,8 +157,14 @@ * every subclass of {@link Node} that is used. */ public static final class NodeClass { - - private static final Map, NodeClass> nodeClasses = new IdentityHashMap<>(); + private static final ClassValue nodeClasses = new ClassValue() { + @SuppressWarnings("unchecked") + @Override + protected NodeClass computeValue(Class clazz) { + assert Node.class.isAssignableFrom(clazz); + return new NodeClass((Class) clazz, unsafeFieldOffsetProvider); + } + }; // The comprehensive list of all fields. private final NodeField[] fields; @@ -166,14 +172,10 @@ private final long parentOffset; private final long[] childOffsets; private final long[] childrenOffsets; + private final Class clazz; public static NodeClass get(Class clazz) { - NodeClass nodeClass = nodeClasses.get(clazz); - if (nodeClass == null) { - nodeClass = new NodeClass(clazz, unsafeFieldOffsetProvider); - nodeClasses.put(clazz, nodeClass); - } - return nodeClass; + return nodeClasses.get(clazz); } public NodeClass(Class clazz, FieldOffsetProvider fieldOffsetProvider) { @@ -209,6 +211,7 @@ this.parentOffset = parentOffsetsList.get(0); this.childOffsets = toLongArray(childOffsetsList); this.childrenOffsets = toLongArray(childrenOffsetsList); + this.clazz = clazz; } public NodeField[] getFields() { @@ -241,73 +244,71 @@ } return false; } - } - static class NodeIterator implements Iterator { - - private final Node node; - private final NodeClass nodeClass; - private final int childrenCount; - private int index; - - protected NodeIterator(Node node) { - this.node = node; - this.index = 0; - this.nodeClass = NodeClass.get(node.getClass()); - this.childrenCount = childrenCount(); - } - - private int childrenCount() { - int nodeCount = nodeClass.childOffsets.length; - for (long fieldOffset : nodeClass.childrenOffsets) { - Node[] children = ((Node[]) unsafe.getObject(node, fieldOffset)); - if (children != null) { - nodeCount += children.length; - } - } - return nodeCount; + public Iterator makeIterator(Node node) { + assert clazz.isInstance(node); + return new NodeIterator(node); } - private Node nodeAt(int idx) { - int nodeCount = nodeClass.childOffsets.length; - if (idx < nodeCount) { - return (Node) unsafe.getObject(node, nodeClass.childOffsets[idx]); - } else { - for (long fieldOffset : nodeClass.childrenOffsets) { - Node[] nodeArray = (Node[]) unsafe.getObject(node, fieldOffset); - if (idx < nodeCount + nodeArray.length) { - return nodeArray[idx - nodeCount]; + private final class NodeIterator implements Iterator { + private final Node node; + private int fieldIndex; + private int arrayIndex; + + protected NodeIterator(Node node) { + this.node = node; + } + + private void forward() { + if (fieldIndex < childOffsets.length) { + fieldIndex++; + } else if (fieldIndex < childOffsets.length + childrenOffsets.length) { + if (arrayIndex + 1 < currentChildrenArrayLength()) { + arrayIndex++; + } else { + arrayIndex = 0; + do { + fieldIndex++; + } while (fieldIndex < childOffsets.length + childrenOffsets.length && currentChildrenArrayLength() == 0); } - nodeCount += nodeArray.length; } } - return null; - } + + public boolean hasNext() { + return fieldIndex < childOffsets.length || (fieldIndex < childOffsets.length + childrenOffsets.length && arrayIndex < currentChildrenArrayLength()); + } + + private Node[] currentChildrenArray() { + assert fieldIndex >= childOffsets.length && fieldIndex < childOffsets.length + childrenOffsets.length; + return (Node[]) unsafe.getObject(node, childrenOffsets[fieldIndex - childOffsets.length]); + } + + private int currentChildrenArrayLength() { + Node[] childrenArray = currentChildrenArray(); + return childrenArray != null ? childrenArray.length : 0; + } - private void forward() { - if (index < childrenCount) { - index++; + public Node next() { + Node next; + if (fieldIndex < childOffsets.length) { + next = (Node) unsafe.getObject(node, childOffsets[fieldIndex]); + } else if (fieldIndex < childOffsets.length + childrenOffsets.length) { + next = currentChildrenArray()[arrayIndex]; + } else { + throw new NoSuchElementException(); + } + forward(); + return next; + } + + public void remove() { + throw new UnsupportedOperationException(); } } - - @Override - public boolean hasNext() { - return index < childrenCount; - } + } - @Override - public Node next() { - try { - return nodeAt(index); - } finally { - forward(); - } - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } + static Iterator makeIterator(Node node) { + return NodeClass.get(node.getClass()).makeIterator(node); } private static long[] toLongArray(List list) { @@ -542,15 +543,12 @@ return null; } - public static List findAllNodeInstances(final Node root, final Class clazz) { + public static List findAllNodeInstances(final Node root, final Class clazz) { final List nodeList = new ArrayList<>(); root.accept(new NodeVisitor() { - - @SuppressWarnings("unchecked") - @Override public boolean visit(Node node) { if (clazz.isInstance(node)) { - nodeList.add((T) node); + nodeList.add(clazz.cast(node)); } return true; } @@ -558,53 +556,15 @@ return nodeList; } - // Don't visit found node instances. - public static List findNodeInstancesShallow(final Node root, final Class clazz) { - final List nodeList = new ArrayList<>(); - root.accept(new NodeVisitor() { - - @SuppressWarnings("unchecked") - @Override - public boolean visit(Node node) { - if (clazz.isInstance(node)) { - nodeList.add((T) node); - return false; - } - return true; - } - }); - return nodeList; - } - - /** Find node instances within current function only (not in nested functions). */ - public static List findNodeInstancesInFunction(final Node root, final Class clazz) { + /** + * Like {@link #findAllNodeInstances(Node, Class)} but do not visit children of found nodes. + */ + public static List findNodeInstancesShallow(final Node root, final Class clazz) { final List nodeList = new ArrayList<>(); root.accept(new NodeVisitor() { - - @SuppressWarnings("unchecked") - @Override public boolean visit(Node node) { if (clazz.isInstance(node)) { - nodeList.add((T) node); - } else if (node instanceof RootNode && node != root) { - return false; - } - return true; - } - }); - return nodeList; - } - - public static List findNodeInstancesInFunctionInterface(final Node root, final Class clazz) { - final List nodeList = new ArrayList<>(); - root.accept(new NodeVisitor() { - - @SuppressWarnings("unchecked") - @Override - public boolean visit(Node node) { - if (clazz.isInstance(node)) { - nodeList.add((I) node); - } else if (node instanceof RootNode && node != root) { + nodeList.add(clazz.cast(node)); return false; } return true; @@ -891,4 +851,68 @@ private static String toStringWithClass(Object obj) { return obj == null ? "null" : obj + "(" + obj.getClass().getName() + ")"; } + + static void traceRewrite(Node oldNode, Node newNode, CharSequence reason) { + if (TruffleOptions.TraceRewritesFilterFromCost != null) { + if (filterByKind(oldNode, TruffleOptions.TraceRewritesFilterFromCost)) { + return; + } + } + + if (TruffleOptions.TraceRewritesFilterToCost != null) { + if (filterByKind(newNode, TruffleOptions.TraceRewritesFilterToCost)) { + return; + } + } + + String filter = TruffleOptions.TraceRewritesFilterClass; + Class from = oldNode.getClass(); + Class to = newNode.getClass(); + if (filter != null && (filterByContainsClassName(from, filter) || filterByContainsClassName(to, filter))) { + return; + } + + final SourceSection reportedSourceSection = oldNode.getEncapsulatingSourceSection(); + + PrintStream out = System.out; + out.printf("[truffle] rewrite %-50s |From %-40s |To %-40s |Reason %s%s%n", oldNode.toString(), formatNodeInfo(oldNode), formatNodeInfo(newNode), + reason != null && reason.length() > 0 ? reason : "unknown", reportedSourceSection != null ? " at " + reportedSourceSection.getShortDescription() : ""); + } + + private static String formatNodeInfo(Node node) { + String cost = "?"; + switch (node.getCost()) { + case NONE: + cost = "G"; + break; + case MONOMORPHIC: + cost = "M"; + break; + case POLYMORPHIC: + cost = "P"; + break; + case MEGAMORPHIC: + cost = "G"; + break; + default: + cost = "?"; + break; + } + return cost + " " + node.getClass().getSimpleName(); + } + + private static boolean filterByKind(Node node, NodeCost cost) { + return node.getCost() == cost; + } + + private static boolean filterByContainsClassName(Class from, String filter) { + Class currentFrom = from; + while (currentFrom != null) { + if (currentFrom.getName().contains(filter)) { + return false; + } + currentFrom = currentFrom.getSuperclass(); + } + return true; + } } diff -r efbf9195dfcb -r 352de9bd8fd5 mx/mx_graal.py --- a/mx/mx_graal.py Tue Jul 08 20:19:34 2014 +0200 +++ b/mx/mx_graal.py Thu Jul 10 19:36:27 2014 +0200 @@ -1281,6 +1281,12 @@ dacapo(['-Xbatch', 'pmd']) tasks.append(t.stop()) + # ensure -Xcomp still works + with VM('graal', 'product'): + t = Task('XCompMode:product') + vm(['-Xcomp', '-version']) + tasks.append(t.stop()) + if args.jacocout is not None: jacocoreport([args.jacocout]) diff -r efbf9195dfcb -r 352de9bd8fd5 mxtool/mx.py --- a/mxtool/mx.py Tue Jul 08 20:19:34 2014 +0200 +++ b/mxtool/mx.py Thu Jul 10 19:36:27 2014 +0200 @@ -2043,7 +2043,7 @@ rootJdtProperties = join(self.proj.suite.mxDir, 'eclipse-settings', 'org.eclipse.jdt.core.prefs') if not exists(jdtProperties) or os.path.getmtime(jdtProperties) < os.path.getmtime(rootJdtProperties): # Try to fix a missing properties file by running eclipseinit - eclipseinit([], buildProcessorJars=False) + _eclipseinit_project(self.proj) if not exists(jdtProperties): log('JDT properties file {0} not found'.format(jdtProperties)) else: @@ -3174,6 +3174,229 @@ return False return True +def _eclipseinit_project(p, files=None, libFiles=None): + assert java(p.javaCompliance) + + if not exists(p.dir): + os.makedirs(p.dir) + + out = XMLDoc() + out.open('classpath') + + for src in p.srcDirs: + srcDir = join(p.dir, src) + if not exists(srcDir): + os.mkdir(srcDir) + out.element('classpathentry', {'kind' : 'src', 'path' : src}) + + if len(p.annotation_processors()) > 0: + genDir = p.source_gen_dir() + if not exists(genDir): + os.mkdir(genDir) + out.element('classpathentry', {'kind' : 'src', 'path' : 'src_gen'}) + if files: + files.append(genDir) + + # Every Java program depends on a JRE + out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-' + str(p.javaCompliance)}) + + if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project + out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.pde.core.requiredPlugins'}) + + containerDeps = set() + libraryDeps = set() + projectDeps = set() + + for dep in p.all_deps([], True): + if dep == p: + continue + if dep.isLibrary(): + if hasattr(dep, 'eclipse.container'): + container = getattr(dep, 'eclipse.container') + containerDeps.add(container) + libraryDeps -= set(dep.all_deps([], True)) + else: + libraryDeps.add(dep) + elif dep.isProject(): + projectDeps.add(dep) + + for dep in containerDeps: + out.element('classpathentry', {'exported' : 'true', 'kind' : 'con', 'path' : dep}) + + for dep in libraryDeps: + path = dep.path + dep.get_path(resolve=True) + + # Relative paths for "lib" class path entries have various semantics depending on the Eclipse + # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's + # safest to simply use absolute paths. + path = _make_absolute(path, p.suite.dir) + + attributes = {'exported' : 'true', 'kind' : 'lib', 'path' : path} + + sourcePath = dep.get_source_path(resolve=True) + if sourcePath is not None: + attributes['sourcepath'] = sourcePath + out.element('classpathentry', attributes) + if libFiles: + libFiles.append(path) + + for dep in projectDeps: + out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + dep.name}) + + out.element('classpathentry', {'kind' : 'output', 'path' : getattr(p, 'eclipse.output', 'bin')}) + out.close('classpath') + classpathFile = join(p.dir, '.classpath') + update_file(classpathFile, out.xml(indent='\t', newl='\n')) + if files: + files.append(classpathFile) + + csConfig = join(project(p.checkstyleProj).dir, '.checkstyle_checks.xml') + if exists(csConfig): + out = XMLDoc() + + dotCheckstyle = join(p.dir, ".checkstyle") + checkstyleConfigPath = '/' + p.checkstyleProj + '/.checkstyle_checks.xml' + out.open('fileset-config', {'file-format-version' : '1.2.0', 'simple-config' : 'true'}) + out.open('local-check-config', {'name' : 'Checks', 'location' : checkstyleConfigPath, 'type' : 'project', 'description' : ''}) + out.element('additional-data', {'name' : 'protect-config-file', 'value' : 'false'}) + out.close('local-check-config') + out.open('fileset', {'name' : 'all', 'enabled' : 'true', 'check-config-name' : 'Checks', 'local' : 'true'}) + out.element('file-match-pattern', {'match-pattern' : '.', 'include-pattern' : 'true'}) + out.close('fileset') + out.open('filter', {'name' : 'all', 'enabled' : 'true', 'check-config-name' : 'Checks', 'local' : 'true'}) + out.element('filter-data', {'value' : 'java'}) + out.close('filter') + + exclude = join(p.dir, '.checkstyle.exclude') + if exists(exclude): + out.open('filter', {'name' : 'FilesFromPackage', 'enabled' : 'true'}) + with open(exclude) as f: + for line in f: + if not line.startswith('#'): + line = line.strip() + exclDir = join(p.dir, line) + assert isdir(exclDir), 'excluded source directory listed in ' + exclude + ' does not exist or is not a directory: ' + exclDir + out.element('filter-data', {'value' : line}) + out.close('filter') + + out.close('fileset-config') + update_file(dotCheckstyle, out.xml(indent=' ', newl='\n')) + if files: + files.append(dotCheckstyle) + else: + # clean up existing .checkstyle file + dotCheckstyle = join(p.dir, ".checkstyle") + if exists(dotCheckstyle): + os.unlink(dotCheckstyle) + + out = XMLDoc() + out.open('projectDescription') + out.element('name', data=p.name) + out.element('comment', data='') + out.element('projects', data='') + out.open('buildSpec') + out.open('buildCommand') + out.element('name', data='org.eclipse.jdt.core.javabuilder') + out.element('arguments', data='') + out.close('buildCommand') + if exists(csConfig): + out.open('buildCommand') + out.element('name', data='net.sf.eclipsecs.core.CheckstyleBuilder') + out.element('arguments', data='') + out.close('buildCommand') + if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project + for buildCommand in ['org.eclipse.pde.ManifestBuilder', 'org.eclipse.pde.SchemaBuilder']: + out.open('buildCommand') + out.element('name', data=buildCommand) + out.element('arguments', data='') + out.close('buildCommand') + + # The path should always be p.name/dir. independent of where the workspace actually is. + # So we use the parent folder of the project, whatever that is, to generate such a relative path. + logicalWorkspaceRoot = os.path.dirname(p.dir) + binFolder = os.path.relpath(p.output_dir(), logicalWorkspaceRoot) + + if _isAnnotationProcessorDependency(p): + refreshFile = os.path.relpath(join(p.dir, p.name + '.jar'), logicalWorkspaceRoot) + _genEclipseBuilder(out, p, 'Jar', 'archive ' + p.name, refresh=True, refreshFile=refreshFile, relevantResources=[binFolder], async=True, xmlIndent='', xmlStandalone='no') + + out.close('buildSpec') + out.open('natures') + out.element('nature', data='org.eclipse.jdt.core.javanature') + if exists(csConfig): + out.element('nature', data='net.sf.eclipsecs.core.CheckstyleNature') + if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project + out.element('nature', data='org.eclipse.pde.PluginNature') + out.close('natures') + out.close('projectDescription') + projectFile = join(p.dir, '.project') + update_file(projectFile, out.xml(indent='\t', newl='\n')) + if files: + files.append(projectFile) + + settingsDir = join(p.dir, ".settings") + if not exists(settingsDir): + os.mkdir(settingsDir) + + # collect the defaults from mxtool + defaultEclipseSettingsDir = join(dirname(__file__), 'eclipse-settings') + esdict = {} + if exists(defaultEclipseSettingsDir): + for name in os.listdir(defaultEclipseSettingsDir): + if isfile(join(defaultEclipseSettingsDir, name)): + esdict[name] = os.path.abspath(join(defaultEclipseSettingsDir, name)) + + # check for suite overrides + eclipseSettingsDir = join(p.suite.mxDir, 'eclipse-settings') + if exists(eclipseSettingsDir): + for name in os.listdir(eclipseSettingsDir): + if isfile(join(eclipseSettingsDir, name)): + esdict[name] = os.path.abspath(join(eclipseSettingsDir, name)) + + # check for project overrides + projectSettingsDir = join(p.dir, 'eclipse-settings') + if exists(projectSettingsDir): + for name in os.listdir(projectSettingsDir): + if isfile(join(projectSettingsDir, name)): + esdict[name] = os.path.abspath(join(projectSettingsDir, name)) + + # copy a possibly modified file to the project's .settings directory + for name, path in esdict.iteritems(): + # ignore this file altogether if this project has no annotation processors + if name == "org.eclipse.jdt.apt.core.prefs" and not len(p.annotation_processors()) > 0: + continue + + with open(path) as f: + content = f.read() + content = content.replace('${javaCompliance}', str(p.javaCompliance)) + if len(p.annotation_processors()) > 0: + content = content.replace('org.eclipse.jdt.core.compiler.processAnnotations=disabled', 'org.eclipse.jdt.core.compiler.processAnnotations=enabled') + update_file(join(settingsDir, name), content) + if files: + files.append(join(settingsDir, name)) + + if len(p.annotation_processors()) > 0: + out = XMLDoc() + out.open('factorypath') + out.element('factorypathentry', {'kind' : 'PLUGIN', 'id' : 'org.eclipse.jst.ws.annotations.core', 'enabled' : 'true', 'runInBatchMode' : 'false'}) + for ap in p.annotation_processors(): + for dep in dependency(ap).all_deps([], True): + if dep.isLibrary(): + # Relative paths for "lib" class path entries have various semantics depending on the Eclipse + # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's + # safest to simply use absolute paths. + path = _make_absolute(dep.get_path(resolve=True), p.suite.dir) + out.element('factorypathentry', {'kind' : 'EXTJAR', 'id' : path, 'enabled' : 'true', 'runInBatchMode' : 'false'}) + if files: + files.append(path) + elif dep.isProject(): + out.element('factorypathentry', {'kind' : 'WKSPJAR', 'id' : '/' + dep.name + '/' + dep.name + '.jar', 'enabled' : 'true', 'runInBatchMode' : 'false'}) + out.close('factorypath') + update_file(join(p.dir, '.factorypath'), out.xml(indent='\t', newl='\n')) + if files: + files.append(join(p.dir, '.factorypath')) + def _eclipseinit_suite(args, suite, buildProcessorJars=True, refreshOnly=False): configZip = TimeStampFile(join(suite.mxDir, 'eclipse-config.zip')) configLibsZip = join(suite.mxDir, 'eclipse-config-libs.zip') @@ -3184,6 +3407,8 @@ logv('[Eclipse configurations are up to date - skipping]') return + + files = [] libFiles = [] if buildProcessorJars: @@ -3198,220 +3423,7 @@ for p in suite.projects: if p.native: continue - - assert java(p.javaCompliance) - - if not exists(p.dir): - os.makedirs(p.dir) - - out = XMLDoc() - out.open('classpath') - - for src in p.srcDirs: - srcDir = join(p.dir, src) - if not exists(srcDir): - os.mkdir(srcDir) - out.element('classpathentry', {'kind' : 'src', 'path' : src}) - - if len(p.annotation_processors()) > 0: - genDir = p.source_gen_dir() - if not exists(genDir): - os.mkdir(genDir) - out.element('classpathentry', {'kind' : 'src', 'path' : 'src_gen'}) - files.append(genDir) - - # Every Java program depends on a JRE - out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-' + str(p.javaCompliance)}) - - if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project - out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.pde.core.requiredPlugins'}) - - containerDeps = set() - libraryDeps = set() - projectDeps = set() - - for dep in p.all_deps([], True): - if dep == p: - continue - if dep.isLibrary(): - if hasattr(dep, 'eclipse.container'): - container = getattr(dep, 'eclipse.container') - containerDeps.add(container) - libraryDeps -= set(dep.all_deps([], True)) - else: - libraryDeps.add(dep) - elif dep.isProject(): - projectDeps.add(dep) - - for dep in containerDeps: - out.element('classpathentry', {'exported' : 'true', 'kind' : 'con', 'path' : dep}) - - for dep in libraryDeps: - path = dep.path - dep.get_path(resolve=True) - - # Relative paths for "lib" class path entries have various semantics depending on the Eclipse - # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's - # safest to simply use absolute paths. - path = _make_absolute(path, p.suite.dir) - - attributes = {'exported' : 'true', 'kind' : 'lib', 'path' : path} - - sourcePath = dep.get_source_path(resolve=True) - if sourcePath is not None: - attributes['sourcepath'] = sourcePath - out.element('classpathentry', attributes) - libFiles.append(path) - - for dep in projectDeps: - out.element('classpathentry', {'combineaccessrules' : 'false', 'exported' : 'true', 'kind' : 'src', 'path' : '/' + dep.name}) - - out.element('classpathentry', {'kind' : 'output', 'path' : getattr(p, 'eclipse.output', 'bin')}) - out.close('classpath') - classpathFile = join(p.dir, '.classpath') - update_file(classpathFile, out.xml(indent='\t', newl='\n')) - files.append(classpathFile) - - csConfig = join(project(p.checkstyleProj).dir, '.checkstyle_checks.xml') - if exists(csConfig): - out = XMLDoc() - - dotCheckstyle = join(p.dir, ".checkstyle") - checkstyleConfigPath = '/' + p.checkstyleProj + '/.checkstyle_checks.xml' - out.open('fileset-config', {'file-format-version' : '1.2.0', 'simple-config' : 'true'}) - out.open('local-check-config', {'name' : 'Checks', 'location' : checkstyleConfigPath, 'type' : 'project', 'description' : ''}) - out.element('additional-data', {'name' : 'protect-config-file', 'value' : 'false'}) - out.close('local-check-config') - out.open('fileset', {'name' : 'all', 'enabled' : 'true', 'check-config-name' : 'Checks', 'local' : 'true'}) - out.element('file-match-pattern', {'match-pattern' : '.', 'include-pattern' : 'true'}) - out.close('fileset') - out.open('filter', {'name' : 'all', 'enabled' : 'true', 'check-config-name' : 'Checks', 'local' : 'true'}) - out.element('filter-data', {'value' : 'java'}) - out.close('filter') - - exclude = join(p.dir, '.checkstyle.exclude') - if exists(exclude): - out.open('filter', {'name' : 'FilesFromPackage', 'enabled' : 'true'}) - with open(exclude) as f: - for line in f: - if not line.startswith('#'): - line = line.strip() - exclDir = join(p.dir, line) - assert isdir(exclDir), 'excluded source directory listed in ' + exclude + ' does not exist or is not a directory: ' + exclDir - out.element('filter-data', {'value' : line}) - out.close('filter') - - out.close('fileset-config') - update_file(dotCheckstyle, out.xml(indent=' ', newl='\n')) - files.append(dotCheckstyle) - else: - # clean up existing .checkstyle file - dotCheckstyle = join(p.dir, ".checkstyle") - if exists(dotCheckstyle): - os.unlink(dotCheckstyle) - - out = XMLDoc() - out.open('projectDescription') - out.element('name', data=p.name) - out.element('comment', data='') - out.element('projects', data='') - out.open('buildSpec') - out.open('buildCommand') - out.element('name', data='org.eclipse.jdt.core.javabuilder') - out.element('arguments', data='') - out.close('buildCommand') - if exists(csConfig): - out.open('buildCommand') - out.element('name', data='net.sf.eclipsecs.core.CheckstyleBuilder') - out.element('arguments', data='') - out.close('buildCommand') - if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project - for buildCommand in ['org.eclipse.pde.ManifestBuilder', 'org.eclipse.pde.SchemaBuilder']: - out.open('buildCommand') - out.element('name', data=buildCommand) - out.element('arguments', data='') - out.close('buildCommand') - - # The path should always be p.name/dir. independent of where the workspace actually is. - # So we use the parent folder of the project, whatever that is, to generate such a relative path. - logicalWorkspaceRoot = os.path.dirname(p.dir) - binFolder = os.path.relpath(p.output_dir(), logicalWorkspaceRoot) - - if _isAnnotationProcessorDependency(p): - refreshFile = os.path.relpath(join(p.dir, p.name + '.jar'), logicalWorkspaceRoot) - _genEclipseBuilder(out, p, 'Jar', 'archive ' + p.name, refresh=True, refreshFile=refreshFile, relevantResources=[binFolder], async=True, xmlIndent='', xmlStandalone='no') - - out.close('buildSpec') - out.open('natures') - out.element('nature', data='org.eclipse.jdt.core.javanature') - if exists(csConfig): - out.element('nature', data='net.sf.eclipsecs.core.CheckstyleNature') - if exists(join(p.dir, 'plugin.xml')): # eclipse plugin project - out.element('nature', data='org.eclipse.pde.PluginNature') - out.close('natures') - out.close('projectDescription') - projectFile = join(p.dir, '.project') - update_file(projectFile, out.xml(indent='\t', newl='\n')) - files.append(projectFile) - - settingsDir = join(p.dir, ".settings") - if not exists(settingsDir): - os.mkdir(settingsDir) - - # collect the defaults from mxtool - defaultEclipseSettingsDir = join(dirname(__file__), 'eclipse-settings') - esdict = {} - if exists(defaultEclipseSettingsDir): - for name in os.listdir(defaultEclipseSettingsDir): - if isfile(join(defaultEclipseSettingsDir, name)): - esdict[name] = os.path.abspath(join(defaultEclipseSettingsDir, name)) - - # check for suite overrides - eclipseSettingsDir = join(p.suite.mxDir, 'eclipse-settings') - if exists(eclipseSettingsDir): - for name in os.listdir(eclipseSettingsDir): - if isfile(join(eclipseSettingsDir, name)): - esdict[name] = os.path.abspath(join(eclipseSettingsDir, name)) - - # check for project overrides - projectSettingsDir = join(p.dir, 'eclipse-settings') - if exists(projectSettingsDir): - for name in os.listdir(projectSettingsDir): - if isfile(join(projectSettingsDir, name)): - esdict[name] = os.path.abspath(join(projectSettingsDir, name)) - - # copy a possibly modified file to the project's .settings directory - for name, path in esdict.iteritems(): - # ignore this file altogether if this project has no annotation processors - if name == "org.eclipse.jdt.apt.core.prefs" and not len(p.annotation_processors()) > 0: - continue - - with open(path) as f: - content = f.read() - content = content.replace('${javaCompliance}', str(p.javaCompliance)) - if len(p.annotation_processors()) > 0: - content = content.replace('org.eclipse.jdt.core.compiler.processAnnotations=disabled', 'org.eclipse.jdt.core.compiler.processAnnotations=enabled') - update_file(join(settingsDir, name), content) - files.append(join(settingsDir, name)) - - if len(p.annotation_processors()) > 0: - out = XMLDoc() - out.open('factorypath') - out.element('factorypathentry', {'kind' : 'PLUGIN', 'id' : 'org.eclipse.jst.ws.annotations.core', 'enabled' : 'true', 'runInBatchMode' : 'false'}) - for ap in p.annotation_processors(): - for dep in dependency(ap).all_deps([], True): - if dep.isLibrary(): - # Relative paths for "lib" class path entries have various semantics depending on the Eclipse - # version being used (e.g. see https://bugs.eclipse.org/bugs/show_bug.cgi?id=274737) so it's - # safest to simply use absolute paths. - path = _make_absolute(dep.get_path(resolve=True), p.suite.dir) - out.element('factorypathentry', {'kind' : 'EXTJAR', 'id' : path, 'enabled' : 'true', 'runInBatchMode' : 'false'}) - files.append(path) - elif dep.isProject(): - out.element('factorypathentry', {'kind' : 'WKSPJAR', 'id' : '/' + dep.name + '/' + dep.name + '.jar', 'enabled' : 'true', 'runInBatchMode' : 'false'}) - out.close('factorypath') - update_file(join(p.dir, '.factorypath'), out.xml(indent='\t', newl='\n')) - files.append(join(p.dir, '.factorypath')) + _eclipseinit_project(p) _, launchFile = make_eclipse_attach(suite, 'localhost', '8000', deps=sorted_deps(projectNames=None, includeLibs=True)) files.append(launchFile) @@ -3422,7 +3434,6 @@ # Create an Eclipse project for each distribution that will create/update the archive # for the distribution whenever any project of the distribution is updated. for dist in suite.dists: - name = dist.name if hasattr(dist, 'subDir'): projectDir = join(suite.dir, dist.subDir, dist.name + '.dist') else: diff -r efbf9195dfcb -r 352de9bd8fd5 src/share/vm/compiler/compileBroker.cpp --- a/src/share/vm/compiler/compileBroker.cpp Tue Jul 08 20:19:34 2014 +0200 +++ b/src/share/vm/compiler/compileBroker.cpp Thu Jul 10 19:36:27 2014 +0200 @@ -51,6 +51,9 @@ #endif #ifdef GRAAL #include "graal/graalCompiler.hpp" +#ifdef COMPILERGRAAL +#include "runtime/vframe.hpp" +#endif #endif #ifdef COMPILER2 #include "opto/c2compiler.hpp" @@ -1187,10 +1190,22 @@ blocking = is_compile_blocking(method, osr_bci); #ifdef COMPILERGRAAL - // Don't allow blocking compiles for requests triggered by Graal. - if (blocking && thread->is_Compiler_thread()) { - blocking = false; + if (blocking) { + // Don't allow blocking compiles for requests triggered by Graal. + if (thread->is_Compiler_thread()) { + blocking = false; + } + + // Don't allow blocking compiles if inside a class initializer + vframeStream vfst((JavaThread*) thread); + for (; !vfst.at_end(); vfst.next()) { + if (vfst.method()->is_static_initializer()) { + blocking = false; + break; + } + } } + // Don't allow blocking compiles #endif // We will enter the compilation in the queue. diff -r efbf9195dfcb -r 352de9bd8fd5 src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Tue Jul 08 20:19:34 2014 +0200 +++ b/src/share/vm/graal/graalCompiler.cpp Thu Jul 10 19:36:27 2014 +0200 @@ -133,8 +133,7 @@ args.push_int(entry_bci); args.push_long((jlong) (address) task); args.push_int(task->compile_id()); - JavaCalls::call_static(&result, SystemDictionary::CompilationTask_klass(), vmSymbols::compileMetaspaceMethod_name(), vmSymbols::compileMetaspaceMethod_signature(), &args, THREAD); - GUARANTEE_NO_PENDING_EXCEPTION("Error while calling compile_method"); + JavaCalls::call_static(&result, SystemDictionary::CompilationTask_klass(), vmSymbols::compileMetaspaceMethod_name(), vmSymbols::compileMetaspaceMethod_signature(), &args, CHECK_ABORT); _methodsCompiled++; } @@ -159,13 +158,12 @@ CompileTheWorld = false; JavaThread* THREAD = JavaThread::current(); - TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotGraalRuntime", THREAD); + TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotGraalRuntime", CHECK_ABORT); KlassHandle klass = GraalRuntime::load_required_class(name); - TempNewSymbol compileTheWorld = SymbolTable::new_symbol("compileTheWorld", THREAD); + TempNewSymbol compileTheWorld = SymbolTable::new_symbol("compileTheWorld", CHECK_ABORT); JavaValue result(T_VOID); JavaCallArguments args; args.push_oop(GraalRuntime::get_HotSpotGraalRuntime()); - JavaCalls::call_special(&result, klass, compileTheWorld, vmSymbols::void_method_signature(), &args, THREAD); - GUARANTEE_NO_PENDING_EXCEPTION("Error while calling compile_the_world"); + JavaCalls::call_special(&result, klass, compileTheWorld, vmSymbols::void_method_signature(), &args, CHECK_ABORT); } #endif diff -r efbf9195dfcb -r 352de9bd8fd5 src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Tue Jul 08 20:19:34 2014 +0200 +++ b/src/share/vm/graal/graalRuntime.cpp Thu Jul 10 19:36:27 2014 +0200 @@ -62,7 +62,9 @@ env->RegisterNatives(c2vmClass, CompilerToVM_methods, CompilerToVM_methods_count()); } - GUARANTEE_NO_PENDING_EXCEPTION("Could not register natives"); + if (HAS_PENDING_EXCEPTION) { + abort_on_pending_exception(PENDING_EXCEPTION, "Could not register natives"); + } } BufferBlob* GraalRuntime::initialize_buffer_blob() { @@ -652,27 +654,25 @@ // private static TruffleRuntime Truffle.createRuntime() JVM_ENTRY(jobject, JVM_CreateTruffleRuntime(JNIEnv *env, jclass c)) - TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime", THREAD); + TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime", CHECK_NULL); KlassHandle klass = GraalRuntime::resolve_or_fail(name, CHECK_NULL); - TempNewSymbol makeInstance = SymbolTable::new_symbol("makeInstance", THREAD); - TempNewSymbol sig = SymbolTable::new_symbol("()Lcom/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime;", THREAD); + TempNewSymbol makeInstance = SymbolTable::new_symbol("makeInstance", CHECK_NULL); + TempNewSymbol sig = SymbolTable::new_symbol("()Lcom/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime;", CHECK_NULL); JavaValue result(T_OBJECT); - JavaCalls::call_static(&result, klass, makeInstance, sig, THREAD); - GUARANTEE_NO_PENDING_EXCEPTION("Couldn't initialize HotSpotTruffleRuntime"); + JavaCalls::call_static(&result, klass, makeInstance, sig, CHECK_NULL); return JNIHandles::make_local((oop) result.get_jobject()); JVM_END Handle GraalRuntime::get_HotSpotGraalRuntime() { if (JNIHandles::resolve(_HotSpotGraalRuntime_instance) == NULL) { Thread* THREAD = Thread::current(); - TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotGraalRuntime", THREAD); + TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotGraalRuntime", CHECK_ABORT_(Handle())); KlassHandle klass = load_required_class(name); - TempNewSymbol runtime = SymbolTable::new_symbol("runtime", THREAD); - TempNewSymbol sig = SymbolTable::new_symbol("()Lcom/oracle/graal/hotspot/HotSpotGraalRuntime;", THREAD); + TempNewSymbol runtime = SymbolTable::new_symbol("runtime", CHECK_ABORT_(Handle())); + TempNewSymbol sig = SymbolTable::new_symbol("()Lcom/oracle/graal/hotspot/HotSpotGraalRuntime;", CHECK_ABORT_(Handle())); JavaValue result(T_OBJECT); - JavaCalls::call_static(&result, klass, runtime, sig, THREAD); - GUARANTEE_NO_PENDING_EXCEPTION("Couldn't initialize HotSpotGraalRuntime"); + JavaCalls::call_static(&result, klass, runtime, sig, CHECK_ABORT_(Handle())); _HotSpotGraalRuntime_instance = JNIHandles::make_global((oop) result.get_jobject()); } return Handle(JNIHandles::resolve_non_null(_HotSpotGraalRuntime_instance)); @@ -698,9 +698,8 @@ // We now load and initialize HotSpotOptions which in turn // causes argument parsing to be redone with better error messages. CLEAR_PENDING_EXCEPTION; - TempNewSymbol name = SymbolTable::new_symbol("Lcom/oracle/graal/hotspot/HotSpotOptions;", THREAD); - instanceKlassHandle hotSpotOptionsClass = resolve_or_fail(name, THREAD); - GUARANTEE_NO_PENDING_EXCEPTION("Error in check_arguments"); + TempNewSymbol name = SymbolTable::new_symbol("Lcom/oracle/graal/hotspot/HotSpotOptions;", CHECK_ABORT_(JNI_ERR)); + instanceKlassHandle hotSpotOptionsClass = resolve_or_fail(name, CHECK_ABORT_(JNI_ERR)); parse_arguments(hotSpotOptionsClass, THREAD); assert(HAS_PENDING_EXCEPTION, "must be"); @@ -884,8 +883,8 @@ } } - TempNewSymbol setOption = SymbolTable::new_symbol("setOption", THREAD); - TempNewSymbol sig = SymbolTable::new_symbol("(Ljava/lang/String;Lcom/oracle/graal/options/OptionValue;CLjava/lang/String;J)V", THREAD); + TempNewSymbol setOption = SymbolTable::new_symbol("setOption", CHECK); + TempNewSymbol sig = SymbolTable::new_symbol("(Ljava/lang/String;Lcom/oracle/graal/options/OptionValue;CLjava/lang/String;J)V", CHECK); JavaValue result(T_VOID); JavaCallArguments args; args.push_oop(name_handle()); @@ -897,7 +896,7 @@ } Handle GraalRuntime::get_OptionValue(const char* declaringClass, const char* fieldName, const char* fieldSig, TRAPS) { - TempNewSymbol name = SymbolTable::new_symbol(declaringClass, THREAD); + TempNewSymbol name = SymbolTable::new_symbol(declaringClass, CHECK_NH); Klass* klass = resolve_or_fail(name, CHECK_NH); // The class has been loaded so the field and signature should already be in the symbol @@ -920,7 +919,7 @@ } Handle GraalRuntime::create_Service(const char* name, TRAPS) { - TempNewSymbol kname = SymbolTable::new_symbol(name, THREAD); + TempNewSymbol kname = SymbolTable::new_symbol(name, CHECK_NH); Klass* k = resolve_or_fail(kname, CHECK_NH); instanceKlassHandle klass(THREAD, k); klass->initialize(CHECK_NH); @@ -935,13 +934,12 @@ if (_HotSpotGraalRuntime_instance != NULL) { JavaThread* THREAD = JavaThread::current(); HandleMark hm(THREAD); - TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotGraalRuntime", THREAD); + TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/HotSpotGraalRuntime", CHECK_ABORT); KlassHandle klass = load_required_class(name); JavaValue result(T_VOID); JavaCallArguments args; args.push_oop(get_HotSpotGraalRuntime()); - JavaCalls::call_special(&result, klass, vmSymbols::shutdown_method_name(), vmSymbols::void_method_signature(), &args, THREAD); - GUARANTEE_NO_PENDING_EXCEPTION("Error while calling shutdown"); + JavaCalls::call_special(&result, klass, vmSymbols::shutdown_method_name(), vmSymbols::void_method_signature(), &args, CHECK_ABORT); JNIHandles::destroy_global(_HotSpotGraalRuntime_instance); _HotSpotGraalRuntime_instance = NULL; @@ -962,17 +960,12 @@ oop GraalRuntime::compute_graal_class_loader(TRAPS) { assert(UseGraalClassLoader, "must be"); - TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/loader/Factory", THREAD); - KlassHandle klass = SystemDictionary::resolve_or_null(name, THREAD); - if (klass.is_null()) { - tty->print_cr("Could not load class %s", name->as_C_string()); - vm_abort(false); - } + TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/hotspot/loader/Factory", CHECK_NULL); + KlassHandle klass = SystemDictionary::resolve_or_null(name, CHECK_NULL); - TempNewSymbol getClassLoader = SymbolTable::new_symbol("newClassLoader", THREAD); + TempNewSymbol getClassLoader = SymbolTable::new_symbol("newClassLoader", CHECK_NULL); JavaValue result(T_OBJECT); - JavaCalls::call_static(&result, klass, getClassLoader, vmSymbols::void_classloader_signature(), THREAD); - GUARANTEE_NO_PENDING_EXCEPTION("Couldn't initialize HotSpotGraalRuntime"); + JavaCalls::call_static(&result, klass, getClassLoader, vmSymbols::void_classloader_signature(), CHECK_NULL); return (oop) result.get_jobject(); } diff -r efbf9195dfcb -r 352de9bd8fd5 src/share/vm/graal/graalRuntime.hpp --- a/src/share/vm/graal/graalRuntime.hpp Tue Jul 08 20:19:34 2014 +0200 +++ b/src/share/vm/graal/graalRuntime.hpp Thu Jul 10 19:36:27 2014 +0200 @@ -139,11 +139,23 @@ */ static void call_printStackTrace(Handle exception, Thread* thread); -#define GUARANTEE_NO_PENDING_EXCEPTION(error_message) do { \ - if (HAS_PENDING_EXCEPTION) { \ - GraalRuntime::abort_on_pending_exception(PENDING_EXCEPTION, error_message); \ - } \ - } while (0); +#define CHECK_ABORT THREAD); \ + if (HAS_PENDING_EXCEPTION) { \ + char buf[256]; \ + jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ + GraalRuntime::abort_on_pending_exception(PENDING_EXCEPTION, buf); \ + return; \ + } \ + (void)(0 + +#define CHECK_ABORT_(result) THREAD); \ + if (HAS_PENDING_EXCEPTION) { \ + char buf[256]; \ + jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \ + GraalRuntime::abort_on_pending_exception(PENDING_EXCEPTION, buf); \ + return result; \ + } \ + (void)(0 /** * Same as SystemDictionary::resolve_or_null but uses the Graal loader. diff -r efbf9195dfcb -r 352de9bd8fd5 src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp Tue Jul 08 20:19:34 2014 +0200 +++ b/src/share/vm/runtime/thread.cpp Thu Jul 10 19:36:27 2014 +0200 @@ -3679,7 +3679,9 @@ // anymore. We call vm_exit_during_initialization directly instead. SystemDictionary::compute_java_system_loader(THREAD); #ifdef GRAAL - SystemDictionary::initialize_preloaded_graal_classes(THREAD); + if (!HAS_PENDING_EXCEPTION) { + SystemDictionary::initialize_preloaded_graal_classes(THREAD); + } #endif if (HAS_PENDING_EXCEPTION) { vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));