# HG changeset patch # User Gilles Duboscq # Date 1340289397 -7200 # Node ID 494332f39ee8fda0f5c1a5dbaff9fd99e2483101 # Parent 776366f3a41aa37ca73989c21146334208386c92# Parent 17639f600cda407fe923013a5a510b79b5094e8c Merge diff -r 776366f3a41a -r 494332f39ee8 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Thu Jun 21 16:35:23 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Thu Jun 21 16:36:37 2012 +0200 @@ -23,6 +23,7 @@ package com.oracle.graal.compiler.gen; import static com.oracle.graal.api.code.CallingConvention.Type.*; +import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.api.meta.Value.*; import static com.oracle.graal.lir.LIRValueUtil.*; @@ -206,9 +207,15 @@ } @Override + public RegisterAttributes attributes(Register register) { + return frameMap.registerConfig.getAttributesMap()[register.number]; + } + + @Override public Value setResult(ValueNode x, Value operand) { - assert (isVariable(operand) && x.kind() == operand.kind) || (isConstant(operand) && x.kind() == operand.kind.stackKind()) : operand.kind + " for node " + x; - + assert (isVariable(operand) && x.kind() == operand.kind) || + (isRegister(operand) && !attributes(asRegister(operand)).isAllocatable()) || + (isConstant(operand) && x.kind() == operand.kind.stackKind()) : operand.kind + " for node " + x; assert operand(x) == null : "operand cannot be set twice"; assert operand != null && isLegal(operand) : "operand must be legal"; assert operand.kind.stackKind() == x.kind(); @@ -1022,6 +1029,17 @@ } @Override + public void emitTypeSwitch(TypeSwitchNode x) { + Variable tag = load(operand(x.value())); + int len = x.numberOfCases(); + for (int i = 0; i < len; i++) { + ResolvedJavaType type = x.keyAt(i); + emitBranch(tag, type.getEncoding(Representation.ObjectHub), Condition.EQ, false, getLIRBlock(x.blockSuccessor(i)), null); + } + emitJump(getLIRBlock(x.defaultSuccessor()), null); + } + + @Override public void emitTableSwitch(TableSwitchNode x) { Variable value = load(operand(x.value())); // TODO: tune the defaults for the controls used to determine what kind of translation to use diff -r 776366f3a41a -r 494332f39ee8 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Thu Jun 21 16:35:23 2012 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Thu Jun 21 16:36:37 2012 +0200 @@ -398,41 +398,28 @@ private FixedNode createDispatchOnType(StructuredGraph graph, ReadHubNode objectClassNode, BeginNode[] calleeEntryNodes, FixedNode unknownTypeSux) { assert ptypes.length > 1; - int lastIndex = ptypes.length - 1; - double[] branchProbabilities = convertTypeToBranchProbabilities(ptypes, notRecordedTypeProbability); - double nodeProbability = ptypes[lastIndex].probability; - IfNode nextNode = createTypeCheck(graph, objectClassNode, ptypes[lastIndex].type, calleeEntryNodes[typesToConcretes[lastIndex]], unknownTypeSux, branchProbabilities[lastIndex], invoke.probability() * nodeProbability); - for (int i = lastIndex - 1; i >= 0; i--) { - nodeProbability += ptypes[i].probability; - nextNode = createTypeCheck(graph, objectClassNode, ptypes[i].type, calleeEntryNodes[typesToConcretes[i]], nextNode, branchProbabilities[i], invoke.probability() * nodeProbability); - } - - return nextNode; - } + ResolvedJavaType[] types = new ResolvedJavaType[ptypes.length]; + double[] probabilities = new double[ptypes.length + 1]; + BeginNode[] successors = new BeginNode[ptypes.length + 1]; - private static IfNode createTypeCheck(StructuredGraph graph, ReadHubNode objectClassNode, ResolvedJavaType type, BeginNode tsux, FixedNode nextNode, double tsuxProbability, double probability) { - IfNode result; - IsTypeNode isTypeNode = graph.unique(new IsTypeNode(objectClassNode, type)); - if (tsux instanceof MergeNode) { - EndNode endNode = graph.add(new EndNode()); - result = graph.add(new IfNode(isTypeNode, endNode, nextNode, tsuxProbability)); - ((MergeNode) tsux).addForwardEnd(endNode); - } else { - result = graph.add(new IfNode(isTypeNode, tsux, nextNode, tsuxProbability)); + for (int i = 0; i < ptypes.length; i++) { + types[i] = ptypes[i].type; + probabilities[i] = ptypes[i].probability; + FixedNode entry = calleeEntryNodes[typesToConcretes[i]]; + if (entry instanceof MergeNode) { + EndNode endNode = graph.add(new EndNode()); + ((MergeNode) entry).addForwardEnd(endNode); + entry = endNode; + } + successors[i] = BeginNode.begin(entry); } - result.setProbability(probability); - return result; - } + assert !(unknownTypeSux instanceof MergeNode); + successors[successors.length - 1] = BeginNode.begin(unknownTypeSux); + probabilities[successors.length - 1] = notRecordedTypeProbability; - private static double[] convertTypeToBranchProbabilities(ProfiledType[] ptypes, double notRecordedTypeProbability) { - double[] result = new double[ptypes.length]; - double total = notRecordedTypeProbability; - for (int i = ptypes.length - 1; i >= 0; i--) { - total += ptypes[i].probability; - result[i] = ptypes[i].probability / total; - } - assert total > 0.99 && total < 1.01; - return result; + TypeSwitchNode typeSwitch = graph.add(new TypeSwitchNode(objectClassNode, successors, types, probabilities)); + + return typeSwitch; } private static BeginNode createInvocationBlock(StructuredGraph graph, Invoke invoke, MergeNode returnMerge, PhiNode returnValuePhi, diff -r 776366f3a41a -r 494332f39ee8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Thu Jun 21 16:35:23 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Thu Jun 21 16:36:37 2012 +0200 @@ -232,8 +232,8 @@ if (queue != null) { queue.shutdown(); if (Debug.isEnabled() && GraalOptions.Dump != null) { - // Wait 5 seconds to try and flush out all graph dumps - queue.awaitTermination(5, TimeUnit.SECONDS); + // Wait 2 seconds to flush out all graph dumps that may be of interest + queue.awaitTermination(2, TimeUnit.SECONDS); } } } diff -r 776366f3a41a -r 494332f39ee8 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 21 16:35:23 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Jun 21 16:36:37 2012 +0200 @@ -229,7 +229,6 @@ @Override public void lower(Node n, CiLoweringTool tool) { StructuredGraph graph = (StructuredGraph) n.graph(); - if (n instanceof ArrayLengthNode) { ArrayLengthNode arrayLengthNode = (ArrayLengthNode) n; SafeReadNode safeReadArrayLength = safeReadArrayLength(arrayLengthNode.array(), StructuredGraph.INVALID_GRAPH_ID); @@ -367,6 +366,10 @@ if (shouldLower(graph, GraalOptions.HIRLowerNewInstance)) { newInstanceSnippets.lower((NewInstanceNode) n, tool); } + } else if (n instanceof TLABAllocateNode) { + newInstanceSnippets.lower((TLABAllocateNode) n, tool); + } else if (n instanceof InitializeNode) { + newInstanceSnippets.lower((InitializeNode) n, tool); } else { assert false : "Node implementing Lowerable not handled: " + n; } diff -r 776366f3a41a -r 494332f39ee8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/InitializeNode.java Thu Jun 21 16:36:37 2012 +0200 @@ -0,0 +1,66 @@ +/* + * 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.cri.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * Initializes the header and body of an uninitialized object cell. + * This node calls out to a stub to do both the allocation and formatting + * if the memory address it is given is zero/null (e.g. due to + * {@linkplain TLABAllocateNode TLAB allocation} failing). + */ +public final class InitializeNode extends FixedWithNextNode implements Lowerable { + + @Input private final ValueNode memory; + private final ResolvedJavaType type; + + public InitializeNode(ValueNode memory, ResolvedJavaType type) { + super(StampFactory.exactNonNull(type)); + this.memory = memory; + this.type = type; + } + + public ValueNode memory() { + return memory; + } + + public ResolvedJavaType type() { + return type; + } + + @Override + public void lower(CiLoweringTool tool) { + tool.getRuntime().lower(this, tool); + } + + @SuppressWarnings("unused") + @NodeIntrinsic + public static Object initialize(Object memory, @ConstantNodeParameter ResolvedJavaType type) { + throw new UnsupportedOperationException(); + } +} diff -r 776366f3a41a -r 494332f39ee8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/RegisterNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/RegisterNode.java Thu Jun 21 16:35:23 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/RegisterNode.java Thu Jun 21 16:36:37 2012 +0200 @@ -44,8 +44,15 @@ @Override public void generate(LIRGeneratorTool generator) { - Value result = generator.newVariable(kind()); - generator.emitMove(register.asValue(kind()), result); + Value result; + if (generator.attributes(register).isAllocatable()) { + // The register allocator would prefer us not to tie up an allocatable + // register for the complete lifetime of this node. + result = generator.newVariable(kind()); + generator.emitMove(register.asValue(kind()), result); + } else { + result = register.asValue(kind()); + } generator.setResult(this, result); } diff -r 776366f3a41a -r 494332f39ee8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TLABAllocateNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/TLABAllocateNode.java Thu Jun 21 16:36:37 2012 +0200 @@ -0,0 +1,61 @@ +/* + * 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.cri.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +/** + * Allocates some uninitialized area. This is used for TLAB allocation + * only. If allocation fails, zero/null is produced by this node. + */ +public final class TLABAllocateNode extends FixedWithNextNode implements Lowerable { + + private final int size; + + public TLABAllocateNode(int size, Kind wordKind) { + super(StampFactory.forKind(wordKind)); + this.size = size; + } + + public int size() { + return size; + } + + @Override + public void lower(CiLoweringTool tool) { + tool.getRuntime().lower(this, tool); + } + + /** + * @return null if allocation fails + */ + @SuppressWarnings("unused") + @NodeIntrinsic + public static Object allocate(@ConstantNodeParameter int size, @ConstantNodeParameter Kind wordKind) { + throw new UnsupportedOperationException(); + } +} diff -r 776366f3a41a -r 494332f39ee8 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewInstanceSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewInstanceSnippets.java Thu Jun 21 16:35:23 2012 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewInstanceSnippets.java Thu Jun 21 16:36:37 2012 +0200 @@ -33,6 +33,7 @@ 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.*; @@ -54,38 +55,32 @@ */ public class NewInstanceSnippets implements SnippetsInterface { - private static final boolean LOG_ALLOCATION = Boolean.getBoolean("graal.traceAllocation"); + @Snippet + public static Object allocate(@ConstantParameter("size") int size) { + Word thread = asWord(register(r15, wordKind())); + Word top = loadWord(thread, threadTlabTopOffset()); + Word end = loadWord(thread, threadTlabEndOffset()); + Word newTop = top.plus(size); + if (newTop.cmp(BE, end)) { + Object memory = cast(top, Object.class); + store(thread, 0, threadTlabTopOffset(), newTop); + return memory; + } + return null; + } @Snippet - public static Object newInstance( + public static Object initialize( + @Parameter("memory") Object memory, @Parameter("hub") Object hub, - @ConstantParameter("size") int size, - @ConstantParameter("useTLAB") boolean useTLAB, - @ConstantParameter("logType") String logType) { + @ConstantParameter("size") int size) { - if (useTLAB) { - Word thread = asWord(register(r15, wordKind())); - Word top = loadWord(thread, threadTlabTopOffset()); - Word end = loadWord(thread, threadTlabEndOffset()); - Word newTop = top.plus(size); - if (newTop.cmp(BE, end)) { - Object instance = cast(top, Object.class); - store(thread, 0, threadTlabTopOffset(), newTop); - formatInstance(hub, size, instance); - if (logType != null) { - Log.print(logType); - Log.print(" - fast alloc at "); - Log.printlnAddress(instance); - } - return verifyOop(instance); - } + if (memory == null) { + return NewInstanceStubCall.call(hub); } - - if (logType != null) { - Log.print(logType); - Log.println(" - slow alloc"); - } - return verifyOop(NewInstanceStubCall.call(hub)); + Object instance = cast(memory, Object.class); + formatInstance(hub, size, instance); + return verifyOop(instance); } private static Object verifyOop(Object object) { @@ -154,7 +149,8 @@ public static class Templates { private final Cache cache; - private final ResolvedJavaMethod newInstance; + private final ResolvedJavaMethod allocate; + private final ResolvedJavaMethod initialize; private final CodeCacheProvider runtime; private final boolean useTLAB; @@ -163,7 +159,8 @@ this.cache = new Cache(runtime); this.useTLAB = useTLAB; try { - newInstance = runtime.getResolvedJavaMethod(NewInstanceSnippets.class.getDeclaredMethod("newInstance", Object.class, int.class, boolean.class, String.class)); + allocate = runtime.getResolvedJavaMethod(NewInstanceSnippets.class.getDeclaredMethod("allocate", int.class)); + initialize = runtime.getResolvedJavaMethod(NewInstanceSnippets.class.getDeclaredMethod("initialize", Object.class, Object.class, int.class)); } catch (NoSuchMethodException e) { throw new GraalInternalError(e); } @@ -177,16 +174,50 @@ StructuredGraph graph = (StructuredGraph) newInstanceNode.graph(); HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) newInstanceNode.instanceClass(); HotSpotKlassOop hub = type.klassOop(); - int instanceSize = type.instanceSize(); - assert (instanceSize % wordSize()) == 0; - assert instanceSize >= 0; - Key key = new Key(newInstance).add("size", instanceSize).add("useTLAB", useTLAB).add("logType", LOG_ALLOCATION ? type.name() : null); - Arguments arguments = arguments("hub", hub); + int size = type.instanceSize(); + assert (size % wordSize()) == 0; + assert size >= 0; + + ValueNode memory; + if (!useTLAB) { + memory = ConstantNode.forObject(null, runtime, graph); + } else { + TLABAllocateNode tlabAllocateNode = graph.add(new TLABAllocateNode(size, wordKind())); + graph.addBeforeFixed(newInstanceNode, tlabAllocateNode); + memory = tlabAllocateNode; + } + InitializeNode initializeNode = graph.add(new InitializeNode(memory, type)); + graph.replaceFixedWithFixed(newInstanceNode, initializeNode); + } + + @SuppressWarnings("unused") + public void lower(TLABAllocateNode tlabAllocateNode, CiLoweringTool tool) { + StructuredGraph graph = (StructuredGraph) tlabAllocateNode.graph(); + int size = tlabAllocateNode.size(); + assert (size % wordSize()) == 0; + assert size >= 0; + Key key = new Key(allocate).add("size", size); + Arguments arguments = new Arguments(); SnippetTemplate template = cache.get(key); - Debug.log("Lowering newInstance in %s: node=%s, template=%s, arguments=%s", graph, newInstanceNode, template, arguments); - //System.out.printf("Lowering newInstance in %s: node=%s, template=%s, arguments=%s%n", graph, newInstanceNode, template, arguments); - //DebugScope.getConfig().addToContext(graph.method()); - template.instantiate(runtime, newInstanceNode, newInstanceNode, arguments); + Debug.log("Lowering fastAllocate in %s: node=%s, template=%s, arguments=%s", graph, tlabAllocateNode, template, arguments); + template.instantiate(runtime, tlabAllocateNode, tlabAllocateNode, arguments); + } + + @SuppressWarnings("unused") + public void lower(InitializeNode initializeNode, CiLoweringTool tool) { + StructuredGraph graph = (StructuredGraph) initializeNode.graph(); + HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) initializeNode.type(); + HotSpotKlassOop hub = type.klassOop(); + int size = type.instanceSize(); + assert (size % wordSize()) == 0; + assert size >= 0; + Key key = new Key(initialize).add("size", size); + ValueNode memory = initializeNode.memory(); + //assert memory instanceof AllocateNode || memory instanceof ConstantNode : memory; + Arguments arguments = arguments("memory", memory).add("hub", hub); + SnippetTemplate template = cache.get(key); + Debug.log("Lowering initialize in %s: node=%s, template=%s, arguments=%s", graph, initializeNode, template, arguments); + template.instantiate(runtime, initializeNode, initializeNode, arguments); } } } diff -r 776366f3a41a -r 494332f39ee8 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java Thu Jun 21 16:35:23 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueProxyNode.java Thu Jun 21 16:36:37 2012 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.graph.Node.ValueNumberable; import com.oracle.graal.nodes.PhiNode.PhiType; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.type.*; /** * A value proxy that is inserted in the frame state of a loop exit for any value that is @@ -54,6 +55,11 @@ return updateStamp(value.stamp()); } + @Override + public Stamp stamp() { + return value().stamp(); + } + public BeginNode proxyPoint() { return proxyPoint; } diff -r 776366f3a41a -r 494332f39ee8 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Thu Jun 21 16:35:23 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java Thu Jun 21 16:36:37 2012 +0200 @@ -80,9 +80,9 @@ } - private ValueNode optimizeMaterialize(Constant constant, MaterializeNode materializeNode, CodeCacheProvider runtime, Condition cond) { - Constant trueConstant = materializeNode.trueValue().asConstant(); - Constant falseConstant = materializeNode.falseValue().asConstant(); + private ValueNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, CodeCacheProvider runtime, Condition cond) { + Constant trueConstant = conditionalNode.trueValue().asConstant(); + Constant falseConstant = conditionalNode.falseValue().asConstant(); if (falseConstant != null && trueConstant != null) { Boolean trueResult = cond.foldCondition(trueConstant, constant, runtime, unorderedIsTrue()); @@ -96,11 +96,11 @@ } else { if (trueUnboxedResult) { assert falseUnboxedResult == false; - return materializeNode.condition(); + return conditionalNode.condition(); } else { assert falseUnboxedResult == true; negateUsages(); - return materializeNode.condition(); + return conditionalNode.condition(); } } @@ -118,14 +118,14 @@ return ConstantNode.forBoolean(condition().foldCondition(x().asConstant(), y().asConstant(), tool.runtime(), unorderedIsTrue()), graph()); } if (x().isConstant()) { - if (y() instanceof MaterializeNode) { - return optimizeMaterialize(x().asConstant(), (MaterializeNode) y(), tool.runtime(), condition().mirror()); + if (y() instanceof ConditionalNode) { + return optimizeConditional(x().asConstant(), (ConditionalNode) y(), tool.runtime(), condition().mirror()); } else if (y() instanceof NormalizeCompareNode) { return optimizeNormalizeCmp(x().asConstant(), (NormalizeCompareNode) y(), true); } } else if (y().isConstant()) { - if (x() instanceof MaterializeNode) { - return optimizeMaterialize(y().asConstant(), (MaterializeNode) x(), tool.runtime(), condition()); + if (x() instanceof ConditionalNode) { + return optimizeConditional(y().asConstant(), (ConditionalNode) x(), tool.runtime(), condition()); } else if (x() instanceof NormalizeCompareNode) { return optimizeNormalizeCmp(y().asConstant(), (NormalizeCompareNode) x(), false); } diff -r 776366f3a41a -r 494332f39ee8 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java Thu Jun 21 16:36:37 2012 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2009, 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.nodes.java; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; + +/** + * The {@code TypeSwitchNode} performs a lookup based on the type of the input value. + * The type comparison is an exact type comparison, not an instanceof. + */ +public final class TypeSwitchNode extends SwitchNode implements LIRLowerable, Simplifiable { + + private final ResolvedJavaType[] keys; + + public TypeSwitchNode(ValueNode value, BeginNode[] successors, ResolvedJavaType[] keys, double[] probability) { + super(value, successors, probability); + assert successors.length == keys.length + 1; + assert successors.length == probability.length; + this.keys = keys; + } + + public TypeSwitchNode(ValueNode value, ResolvedJavaType[] keys, double[] switchProbability) { + this(value, new BeginNode[switchProbability.length], keys, switchProbability); + } + + public ResolvedJavaType keyAt(int i) { + return keys[i]; + } + + public int keysLength() { + return keys.length; + } + + @Override + public void generate(LIRGeneratorTool gen) { + gen.emitTypeSwitch(this); + } + + @Override + public void simplify(SimplifierTool tool) { + // TODO(ls) perform simplifications based on the type of value + } +} diff -r 776366f3a41a -r 494332f39ee8 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Thu Jun 21 16:35:23 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Thu Jun 21 16:36:37 2012 +0200 @@ -48,6 +48,8 @@ */ public abstract boolean canStoreConstant(Constant c); + public abstract RegisterAttributes attributes(Register register); + public abstract Value operand(ValueNode object); public abstract Value newVariable(Kind kind); public abstract Value setResult(ValueNode x, Value operand); @@ -92,6 +94,7 @@ public abstract void emitLookupSwitch(LookupSwitchNode i); public abstract void emitTableSwitch(TableSwitchNode i); + public abstract void emitTypeSwitch(TypeSwitchNode i); public abstract void emitInvoke(Invoke i); public abstract void emitRuntimeCall(RuntimeCallNode i); diff -r 776366f3a41a -r 494332f39ee8 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java Thu Jun 21 16:35:23 2012 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java Thu Jun 21 16:36:37 2012 +0200 @@ -61,6 +61,10 @@ setCache(Kind.Void, voidStamp); } + public static Stamp forWord(Kind wordKind, boolean nonNull) { + return new WordStamp(wordKind, nonNull); + } + public static Stamp forKind(Kind kind) { assert stampCache[kind.stackKind().ordinal()] != null : "unexpected forKind(" + kind + ")"; return stampCache[kind.stackKind().ordinal()]; diff -r 776366f3a41a -r 494332f39ee8 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/WordStamp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/WordStamp.java Thu Jun 21 16:36:37 2012 +0200 @@ -0,0 +1,89 @@ +/* + * 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.nodes.type; + +import com.oracle.graal.api.meta.*; + +/** + * Models the word type. + */ +public class WordStamp extends Stamp { + + private final boolean nonNull; + + public WordStamp(Kind wordKind, boolean nonNull) { + super(wordKind); + this.nonNull = nonNull; + } + + @Override + public boolean nonNull() { + return nonNull; + } + + @Override + public String toString() { + StringBuilder str = new StringBuilder(); + str.append(kind().typeChar); + str.append(nonNull ? "!" : ""); + return str.toString(); + } + + @Override + public boolean alwaysDistinct(Stamp otherStamp) { + return false; + } + + @Override + public Stamp meet(Stamp otherStamp) { + WordStamp other = (WordStamp) otherStamp; + if (other.nonNull == nonNull) { + return this; + } else { + return new WordStamp(kind(), nonNull && other.nonNull); + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (nonNull ? 1231 : 1237); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + WordStamp other = (WordStamp) obj; + if (nonNull != other.nonNull) { + return false; + } + return true; + } +} diff -r 776366f3a41a -r 494332f39ee8 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java Thu Jun 21 16:35:23 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetInstaller.java Thu Jun 21 16:36:37 2012 +0200 @@ -135,6 +135,14 @@ } public StructuredGraph makeGraph(final ResolvedJavaMethod method, final InliningPolicy policy) { + StructuredGraph graph = parseGraph(method, policy); + + Debug.dump(graph, "%s: Final", method.name()); + + return graph; + } + + private StructuredGraph parseGraph(final ResolvedJavaMethod method, final InliningPolicy policy) { StructuredGraph graph = graphCache.get(method); if (graph == null) { graph = buildGraph(method, policy == null ? inliningPolicy(method) : policy); @@ -161,7 +169,7 @@ MethodCallTargetNode callTarget = invoke.callTarget(); ResolvedJavaMethod callee = callTarget.targetMethod(); if (policy.shouldInline(callee, method)) { - StructuredGraph targetGraph = makeGraph(callee, policy); + StructuredGraph targetGraph = parseGraph(callee, policy); InliningUtil.inline(invoke, targetGraph, true); Debug.dump(graph, "after inlining %s", callee); if (GraalOptions.OptCanonicalizer) { @@ -190,9 +198,6 @@ new DeadCodeEliminationPhase().apply(graph); new ComputeProbabilityPhase().apply(graph); } - - Debug.dump(graph, "%s: Final", method.name()); - return graph; } }); diff -r 776366f3a41a -r 494332f39ee8 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java Thu Jun 21 16:35:23 2012 +0200 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java Thu Jun 21 16:36:37 2012 +0200 @@ -119,7 +119,7 @@ } ValueNode argument = tryBoxingElimination(parameterIndex, target, arguments.get(i)); if (folding || CodeUtil.getParameterAnnotation(ConstantNodeParameter.class, parameterIndex, target) != null) { - assert argument instanceof ConstantNode : "parameter " + parameterIndex + " must be a compile time constant for calling " + invoke.callTarget().targetMethod() + ": " + argument; + assert argument instanceof ConstantNode : "parameter " + parameterIndex + " must be a compile time constant for calling " + invoke.callTarget().targetMethod() + " at " + sourceLocation(invoke.node()) + ": " + argument; ConstantNode constantNode = (ConstantNode) argument; Constant constant = constantNode.asConstant(); Object o = constant.boxedValue(); diff -r 776366f3a41a -r 494332f39ee8 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 Thu Jun 21 16:35:23 2012 +0200 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/EscapeAnalysisTest.java Thu Jun 21 16:36:37 2012 +0200 @@ -117,7 +117,7 @@ } private void test(final String snippet, final Constant expectedResult) { - Debug.scope("ScalarTypeSystemTest", new DebugDumpScope(snippet), new Runnable() { + Debug.scope("EscapeAnalysisTest", new DebugDumpScope(snippet), new Runnable() { public void run() { StructuredGraph graph = parse(snippet); for (Invoke n : graph.getInvokes()) { diff -r 776366f3a41a -r 494332f39ee8 src/cpu/x86/vm/c1_Runtime1_x86.cpp --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp Thu Jun 21 16:35:23 2012 +0200 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp Thu Jun 21 16:36:37 2012 +0200 @@ -1956,7 +1956,10 @@ } case graal_verify_oop_id: { + // We use enter & leave so that a better stack trace is produced in the hs_err file + __ enter(); __ verify_oop(r13, "graal verify oop"); + __ leave(); __ ret(0); break; }