# HG changeset patch # User Thomas Wuerthinger # Date 1339427166 -7200 # Node ID 102f87543d5e2a3e8ec91fd720c08aa33e474227 # Parent 30162e74f11f7d9b5e06240d36656eb5d7c2a4da# Parent 6a26710662046d24172e2604fc6d1e922450ea62 Merge. diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java Mon Jun 11 17:06:06 2012 +0200 @@ -257,11 +257,11 @@ public static int InstanceOfMaxHints = 1; /** - * Use HIR lowering instead of LIR lowering for checkcast instructions. - * Only checkcasts in methods whose fully qualified name contains this option will be HIR lowered. - * TODO (dnsimon) remove once HIR checkcast lowering works reliably + * Use HIR lowering instead of LIR lowering for certain instructions. + * Only instructions in methods whose fully qualified name contains this option will be HIR lowered. */ public static String HIRLowerCheckcast = ""; + public static String HIRLowerNewInstance = null; /** * The profiling info cache directory. diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CanonicalizerPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CanonicalizerPhase.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/CanonicalizerPhase.java Mon Jun 11 17:06:06 2012 +0200 @@ -22,6 +22,8 @@ */ package com.oracle.graal.compiler.phases; +import java.util.concurrent.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; @@ -158,10 +160,14 @@ return false; } - public static void tryCanonicalize(Node node, StructuredGraph graph, SimplifierTool tool) { + public static void tryCanonicalize(final Node node, StructuredGraph graph, final SimplifierTool tool) { if (node instanceof Canonicalizable) { METRIC_CANONICALIZATION_CONSIDERED_NODES.increment(); - ValueNode canonical = ((Canonicalizable) node).canonical(tool); + ValueNode canonical = Debug.scope("CanonicalizeNode", node, new Callable() { + public ValueNode call() throws Exception { + return ((Canonicalizable) node).canonical(tool); + } + }); // cases: original node: // |Floating|Fixed-unconnected|Fixed-connected| // -------------------------------------------- diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/SnippetIntrinsificationPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/SnippetIntrinsificationPhase.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/SnippetIntrinsificationPhase.java Mon Jun 11 17:06:06 2012 +0200 @@ -233,6 +233,11 @@ } } + private static String sourceLocation(Node n) { + String loc = GraphUtil.approxSourceLocation(n); + return loc == null ? "" : loc; + } + public void cleanUpReturnCheckCast(Node newInstance) { if (newInstance instanceof ValueNode && ((ValueNode) newInstance).kind() != Kind.Object) { StructuredGraph graph = (StructuredGraph) newInstance.graph(); @@ -246,7 +251,9 @@ graph.removeFixed(valueAnchorNode); } else if (checkCastUsage instanceof MethodCallTargetNode) { MethodCallTargetNode checkCastCallTarget = (MethodCallTargetNode) checkCastUsage; - assert pool.isUnboxingMethod(checkCastCallTarget.targetMethod()); + assert pool.isUnboxingMethod(checkCastCallTarget.targetMethod()) : + "checkcast at " + sourceLocation(checkCastNode) + " not used by an unboxing method but by a call at " + + sourceLocation(checkCastCallTarget.usages().first()) + " to " + checkCastCallTarget.targetMethod(); Invoke invokeNode = checkCastCallTarget.invoke(); invokeNode.node().replaceAtUsages(newInstance); if (invokeNode instanceof InvokeWithExceptionNode) { @@ -262,7 +269,7 @@ } else if (checkCastUsage instanceof FrameState) { checkCastUsage.replaceFirstInput(checkCastNode, null); } else { - assert false : "unexpected checkcast usage: " + checkCastUsage; + assert false : sourceLocation(checkCastUsage) + " has unexpected usage " + checkCastUsage + " of checkcast at " + sourceLocation(checkCastNode); } } FixedNode next = checkCastNode.next(); diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugConfig.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugConfig.java Mon Jun 11 17:06:06 2012 +0200 @@ -30,6 +30,7 @@ import com.oracle.graal.compiler.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.util.*; import com.oracle.graal.printer.*; import com.oracle.max.criutils.*; @@ -150,13 +151,22 @@ Debug.setConfig(Debug.fixedConfig(true, true, false, false, dumpHandlers, output)); Debug.log(String.format("Exception occurred in scope: %s", Debug.currentScope())); for (Object o : Debug.context()) { - Debug.log("Context obj %s", o); if (o instanceof Graph) { + Debug.log("Context obj %s", o); if (GraalOptions.DumpOnError) { Debug.dump(o, "Exception graph"); } else { Debug.log("Use -G:+DumpOnError to enable dumping of graphs on this error"); } + } else if (o instanceof Node) { + String location = GraphUtil.approxSourceLocation((Node) o); + if (location != null) { + Debug.log("Context obj %s (approx. location: %s)", o, location); + } else { + Debug.log("Context obj %s", o); + } + } else { + Debug.log("Context obj %s", o); } } return null; diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Mon Jun 11 17:06:06 2012 +0200 @@ -207,6 +207,9 @@ if (clazz == ExtendedRiRuntime.class) { return (T) getRuntime(); } + if (clazz == GraalCompiler.class) { + return (T) getCompiler(); + } return null; } } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Mon Jun 11 17:06:06 2012 +0200 @@ -89,7 +89,6 @@ public long debugStub; public long instanceofStub; public long newInstanceStub; - public long unresolvedNewInstanceStub; public long newTypeArrayStub; public long newObjectArrayStub; public long newMultiArrayStub; diff -r 30162e74f11f -r 102f87543d5e 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 Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Mon Jun 11 17:06:06 2012 +0200 @@ -56,7 +56,8 @@ final HotSpotRegisterConfig regConfig; private final HotSpotRegisterConfig globalStubRegConfig; private final HotSpotGraalRuntime compiler; - private CheckCastSnippets.Templates checkcasts; + private CheckCastSnippets.Templates checkcastSnippets; + private NewInstanceSnippets.Templates newInstanceSnippets; public HotSpotRuntime(HotSpotVMConfig config, HotSpotGraalRuntime compiler) { this.config = config; @@ -72,7 +73,9 @@ Snippets.install(this, compiler.getTarget(), new UnsafeSnippets()); Snippets.install(this, compiler.getTarget(), new ArrayCopySnippets()); Snippets.install(this, compiler.getTarget(), new CheckCastSnippets()); - checkcasts = new CheckCastSnippets.Templates(this); + Snippets.install(this, compiler.getTarget(), new NewInstanceSnippets()); + checkcastSnippets = new CheckCastSnippets.Templates(this); + newInstanceSnippets = new NewInstanceSnippets.Templates(this); } @@ -336,7 +339,9 @@ assert load.kind() != Kind.Illegal; IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, load.loadKind(), load.displacement(), load.offset(), graph, false); ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, load.stamp())); - memoryRead.dependencies().add(tool.createNullCheckGuard(load.object(), StructuredGraph.INVALID_GRAPH_ID)); + if (load.object().kind().isObject()) { + memoryRead.dependencies().add(tool.createNullCheckGuard(load.object(), StructuredGraph.INVALID_GRAPH_ID)); + } graph.replaceFixedWithFixed(load, memoryRead); } else if (n instanceof UnsafeStoreNode) { UnsafeStoreNode store = (UnsafeStoreNode) n; @@ -355,16 +360,19 @@ memoryRead.dependencies().add(tool.createNullCheckGuard(objectClassNode.object(), StructuredGraph.INVALID_GRAPH_ID)); graph.replaceFixed(objectClassNode, memoryRead); } else if (n instanceof CheckCastNode) { - if (shouldLowerCheckcast(graph)) { - checkcasts.lower((CheckCastNode) n, tool); + if (shouldLower(graph, GraalOptions.HIRLowerCheckcast)) { + checkcastSnippets.lower((CheckCastNode) n, tool); + } + } else if (n instanceof NewInstanceNode) { + if (shouldLower(graph, GraalOptions.HIRLowerNewInstance)) { + newInstanceSnippets.lower((NewInstanceNode) n, tool); } } else { assert false : "Node implementing Lowerable not handled: " + n; } } - private static boolean shouldLowerCheckcast(StructuredGraph graph) { - String option = GraalOptions.HIRLowerCheckcast; + private static boolean shouldLower(StructuredGraph graph, String option) { if (option != null) { if (option.length() == 0) { return true; diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentThread.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentThread.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CurrentThread.java Mon Jun 11 17:06:06 2012 +0200 @@ -45,7 +45,7 @@ @SuppressWarnings("unused") @NodeIntrinsic - public static Object get(int threadObjectOffset) { + public static Object get(@ConstantNodeParameter int threadObjectOffset) { throw new UnsupportedOperationException(); } } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java Mon Jun 11 17:06:06 2012 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012, 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.nodes; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.hotspot.target.*; +import com.oracle.graal.lir.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.max.asm.target.amd64.*; + +/** + * Node implementing a call to HotSpot's {@code new_instance} stub. + * + * @see AMD64NewInstanceStubCallOp + */ +public class NewInstanceStubCall extends FixedWithNextNode implements LIRGenLowerable { + + @Input private final ValueNode hub; + + public NewInstanceStubCall(ValueNode hub) { + super(StampFactory.objectNonNull()); + this.hub = hub; + } + + @Override + public void generate(LIRGenerator gen) { + Variable result = gen.newVariable(Kind.Object); + gen.emitMove(gen.operand(hub), AMD64.rdx.asValue()); + AMD64NewInstanceStubCallOp op = new AMD64NewInstanceStubCallOp(result, AMD64.rdx.asValue()); + gen.append(op); + gen.setResult(this, result); + } + + @SuppressWarnings("unused") + @NodeIntrinsic + public static Object call(Object hub) { + throw new UnsupportedOperationException(); + } + + +} diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/RegisterNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/RegisterNode.java Mon Jun 11 17:06:06 2012 +0200 @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2012, 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.nodes; + +import java.util.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * Access the value of a specific register. + */ +public final class RegisterNode extends FloatingNode implements LIRLowerable { + + private final Register register; + + public RegisterNode(Register register, Kind kind) { + super(StampFactory.forKind(kind)); + this.register = register; + } + + @Override + public void generate(LIRGeneratorTool generator) { + Value result = generator.newVariable(kind()); + generator.emitMove(register.asValue(kind()), result); + generator.setResult(this, result); + } + + @Override + public String toString(Verbosity verbosity) { + if (verbosity == Verbosity.Name) { + return super.toString(Verbosity.Name) + "%" + register; + } else { + return super.toString(verbosity); + } + } + + @Override + public Map getDebugProperties() { + Map properties = super.getDebugProperties(); + properties.put("register", register.toString()); + return properties; + } + + @SuppressWarnings("unused") + @NodeIntrinsic + public static T register(@ConstantNodeParameter Register register, @ConstantNodeParameter Kind kind) { + throw new UnsupportedOperationException(); + } +} diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewInstanceSnippets.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewInstanceSnippets.java Mon Jun 11 17:06:06 2012 +0200 @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2012, 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.snippets; + +import static com.oracle.graal.hotspot.nodes.RegisterNode.*; +import static com.oracle.graal.hotspot.snippets.DirectObjectStoreNode.*; +import static com.oracle.graal.nodes.calc.Condition.*; +import static com.oracle.graal.nodes.extended.UnsafeCastNode.*; +import static com.oracle.graal.nodes.extended.UnsafeLoadNode.*; +import static com.oracle.graal.snippets.SnippetTemplate.Arguments.*; +import static com.oracle.graal.snippets.nodes.ExplodeLoopNode.*; +import static com.oracle.max.asm.target.amd64.AMD64.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.phases.*; +import com.oracle.graal.cri.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.Node.Fold; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.snippets.*; +import com.oracle.graal.snippets.Snippet.ConstantParameter; +import com.oracle.graal.snippets.Snippet.Parameter; +import com.oracle.graal.snippets.SnippetTemplate.Arguments; +import com.oracle.graal.snippets.SnippetTemplate.Cache; +import com.oracle.graal.snippets.SnippetTemplate.Key; + +/** + * Snippets used for implementing NEW. + */ +public class NewInstanceSnippets implements SnippetsInterface { + + /** + * Type test used when the type being tested against is a final type. + */ + @Snippet + public static Object newInstance(@Parameter("hub") Object hub, @ConstantParameter("size") int size, @ConstantParameter("checkInit") boolean checkInit) { + if (checkInit) { + int klassState = load(hub, 0, klassStateOffset(), Kind.Int); + if (klassState != klassStateFullyInitialized()) { + Object instance = NewInstanceStubCall.call(hub); + return formatInstance(hub, size, instance); + } + } + + Word thread = asWord(register(r15, wordKind())); + Word top = loadWord(thread, threadTlabTopOffset()); + Word end = loadWord(thread, threadTlabEndOffset()); + Word newTop = top.plus(size); + Object instance; + if (newTop.cmp(BE, end)) { + instance = cast(top, Object.class); + store(thread, 0, threadTlabTopOffset(), newTop); + } else { + instance = NewInstanceStubCall.call(hub); + } + + return formatInstance(hub, size, instance); + } + + private static Word asWord(Object object) { + return cast(object, Word.class); + } + + private static Word loadWord(Object object, int offset) { + return cast(load(object, 0, offset, wordKind()), Word.class); + } + + /** + * Formats the header of a created instance and zeroes out its body. + */ + private static Object formatInstance(Object hub, int size, Object instance) { + Word headerPrototype = cast(load(hub, 0, instanceHeaderPrototypeOffset(), wordKind()), Word.class); + store(instance, 0, 0, headerPrototype); + store(instance, 0, hubOffset(), hub); + explodeLoop(); + for (int offset = 2 * wordSize(); offset < size; offset += wordSize()) { + store(instance, 0, offset, 0); + } + return instance; + } + + @Fold + private static int klassStateOffset() { + return HotSpotGraalRuntime.getInstance().getConfig().klassStateOffset; + } + + @Fold + private static int klassStateFullyInitialized() { + return HotSpotGraalRuntime.getInstance().getConfig().klassStateFullyInitialized; + } + + @Fold + private static int threadTlabTopOffset() { + return HotSpotGraalRuntime.getInstance().getConfig().threadTlabTopOffset; + } + + @Fold + private static int threadTlabEndOffset() { + return HotSpotGraalRuntime.getInstance().getConfig().threadTlabEndOffset; + } + + @Fold + private static Kind wordKind() { + return HotSpotGraalRuntime.getInstance().getTarget().wordKind; + } + + @Fold + private static int wordSize() { + return HotSpotGraalRuntime.getInstance().getTarget().wordSize; + } + + @Fold + private static int instanceHeaderPrototypeOffset() { + return HotSpotGraalRuntime.getInstance().getConfig().instanceHeaderPrototypeOffset; + } + + @Fold + private static int hubOffset() { + return HotSpotGraalRuntime.getInstance().getConfig().hubOffset; + } + + public static class Templates { + + private final Cache cache; + private final ResolvedJavaMethod newInstance; + private final CodeCacheProvider runtime; + + public Templates(CodeCacheProvider runtime) { + this.runtime = runtime; + this.cache = new Cache(runtime); + try { + newInstance = runtime.getResolvedJavaMethod(NewInstanceSnippets.class.getDeclaredMethod("newInstance", Object.class, int.class, boolean.class)); + } catch (NoSuchMethodException e) { + throw new GraalInternalError(e); + } + } + + /** + * Lowers a {@link NewInstanceNode}. + */ + @SuppressWarnings("unused") + public void lower(NewInstanceNode newInstanceNode, CiLoweringTool tool) { + StructuredGraph graph = (StructuredGraph) newInstanceNode.graph(); + HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) newInstanceNode.instanceClass(); + HotSpotKlassOop hub = type.klassOop(); + int instanceSize = type.instanceSize(); + Key key = new Key(newInstance).add("size", instanceSize).add("checkInit", !type.isInitialized()); + Arguments arguments = arguments("hub", hub); + SnippetTemplate template = cache.get(key); + Debug.log("Lowering newInstance in %s: node=%s, template=%s, arguments=%s", graph, newInstanceNode, template, arguments); + template.instantiate(runtime, newInstanceNode, newInstanceNode, arguments); + new DeadCodeEliminationPhase().apply(graph); + } + } +} diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/AMD64NewInstanceStubCallOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/AMD64NewInstanceStubCallOp.java Mon Jun 11 17:06:06 2012 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012, 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.target; + +import static com.oracle.graal.api.code.ValueUtil.*; + +import java.util.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.max.asm.target.amd64.*; + +/** + * LIR instruction for calling HotSpot's {@code new_instance} stub. This stub is declared in c1_Runtime1.hpp + * and implemented in Runtime1::generate_code_for() which is located in c1_Runtime1_x86.cpp. + */ +public class AMD64NewInstanceStubCallOp extends AMD64LIRInstruction { + public AMD64NewInstanceStubCallOp(Value result, Value hub) { + super("NEW_INSTANCE", new Value[] {result}, null, new Value[] {hub}, NO_OPERANDS, NO_OPERANDS); + } + + @Override + public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { + Value result = output(0); + Value hub = input(0); + + // rdx: (in) hub + // rax: (out) result + assert asRegister(hub) == AMD64.rdx; + AMD64Call.directCall(tasm, masm, HotSpotGraalRuntime.getInstance().getConfig().newInstanceStub, null); + if (asRegister(result) != AMD64.rax) { + masm.movq(asRegister(result), AMD64.rax); + } + } + + @Override + protected EnumSet flagsFor(OperandMode mode, int index) { + if (mode == OperandMode.Input) { + return EnumSet.of(OperandFlag.Register); + } else if (mode == OperandMode.Output) { + return EnumSet.of(OperandFlag.Register); + } + throw GraalInternalError.shouldNotReachHere(); + } +} diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Mon Jun 11 17:06:06 2012 +0200 @@ -592,17 +592,17 @@ } private Object lookupConstant(int cpi, int opcode) { - eagerResolving(cpi, opcode); + eagerResolvingForSnippets(cpi, opcode); Object result = constantPool.lookupConstant(cpi); assert !graphBuilderConfig.eagerResolving() || !(result instanceof JavaType) || (result instanceof ResolvedJavaType); return result; } - private void eagerResolving(int cpi, int bytecode) { - if (graphBuilderConfig.eagerResolving()) { - constantPool.loadReferencedType(cpi, bytecode); - } - } +// private void eagerResolving(int cpi, int bytecode) { +// if (graphBuilderConfig.eagerResolving()) { +// constantPool.loadReferencedType(cpi, bytecode); +// } +// } private void eagerResolvingForSnippets(int cpi, int bytecode) { if (graphBuilderConfig.eagerResolvingForSnippets()) { diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Mon Jun 11 17:06:06 2012 +0200 @@ -98,7 +98,8 @@ } @Override - public void negate() { + public Negatable negate() { negated = !negated; + return this; } } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FrameState.java Mon Jun 11 17:06:06 2012 +0200 @@ -322,6 +322,10 @@ properties.put("bci", bci); if (method != null) { properties.put("method", CodeUtil.format("%H.%n(%p):%r", method)); + StackTraceElement ste = method.toStackTraceElement(bci); + if (ste.getFileName() != null && ste.getLineNumber() >= 0) { + properties.put("source", ste.getFileName() + ":" + ste.getLineNumber()); + } } else { properties.put("method", "None"); } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Mon Jun 11 17:06:06 2012 +0200 @@ -134,7 +134,8 @@ } @Override - public void negate() { + public Negatable negate() { negated = !negated; + return this; } } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Mon Jun 11 17:06:06 2012 +0200 @@ -188,7 +188,7 @@ } @Override - public void negate() { + public Negatable negate() { BeginNode trueSucc = trueSuccessor(); BeginNode falseSucc = falseSuccessor(); setTrueSuccessor(null); @@ -198,5 +198,6 @@ double prop = branchProbability[TRUE_EDGE]; branchProbability[TRUE_EDGE] = branchProbability[FALSE_EDGE]; branchProbability[FALSE_EDGE] = prop; + return this; } } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java Mon Jun 11 17:06:06 2012 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.type.GenericStamp.*; +import com.oracle.graal.nodes.util.*; /** * This class represents a value within the graph, including local variables, phis, and @@ -108,15 +109,24 @@ return null; } + public boolean verifyStamp(Class stampClass) { + assert stampClass.isInstance(stamp) : this + " (" + GraphUtil.approxSourceLocation(this) + ") has unexpected stamp type: expected " + stampClass.getName() + + ", got " + stamp.getClass().getName(); + return true; + } + public final ObjectStamp objectStamp() { + assert verifyStamp(ObjectStamp.class); return (ObjectStamp) stamp; } public final IntegerStamp integerStamp() { + assert verifyStamp(IntegerStamp.class); return (IntegerStamp) stamp; } public final FloatStamp floatStamp() { + assert verifyStamp(FloatStamp.class); return (FloatStamp) stamp; } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Mon Jun 11 17:06:06 2012 +0200 @@ -74,7 +74,9 @@ } @Override - public void negate() { - ((StructuredGraph) graph()).replaceFloating(this, graph().unique(new ConditionalNode(condition, falseValue(), trueValue()))); + public Negatable negate() { + ConditionalNode replacement = graph().unique(new ConditionalNode(condition, falseValue(), trueValue())); + ((StructuredGraph) graph()).replaceFloating(this, replacement); + return replacement; } } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Mon Jun 11 17:06:06 2012 +0200 @@ -32,7 +32,7 @@ /** * The {@code UnsafeCastNode} produces the same value as its input, but with a different type. */ -public final class UnsafeCastNode extends FloatingNode implements Canonicalizable, Lowerable { +public final class UnsafeCastNode extends FloatingNode implements Canonicalizable, Lowerable, LIRLowerable { @Input private ValueNode object; private ResolvedJavaType toType; @@ -49,15 +49,20 @@ @Override public ValueNode canonical(CanonicalizerTool tool) { - if (object != null && object.objectStamp().type() != null && object.objectStamp().type().isSubtypeOf(toType)) { + if (object != null && object.kind().isObject() && object.objectStamp().type() != null && object.objectStamp().type().isSubtypeOf(toType)) { return object; } return this; } + @Override public void lower(CiLoweringTool tool) { - ((StructuredGraph) graph()).replaceFloating(this, object); + if (object.kind() == kind()) { + ((StructuredGraph) graph()).replaceFloating(this, object); + } else { + // Cannot remove an unsafe cast between two different kinds + } } @SuppressWarnings("unused") @@ -65,4 +70,11 @@ public static T cast(Object object, @ConstantNodeParameter Class toType) { throw new UnsupportedOperationException("This method may only be compiled with the Graal compiler"); } + + @Override + public void generate(LIRGeneratorTool generator) { + Value result = generator.newVariable(kind()); + generator.emitMove(generator.operand(object), result); + generator.setResult(this, result); + } } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Mon Jun 11 17:06:06 2012 +0200 @@ -25,6 +25,7 @@ import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.cri.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -34,7 +35,7 @@ /** * The {@code NewInstanceNode} represents the allocation of an instance class object. */ -public final class NewInstanceNode extends FixedWithNextNode implements EscapeAnalyzable, LIRLowerable, Node.IterableNodeType { +public final class NewInstanceNode extends FixedWithNextNode implements EscapeAnalyzable, Lowerable, LIRLowerable, Node.IterableNodeType { private final ResolvedJavaType instanceClass; @@ -56,6 +57,11 @@ } @Override + public void lower(CiLoweringTool tool) { + tool.getRuntime().lower(this, tool); + } + + @Override public void generate(LIRGeneratorTool gen) { gen.visitNewInstance(this); } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Negatable.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Negatable.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Negatable.java Mon Jun 11 17:06:06 2012 +0200 @@ -36,5 +36,5 @@ * Tells this node that a condition it depends has been negated, and that it thus needs to invert its own effect. * For example, an {@link IfNode} would switch its true and false successors. */ - void negate(); + Negatable negate(); } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java Mon Jun 11 17:06:06 2012 +0200 @@ -26,12 +26,14 @@ import java.util.*; +import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.graph.iterators.NodePredicates.PositiveTypePredicate; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.virtual.*; public class GraphUtil { @@ -180,6 +182,36 @@ } } + /** + * Gets an approximate source code location for a node if possible. + * + * @return a file name and source line number in stack trace format (e.g. "String.java:32") + * if an approximate source location is found, null otherwise + */ + public static String approxSourceLocation(Node node) { + Node n = node; + while (n != null) { + if (n instanceof MethodCallTargetNode) { + n = ((MethodCallTargetNode) n).invoke().node(); + } + + if (n instanceof StateSplit) { + FrameState stateAfter = ((StateSplit) n).stateAfter(); + if (stateAfter != null) { + ResolvedJavaMethod method = stateAfter.method(); + if (method != null) { + StackTraceElement stackTraceElement = method.toStackTraceElement(stateAfter.bci); + if (stackTraceElement.getFileName() != null && stackTraceElement.getLineNumber() >= 0) { + return stackTraceElement.getFileName() + ":" + stackTraceElement.getLineNumber(); + } + } + } + } + n = n.predecessor(); + } + return null; + } + public static ValueNode unProxify(ValueNode proxy) { ValueNode v = proxy; while (v instanceof ValueProxyNode) { diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java Mon Jun 11 17:06:06 2012 +0200 @@ -25,7 +25,6 @@ import java.io.*; import java.util.*; -import com.oracle.max.criutils.*; import com.oracle.graal.alloc.util.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; @@ -38,6 +37,7 @@ import com.oracle.graal.lir.*; import com.oracle.graal.lir.cfg.*; import com.oracle.graal.nodes.*; +import com.oracle.max.criutils.*; /** * Observes compilation events and uses {@link CFGPrinter} to produce a control flow graph for the arguments = callTargetNode.arguments(); + Invoke invoke = (Invoke) callTargetNode.usages().first(); + assert invoke != null; + + Opcode opcode = operation.value(); + switch (opcode) { + case COMPARE: { + assert arguments.size() == 3; + assert arguments.get(1) instanceof ConstantNode; + Condition condition = (Condition) arguments.get(1).asConstant().asObject(); + invoke.intrinsify(compare(condition, graph, arguments.first(), arguments.last())); + break; + } + + case PLUS: { + ValueNode addend = asWordKind(graph, arguments.last()); + IntegerAddNode op = graph.unique(new IntegerAddNode(wordKind, arguments.first(), addend)); + invoke.intrinsify(op); + break; + } + default: { + throw new GraalInternalError("Unknown opcode: %s", opcode); + } + } + } + } + } + + /** + * Creates comparison node for a given condition and two input values. + */ + private ValueNode compare(Condition condition, StructuredGraph graph, ValueNode left, ValueNode right) { + assert condition.isUnsigned(); + assert left.kind() == wordKind; + assert right.kind() == wordKind; + + // mirroring gets the condition into canonical form + boolean mirror = condition.canonicalMirror(); + + ValueNode a = mirror ? right : left; + ValueNode b = mirror ? left : right; + + MaterializeNode materialize; + if (condition == Condition.EQ || condition == Condition.NE) { + materialize = MaterializeNode.create(graph.unique(new IntegerEqualsNode(a, b)), graph); + } else { + materialize = MaterializeNode.create(graph.unique(new IntegerBelowThanNode(a, b)), graph); + } + + ValueNode op; + if (condition.canonicalNegate()) { + op = (ValueNode) materialize.negate(); + } else { + op = materialize; + } + return op; + } + + /** + * Adds a node if necessary to convert a given value into the word kind. + * + * @return the node for {@code value} producing a value of word kind + */ + private ValueNode asWordKind(StructuredGraph graph, ValueNode value) { + if (value.kind() != wordKind) { + Op op; + if (wordKind.isLong()) { + assert value.kind().isInt(); + op = Op.I2L; + } else { + assert wordKind.isInt(); + assert value.kind().isLong(); + op = Op.L2I; + } + return graph.unique(new ConvertNode(op, value)); + } + return value; + } + + public boolean isWord(ValueNode node) { + return isWord(node.stamp().declaredType()); + } + + public boolean isWord(ResolvedJavaType type) { + if (type != null && type.toJava() == Word.class) { + return true; + } + return false; + } + + private void changeToWord(ValueNode valueNode) { + assert !(valueNode instanceof ConstantNode); + valueNode.setStamp(StampFactory.forKind(wordKind)); + + // Propagate word kind. + for (Node n : valueNode.usages()) { + if (n instanceof PhiNode) { + changeToWord((ValueNode) n); + PhiNode phi = (PhiNode) n; + assert phi.type() == PhiType.Value; +// for (ValueNode v : phi.values()) { +// assertTrue(v.kind() == phi.kind(), "all phi values must have same kind"); +// } + + } else if (n instanceof ReturnNode) { + changeToWord((ValueNode) n); + } + } + } +} diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/DegeneratedLoopsTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/DegeneratedLoopsTest.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/DegeneratedLoopsTest.java Mon Jun 11 17:06:06 2012 +0200 @@ -73,15 +73,19 @@ } - private void test(String snippet) { - StructuredGraph graph = parse(snippet); - Debug.dump(graph, "Graph"); - for (Invoke invoke : graph.getInvokes()) { - invoke.intrinsify(null); - } - new CanonicalizerPhase(null, runtime(), null).apply(graph); - StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); - Debug.dump(referenceGraph, "Graph"); - assertEquals(referenceGraph, graph); + private void test(final String snippet) { + Debug.scope("DegeneratedLoopsTest", new DebugDumpScope(snippet), new Runnable() { + public void run() { + StructuredGraph graph = parse(snippet); + Debug.dump(graph, "Graph"); + for (Invoke invoke : graph.getInvokes()) { + invoke.intrinsify(null); + } + new CanonicalizerPhase(null, runtime(), null).apply(graph); + StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); + Debug.dump(referenceGraph, "Graph"); + assertEquals(referenceGraph, graph); + } + }); } } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/EscapeAnalysisTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/EscapeAnalysisTest.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/EscapeAnalysisTest.java Mon Jun 11 17:06:06 2012 +0200 @@ -116,31 +116,35 @@ } } - private void test(String snippet, Constant expectedResult) { - StructuredGraph graph = parse(snippet); - for (Invoke n : graph.getInvokes()) { - n.node().setProbability(100000); - } + private void test(final String snippet, final Constant expectedResult) { + Debug.scope("ScalarTypeSystemTest", new DebugDumpScope(snippet), new Runnable() { + public void run() { + StructuredGraph graph = parse(snippet); + for (Invoke n : graph.getInvokes()) { + n.node().setProbability(100000); + } - new InliningPhase(null, runtime(), null, null, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); - new DeadCodeEliminationPhase().apply(graph); - Debug.dump(graph, "Graph"); - new EscapeAnalysisPhase(null, runtime(), null, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); - Debug.dump(graph, "Graph"); - int retCount = 0; - for (ReturnNode ret : graph.getNodes(ReturnNode.class)) { - Assert.assertTrue(ret.result().isConstant()); - Assert.assertEquals(ret.result().asConstant(), expectedResult); - retCount++; - } - Assert.assertEquals(1, retCount); - int newInstanceCount = 0; - for (@SuppressWarnings("unused") NewInstanceNode n : graph.getNodes(NewInstanceNode.class)) { - newInstanceCount++; - } - for (@SuppressWarnings("unused") NewObjectArrayNode n : graph.getNodes(NewObjectArrayNode.class)) { - newInstanceCount++; - } - Assert.assertEquals(0, newInstanceCount); + new InliningPhase(null, runtime(), null, null, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); + new DeadCodeEliminationPhase().apply(graph); + Debug.dump(graph, "Graph"); + new EscapeAnalysisPhase(null, runtime(), null, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); + Debug.dump(graph, "Graph"); + int retCount = 0; + for (ReturnNode ret : graph.getNodes(ReturnNode.class)) { + Assert.assertTrue(ret.result().isConstant()); + Assert.assertEquals(ret.result().asConstant(), expectedResult); + retCount++; + } + Assert.assertEquals(1, retCount); + int newInstanceCount = 0; + for (@SuppressWarnings("unused") NewInstanceNode n : graph.getNodes(NewInstanceNode.class)) { + newInstanceCount++; + } + for (@SuppressWarnings("unused") NewObjectArrayNode n : graph.getNodes(NewObjectArrayNode.class)) { + newInstanceCount++; + } + Assert.assertEquals(0, newInstanceCount); + } + }); } } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/FloatingReadTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/FloatingReadTest.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/FloatingReadTest.java Mon Jun 11 17:06:06 2012 +0200 @@ -25,6 +25,7 @@ import org.junit.*; import com.oracle.graal.compiler.phases.*; +import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; @@ -50,28 +51,32 @@ test("test1Snippet"); } - private void test(String snippet) { - StructuredGraph graph = parse(snippet); - new LoweringPhase(runtime(), null).apply(graph); - new FloatingReadPhase().apply(graph); + private void test(final String snippet) { + Debug.scope("FloatingReadTest", new DebugDumpScope(snippet), new Runnable() { + public void run() { + StructuredGraph graph = parse(snippet); + new LoweringPhase(runtime(), null).apply(graph); + new FloatingReadPhase().apply(graph); - ReturnNode returnNode = null; - MonitorExitNode monitor = null; + ReturnNode returnNode = null; + MonitorExitNode monitor = null; - for (Node n : graph.getNodes()) { - if (n instanceof ReturnNode) { - returnNode = (ReturnNode) n; - } else if (n instanceof MonitorExitNode) { - monitor = (MonitorExitNode) n; - } - } + for (Node n : graph.getNodes()) { + if (n instanceof ReturnNode) { + returnNode = (ReturnNode) n; + } else if (n instanceof MonitorExitNode) { + monitor = (MonitorExitNode) n; + } + } - Assert.assertNotNull(returnNode); - Assert.assertNotNull(monitor); - Assert.assertTrue(returnNode.result() instanceof FloatingReadNode); + Assert.assertNotNull(returnNode); + Assert.assertNotNull(monitor); + Assert.assertTrue(returnNode.result() instanceof FloatingReadNode); - FloatingReadNode read = (FloatingReadNode) returnNode.result(); + FloatingReadNode read = (FloatingReadNode) returnNode.result(); - assertOrderedAfterSchedule(graph, read, monitor); + assertOrderedAfterSchedule(graph, read, monitor); + } + }); } } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/GraalCompilerTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/GraalCompilerTest.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/GraalCompilerTest.java Mon Jun 11 17:06:06 2012 +0200 @@ -147,6 +147,34 @@ private static int compilationId = 0; + protected void test(String name, Object... args) { + Method method = getMethod(name); + Object expect = null; + Throwable exception = null; + try { + // This gives us both the expected return value as well as ensuring that the method to be compiled is fully resolved + expect = method.invoke(null, args); + } catch (InvocationTargetException e) { + exception = e.getTargetException(); + } catch (Exception e) { + throw new RuntimeException(e); + } + InstalledCode compiledMethod = compile(runtime.getResolvedJavaMethod(method), parse(method)); + compiledMethod.method(); + + if (exception != null) { + try { + compiledMethod.executeVarargs(args); + Assert.fail("expected " + exception); + } catch (Throwable e) { + Assert.assertEquals(exception.getClass(), e.getClass()); + } + } else { + Object actual = compiledMethod.executeVarargs(args); + Assert.assertEquals(expect, actual); + } + } + protected InstalledCode compile(final ResolvedJavaMethod method, final StructuredGraph graph) { return Debug.scope("Compiling", new DebugDumpScope(String.valueOf(compilationId++), true), new Callable() { public InstalledCode call() throws Exception { @@ -157,13 +185,15 @@ } protected InstalledCode addMethod(final ResolvedJavaMethod method, final CompilationResult tm) { - return Debug.scope("CodeInstall", new Object[] {method}, new Callable() { + GraalCompiler graalCompiler = Graal.getRuntime().getCapability(GraalCompiler.class); + assert graalCompiler != null; + return Debug.scope("CodeInstall", new Object[] {graalCompiler, method}, new Callable() { @Override public InstalledCode call() throws Exception { final CodeInfo[] info = Debug.isDumpEnabled() ? new CodeInfo[1] : null; InstalledCode installedMethod = runtime.addMethod(method, tm, info); if (info != null) { - Debug.dump(info[0], "After code installation"); + Debug.dump(new Object[] {tm, info[0]}, "After code installation"); } return installedMethod; } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/MonitorTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/MonitorTest.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/MonitorTest.java Mon Jun 11 17:06:06 2012 +0200 @@ -26,10 +26,7 @@ import java.util.*; -import junit.framework.*; - -import org.junit.Assert; -import org.junit.Test; +import org.junit.*; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.phases.*; @@ -56,7 +53,7 @@ return 1; } - @Test(expected = AssertionFailedError.class) + @Test(expected = AssertionError.class) public void test1() { test("test1Snippet"); } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/NewInstanceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/NewInstanceTest.java Mon Jun 11 17:06:06 2012 +0200 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler.tests; + +import java.util.*; + +import org.junit.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; + +/** + * Tests the implementation of {@code NEW}. + */ +public class NewInstanceTest extends TypeCheckTest { + + @Override + protected void replaceProfile(StructuredGraph graph, JavaTypeProfile profile) { + } + + @Test + public void test1() { + test("newEmptyString"); + test("newString", "value"); + test("newHashMap", 31); + } + + public static String newEmptyString() { + return new String(); + } + + public static String newString(String value) { + return new String(value); + } + + public static HashMap newHashMap(int initialCapacity) { + return new HashMap(initialCapacity); + } +} diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/ScalarTypeSystemTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/ScalarTypeSystemTest.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/ScalarTypeSystemTest.java Mon Jun 11 17:06:06 2012 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.compiler.tests; -import junit.framework.AssertionFailedError; - import org.junit.*; import com.oracle.graal.compiler.phases.*; @@ -43,7 +41,7 @@ } } - @Test(expected = AssertionFailedError.class) + @Test(expected = AssertionError.class) public void test1() { test("test1Snippet", "referenceSnippet1"); } @@ -60,7 +58,7 @@ } } - @Test(expected = AssertionFailedError.class) + @Test(expected = AssertionError.class) public void test2() { test("test2Snippet", "referenceSnippet1"); } @@ -77,7 +75,7 @@ } } - @Test(expected = AssertionFailedError.class) + @Test(expected = AssertionError.class) public void test3() { test("test3Snippet", "referenceSnippet2"); } @@ -144,7 +142,7 @@ } } - @Test(expected = AssertionFailedError.class) + @Test(expected = AssertionError.class) public void test6() { test("test6Snippet", "referenceSnippet3"); } @@ -161,14 +159,18 @@ } } - private void test(String snippet, String referenceSnippet) { - StructuredGraph graph = parse(snippet); - Debug.dump(graph, "Graph"); -// TypeSystemTest.outputGraph(graph); - new CanonicalizerPhase(null, runtime(), null).apply(graph); - new CheckCastEliminationPhase().apply(graph); - new CanonicalizerPhase(null, runtime(), null).apply(graph); - StructuredGraph referenceGraph = parse(referenceSnippet); - assertEquals(referenceGraph, graph); + private void test(final String snippet, final String referenceSnippet) { + Debug.scope("ScalarTypeSystemTest", new DebugDumpScope(snippet), new Runnable() { + public void run() { + StructuredGraph graph = parse(snippet); + Debug.dump(graph, "Graph"); +// TypeSystemTest.outputGraph(graph); + new CanonicalizerPhase(null, runtime(), null).apply(graph); + new CheckCastEliminationPhase().apply(graph); + new CanonicalizerPhase(null, runtime(), null).apply(graph); + StructuredGraph referenceGraph = parse(referenceSnippet); + assertEquals(referenceGraph, graph); + } + }); } } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/StraighteningTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/StraighteningTest.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/StraighteningTest.java Mon Jun 11 17:06:06 2012 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.compiler.tests; -import junit.framework.AssertionFailedError; - import org.junit.*; import com.oracle.graal.compiler.phases.*; @@ -71,26 +69,30 @@ return c == 1; } - @Test(expected = AssertionFailedError.class) + @Test(expected = AssertionError.class) public void test1() { test("test1Snippet"); } - @Test(expected = AssertionFailedError.class) + @Test(expected = AssertionError.class) public void test2() { test("test2Snippet"); } - @Test(expected = AssertionFailedError.class) + @Test(expected = AssertionError.class) public void test3() { test("test3Snippet"); } - private void test(String snippet) { - StructuredGraph graph = parse(snippet); - Debug.dump(graph, "Graph"); - new CanonicalizerPhase(null, runtime(), null).apply(graph); - StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); - assertEquals(referenceGraph, graph); + private void test(final String snippet) { + Debug.scope("StraighteningTest", new DebugDumpScope(snippet), new Runnable() { + public void run() { + StructuredGraph graph = parse(snippet); + Debug.dump(graph, "Graph"); + new CanonicalizerPhase(null, runtime(), null).apply(graph); + StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); + assertEquals(referenceGraph, graph); + } + }); } } diff -r 30162e74f11f -r 102f87543d5e graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/TypeCheckTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/TypeCheckTest.java Mon Jun 11 17:04:59 2012 +0200 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/TypeCheckTest.java Mon Jun 11 17:06:06 2012 +0200 @@ -22,10 +22,6 @@ */ package com.oracle.graal.compiler.tests; -import java.lang.reflect.*; - -import org.junit.*; - import com.oracle.graal.api.meta.*; import com.oracle.graal.api.meta.JavaTypeProfile.*; import com.oracle.graal.nodes.*; @@ -37,10 +33,14 @@ protected abstract void replaceProfile(StructuredGraph graph, JavaTypeProfile profile); - private InstalledCode compile(Method method, JavaTypeProfile profile) { - final StructuredGraph graph = parse(method); - replaceProfile(graph, profile); - return compile(runtime.getResolvedJavaMethod(method), graph); + protected JavaTypeProfile currentProfile; + + @Override + protected InstalledCode compile(final ResolvedJavaMethod method, final StructuredGraph graph) { + if (currentProfile != null) { + replaceProfile(graph, currentProfile); + } + return super.compile(method, graph); } protected JavaTypeProfile profile(Class... types) { @@ -55,30 +55,12 @@ } protected void test(String name, JavaTypeProfile profile, Object... args) { - Method method = getMethod(name); - Object expect = null; - Throwable exception = null; + assert currentProfile == null; + currentProfile = profile; try { - // This gives us both the expected return value as well as ensuring that the method to be compiled is fully resolved - expect = method.invoke(null, args); - } catch (InvocationTargetException e) { - exception = e.getTargetException(); - } catch (Exception e) { - throw new RuntimeException(e); - } - InstalledCode compiledMethod = compile(method, profile); - compiledMethod.method(); - - if (exception != null) { - try { - compiledMethod.executeVarargs(args); - Assert.fail("expected " + exception); - } catch (Throwable e) { - Assert.assertEquals(exception.getClass(), e.getClass()); - } - } else { - Object actual = compiledMethod.executeVarargs(args); - Assert.assertEquals(expect, actual); + super.test(name, args); + } finally { + currentProfile = null; } } } diff -r 30162e74f11f -r 102f87543d5e src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Mon Jun 11 17:04:59 2012 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Mon Jun 11 17:06:06 2012 +0200 @@ -818,8 +818,7 @@ set_long(env, config, "debugStub", VmIds::addStub((address)warning)); set_long(env, config, "instanceofStub", VmIds::addStub(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); set_long(env, config, "verifyPointerStub", VmIds::addStub(Runtime1::entry_for(Runtime1::graal_verify_pointer_id))); - set_long(env, config, "newInstanceStub", VmIds::addStub(Runtime1::entry_for(Runtime1::fast_new_instance_init_check_id))); - set_long(env, config, "unresolvedNewInstanceStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_instance_id))); + set_long(env, config, "newInstanceStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_instance_id))); set_long(env, config, "newTypeArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_type_array_id))); set_long(env, config, "newObjectArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_object_array_id))); set_long(env, config, "newMultiArrayStub", VmIds::addStub(Runtime1::entry_for(Runtime1::new_multi_array_id)));