# HG changeset patch # User Christos Kotselidis # Date 1371115546 -7200 # Node ID 4ebe31e19892c42af2ce87d3d344f9a297c11227 # Parent 6e4b72bcc97ffd4d7e6088958d2324b50eb99422# Parent 53f090c5975aa8c418a198ecb1bba472a8702b26 Merge diff -r 6e4b72bcc97f -r 4ebe31e19892 graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/BasicSPARCTest.java --- a/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/BasicSPARCTest.java Thu Jun 13 11:25:07 2013 +0200 +++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/BasicSPARCTest.java Thu Jun 13 11:25:46 2013 +0200 @@ -26,7 +26,6 @@ import org.junit.Test; - public class BasicSPARCTest extends SPARCTestBase { @Test diff -r 6e4b72bcc97f -r 4ebe31e19892 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Thu Jun 13 11:25:07 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Thu Jun 13 11:25:46 2013 +0200 @@ -141,7 +141,7 @@ new VerifyUsageWithEquals(runtime, Register.class).apply(graph); } - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(OptCanonicalizeReads.getValue()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue()); HighTierContext highTierContext = new HighTierContext(runtime, assumptions, replacements); if (OptCanonicalizer.getValue()) { diff -r 6e4b72bcc97f -r 4ebe31e19892 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Thu Jun 13 11:25:07 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Thu Jun 13 11:25:46 2013 +0200 @@ -34,10 +34,10 @@ public class HighTier extends PhaseSuite { public HighTier() { - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(OptCanonicalizeReads.getValue()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue()); if (FullUnroll.getValue()) { - addPhase(new LoopFullUnrollPhase(OptCanonicalizeReads.getValue())); + addPhase(new LoopFullUnrollPhase(!AOTCompilation.getValue())); } if (OptTailDuplication.getValue()) { diff -r 6e4b72bcc97f -r 4ebe31e19892 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Thu Jun 13 11:25:07 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Thu Jun 13 11:25:46 2013 +0200 @@ -32,7 +32,7 @@ public class MidTier extends PhaseSuite { public MidTier() { - CanonicalizerPhase canonicalizer = new CanonicalizerPhase(OptCanonicalizeReads.getValue()); + CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue()); if (OptPushThroughPi.getValue()) { addPhase(new PushThroughPiPhase()); diff -r 6e4b72bcc97f -r 4ebe31e19892 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Thu Jun 13 11:25:07 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Thu Jun 13 11:25:46 2013 +0200 @@ -35,7 +35,6 @@ import com.oracle.graal.compiler.test.*; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.phases.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; @@ -55,6 +54,7 @@ public class AheadOfTimeCompilationTest extends GraalCompilerTest { public static final Object STATICFINALOBJECT = new Object(); + public static final String STATICFINALSTRING = "test string"; public static Object getStaticFinalObject() { return AheadOfTimeCompilationTest.STATICFINALOBJECT; @@ -63,15 +63,19 @@ @Test public void testStaticFinalObjectAOT() { StructuredGraph result = compile("getStaticFinalObject", true); - assert result.getNodes().filter(ConstantNode.class).count() == 1; - assert result.getNodes(FloatingReadNode.class).count() == 2; + assertEquals(1, result.getNodes().filter(ConstantNode.class).count()); + assertEquals(runtime.getTarget().wordKind, result.getNodes().filter(ConstantNode.class).first().kind()); + assertEquals(2, result.getNodes(FloatingReadNode.class).count()); + assertEquals(0, result.getNodes(ReadNode.class).count()); } @Test public void testStaticFinalObject() { StructuredGraph result = compile("getStaticFinalObject", false); - assert result.getNodes().filter(ConstantNode.class).count() == 1; - assert result.getNodes(FloatingReadNode.class).count() == 0; + assertEquals(1, result.getNodes().filter(ConstantNode.class).count()); + assertEquals(Kind.Object, result.getNodes().filter(ConstantNode.class).first().kind()); + assertEquals(0, result.getNodes(FloatingReadNode.class).count()); + assertEquals(0, result.getNodes(ReadNode.class).count()); } public static Class getClassObject() { @@ -83,12 +87,12 @@ StructuredGraph result = compile("getClassObject", true); NodeIterable filter = result.getNodes().filter(ConstantNode.class); - assert filter.count() == 1; + assertEquals(1, filter.count()); HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) runtime.lookupJavaType(AheadOfTimeCompilationTest.class); - assert filter.first().asConstant().equals(type.klass()); + assertEquals(type.klass(), filter.first().asConstant()); - assert result.getNodes(FloatingReadNode.class).count() == 1; - assert result.getNodes(ReadNode.class).count() == 0; + assertEquals(1, result.getNodes(FloatingReadNode.class).count()); + assertEquals(0, result.getNodes(ReadNode.class).count()); } @Test @@ -96,21 +100,77 @@ StructuredGraph result = compile("getClassObject", false); NodeIterable filter = result.getNodes().filter(ConstantNode.class); - assert filter.count() == 1; + assertEquals(1, filter.count()); + Object mirror = filter.first().asConstant().asObject(); + assertEquals(Class.class, mirror.getClass()); + assertEquals(AheadOfTimeCompilationTest.class, mirror); + + assertEquals(0, result.getNodes(FloatingReadNode.class).count()); + assertEquals(0, result.getNodes(ReadNode.class).count()); + } + + public static Class getPrimitiveClassObject() { + return int.class; + } + + @Test + public void testPrimitiveClassObjectAOT() { + StructuredGraph result = compile("getPrimitiveClassObject", true); + NodeIterable filter = result.getNodes().filter(ConstantNode.class); + assertEquals(1, filter.count()); + assertEquals(runtime.getTarget().wordKind, filter.first().kind()); + + assertEquals(2, result.getNodes(FloatingReadNode.class).count()); + assertEquals(0, result.getNodes(ReadNode.class).count()); + } + + @Test + public void testPrimitiveClassObject() { + StructuredGraph result = compile("getPrimitiveClassObject", false); + NodeIterable filter = result.getNodes().filter(ConstantNode.class); + assertEquals(1, filter.count()); Object mirror = filter.first().asConstant().asObject(); - assert mirror.getClass().equals(Class.class); - assert mirror.equals(AheadOfTimeCompilationTest.class); + assertEquals(Class.class, mirror.getClass()); + assertEquals(Integer.TYPE, mirror); + + assertEquals(0, result.getNodes(FloatingReadNode.class).count()); + assertEquals(0, result.getNodes(ReadNode.class).count()); + } + + public static String getStringObject() { + return AheadOfTimeCompilationTest.STATICFINALSTRING; + } + + @Test + public void testStringObjectAOT() { + // embedded strings are fine + testStringObjectCommon(true); + } - assert result.getNodes(FloatingReadNode.class).count() == 0; - assert result.getNodes(ReadNode.class).count() == 0; + @Test + public void testStringObject() { + testStringObjectCommon(false); + } + + private void testStringObjectCommon(boolean compileAOT) { + StructuredGraph result = compile("getStringObject", compileAOT); + + NodeIterable filter = result.getNodes().filter(ConstantNode.class); + assertEquals(1, filter.count()); + Object mirror = filter.first().asConstant().asObject(); + assertEquals(String.class, mirror.getClass()); + assertEquals("test string", mirror); + + assertEquals(0, result.getNodes(FloatingReadNode.class).count()); + assertEquals(0, result.getNodes(ReadNode.class).count()); } private StructuredGraph compile(String test, boolean compileAOT) { StructuredGraph graph = parse(test); ResolvedJavaMethod method = graph.method(); - boolean originalSetting = OptCanonicalizeReads.getValue(); - OptCanonicalizeReads.setValue(!compileAOT); + boolean originalSetting = AOTCompilation.getValue(); + AOTCompilation.setValue(compileAOT); PhasePlan phasePlan = new PhasePlan(); GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); @@ -118,14 +178,11 @@ CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); // create suites everytime, as we modify options for the compiler final Suites suitesLocal = Graal.getRequiredCapability(SuitesProvider.class).createSuites(); - if (compileAOT) { - suitesLocal.getHighTier().addPhase(new LoadJavaMirrorWithKlassPhase()); - } final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, backend, runtime().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog(), suitesLocal); addMethod(method, compResult); - OptCanonicalizeReads.setValue(originalSetting); + AOTCompilation.setValue(originalSetting); return graph; } diff -r 6e4b72bcc97f -r 4ebe31e19892 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Jun 13 11:25:07 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Jun 13 11:25:46 2013 +0200 @@ -1068,6 +1068,14 @@ public Suites createSuites() { Suites ret = Suites.createDefaultSuites(); + if (AOTCompilation.getValue()) { + // lowering introduces class constants, therefore it must be after lowering + ret.getHighTier().addPhase(new LoadJavaMirrorWithKlassPhase()); + if (VerifyPhases.getValue()) { + ret.getHighTier().addPhase(new AheadOfTimeVerifcationPhase()); + } + } + ret.getMidTier().addPhase(new WriteBarrierAdditionPhase()); if (VerifyPhases.getValue()) { ret.getMidTier().addPhase(new WriteBarrierVerificationPhase()); diff -r 6e4b72bcc97f -r 4ebe31e19892 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerifcationPhase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/AheadOfTimeVerifcationPhase.java Thu Jun 13 11:25:46 2013 +0200 @@ -0,0 +1,50 @@ +/* + * 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.phases; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.phases.*; + +public class AheadOfTimeVerifcationPhase extends VerifyPhase { + + @Override + protected boolean verify(StructuredGraph graph) { + for (ConstantNode node : graph.getNodes().filter(ConstantNode.class)) { + assert !isOop(node) || isNullReference(node) || isString(node) : "embedded oop: " + node; + } + return true; + } + + private static boolean isOop(ConstantNode node) { + return node.kind() == Kind.Object; + } + + private static boolean isNullReference(ConstantNode node) { + return isOop(node) && node.asConstant().asObject() == null; + } + + private static boolean isString(ConstantNode node) { + return isOop(node) && node.asConstant().asObject() instanceof String; + } +} diff -r 6e4b72bcc97f -r 4ebe31e19892 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Thu Jun 13 11:25:07 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Thu Jun 13 11:25:46 2013 +0200 @@ -27,7 +27,6 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.HeapAccess.WriteBarrierType; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.*; @@ -41,22 +40,18 @@ Constant constant = node.asConstant(); if (constant.getKind() == Kind.Object && constant.asObject() instanceof Class) { ResolvedJavaType type = context.getRuntime().lookupJavaType((Class) constant.asObject()); - if (type instanceof HotSpotResolvedObjectType) { - HotSpotRuntime runtime = (HotSpotRuntime) context.getRuntime(); + assert type instanceof HotSpotResolvedObjectType; - Constant klass = ((HotSpotResolvedObjectType) type).klass(); - ConstantNode klassNode = ConstantNode.forConstant(klass, runtime, graph); + HotSpotRuntime runtime = (HotSpotRuntime) context.getRuntime(); - Stamp stamp = StampFactory.exactNonNull(runtime.lookupJavaType(Class.class)); - LocationNode location = graph.unique(ConstantLocationNode.create(FINAL_LOCATION, stamp.kind(), runtime.config.classMirrorOffset, graph)); - ReadNode readNode = graph.add(new ReadNode(klassNode, location, stamp, WriteBarrierType.NONE, false)); + Constant klass = ((HotSpotResolvedObjectType) type).klass(); + ConstantNode klassNode = ConstantNode.forConstant(klass, runtime, graph); - FixedNode afterStart = graph.start().next(); - graph.start().setNext(readNode); - readNode.setNext(afterStart); + Stamp stamp = StampFactory.exactNonNull(runtime.lookupJavaType(Class.class)); + LocationNode location = graph.unique(ConstantLocationNode.create(FINAL_LOCATION, stamp.kind(), runtime.config.classMirrorOffset, graph)); + FloatingReadNode freadNode = graph.add(new FloatingReadNode(klassNode, location, null, stamp)); - graph.replaceFloating(node, readNode); - } + graph.replaceFloating(node, freadNode); } } } diff -r 6e4b72bcc97f -r 4ebe31e19892 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Thu Jun 13 11:25:07 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Thu Jun 13 11:25:46 2013 +0200 @@ -39,6 +39,7 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.phases.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.replacements.Snippet.VarargsParameter; @@ -58,8 +59,10 @@ public class InstanceOfSnippets implements Snippets { /** - * A test against a set of hints derived from a profile with 100% precise coverage of seen - * types. This snippet deoptimizes on any path that contradicts the profile. + * A test against a set of hints derived from a profile with very close to 100% precise coverage + * of seen types. This snippet deoptimizes on hint miss paths. + * + * @see GraalOptions#InstanceOfFullCoverageSpeculationThreshold */ @Snippet public static Object instanceofWithProfile(Object object, @VarargsParameter Word[] hints, @VarargsParameter boolean[] hintIsPositive, Object trueValue, Object falseValue, @@ -67,6 +70,8 @@ if (probability(NOT_FREQUENT_PROBABILITY, checkNull && object == null)) { isNull.inc(); if (!nullSeen) { + // In this case, the execution is contradicting the profile + // so invalidating and re-profiling is justified. DeoptimizeNode.deopt(InvalidateReprofile, OptimizedTypeCheckViolated); } return falseValue; @@ -82,6 +87,8 @@ return positive ? trueValue : falseValue; } } + // Don't throw away the code as we assume this is a rare event + // that will periodically occur. DeoptimizeNode.deopt(InvalidateReprofile, OptimizedTypeCheckViolated); return falseValue; } @@ -189,7 +196,7 @@ ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, instanceOf.graph()); Arguments args; - if (hintInfo.hintHitProbability == 1.0D) { + if (hintInfo.hintHitProbability >= InstanceOfFullCoverageSpeculationThreshold.getValue()) { Hints hints = createHints(hintInfo, runtime, false, hub.graph()); args = new Arguments(instanceofWithProfile); args.add("object", object); @@ -215,7 +222,7 @@ args.add("trueValue", replacer.trueValue); args.add("falseValue", replacer.falseValue); args.addConst("checkNull", !object.stamp().nonNull()); - if (hintInfo.hintHitProbability == 1.0D) { + if (hintInfo.hintHitProbability >= InstanceOfFullCoverageSpeculationThreshold.getValue()) { args.addConst("nullSeen", hintInfo.profile.getNullSeen() != TriState.FALSE); } return args; diff -r 6e4b72bcc97f -r 4ebe31e19892 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 Thu Jun 13 11:25:07 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Thu Jun 13 11:25:46 2013 +0200 @@ -24,6 +24,7 @@ import static com.oracle.graal.api.meta.LocationIdentity.*; +import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; @@ -54,6 +55,13 @@ return (stamp() == StampFactory.forVoid()); } + /** + * The frame state upon entry to an exception handler is such that it is a + * {@link BytecodeFrame#rethrowException rethrow exception} state and the stack contains exactly + * the exception object (per the JVM spec) to rethrow. This means that the code creating this + * state (i.e. the {@link LoadExceptionObjectNode}) cannot cause a deoptimization as the + * runtime/interpreter would not have a valid location for the exception object to be rethrown. + */ @Override public void lower(LoweringTool tool, LoweringType loweringType) { if (isLowered()) { diff -r 6e4b72bcc97f -r 4ebe31e19892 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java Thu Jun 13 11:25:07 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java Thu Jun 13 11:25:46 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.java; +import com.oracle.graal.api.code.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -29,6 +30,12 @@ /** * Loads an exception object passed by the runtime from a callee to an exception handler in a * caller. The node is only produced when lowering an {@link ExceptionObjectNode}. + *

