# HG changeset patch # User Doug Simon # Date 1363374490 -3600 # Node ID a90648ecf04ff4c979998585a33a8535344133ec # Parent 0e6cac0470dc17af078e009ec3a8fcc1c4a40178# Parent 338b0d2382b366b402a4e0626c1b95923ac14783 Merge. diff -r 338b0d2382b3 -r a90648ecf04f graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Fri Mar 15 18:51:58 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Fri Mar 15 20:08:10 2013 +0100 @@ -25,6 +25,7 @@ import static com.oracle.graal.amd64.AMD64.*; import static com.oracle.graal.compiler.amd64.AMD64LIRGenerator.*; import static com.oracle.graal.hotspot.amd64.AMD64DeoptimizeOp.*; +import static com.oracle.graal.hotspot.amd64.AMD64HotSpotUnwindOp.*; import static com.oracle.graal.hotspot.nodes.IdentityHashCodeStubCall.*; import static com.oracle.graal.hotspot.nodes.MonitorEnterStubCall.*; import static com.oracle.graal.hotspot.nodes.MonitorExitStubCall.*; @@ -46,11 +47,11 @@ import com.oracle.graal.compiler.target.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.amd64.snippets.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.snippets.*; +import com.oracle.graal.snippets.amd64.*; public class AMD64HotSpotRuntime extends HotSpotRuntime { @@ -60,7 +61,7 @@ Kind word = graalRuntime.getTarget().wordKind; // @formatter:off - addRuntimeCall(AMD64HotSpotUnwindOp.UNWIND_EXCEPTION, config.unwindExceptionStub, + addRuntimeCall(UNWIND_EXCEPTION, config.unwindExceptionStub, /* temps */ null, /* ret */ ret(Kind.Void), /* arg0: exception */ rax.asValue(Kind.Object)); diff -r 338b0d2382b3 -r a90648ecf04f graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/snippets/AMD64ConvertSnippets.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/snippets/AMD64ConvertSnippets.java Fri Mar 15 18:51:58 2013 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,196 +0,0 @@ -/* - * Copyright (c) 2013, 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.hotspot.amd64.snippets; - -import static com.oracle.graal.snippets.SnippetTemplate.*; -import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*; -import static com.oracle.graal.snippets.nodes.BranchProbabilityNode.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.debug.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.calc.ConvertNode.Op; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.snippets.*; -import com.oracle.graal.snippets.Snippet.Parameter; -import com.oracle.graal.snippets.SnippetTemplate.AbstractTemplates; -import com.oracle.graal.snippets.SnippetTemplate.Arguments; -import com.oracle.graal.snippets.SnippetTemplate.Key; - -/** - * Snippets used for conversion operations on AMD64 where the AMD64 instruction used does not match - * the semantics of the JVM specification. - */ -public class AMD64ConvertSnippets implements SnippetsInterface { - - /** - * Converts a float to an int. - *

