# HG changeset patch # User Christian Haeubl # Date 1371109266 -7200 # Node ID 53f090c5975aa8c418a198ecb1bba472a8702b26 # Parent 4d9d0cb1520a1b64b68b0c3dbe7ff6ee2200c0a4# Parent 7709bb83191682c7902ec2e64acc96353b32857d Merge. diff -r 4d9d0cb1520a -r 53f090c5975a graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java Thu Jun 13 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java Thu Jun 13 09:41:06 2013 +0200 @@ -47,7 +47,7 @@ public final ResolvedJavaType type; /** - * Specifies if {@link #type} was a sub-type of the checked type. + * Specifies if {@link #type} is a sub-type of the checked type. */ public final boolean positive; @@ -60,11 +60,11 @@ private static final Hint[] NO_HINTS = {}; /** - * If true, then {@link #hints} contains the only possible type that could pass the type check - * because the target of the type check is a final class or has been speculated to be a final - * class. + * If non-null, then this is the only type that could pass the type check because the target of + * the type check is a final class or has been speculated to be a final class and this value is + * the only concrete subclass of the target type. */ - public final boolean exact; + public final ResolvedJavaType exact; /** * The most likely types that the type check instruction will see. @@ -72,6 +72,16 @@ public final Hint[] hints; /** + * The profile from which this information was derived. + */ + public final JavaTypeProfile profile; + + /** + * The total probability that the type check will hit one of the types in {@link #hints}. + */ + public final double hintHitProbability; + + /** * Derives hint information for use when generating the code for a type check instruction. * * @param targetType the target type of the type check @@ -84,50 +94,58 @@ * @param maxHints the maximum length of {@link #hints} */ public TypeCheckHints(ResolvedJavaType targetType, JavaTypeProfile profile, Assumptions assumptions, double minHintHitProbability, int maxHints) { + this.profile = profile; if (targetType != null && !canHaveSubtype(targetType)) { - hints = new Hint[]{new Hint(targetType, true)}; - exact = true; + exact = targetType; } else { ResolvedJavaType uniqueSubtype = targetType == null ? null : targetType.findUniqueConcreteSubtype(); if (uniqueSubtype != null) { - hints = new Hint[]{new Hint(uniqueSubtype, true)}; if (assumptions.useOptimisticAssumptions()) { assumptions.recordConcreteSubtype(targetType, uniqueSubtype); - exact = true; + exact = uniqueSubtype; } else { - exact = false; + exact = null; } } else { - exact = false; - Hint[] hintsBuf = NO_HINTS; - JavaTypeProfile typeProfile = profile; - if (typeProfile != null) { - double notRecordedTypes = typeProfile.getNotRecordedProbability(); - ProfiledType[] ptypes = typeProfile.getTypes(); - if (notRecordedTypes < (1D - minHintHitProbability) && ptypes != null && ptypes.length > 0) { - hintsBuf = new Hint[ptypes.length]; - int hintCount = 0; - double totalHintProbability = 0.0d; - for (ProfiledType ptype : ptypes) { - if (targetType != null) { - ResolvedJavaType hintType = ptype.getType(); - hintsBuf[hintCount++] = new Hint(hintType, targetType.isAssignableFrom(hintType)); - totalHintProbability += ptype.getProbability(); - } - } - if (totalHintProbability >= minHintHitProbability) { - if (hintsBuf.length != hintCount || hintCount > maxHints) { - hintsBuf = Arrays.copyOf(hintsBuf, Math.min(maxHints, hintCount)); - } - } else { - hintsBuf = NO_HINTS; - } + exact = null; + } + } + Double[] hitProbability = {null}; + this.hints = makeHints(targetType, profile, minHintHitProbability, maxHints, hitProbability); + this.hintHitProbability = hitProbability[0]; + } + private static Hint[] makeHints(ResolvedJavaType targetType, JavaTypeProfile profile, double minHintHitProbability, int maxHints, Double[] hitProbability) { + double hitProb = 0.0d; + Hint[] hintsBuf = NO_HINTS; + if (profile != null) { + double notRecordedTypes = profile.getNotRecordedProbability(); + ProfiledType[] ptypes = profile.getTypes(); + if (notRecordedTypes < (1D - minHintHitProbability) && ptypes != null && ptypes.length > 0) { + hintsBuf = new Hint[ptypes.length]; + int hintCount = 0; + for (ProfiledType ptype : ptypes) { + if (targetType != null) { + ResolvedJavaType hintType = ptype.getType(); + hintsBuf[hintCount++] = new Hint(hintType, targetType.isAssignableFrom(hintType)); + hitProb += ptype.getProbability(); + } + if (hintCount == maxHints) { + break; } } - this.hints = hintsBuf; + if (hitProb >= minHintHitProbability) { + if (hintsBuf.length != hintCount || hintCount > maxHints) { + hintsBuf = Arrays.copyOf(hintsBuf, Math.min(maxHints, hintCount)); + } + } else { + hintsBuf = NO_HINTS; + hitProb = 0.0d; + } } } + hitProbability[0] = hitProb; + return hintsBuf; } /** diff -r 4d9d0cb1520a -r 53f090c5975a graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java Thu Jun 13 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaTypeProfile.java Thu Jun 13 09:41:06 2013 +0200 @@ -62,7 +62,7 @@ public JavaTypeProfile restrict(JavaTypeProfile otherProfile) { if (otherProfile.getNotRecordedProbability() > 0.0) { - // Not useful for restricting since there is an unknown set of types occuring. + // Not useful for restricting since there is an unknown set of types occurring. return this; } @@ -155,7 +155,20 @@ @Override public String toString() { - return "{" + item.getName() + ", " + probability + "}"; + return String.format("%.6f#%s", probability, item); } } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder("JavaTypeProfile", getNotRecordedProbability())).toString(); + } } diff -r 4d9d0cb1520a -r 53f090c5975a 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 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.compiler.sparc.test/src/com/oracle/graal/compiler/sparc/test/BasicSPARCTest.java Thu Jun 13 09:41:06 2013 +0200 @@ -26,7 +26,6 @@ import org.junit.Test; - public class BasicSPARCTest extends SPARCTestBase { @Test diff -r 4d9d0cb1520a -r 53f090c5975a 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 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Thu Jun 13 09:41:06 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 4d9d0cb1520a -r 53f090c5975a 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 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Thu Jun 13 09:41:06 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 4d9d0cb1520a -r 53f090c5975a 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 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Thu Jun 13 09:41:06 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 4d9d0cb1520a -r 53f090c5975a 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 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Thu Jun 13 09:41:06 2013 +0200 @@ -30,13 +30,17 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.test.*; +import com.oracle.graal.graph.iterators.*; +import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; +import com.oracle.graal.phases.tiers.*; /** * use @@ -50,43 +54,136 @@ 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; } @Test - @Ignore - public void testStaticFinalObject1() { - StructuredGraph result2 = compile("getStaticFinalObject", true); - assert result2.getNodes().filter(ConstantNode.class).count() == 1; - assert result2.getNodes(FloatingReadNode.class).count() == 1; + public void testStaticFinalObjectAOT() { + StructuredGraph result = compile("getStaticFinalObject", true); + 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); + 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() { + return AheadOfTimeCompilationTest.class; + } + + @Test + public void testClassObjectAOT() { + StructuredGraph result = compile("getClassObject", true); + + NodeIterable filter = result.getNodes().filter(ConstantNode.class); + assertEquals(1, filter.count()); + HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) runtime.lookupJavaType(AheadOfTimeCompilationTest.class); + assertEquals(type.klass(), filter.first().asConstant()); + + assertEquals(1, result.getNodes(FloatingReadNode.class).count()); + assertEquals(0, result.getNodes(ReadNode.class).count()); } @Test - public void testStaticFinalObject2() { - StructuredGraph result1 = compile("getStaticFinalObject", false); - assert result1.getNodes().filter(ConstantNode.class).count() == 1; - assert result1.getNodes(FloatingReadNode.class).count() == 0; + public void testClassObject() { + StructuredGraph result = compile("getClassObject", false); + + NodeIterable filter = result.getNodes().filter(ConstantNode.class); + 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(); + 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); + } + + @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(); final StructuredGraph graphCopy = graph.copy(); GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); editPhasePlan(method, graph, phasePlan); 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(); final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, backend, runtime().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, - new SpeculationLog(), suites); + new SpeculationLog(), suitesLocal); addMethod(method, compResult, graphCopy); - OptCanonicalizeReads.setValue(originalSetting); + AOTCompilation.setValue(originalSetting); return graph; } diff -r 4d9d0cb1520a -r 53f090c5975a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethod.java Thu Jun 13 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethod.java Thu Jun 13 09:41:06 2013 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.hotspot.meta; +import static com.oracle.graal.api.meta.MetaUtil.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.hotspot.*; @@ -30,8 +32,22 @@ private static final long serialVersionUID = 7167491397941960839L; protected String name; + /** + * Controls whether {@link #toString()} includes the qualified or simple name of the class in + * which the method is declared. + */ + public static final boolean FULLY_QUALIFIED_METHOD_NAME = false; + @Override public final String getName() { return name; } + + @Override + public final String toString() { + char h = FULLY_QUALIFIED_METHOD_NAME ? 'H' : 'h'; + String suffix = this instanceof ResolvedJavaMethod ? "" : ", unresolved"; + String fmt = String.format("HotSpotMethod<%%%c.%%n(%%p)%s>", h, suffix); + return format(fmt, this); + } } diff -r 4d9d0cb1520a -r 53f090c5975a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodUnresolved.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodUnresolved.java Thu Jun 13 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodUnresolved.java Thu Jun 13 09:41:06 2013 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.api.meta.MetaUtil.*; - import com.oracle.graal.api.meta.*; /** @@ -50,9 +48,4 @@ public JavaType getDeclaringClass() { return holder; } - - @Override - public String toString() { - return format("HotSpotMethod<%H.%n(%p), unresolved>", this); - } } diff -r 4d9d0cb1520a -r 53f090c5975a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Thu Jun 13 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Thu Jun 13 09:41:06 2013 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot.meta; -import static com.oracle.graal.api.meta.MetaUtil.*; import static com.oracle.graal.graph.UnsafeAccess.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.phases.GraalOptions.*; @@ -259,11 +258,6 @@ return signature; } - @Override - public String toString() { - return format("HotSpotMethod<%H.%n(%p)>", this); - } - public int getCompiledCodeSize() { return graalRuntime().getCompilerToVM().getCompiledCodeSize(metaspaceMethod); } diff -r 4d9d0cb1520a -r 53f090c5975a 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 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Jun 13 09:41:06 2013 +0200 @@ -1073,6 +1073,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 4d9d0cb1520a -r 53f090c5975a 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 09:41:06 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 4d9d0cb1520a -r 53f090c5975a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Thu Jun 13 09:41:06 2013 +0200 @@ -0,0 +1,58 @@ +/* + * 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 static com.oracle.graal.api.meta.LocationIdentity.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.tiers.*; + +public class LoadJavaMirrorWithKlassPhase extends BasePhase { + + @Override + protected void run(StructuredGraph graph, PhaseContext context) { + for (ConstantNode node : graph.getNodes().filter(ConstantNode.class)) { + Constant constant = node.asConstant(); + if (constant.getKind() == Kind.Object && constant.asObject() instanceof Class) { + ResolvedJavaType type = context.getRuntime().lookupJavaType((Class) constant.asObject()); + assert type instanceof HotSpotResolvedObjectType; + + HotSpotRuntime runtime = (HotSpotRuntime) context.getRuntime(); + + Constant klass = ((HotSpotResolvedObjectType) type).klass(); + ConstantNode klassNode = ConstantNode.forConstant(klass, runtime, graph); + + 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, freadNode); + } + } + } +} diff -r 4d9d0cb1520a -r 53f090c5975a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Thu Jun 13 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastSnippets.java Thu Jun 13 09:41:06 2013 +0200 @@ -172,12 +172,10 @@ ValueNode hub = ConstantNode.forConstant(type.klass(), runtime, checkcast.graph()); Arguments args; - if (hintInfo.exact) { - ConstantNode[] hints = createHints(hintInfo, runtime, true, graph).hubs; - assert hints.length == 1; + if (hintInfo.exact != null) { args = new Arguments(exact); args.add("object", object); - args.add("exactHub", hints[0]); + args.add("exactHub", ConstantNode.forConstant(((HotSpotResolvedObjectType) hintInfo.exact).klass(), runtime, graph)); } else if (type.isPrimaryType()) { args = new Arguments(primary); args.add("hub", hub); diff -r 4d9d0cb1520a -r 53f090c5975a 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 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Thu Jun 13 09:41:06 2013 +0200 @@ -22,6 +22,9 @@ */ package com.oracle.graal.hotspot.replacements; +import static com.oracle.graal.api.code.DeoptimizationAction.*; +import static com.oracle.graal.api.meta.DeoptimizationReason.*; +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.*; import static com.oracle.graal.phases.GraalOptions.*; @@ -29,12 +32,14 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.meta.ProfilingInfo.TriState; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.Hints; import com.oracle.graal.nodes.*; 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; @@ -54,6 +59,41 @@ public class InstanceOfSnippets implements Snippets { /** + * 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, + @ConstantParameter boolean checkNull, @ConstantParameter boolean nullSeen) { + 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; + } + Word objectHub = loadHub(object); + // if we get an exact match: succeed immediately + ExplodeLoopNode.explodeLoop(); + for (int i = 0; i < hints.length; i++) { + Word hintHub = hints[i]; + boolean positive = hintIsPositive[i]; + if (probability(NOT_FREQUENT_PROBABILITY, hintHub.equal(objectHub))) { + hintsHit.inc(); + 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; + } + + /** * A test against a final type. */ @Snippet @@ -136,6 +176,7 @@ public static class Templates extends InstanceOfSnippetsTemplates { + private final SnippetInfo instanceofWithProfile = snippet(InstanceOfSnippets.class, "instanceofWithProfile"); private final SnippetInfo instanceofExact = snippet(InstanceOfSnippets.class, "instanceofExact"); private final SnippetInfo instanceofPrimary = snippet(InstanceOfSnippets.class, "instanceofPrimary"); private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary"); @@ -155,12 +196,16 @@ ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, instanceOf.graph()); Arguments args; - if (hintInfo.exact) { - ConstantNode[] hints = createHints(hintInfo, runtime, true, hub.graph()).hubs; - assert hints.length == 1; + if (hintInfo.hintHitProbability >= InstanceOfFullCoverageSpeculationThreshold.getValue()) { + Hints hints = createHints(hintInfo, runtime, false, hub.graph()); + args = new Arguments(instanceofWithProfile); + args.add("object", object); + args.addVarargs("hints", Word.class, StampFactory.forKind(wordKind()), hints.hubs); + args.addVarargs("hintIsPositive", boolean.class, StampFactory.forKind(Kind.Boolean), hints.isPositive); + } else if (hintInfo.exact != null) { args = new Arguments(instanceofExact); args.add("object", object); - args.add("exactHub", hints[0]); + args.add("exactHub", ConstantNode.forConstant(((HotSpotResolvedObjectType) hintInfo.exact).klass(), runtime, hub.graph())); } else if (type.isPrimaryType()) { args = new Arguments(instanceofPrimary); args.add("hub", hub); @@ -177,6 +222,9 @@ args.add("trueValue", replacer.trueValue); args.add("falseValue", replacer.falseValue); args.addConst("checkNull", !object.stamp().nonNull()); + if (hintInfo.hintHitProbability >= InstanceOfFullCoverageSpeculationThreshold.getValue()) { + args.addConst("nullSeen", hintInfo.profile.getNullSeen() != TriState.FALSE); + } return args; } else { diff -r 4d9d0cb1520a -r 53f090c5975a graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Thu Jun 13 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java Thu Jun 13 09:41:06 2013 +0200 @@ -33,6 +33,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.MoveOp; @@ -667,6 +668,8 @@ } else { // Otherwise the narrow heap base, which resides always in register 12, is subtracted // followed by right shift. + masm.testq(scratchRegister, scratchRegister); + masm.cmovq(ConditionFlag.Equal, scratchRegister, AMD64.r12); masm.subq(scratchRegister, AMD64.r12); masm.shrq(scratchRegister, logMinObjAlignment); } @@ -681,9 +684,12 @@ masm.shlq(resRegister, logMinObjAlignment); } } else { - // Otherwise the narrow heap base is added to the shifted address. + Label done = new Label(); masm.shlq(resRegister, logMinObjAlignment); + masm.jccb(ConditionFlag.Equal, done); + // Otherwise the narrow heap base is added to the shifted address. masm.addq(resRegister, AMD64.r12); + masm.bind(done); } } diff -r 4d9d0cb1520a -r 53f090c5975a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Thu Jun 13 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java Thu Jun 13 09:41:06 2013 +0200 @@ -30,7 +30,7 @@ import com.oracle.graal.nodes.type.*; /** - * A node that attached a type profile to a proxied input node. + * A node that attaches a type profile to a proxied input node. */ public final class TypeProfileProxyNode extends FloatingNode implements Canonicalizable, Node.IterableNodeType { diff -r 4d9d0cb1520a -r 53f090c5975a 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 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java Thu Jun 13 09:41:06 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 4d9d0cb1520a -r 53f090c5975a 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 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java Thu Jun 13 09:41:06 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 4d9d0cb1520a -r 53f090c5975a 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 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java Thu Jun 13 09:41:06 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 4d9d0cb1520a -r 53f090c5975a 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 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Thu Jun 13 09:41:06 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 4d9d0cb1520a -r 53f090c5975a 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 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java Thu Jun 13 09:41:06 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 4d9d0cb1520a -r 53f090c5975a 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 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Thu Jun 13 09:41:06 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 4d9d0cb1520a -r 53f090c5975a 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 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Thu Jun 13 09:41:06 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 4d9d0cb1520a -r 53f090c5975a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Thu Jun 13 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java Thu Jun 13 09:41:06 2013 +0200 @@ -108,12 +108,12 @@ } /** - * The result of an instantiating an instanceof snippet. This enables a snippet instantiation to - * be re-used which reduces compile time and produces better code. + * The result of instantiating an instanceof snippet. This enables a snippet instantiation to be + * re-used which reduces compile time and produces better code. */ public static final class Instantiation { - private PhiNode result; + private ValueNode result; private CompareNode condition; private ValueNode trueValue; private ValueNode falseValue; @@ -125,9 +125,9 @@ return result != null; } - void initialize(PhiNode phi, ValueNode t, ValueNode f) { + void initialize(ValueNode r, ValueNode t, ValueNode f) { assert !isInitialized(); - this.result = phi; + this.result = r; this.trueValue = t; this.falseValue = f; } @@ -137,8 +137,12 @@ * * @param testValue the returned condition is true if the result is equal to this value */ - CompareNode asCondition(ValueNode testValue) { + LogicNode asCondition(ValueNode testValue) { assert isInitialized(); + if (result.isConstant()) { + assert testValue.isConstant(); + return LogicConstantNode.forBoolean(result.asConstant().equals(testValue.asConstant()), result.graph()); + } if (condition == null || condition.y() != testValue) { // Re-use previously generated condition if the trueValue for the test is the same condition = createCompareNode(Condition.EQ, result, testValue); @@ -207,10 +211,18 @@ @Override public void replace(ValueNode oldNode, ValueNode newNode) { + if (newNode.isConstant()) { + LogicConstantNode logicConstant = LogicConstantNode.forBoolean(newNode.asConstant().asInt() != 0, newNode.graph()); + usage.replaceFirstInput(oldNode, logicConstant); + // PrintStream out = System.out; + // out.println(newNode.graph() + ": " + this); + GraalInternalError.shouldNotReachHere(instanceOf.graph().toString()); + return; + } assert newNode instanceof PhiNode; assert oldNode == instanceOf; newNode.inferStamp(); - instantiation.initialize((PhiNode) newNode, trueValue, falseValue); + instantiation.initialize(newNode, trueValue, falseValue); usage.replaceFirstInput(oldNode, instantiation.asCondition(trueValue)); } } @@ -239,10 +251,18 @@ @Override public void replace(ValueNode oldNode, ValueNode newNode) { + if (newNode.isConstant()) { + LogicConstantNode logicConstant = LogicConstantNode.forBoolean(newNode.asConstant().asInt() != 0, newNode.graph()); + usage.replaceFirstInput(oldNode, logicConstant); + // PrintStream out = System.out; + // out.println(newNode.graph() + ": " + this); + GraalInternalError.shouldNotReachHere(instanceOf.graph().toString()); + return; + } assert newNode instanceof PhiNode; assert oldNode == instanceOf; newNode.inferStamp(); - instantiation.initialize((PhiNode) newNode, trueValue, falseValue); + instantiation.initialize(newNode, trueValue, falseValue); usage.replaceAtUsages(newNode); usage.clearInputs(); assert usage.usages().isEmpty(); diff -r 4d9d0cb1520a -r 53f090c5975a 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 09:40:36 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Thu Jun 13 09:41:06 2013 +0200 @@ -192,7 +192,7 @@ @Override public String toString() { StringBuilder result = new StringBuilder(); - result.append("Parameters<").append(MetaUtil.format("%H.%n", info.method)).append(" ["); + result.append("Parameters<").append(MetaUtil.format("%h.%n", info.method)).append(" ["); String sep = ""; for (int i = 0; i < info.getParameterCount(); i++) { result.append(sep); @@ -229,6 +229,38 @@ this.length = Array.getLength(value); } } + + @Override + public String toString() { + if (value instanceof boolean[]) { + return Arrays.toString((boolean[]) value); + } + if (value instanceof byte[]) { + return Arrays.toString((byte[]) value); + } + if (value instanceof char[]) { + return Arrays.toString((char[]) value); + } + if (value instanceof short[]) { + return Arrays.toString((short[]) value); + } + if (value instanceof int[]) { + return Arrays.toString((int[]) value); + } + if (value instanceof long[]) { + return Arrays.toString((long[]) value); + } + if (value instanceof float[]) { + return Arrays.toString((float[]) value); + } + if (value instanceof double[]) { + return Arrays.toString((double[]) value); + } + if (value instanceof Object[]) { + return Arrays.toString((Object[]) value); + } + return String.valueOf(value); + } } static class CacheKey { diff -r 4d9d0cb1520a -r 53f090c5975a mx/commands.py --- a/mx/commands.py Thu Jun 13 09:40:36 2013 +0200 +++ b/mx/commands.py Thu Jun 13 09:41:06 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') diff -r 4d9d0cb1520a -r 53f090c5975a src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Thu Jun 13 09:40:36 2013 +0200 +++ b/src/share/vm/runtime/arguments.cpp Thu Jun 13 09:41:06 2013 +0200 @@ -2102,9 +2102,8 @@ warning("UseCompressedOops is disabled, because it is not supported by Graal"); FLAG_SET_CMDLINE(bool, UseCompressedOops, false); } else { - jio_fprintf(defaultStream::error_stream(), - "CompressedOops are not supported in Graal at the moment\n"); - status = false; + status = true; + FLAG_SET_CMDLINE(bool, UseCompressedOops, true); } } else { // This prevents the flag being set to true by set_ergonomics_flags()