+ * The frame state upon entry to an exception handler is such that it is a + * {@link BytecodeFrame#rethrowException rethrow exception} state and the stack contains exactly the + * exception object (per the JVM spec) to rethrow. This means that the code generated for this node + * must not cause a deoptimization as the runtime/interpreter would not have a valid location to + * find the exception object to be rethrown. */ public class LoadExceptionObjectNode extends AbstractStateSplit implements Lowerable { diff -r 6e4b72bcc97f -r 4ebe31e19892 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java Thu Jun 13 11:25:07 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java Thu Jun 13 11:25:46 2013 +0200 @@ -45,6 +45,6 @@ protected void run(StructuredGraph graph, C context) { int mark = graph.getMark(); super.run(graph, context); - new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), OptCanonicalizeReads.getValue(), mark, customCanonicalizer).apply(graph); + new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), !AOTCompilation.getValue(), mark, customCanonicalizer).apply(graph); } } diff -r 6e4b72bcc97f -r 4ebe31e19892 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Thu Jun 13 11:25:07 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Thu Jun 13 11:25:46 2013 +0200 @@ -195,7 +195,7 @@ if (OptCanonicalizer.getValue()) { int markBeforeCanonicalization = callerGraph.getMark(); - new CanonicalizerPhase.Instance(runtime, callerAssumptions, OptCanonicalizeReads.getValue(), invokeUsages, markBeforeInlining, customCanonicalizer).apply(callerGraph); + new CanonicalizerPhase.Instance(runtime, callerAssumptions, !AOTCompilation.getValue(), invokeUsages, markBeforeInlining, customCanonicalizer).apply(callerGraph); // process invokes that are possibly created during canonicalization for (Node newNode : callerGraph.getNewNodes(markBeforeCanonicalization)) { @@ -280,7 +280,7 @@ } if (OptCanonicalizer.getValue()) { - new CanonicalizerPhase.Instance(runtime, assumptions, OptCanonicalizeReads.getValue()).apply(newGraph); + new CanonicalizerPhase.Instance(runtime, assumptions, !AOTCompilation.getValue()).apply(newGraph); } return newGraph; @@ -309,7 +309,7 @@ new DeadCodeEliminationPhase().apply(newGraph); if (OptCanonicalizer.getValue()) { - new CanonicalizerPhase.Instance(runtime, assumptions, OptCanonicalizeReads.getValue()).apply(newGraph); + new CanonicalizerPhase.Instance(runtime, assumptions, !AOTCompilation.getValue()).apply(newGraph); } if (CullFrameStates.getValue()) { diff -r 6e4b72bcc97f -r 4ebe31e19892 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Thu Jun 13 11:25:07 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Thu Jun 13 11:25:46 2013 +0200 @@ -46,7 +46,7 @@ if (canonicalizationRoots.isEmpty()) { break; } - new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), OptCanonicalizeReads.getValue(), canonicalizationRoots, null).apply(graph); + new CanonicalizerPhase.Instance(context.getRuntime(), context.getAssumptions(), !AOTCompilation.getValue(), canonicalizationRoots, null).apply(graph); canonicalizationRoots.clear(); } } diff -r 6e4b72bcc97f -r 4ebe31e19892 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Thu Jun 13 11:25:07 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Thu Jun 13 11:25:46 2013 +0200 @@ -300,7 +300,7 @@ phi.setMerge(mergeAfter); } } - new CanonicalizerPhase.Instance(phaseContext.getRuntime(), phaseContext.getAssumptions(), OptCanonicalizeReads.getValue(), graph.getNewNodes(startMark), null).apply(graph); + new CanonicalizerPhase.Instance(phaseContext.getRuntime(), phaseContext.getAssumptions(), !AOTCompilation.getValue(), graph.getNewNodes(startMark), null).apply(graph); Debug.dump(graph, "After tail duplication at %s", merge); } diff -r 6e4b72bcc97f -r 4ebe31e19892 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 Thu Jun 13 11:25:07 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Thu Jun 13 11:25:46 2013 +0200 @@ -241,6 +241,10 @@ @Option(help = "") public static final OptionValue MinTableSwitchDensity = new OptionValue<>(0.5); + // Ahead of time compilation + @Option(help = "configure compiler to emit code compatible with AOT requirements for HotSpot") + public static final OptionValue AOTCompilation = new OptionValue<>(false); + // Runtime settings @Option(help = "") public static final OptionValue StackShadowPages = new OptionValue<>(2); @@ -257,8 +261,6 @@ @Option(help = "") public static final OptionValue OptCanonicalizer = new OptionValue<>(true); @Option(help = "") - public static final OptionValue OptCanonicalizeReads = new OptionValue<>(true); - @Option(help = "") public static final OptionValue OptScheduleOutOfLoops = new OptionValue<>(true); @Option(help = "") public static final OptionValue OptEliminateGuards = new OptionValue<>(true); @@ -330,14 +332,25 @@ public static final OptionValue CheckcastMaxHints = new OptionValue<>(2); /** - * @see #CheckcastMinHintHitProbability + * If the probability that an instanceof will hit one the profiled types (up to {@link #InstanceOfMaxHints}) + * is below this value, the instanceof will be compiled without hints. */ @Option(help = "") public static final OptionValue InstanceOfMinHintHitProbability = new OptionValue<>(0.5); /** - * @see #CheckcastMaxHints + * The maximum number of hint types that will be used when compiling an instanceof for which + * profiling information is available. Note that {@link #InstanceOfMinHintHitProbability} + * also influences whether hints are used. */ @Option(help = "") public static final OptionValue InstanceOfMaxHints = new OptionValue<>(2); + + /** + * If the probability that an instanceof will hit one the profiled types (up to {@link #InstanceOfMaxHints}) + * is above this value, the compiled instanceof will deoptimize if all hints are missed. + */ + @Option(help = "") + public static final OptionValue InstanceOfFullCoverageSpeculationThreshold = new OptionValue<>(0.998); + } diff -r 6e4b72bcc97f -r 4ebe31e19892 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeInliningRelevanceClosure.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeInliningRelevanceClosure.java Thu Jun 13 11:25:07 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeInliningRelevanceClosure.java Thu Jun 13 11:25:46 2013 +0200 @@ -24,7 +24,6 @@ import java.util.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.util.*; @@ -94,8 +93,7 @@ HashMap result = new HashMap<>(); for (Scope scope : computeScopes()) { - double lowestPathProbability = computeLowestPathProbability(scope); - scope.minPathProbability = Math.max(EPSILON, lowestPathProbability); + scope.minPathProbability = Math.max(EPSILON, nodeProbabilities.get(scope.start)); result.put(scope.start, scope); } @@ -128,85 +126,6 @@ processedLoops.put(loop, result); return result; } - - private double computeLowestPathProbability(Scope scope) { - FixedNode scopeStart = scope.start; - ArrayList pathBeginNodes = new ArrayList<>(); - pathBeginNodes.add(scopeStart); - double minPathProbability = nodeProbabilities.get(scopeStart); - boolean isLoopScope = scopeStart instanceof LoopBeginNode; - - do { - Node current = pathBeginNodes.remove(pathBeginNodes.size() - 1); - do { - if (isLoopScope && current instanceof LoopExitNode && ((LoopBeginNode) scopeStart).loopExits().contains((LoopExitNode) current)) { - return minPathProbability; - } else if (current instanceof LoopBeginNode && current != scopeStart) { - current = getMaxProbabilityLoopExit((LoopBeginNode) current, pathBeginNodes); - minPathProbability = getMinPathProbability((FixedNode) current, minPathProbability); - } else if (current instanceof ControlSplitNode) { - current = getMaxProbabilitySux((ControlSplitNode) current, pathBeginNodes); - minPathProbability = getMinPathProbability((FixedNode) current, minPathProbability); - } else { - assert current.successors().count() <= 1; - current = current.successors().first(); - } - } while (current != null); - } while (!pathBeginNodes.isEmpty()); - - return minPathProbability; - } - - private double getMinPathProbability(FixedNode current, double minPathProbability) { - if (current != null && nodeProbabilities.get(current) < minPathProbability) { - return nodeProbabilities.get(current); - } - return minPathProbability; - } - - private Node getMaxProbabilitySux(ControlSplitNode controlSplit, ArrayList pathBeginNodes) { - Node maxSux = null; - double maxProbability = 0.0; - int pathBeginCount = pathBeginNodes.size(); - - for (Node sux : controlSplit.successors()) { - double probability = controlSplit.probability((AbstractBeginNode) sux); - if (probability > maxProbability) { - maxProbability = probability; - maxSux = sux; - truncate(pathBeginNodes, pathBeginCount); - } else if (probability == maxProbability) { - pathBeginNodes.add((FixedNode) sux); - } - } - - return maxSux; - } - - private Node getMaxProbabilityLoopExit(LoopBeginNode loopBegin, ArrayList pathBeginNodes) { - Node maxSux = null; - double maxProbability = 0.0; - int pathBeginCount = pathBeginNodes.size(); - - for (LoopExitNode sux : loopBegin.loopExits()) { - double probability = nodeProbabilities.get(sux); - if (probability > maxProbability) { - maxProbability = probability; - maxSux = sux; - truncate(pathBeginNodes, pathBeginCount); - } else if (probability == maxProbability) { - pathBeginNodes.add(sux); - } - } - - return maxSux; - } - - private void truncate(ArrayList pathBeginNodes, int pathBeginCount) { - for (int i = pathBeginNodes.size() - pathBeginCount; i > 0; i--) { - pathBeginNodes.remove(pathBeginNodes.size() - 1); - } - } } private static class Scope { diff -r 6e4b72bcc97f -r 4ebe31e19892 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 Thu Jun 13 11:25:07 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Thu Jun 13 11:25:46 2013 +0200 @@ -241,13 +241,13 @@ if (value instanceof char[]) { return Arrays.toString((char[]) value); } - if (value instanceof float[]) { + if (value instanceof short[]) { return Arrays.toString((short[]) value); } - if (value instanceof float[]) { + if (value instanceof int[]) { return Arrays.toString((int[]) value); } - if (value instanceof float[]) { + if (value instanceof long[]) { return Arrays.toString((long[]) value); } if (value instanceof float[]) { diff -r 6e4b72bcc97f -r 4ebe31e19892 mx/commands.py --- a/mx/commands.py Thu Jun 13 11:25:07 2013 +0200 +++ b/mx/commands.py Thu Jun 13 11:25:46 2013 +0200 @@ -1044,6 +1044,11 @@ vm(['-G:RegisterPressure=rbx,r11,r14,xmm3,xmm11,xmm14', '-esa', '-version']) tasks.append(t.stop()) + _vmbuild = 'product' + t = Task('BootstrapWithAOTConfiguration:product') + vm(['-G:+AOTCompilation', '-esa', '-version']) + tasks.append(t.stop()) + originalVm = _vm _vm = 'server' # hosted mode t = Task('UnitTests:hosted-product')