- * This snippet accounts for the semantics of the x64 CVTTSS2SI instruction used to do the - * conversion. If the float value is a NaN, infinity or if the result of the conversion is - * larger than {@link Integer#MAX_VALUE} then CVTTSS2SI returns {@link Integer#MIN_VALUE} and - * extra tests are required on the float value to return the correct int value. - * - * @param input the float being converted - * @param result the result produced by the CVTTSS2SI instruction - */ - @Snippet - public static int f2i(@Parameter("input") float input, @Parameter("result") int result) { - if (result == Integer.MIN_VALUE) { - probability(NOT_FREQUENT_PROBABILITY); - if (Float.isNaN(input)) { - // input is NaN -> return 0 - return 0; - } else if (input > 0.0f) { - // input is > 0 -> return max int - return Integer.MAX_VALUE; - } - } - return result; - } - - /** - * Converts a float to a long. - *

- * This snippet accounts for the semantics of the x64 CVTTSS2SI instruction used to do the - * conversion. If the float value is a NaN or infinity then CVTTSS2SI returns - * {@link Long#MIN_VALUE} and extra tests are required on the float value to return the correct - * long value. - * - * @param input the float being converted - * @param result the result produced by the CVTTSS2SI instruction - */ - @Snippet - public static long f2l(@Parameter("input") float input, @Parameter("result") long result) { - if (result == Long.MIN_VALUE) { - probability(NOT_FREQUENT_PROBABILITY); - if (Float.isNaN(input)) { - // input is NaN -> return 0 - return 0; - } else if (input > 0.0f) { - // input is > 0 -> return max int - return Long.MAX_VALUE; - } - } - return result; - } - - /** - * Converts a double to an int. - *

- * This snippet accounts for the semantics of the x64 CVTTSD2SI instruction used to do the - * conversion. If the double value is a NaN, infinity or if the result of the conversion is - * larger than {@link Integer#MAX_VALUE} then CVTTSD2SI returns {@link Integer#MIN_VALUE} and - * extra tests are required on the double value to return the correct int value. - * - * @param input the double being converted - * @param result the result produced by the CVTTSS2SI instruction - */ - @Snippet - public static int d2i(@Parameter("input") double input, @Parameter("result") int result) { - if (result == Integer.MIN_VALUE) { - probability(NOT_FREQUENT_PROBABILITY); - if (Double.isNaN(input)) { - // input is NaN -> return 0 - return 0; - } else if (input > 0.0d) { - // input is positive -> return maxInt - return Integer.MAX_VALUE; - } - } - return result; - } - - /** - * Converts a double to a long. - *

- * This snippet accounts for the semantics of the x64 CVTTSD2SI instruction used to do the - * conversion. If the double value is a NaN, infinity or if the result of the conversion is - * larger than {@link Long#MAX_VALUE} then CVTTSD2SI returns {@link Long#MIN_VALUE} and extra - * tests are required on the double value to return the correct long value. - * - * @param input the double being converted - * @param result the result produced by the CVTTSS2SI instruction - */ - @Snippet - public static long d2l(@Parameter("input") double input, @Parameter("result") long result) { - if (result == Long.MIN_VALUE) { - probability(NOT_FREQUENT_PROBABILITY); - if (Double.isNaN(input)) { - // input is NaN -> return 0 - return 0; - } else if (input > 0.0d) { - // input is positive -> return maxInt - return Long.MAX_VALUE; - } - } - return result; - } - - public static class Templates extends AbstractTemplates { - - private final ResolvedJavaMethod f2i; - private final ResolvedJavaMethod f2l; - private final ResolvedJavaMethod d2i; - private final ResolvedJavaMethod d2l; - - public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target) { - super(runtime, assumptions, target, AMD64ConvertSnippets.class); - f2i = snippet("f2i", float.class, int.class); - f2l = snippet("f2l", float.class, long.class); - d2i = snippet("d2i", double.class, int.class); - d2l = snippet("d2l", double.class, long.class); - } - - public void lower(ConvertNode convert, LoweringTool tool) { - if (convert.opcode == Op.F2I) { - lower0(convert, tool, f2i); - } else if (convert.opcode == Op.F2L) { - lower0(convert, tool, f2l); - } else if (convert.opcode == Op.D2I) { - lower0(convert, tool, d2i); - } else if (convert.opcode == Op.D2L) { - lower0(convert, tool, d2l); - } - } - - private void lower0(ConvertNode convert, LoweringTool tool, ResolvedJavaMethod snippet) { - StructuredGraph graph = (StructuredGraph) convert.graph(); - - // Insert a unique placeholder node in place of the Convert node so that the - // Convert node can be used as an input to the snippet. All usage of the - // Convert node are replaced by the placeholder which in turn is replaced by the - // snippet. - - LocalNode replacee = graph.add(new LocalNode(Integer.MAX_VALUE, convert.stamp())); - convert.replaceAtUsages(replacee); - Key key = new Key(snippet); - Arguments arguments = arguments("input", convert.value()).add("result", convert); - SnippetTemplate template = cache.get(key, assumptions); - Debug.log("Lowering %s in %s: node=%s, template=%s, arguments=%s", convert.opcode, graph, convert, template, arguments); - template.instantiate(runtime, replacee, DEFAULT_REPLACER, tool, arguments); - } - } -} diff -r 338b0d2382b3 -r a90648ecf04f graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Fri Mar 15 18:51:58 2013 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Fri Mar 15 20:08:10 2013 +0100 @@ -167,7 +167,7 @@ public static boolean GenAssertionCode = ____; public static boolean AlignCallsForPatching = true; public static boolean ResolveClassBeforeStaticInvoke = ____; - public static boolean CanOmitFrame = false; + public static boolean CanOmitFrame = true; public static int SafepointPollOffset = 256; public static boolean MemoryAwareScheduling = true; diff -r 338b0d2382b3 -r a90648ecf04f graal/com.oracle.graal.snippets.amd64/src/com/oracle/graal/snippets/amd64/AMD64ConvertSnippets.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.snippets.amd64/src/com/oracle/graal/snippets/amd64/AMD64ConvertSnippets.java Fri Mar 15 20:08:10 2013 +0100 @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2013, 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.snippets.amd64; + +import static com.oracle.graal.snippets.SnippetTemplate.*; +import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*; +import static com.oracle.graal.snippets.nodes.BranchProbabilityNode.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.calc.ConvertNode.Op; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.snippets.*; +import com.oracle.graal.snippets.Snippet.Parameter; +import com.oracle.graal.snippets.SnippetTemplate.AbstractTemplates; +import com.oracle.graal.snippets.SnippetTemplate.Arguments; +import com.oracle.graal.snippets.SnippetTemplate.Key; + +/** + * Snippets used for conversion operations on AMD64 where the AMD64 instruction used does not match + * the semantics of the JVM specification. + */ +public class AMD64ConvertSnippets implements SnippetsInterface { + + /** + * Converts a float to an int. + *

+ * This snippet accounts for the semantics of the x64 CVTTSS2SI instruction used to do the + * conversion. If the float value is a NaN, infinity or if the result of the conversion is + * larger than {@link Integer#MAX_VALUE} then CVTTSS2SI returns {@link Integer#MIN_VALUE} and + * extra tests are required on the float value to return the correct int value. + * + * @param input the float being converted + * @param result the result produced by the CVTTSS2SI instruction + */ + @Snippet + public static int f2i(@Parameter("input") float input, @Parameter("result") int result) { + if (result == Integer.MIN_VALUE) { + probability(NOT_FREQUENT_PROBABILITY); + if (Float.isNaN(input)) { + // input is NaN -> return 0 + return 0; + } else if (input > 0.0f) { + // input is > 0 -> return max int + return Integer.MAX_VALUE; + } + } + return result; + } + + /** + * Converts a float to a long. + *

+ * This snippet accounts for the semantics of the x64 CVTTSS2SI instruction used to do the + * conversion. If the float value is a NaN or infinity then CVTTSS2SI returns + * {@link Long#MIN_VALUE} and extra tests are required on the float value to return the correct + * long value. + * + * @param input the float being converted + * @param result the result produced by the CVTTSS2SI instruction + */ + @Snippet + public static long f2l(@Parameter("input") float input, @Parameter("result") long result) { + if (result == Long.MIN_VALUE) { + probability(NOT_FREQUENT_PROBABILITY); + if (Float.isNaN(input)) { + // input is NaN -> return 0 + return 0; + } else if (input > 0.0f) { + // input is > 0 -> return max int + return Long.MAX_VALUE; + } + } + return result; + } + + /** + * Converts a double to an int. + *

+ * This snippet accounts for the semantics of the x64 CVTTSD2SI instruction used to do the + * conversion. If the double value is a NaN, infinity or if the result of the conversion is + * larger than {@link Integer#MAX_VALUE} then CVTTSD2SI returns {@link Integer#MIN_VALUE} and + * extra tests are required on the double value to return the correct int value. + * + * @param input the double being converted + * @param result the result produced by the CVTTSS2SI instruction + */ + @Snippet + public static int d2i(@Parameter("input") double input, @Parameter("result") int result) { + if (result == Integer.MIN_VALUE) { + probability(NOT_FREQUENT_PROBABILITY); + if (Double.isNaN(input)) { + // input is NaN -> return 0 + return 0; + } else if (input > 0.0d) { + // input is positive -> return maxInt + return Integer.MAX_VALUE; + } + } + return result; + } + + /** + * Converts a double to a long. + *

+ * This snippet accounts for the semantics of the x64 CVTTSD2SI instruction used to do the + * conversion. If the double value is a NaN, infinity or if the result of the conversion is + * larger than {@link Long#MAX_VALUE} then CVTTSD2SI returns {@link Long#MIN_VALUE} and extra + * tests are required on the double value to return the correct long value. + * + * @param input the double being converted + * @param result the result produced by the CVTTSS2SI instruction + */ + @Snippet + public static long d2l(@Parameter("input") double input, @Parameter("result") long result) { + if (result == Long.MIN_VALUE) { + probability(NOT_FREQUENT_PROBABILITY); + if (Double.isNaN(input)) { + // input is NaN -> return 0 + return 0; + } else if (input > 0.0d) { + // input is positive -> return maxInt + return Long.MAX_VALUE; + } + } + return result; + } + + public static class Templates extends AbstractTemplates { + + private final ResolvedJavaMethod f2i; + private final ResolvedJavaMethod f2l; + private final ResolvedJavaMethod d2i; + private final ResolvedJavaMethod d2l; + + public Templates(CodeCacheProvider runtime, Assumptions assumptions, TargetDescription target) { + super(runtime, assumptions, target, AMD64ConvertSnippets.class); + f2i = snippet("f2i", float.class, int.class); + f2l = snippet("f2l", float.class, long.class); + d2i = snippet("d2i", double.class, int.class); + d2l = snippet("d2l", double.class, long.class); + } + + public void lower(ConvertNode convert, LoweringTool tool) { + if (convert.opcode == Op.F2I) { + lower0(convert, tool, f2i); + } else if (convert.opcode == Op.F2L) { + lower0(convert, tool, f2l); + } else if (convert.opcode == Op.D2I) { + lower0(convert, tool, d2i); + } else if (convert.opcode == Op.D2L) { + lower0(convert, tool, d2l); + } + } + + private void lower0(ConvertNode convert, LoweringTool tool, ResolvedJavaMethod snippet) { + StructuredGraph graph = (StructuredGraph) convert.graph(); + + // Insert a unique placeholder node in place of the Convert node so that the + // Convert node can be used as an input to the snippet. All usage of the + // Convert node are replaced by the placeholder which in turn is replaced by the + // snippet. + + LocalNode replacee = graph.add(new LocalNode(Integer.MAX_VALUE, convert.stamp())); + convert.replaceAtUsages(replacee); + Key key = new Key(snippet); + Arguments arguments = arguments("input", convert.value()).add("result", convert); + SnippetTemplate template = cache.get(key, assumptions); + Debug.log("Lowering %s in %s: node=%s, template=%s, arguments=%s", convert.opcode, graph, convert, template, arguments); + template.instantiate(runtime, replacee, DEFAULT_REPLACER, tool, arguments); + } + } +} diff -r 338b0d2382b3 -r a90648ecf04f mx/projects --- a/mx/projects Fri Mar 15 18:51:58 2013 +0100 +++ b/mx/projects Fri Mar 15 20:08:10 2013 +0100 @@ -89,7 +89,7 @@ # graal.hotspot.amd64 project@com.oracle.graal.hotspot.amd64@subDir=graal project@com.oracle.graal.hotspot.amd64@sourceDirs=src -project@com.oracle.graal.hotspot.amd64@dependencies=com.oracle.graal.hotspot,com.oracle.graal.compiler.amd64 +project@com.oracle.graal.hotspot.amd64@dependencies=com.oracle.graal.hotspot,com.oracle.graal.compiler.amd64,com.oracle.graal.snippets.amd64 project@com.oracle.graal.hotspot.amd64@checkstyle=com.oracle.graal.graph project@com.oracle.graal.hotspot.amd64@javaCompliance=1.7 @@ -182,6 +182,13 @@ project@com.oracle.graal.snippets@checkstyle=com.oracle.graal.graph project@com.oracle.graal.snippets@javaCompliance=1.7 +# graal.snippets.amd64 +project@com.oracle.graal.snippets.amd64@subDir=graal +project@com.oracle.graal.snippets.amd64@sourceDirs=src +project@com.oracle.graal.snippets.amd64@dependencies=com.oracle.graal.snippets,com.oracle.graal.amd64 +project@com.oracle.graal.snippets.amd64@checkstyle=com.oracle.graal.graph +project@com.oracle.graal.snippets.amd64@javaCompliance=1.7 + # graal.snippets.test project@com.oracle.graal.snippets.test@subDir=graal project@com.oracle.graal.snippets.test@sourceDirs=src