# HG changeset patch # User Christian Humer # Date 1376668525 -7200 # Node ID 77bf4af4cc94c3c85114b663bb5d5195f15800f5 # Parent 80de3bbfa8b9d09ebe76af45d37ce8b0d99f77a7# Parent 602a25aade245468eb60c4f52996bf552e530f1b Merge. diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java Fri Aug 16 17:55:25 2013 +0200 @@ -87,7 +87,8 @@ TriState getExceptionSeen(int bci); /** - * Returns information if null was ever seen for the given BCI. + * Returns information if null was ever seen for the given BCI. This information is collected + * for the aastore, checkcast and instanceof bytecodes. * * @return {@link TriState#TRUE} if null was seen for the instruction, {@link TriState#FALSE} if * null was NOT seen, and {@link TriState#UNKNOWN} if this information was not recorded. diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Aug 16 17:55:25 2013 +0200 @@ -363,11 +363,13 @@ protected Result executeActualCheckDeopt(Method method, Set shouldNotDeopt, Object receiver, Object... args) { Map deoptCounts = new EnumMap<>(DeoptimizationReason.class); - ProfilingInfo profile = runtime.lookupJavaMethod(method).getProfilingInfo(); + ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method); + ProfilingInfo profile = javaMethod.getProfilingInfo(); for (DeoptimizationReason reason : shouldNotDeopt) { deoptCounts.put(reason, profile.getDeoptimizationCount(reason)); } Result actual = executeActual(method, receiver, args); + profile = javaMethod.getProfilingInfo(); // profile can change after execution for (DeoptimizationReason reason : shouldNotDeopt) { Assert.assertEquals((int) deoptCounts.get(reason), profile.getDeoptimizationCount(reason)); } diff -r 80de3bbfa8b9 -r 77bf4af4cc94 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 Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri Aug 16 17:55:25 2013 +0200 @@ -722,8 +722,8 @@ value = allocations[commit.getVirtualObjects().indexOf(value)]; } if (!(value.isConstant() && value.asConstant().isDefaultForKind())) { - WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) virtualInstance.field(i)), BarrierType.NONE, - virtualInstance.field(i).getKind() == Kind.Object); + WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) virtualInstance.field(i)), + virtualInstance.field(i).getKind() == Kind.Object ? BarrierType.IMPRECISE : BarrierType.NONE, virtualInstance.field(i).getKind() == Kind.Object); graph.addBeforeFixed(commit, graph.add(write)); } @@ -740,8 +740,8 @@ value = allocations[indexOf]; } if (!(value.isConstant() && value.asConstant().isDefaultForKind())) { - WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph)), BarrierType.NONE, - value.kind() == Kind.Object); + WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph)), + value.kind() == Kind.Object ? BarrierType.PRECISE : BarrierType.NONE, value.kind() == Kind.Object); graph.addBeforeFixed(commit, graph.add(write)); } } diff -r 80de3bbfa8b9 -r 77bf4af4cc94 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 Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Fri Aug 16 17:55:25 2013 +0200 @@ -812,7 +812,7 @@ if (type instanceof ResolvedJavaType) { ResolvedJavaType resolvedType = (ResolvedJavaType) type; InstanceOfNode instanceOfNode = new InstanceOfNode((ResolvedJavaType) type, object, getProfileForTypeCheck(resolvedType)); - frameState.ipush(append(new ConditionalNode(currentGraph.unique(instanceOfNode), ConstantNode.forInt(1, currentGraph), ConstantNode.forInt(0, currentGraph)))); + frameState.ipush(append(new ConditionalNode(currentGraph.unique(instanceOfNode)))); } else { handleUnresolvedInstanceOf(type, object); } @@ -1137,9 +1137,12 @@ if (graphBuilderConfig.eagerResolving()) { returnType = returnType.resolve(targetMethod.getDeclaringClass()); } - if (invokeKind != InvokeKind.Static && invokeKind != InvokeKind.Special) { - JavaTypeProfile profile = profilingInfo.getTypeProfile(bci()); - args[0] = TypeProfileProxyNode.create(args[0], profile); + if (invokeKind != InvokeKind.Static) { + emitExplicitExceptions(args[0], null); + if (invokeKind != InvokeKind.Special) { + JavaTypeProfile profile = profilingInfo.getTypeProfile(bci()); + args[0] = TypeProfileProxyNode.create(args[0], profile); + } } MethodCallTargetNode callTarget = currentGraph.add(new MethodCallTargetNode(invokeKind, targetMethod, args, returnType)); createInvokeNode(callTarget, resultType); diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ConditionalEliminiation01.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ConditionalEliminiation01.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2011, 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.jtt.optimize; + +import java.lang.reflect.*; +import java.util.*; + +import org.junit.*; + +import com.oracle.graal.test.*; +import com.oracle.graal.jtt.*; + +@SuppressWarnings("unused") +public class ConditionalEliminiation01 extends JTTTest { + + private static int x; + private static Object o = new Object(); + + private static class A { + + public A(int y) { + this.y = y; + } + + int y; + } + + @Override + protected void before(Method method) { + super.before(method); + x = 0; + } + + public int test(A a) { + if (o == null) { + return -1; + } + if (a == null) { + return -2; + } + if (o == null) { + return -3; + } + x = 3; + return a.y + x; + } + + @Test + public void run0() throws Throwable { + runTest("test", new A(5)); + } + + @Test + public void run1() throws Throwable { + runTest("test", new Object[]{null}); + } + +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ConditionalEliminiation02.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/optimize/ConditionalEliminiation02.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011, 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.jtt.optimize; + +import java.lang.reflect.*; +import java.util.*; + +import org.junit.*; + +import com.oracle.graal.test.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.jtt.*; + +@SuppressWarnings("unused") +public class ConditionalEliminiation02 extends JTTTest { + + private static Object o = null; + + private static class A { + + public A(int y) { + this.y = y; + } + + int y; + } + + public int test(A a, boolean isNull, boolean isVeryNull) { + if (o == null) { + if (!isNull) { + if (o == null) { + return a.y; + } + } + if (!isVeryNull) { + if (o == null) { + return a.y; + } + } + } + return -1; + } + + @Test + public void run0() throws Throwable { + runTest(EnumSet.of(DeoptimizationReason.NullCheckException), "test", new A(5), false, false); + } + + @Test + public void run1() throws Throwable { + runTest(EnumSet.of(DeoptimizationReason.NullCheckException), "test", new Object[]{null, true, true}); + } + +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 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 Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -42,6 +42,10 @@ return condition; } + public ConditionalNode(LogicNode condition) { + this(condition, ConstantNode.forInt(1, condition.graph()), ConstantNode.forInt(0, condition.graph())); + } + public ConditionalNode(LogicNode condition, ValueNode trueValue, ValueNode falseValue) { super(trueValue.kind(), trueValue, falseValue); assert trueValue.kind() == falseValue.kind(); @@ -104,11 +108,11 @@ } private ConditionalNode(Condition condition, ValueNode x, ValueNode y) { - this(createCompareNode(condition, x, y), ConstantNode.forInt(1, x.graph()), ConstantNode.forInt(0, x.graph())); + this(createCompareNode(condition, x, y)); } private ConditionalNode(ValueNode type, ValueNode object) { - this(type.graph().add(new InstanceOfDynamicNode(type, object)), ConstantNode.forInt(1, type.graph()), ConstantNode.forInt(0, type.graph())); + this(type.graph().add(new InstanceOfDynamicNode(type, object))); } @NodeIntrinsic diff -r 80de3bbfa8b9 -r 77bf4af4cc94 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 Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -32,12 +32,21 @@ */ public class UnsafeCastNode extends PiNode implements Canonicalizable, LIRLowerable { + private final Object customType; + public UnsafeCastNode(ValueNode object, Stamp stamp) { super(object, stamp); + customType = null; } public UnsafeCastNode(ValueNode object, Stamp stamp, GuardingNode anchor) { super(object, stamp, anchor); + customType = null; + } + + public UnsafeCastNode(ValueNode object, Stamp stamp, GuardingNode anchor, Object customType) { + super(object, stamp, anchor); + this.customType = customType; } public UnsafeCastNode(ValueNode object, Stamp stamp, ValueNode anchor) { @@ -48,6 +57,10 @@ this(object, toType.getKind() == Kind.Object ? StampFactory.object(toType, exactType, nonNull || ObjectStamp.isObjectNonNull(object.stamp())) : StampFactory.forKind(toType.getKind())); } + public Object getCustomType() { + return customType; + } + @Override public boolean inferStamp() { if (stamp() == StampFactory.forNodeIntrinsic()) { diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Fri Aug 16 17:55:25 2013 +0200 @@ -33,7 +33,7 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.java.MethodCallTargetNode.*; +import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; @@ -547,6 +547,10 @@ } if (replacement != null) { + if (replacementAnchor instanceof GuardNode) { + ValueAnchorNode anchor = graph.add(new ValueAnchorNode(replacementAnchor)); + graph.addBeforeFixed(ifNode, anchor); + } for (Node n : survivingSuccessor.usages().snapshot()) { if (n instanceof GuardNode || n instanceof ProxyNode) { // Keep wired to the begin node. @@ -555,7 +559,6 @@ // Cannot simplify this IfNode as there is no anchor. return; } - // Rewire to the replacement anchor. n.replaceFirstInput(survivingSuccessor, replacementAnchor); } diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Fri Aug 16 17:55:25 2013 +0200 @@ -100,7 +100,7 @@ compilable.call(null, arguments); } while (compilable.inline()); - StructuredGraph graph = Debug.scope("Truffle", new DebugDumpScope("Truffle: " + compilable), new Callable() { + StructuredGraph graph = Debug.scope("TruffleCompilation", new DebugDumpScope("TruffleCompilation: " + compilable), new Callable() { @Override public StructuredGraph call() { diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Fri Aug 16 17:55:25 2013 +0200 @@ -47,8 +47,9 @@ import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer; import com.oracle.graal.phases.tiers.*; -import com.oracle.graal.truffle.nodes.*; -import com.oracle.graal.truffle.nodes.NewFrameNode.VirtualOnlyInstanceNode; +import com.oracle.graal.truffle.nodes.asserts.*; +import com.oracle.graal.truffle.nodes.frame.*; +import com.oracle.graal.truffle.nodes.frame.NewFrameNode.VirtualOnlyInstanceNode; import com.oracle.graal.truffle.phases.*; import com.oracle.graal.truffle.printer.*; import com.oracle.graal.truffle.printer.method.*; diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/CompilationConstantNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/CompilationConstantNode.java Fri Aug 16 14:00:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.nodes; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; - -public class CompilationConstantNode extends NeverPartOfCompilationNode implements Canonicalizable { - - public CompilationConstantNode(Invoke invoke) { - super(invoke, "The value could not be reduced to a compile time constant."); - assert arguments.size() == 1; - } - - @Override - public ValueNode canonical(CanonicalizerTool tool) { - if (arguments.get(0).isConstant()) { - return arguments.get(0); - } - return this; - } -} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/FrameAccessNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/FrameAccessNode.java Fri Aug 16 14:00:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.nodes; - -import java.lang.reflect.*; -import java.util.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.truffle.*; -import com.oracle.truffle.api.frame.*; - -/** - * Base node class for the intrinsic nodes for read and write access to a Truffle frame. - */ -public abstract class FrameAccessNode extends FixedWithNextNode implements Simplifiable { - - @Input private ValueNode frame; - @Input private ValueNode slot; - protected final ResolvedJavaField field; - protected final Kind slotKind; - - public FrameAccessNode(Stamp stamp, Kind slotKind, ValueNode frame, ValueNode slot, ResolvedJavaField field) { - super(stamp); - this.slotKind = slotKind; - this.frame = frame; - this.slot = slot; - this.field = field; - } - - public ValueNode getFrame() { - return frame; - } - - public ValueNode getSlot() { - return slot; - } - - public Kind getSlotKind() { - return slotKind; - } - - protected int getSlotIndex() { - return getConstantFrameSlot().getIndex(); - } - - protected boolean isConstantFrameSlot() { - return slot.isConstant() && !slot.isNullConstant(); - } - - protected FrameSlot getConstantFrameSlot() { - assert isConstantFrameSlot() : slot; - return (FrameSlot) slot.asConstant().asObject(); - } - - protected final void insertDeoptimization(VirtualizerTool tool) { - LogicNode contradiction = LogicConstantNode.contradiction(graph()); - FixedGuardNode fixedGuard = new FixedGuardNode(contradiction, DeoptimizationReason.UnreachedCode, DeoptimizationAction.InvalidateReprofile); - tool.addNode(fixedGuard); - } - - @Override - public String toString(Verbosity verbosity) { - if (verbosity == Verbosity.Name) { - return super.toString(verbosity) + getSlotKind().name() + (isConstantFrameSlot() ? " " + getConstantFrameSlot() : ""); - } else { - return super.toString(verbosity); - } - } - - protected final ValueNode getSlotOffset(int scale, MetaAccessProvider metaAccessProvider) { - if (isConstantFrameSlot()) { - return ConstantNode.forInt(getSlotIndex() * scale, graph()); - } else { - LoadFieldNode loadFrameSlotIndex = graph().add(new LoadFieldNode(getSlot(), metaAccessProvider.lookupJavaField(getFrameSlotIndexField()))); - graph().addBeforeFixed(this, loadFrameSlotIndex); - return scale == 1 ? loadFrameSlotIndex : IntegerArithmeticNode.mul(loadFrameSlotIndex, ConstantNode.forInt(scale, graph())); - } - } - - private static Field getFrameSlotIndexField() { - try { - return FrameSlotImpl.class.getDeclaredField("index"); - } catch (NoSuchFieldException e) { - throw new RuntimeException(e); - } - } - - protected final boolean isValidAccessKind() { - if (getSlotKind() == Kind.Byte) { - // tag access - return true; - } - - return getSlotKind() == getGraalKind(getConstantFrameSlot().getKind()); - } - - private static Kind getGraalKind(FrameSlotKind kind) { - switch (kind) { - case Object: - return Kind.Object; - case Long: - return Kind.Long; - case Int: - return Kind.Int; - case Double: - return Kind.Double; - case Float: - return Kind.Float; - case Boolean: - return Kind.Boolean; - case Illegal: - default: - return Kind.Illegal; - } - } - - @Override - public final void simplify(SimplifierTool tool) { - if (isConstantFrameSlot()) { - if (!isValidAccessKind()) { - tool.deleteBranch(this.next()); - this.replaceAndDelete(graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.UnreachedCode))); - } else { - tool.assumptions().record(new AssumptionValidAssumption((OptimizedAssumption) getConstantFrameSlot().getFrameDescriptor().getVersion())); - } - } - } - - @Override - public Map getDebugProperties(Map map) { - Map properties = super.getDebugProperties(map); - if (isConstantFrameSlot()) { - properties.put("frameSlot", getConstantFrameSlot().toString()); - } - return properties; - } -} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/FrameGetNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/FrameGetNode.java Fri Aug 16 14:00:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.nodes; - -import sun.misc.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.Node.IterableNodeType; -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.nodes.virtual.*; -import com.oracle.graal.truffle.*; -import com.oracle.truffle.api.frame.*; - -/** - * Intrinsic node for read access to a Truffle frame. - */ -@NodeInfo(nameTemplate = "FrameGet{p#slotKind/s}{p#frameSlot/s}") -public class FrameGetNode extends FrameAccessNode implements IterableNodeType, Virtualizable, Lowerable { - - public FrameGetNode(Kind kind, ValueNode frame, ValueNode slot, ResolvedJavaField field) { - super(StampFactory.forKind(kind), kind, frame, slot, field); - } - - @Override - public void virtualize(VirtualizerTool tool) { - if (!isConstantFrameSlot()) { - return; - } - assert isValidAccessKind(); - State virtualFrame = tool.getObjectState(getFrame()); - if (virtualFrame == null || virtualFrame.getState() != EscapeState.Virtual) { - return; - } - assert virtualFrame.getVirtualObject().type() == NewFrameNode.FRAME_TYPE : virtualFrame; - VirtualInstanceNode virtualFrameObject = (VirtualInstanceNode) virtualFrame.getVirtualObject(); - int arrayFieldIndex = virtualFrameObject.fieldIndex(field); - State virtualArray = tool.getObjectState(virtualFrame.getEntry(arrayFieldIndex)); - assert virtualArray != null; - ValueNode result = virtualArray.getEntry(getSlotIndex()); - State virtualResult = tool.getObjectState(result); - if (virtualResult != null) { - tool.replaceWithVirtual(virtualResult.getVirtualObject()); - } else { - tool.replaceWithValue(result); - } - } - - @Override - public void lower(LoweringTool tool, LoweringType loweringType) { - assert !(getFrame() instanceof NewFrameNode); - StructuredGraph structuredGraph = graph(); - - LoadFieldNode loadFieldNode = graph().add(new LoadFieldNode(getFrame(), field)); - structuredGraph.addBeforeFixed(this, loadFieldNode); - FixedWithNextNode loadNode; - if (!getSlotKind().isPrimitive()) { - ValueNode slotIndex = getSlotOffset(1, tool.getRuntime()); - loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, Kind.Object)); - } else if (getSlotKind() == Kind.Byte) { - ValueNode slotIndex = getSlotOffset(1, tool.getRuntime()); - loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, Kind.Byte)); - } else { - ValueNode slotOffset = getSlotOffset(Unsafe.ARRAY_LONG_INDEX_SCALE, tool.getRuntime()); - loadNode = graph().add(new UnsafeLoadNode(loadFieldNode, Unsafe.ARRAY_LONG_BASE_OFFSET, slotOffset, getSlotKind())); - } - structuredGraph.replaceFixedWithFixed(this, loadNode); - } - - @NodeIntrinsic - public static native T get(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, @ConstantNodeParameter ResolvedJavaField field); -} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/FrameSetNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/FrameSetNode.java Fri Aug 16 14:00:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.nodes; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.Node.IterableNodeType; -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.nodes.virtual.*; -import com.oracle.graal.truffle.*; -import com.oracle.truffle.api.frame.*; - -/** - * Intrinsic node for write access to a Truffle frame. - */ -@NodeInfo(nameTemplate = "FrameSet{p#slotKind/s}{p#frameSlot/s}") -public class FrameSetNode extends FrameAccessNode implements IterableNodeType, Virtualizable, Lowerable { - - @Input private ValueNode value; - - public FrameSetNode(Kind kind, ValueNode frame, ValueNode frameSlot, ValueNode value, ResolvedJavaField field) { - super(StampFactory.forVoid(), kind, frame, frameSlot, field); - this.value = value; - } - - public ValueNode getValue() { - return value; - } - - @Override - public void virtualize(VirtualizerTool tool) { - if (!isConstantFrameSlot()) { - return; - } - assert isValidAccessKind(); - State virtualFrame = tool.getObjectState(getFrame()); - if (virtualFrame == null || virtualFrame.getState() != EscapeState.Virtual) { - return; - } - assert virtualFrame.getVirtualObject().type() == NewFrameNode.FRAME_TYPE : virtualFrame; - VirtualInstanceNode virtualFrameObject = (VirtualInstanceNode) virtualFrame.getVirtualObject(); - int arrayFieldIndex = virtualFrameObject.fieldIndex(field); - State virtualArray = tool.getObjectState(virtualFrame.getEntry(arrayFieldIndex)); - assert virtualArray != null; - ValueNode storedValue = value; - tool.setVirtualEntry(virtualArray, getSlotIndex(), storedValue); - tool.delete(); - } - - @Override - public void lower(LoweringTool tool, LoweringType loweringType) { - assert !(getFrame() instanceof NewFrameNode); - StructuredGraph structuredGraph = graph(); - - LoadFieldNode loadFieldNode = graph().add(new LoadFieldNode(getFrame(), field)); - structuredGraph.addBeforeFixed(this, loadFieldNode); - FixedWithNextNode storeNode; - ValueNode slotIndex = getSlotOffset(1, tool.getRuntime()); - if (!getSlotKind().isPrimitive()) { - storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, Kind.Object, value)); - } else if (getSlotKind() == Kind.Byte) { - storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, Kind.Byte, value)); - } else { - storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, Kind.Long, value)); - } - structuredGraph.replaceFixedWithFixed(this, storeNode); - } - - @NodeIntrinsic - public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, Object value, @ConstantNodeParameter ResolvedJavaField field); - - @NodeIntrinsic - public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, byte value, @ConstantNodeParameter ResolvedJavaField field); - - @NodeIntrinsic - public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, boolean value, @ConstantNodeParameter ResolvedJavaField field); - - @NodeIntrinsic - public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, int value, @ConstantNodeParameter ResolvedJavaField field); - - @NodeIntrinsic - public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, long value, @ConstantNodeParameter ResolvedJavaField field); - - @NodeIntrinsic - public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, double value, @ConstantNodeParameter ResolvedJavaField field); - - @NodeIntrinsic - public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, float value, @ConstantNodeParameter ResolvedJavaField field); -} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerAddExactNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerAddExactNode.java Fri Aug 16 14:00:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.nodes; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.truffle.api.*; - -/** - * Node representing an exact integer addition that will throw an {@link ArithmeticException} in - * case the addition would overflow the 32 bit range. - */ -public class IntegerAddExactNode extends IntegerAddNode implements Canonicalizable, IntegerExactArithmeticNode { - - public IntegerAddExactNode(ValueNode x, ValueNode y) { - super(x.kind(), x, y); - assert x.kind() == y.kind() && (x.kind() == Kind.Int || x.kind() == Kind.Long); - } - - @Override - public boolean inferStamp() { - // TODO Should probably use a specialised version which understands that it can't overflow - return updateStamp(StampTool.add(x().stamp(), y().stamp())); - } - - @Override - public ValueNode canonical(CanonicalizerTool tool) { - if (x().isConstant() && !y().isConstant()) { - return graph().unique(new IntegerAddExactNode(y(), x())); - } - if (x().isConstant()) { - try { - if (kind() == Kind.Int) { - return ConstantNode.forInt(ExactMath.addExact(x().asConstant().asInt(), y().asConstant().asInt()), graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(ExactMath.addExact(x().asConstant().asLong(), y().asConstant().asLong()), graph()); - } - } catch (ArithmeticException ex) { - // The operation will result in an overflow exception, so do not canonicalize. - } - } else if (y().isConstant()) { - long c = y().asConstant().asLong(); - if (c == 0) { - return x(); - } - } - return this; - } - - @Override - public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) { - return graph().add(new IntegerAddExactSplitNode(stamp(), x(), y(), next, deopt)); - } - - @Override - public void lower(LoweringTool tool, LoweringType loweringType) { - IntegerExactArithmeticSplitNode.lower(tool, this); - } - - @NodeIntrinsic - public static native int addExact(int a, int b); - - @NodeIntrinsic - public static native long addExact(long a, long b); -} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerAddExactSplitNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerAddExactSplitNode.java Fri Aug 16 14:00:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.nodes; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -public class IntegerAddExactSplitNode extends IntegerExactArithmeticSplitNode { - - public IntegerAddExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) { - super(stamp, x, y, next, overflowSuccessor); - } - - @Override - protected Value generateArithmetic(LIRGeneratorTool gen) { - return gen.emitAdd(gen.operand(getX()), gen.operand(getY())); - } -} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerExactArithmeticNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerExactArithmeticNode.java Fri Aug 16 14:00:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.nodes; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; - -interface IntegerExactArithmeticNode extends Lowerable { - - IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt); -} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerExactArithmeticSplitNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerExactArithmeticSplitNode.java Fri Aug 16 14:00:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.nodes; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.compiler.target.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -public abstract class IntegerExactArithmeticSplitNode extends ControlSplitNode implements LIRGenLowerable { - - @Successor private AbstractBeginNode overflowSuccessor; - @Successor private AbstractBeginNode next; - @Input private ValueNode x; - @Input private ValueNode y; - - public IntegerExactArithmeticSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) { - super(stamp); - this.x = x; - this.y = y; - this.overflowSuccessor = overflowSuccessor; - this.next = next; - } - - @Override - public double probability(AbstractBeginNode successor) { - return successor == next ? 1 : 0; - } - - @Override - public void setProbability(AbstractBeginNode successor, double value) { - assert probability(successor) == value; - } - - public AbstractBeginNode getNext() { - return next; - } - - public AbstractBeginNode getOverflowSuccessor() { - return overflowSuccessor; - } - - public ValueNode getX() { - return x; - } - - public ValueNode getY() { - return y; - } - - @Override - public void generate(LIRGenerator generator) { - generator.setResult(this, generateArithmetic(generator)); - generator.emitOverflowCheckBranch(generator.getLIRBlock(getNext()), generator.getLIRBlock(getOverflowSuccessor())); - } - - protected abstract Value generateArithmetic(LIRGeneratorTool generator); - - static void lower(LoweringTool tool, IntegerExactArithmeticNode node) { - FloatingNode floatingNode = (FloatingNode) node; - FixedWithNextNode previous = tool.lastFixedNode(); - FixedNode next = previous.next(); - previous.setNext(null); - DeoptimizeNode deopt = floatingNode.graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ArithmeticException)); - BeginNode normalBegin = floatingNode.graph().add(new BeginNode()); - normalBegin.setNext(next); - IntegerExactArithmeticSplitNode split = node.createSplit(normalBegin, BeginNode.begin(deopt)); - previous.setNext(split); - floatingNode.replaceAndDelete(split); - } -} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerMulExactNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerMulExactNode.java Fri Aug 16 14:00:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.nodes; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.truffle.api.*; - -/** - * Node representing an exact integer multiplication that will throw an {@link ArithmeticException} - * in case the addition would overflow the 32 bit range. - */ -public class IntegerMulExactNode extends IntegerMulNode implements Canonicalizable, IntegerExactArithmeticNode { - - public IntegerMulExactNode(ValueNode x, ValueNode y) { - super(x.kind(), x, y); - assert x.kind() == y.kind() && (x.kind() == Kind.Int || x.kind() == Kind.Long); - } - - @Override - public ValueNode canonical(CanonicalizerTool tool) { - if (x().isConstant() && !y().isConstant()) { - return graph().unique(new IntegerMulExactNode(y(), x())); - } - if (x().isConstant()) { - try { - if (kind() == Kind.Int) { - return ConstantNode.forInt(ExactMath.multiplyExact(x().asConstant().asInt(), y().asConstant().asInt()), graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(ExactMath.multiplyExact(x().asConstant().asLong(), y().asConstant().asLong()), graph()); - } - } catch (ArithmeticException ex) { - // The operation will result in an overflow exception, so do not canonicalize. - } - } else if (y().isConstant()) { - long c = y().asConstant().asLong(); - if (c == 1) { - return x(); - } - if (c == 0) { - return ConstantNode.defaultForKind(kind(), graph()); - } - } - return this; - } - - @Override - public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) { - return graph().add(new IntegerMulExactSplitNode(stamp(), x(), y(), next, deopt)); - } - - @Override - public void lower(LoweringTool tool, LoweringType loweringType) { - IntegerExactArithmeticSplitNode.lower(tool, this); - } - - @NodeIntrinsic - public static native int multiplyExact(int a, int b); - - @NodeIntrinsic - public static native long multiplyExact(long a, long b); -} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerMulExactSplitNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerMulExactSplitNode.java Fri Aug 16 14:00:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.nodes; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -public class IntegerMulExactSplitNode extends IntegerExactArithmeticSplitNode { - - public IntegerMulExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) { - super(stamp, x, y, next, overflowSuccessor); - } - - @Override - protected Value generateArithmetic(LIRGeneratorTool gen) { - return gen.emitMul(gen.operand(getX()), gen.operand(getY())); - } -} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerSubExactNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerSubExactNode.java Fri Aug 16 14:00:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.nodes; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.truffle.api.*; - -/** - * Node representing an exact integer substraction that will throw an {@link ArithmeticException} in - * case the addition would overflow the 32 bit range. - */ -public class IntegerSubExactNode extends IntegerSubNode implements Canonicalizable, IntegerExactArithmeticNode { - - public IntegerSubExactNode(ValueNode x, ValueNode y) { - super(x.kind(), x, y); - assert x.kind() == y.kind() && (x.kind() == Kind.Int || x.kind() == Kind.Long); - } - - @Override - public boolean inferStamp() { - // TODO Should probably use a specialised version which understands that it can't overflow - return updateStamp(StampTool.sub(x().stamp(), y().stamp())); - } - - @Override - public ValueNode canonical(CanonicalizerTool tool) { - if (x() == y()) { - return ConstantNode.forIntegerKind(kind(), 0, graph()); - } - if (x().isConstant() && y().isConstant()) { - try { - if (kind() == Kind.Int) { - return ConstantNode.forInt(ExactMath.subtractExact(x().asConstant().asInt(), y().asConstant().asInt()), graph()); - } else { - assert kind() == Kind.Long; - return ConstantNode.forLong(ExactMath.subtractExact(x().asConstant().asLong(), y().asConstant().asLong()), graph()); - } - } catch (ArithmeticException ex) { - // The operation will result in an overflow exception, so do not canonicalize. - } - } else if (y().isConstant()) { - long c = y().asConstant().asLong(); - if (c == 0) { - return x(); - } - } - return this; - } - - @Override - public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) { - return graph().add(new IntegerSubExactSplitNode(stamp(), x(), y(), next, deopt)); - } - - @Override - public void lower(LoweringTool tool, LoweringType loweringType) { - IntegerExactArithmeticSplitNode.lower(tool, this); - } - - @NodeIntrinsic - public static native int subtractExact(int a, int b); - - @NodeIntrinsic - public static native long subtractExact(long a, long b); -} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerSubExactSplitNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/IntegerSubExactSplitNode.java Fri Aug 16 14:00:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.nodes; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -public class IntegerSubExactSplitNode extends IntegerExactArithmeticSplitNode { - - public IntegerSubExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) { - super(stamp, x, y, next, overflowSuccessor); - } - - @Override - protected Value generateArithmetic(LIRGeneratorTool gen) { - return gen.emitSub(gen.operand(getX()), gen.operand(getY())); - } -} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/MaterializeFrameNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/MaterializeFrameNode.java Fri Aug 16 14:00:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.nodes; - -import com.oracle.graal.graph.Node.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.truffle.*; - -/** - * Intrinsic node for materializing a Truffle frame. - */ -@NodeInfo(nameTemplate = "MaterializeFrame{p#frame/s}") -public class MaterializeFrameNode extends FixedWithNextNode implements IterableNodeType { - - @Input private ValueNode frame; - - public MaterializeFrameNode(ValueNode frame) { - super(frame.stamp()); - this.frame = frame; - } - - public ValueNode getFrame() { - return frame; - } - - @NodeIntrinsic - public static native T materialize(FrameWithoutBoxing frame); -} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/NeverInlineMacroNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/NeverInlineMacroNode.java Fri Aug 16 14:00:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.nodes; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.replacements.nodes.*; - -public class NeverInlineMacroNode extends MacroNode implements com.oracle.graal.graph.Node.IterableNodeType { - - public NeverInlineMacroNode(Invoke invoke) { - super(invoke); - } - - @Override - public void lower(LoweringTool tool, LoweringType loweringType) { - InvokeNode invoke = createInvoke(); - graph().replaceFixedWithFixed(this, invoke); - invoke.setUseForInlining(false); - } -} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/NeverPartOfCompilationNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/NeverPartOfCompilationNode.java Fri Aug 16 14:00:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.nodes; - -import com.oracle.graal.nodes.*; -import com.oracle.graal.replacements.nodes.*; - -public class NeverPartOfCompilationNode extends MacroNode implements com.oracle.graal.graph.Node.IterableNodeType { - - private final String message; - - public NeverPartOfCompilationNode(Invoke invoke) { - this(invoke, "This code path should never be part of a compilation."); - } - - public NeverPartOfCompilationNode(Invoke invoke, String message) { - super(invoke); - this.message = message; - } - - public final String getMessage() { - return message; - } -} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/NewFrameNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/NewFrameNode.java Fri Aug 16 14:00:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,218 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.nodes; - -import java.util.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.Node.IterableNodeType; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.java.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.nodes.util.*; -import com.oracle.graal.nodes.virtual.*; -import com.oracle.graal.truffle.*; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; - -/** - * Intrinsic node representing the call for creating a frame in the {@link OptimizedCallTarget} - * class. - */ -public class NewFrameNode extends FixedWithNextNode implements IterableNodeType, VirtualizableAllocation, Canonicalizable { - - static final ResolvedJavaType FRAME_TYPE = Graal.getRequiredCapability(MetaAccessProvider.class).lookupJavaType(FrameWithoutBoxing.class); - - @Input private ValueNode descriptor; - @Input private ValueNode caller; - @Input private ValueNode arguments; - - public NewFrameNode(Stamp stamp, ValueNode descriptor, ValueNode caller, ValueNode arguments) { - super(stamp); - this.descriptor = descriptor; - this.caller = caller; - this.arguments = arguments; - } - - public NewFrameNode(ValueNode descriptor, ValueNode caller, ValueNode arguments) { - this(StampFactory.declaredNonNull(FRAME_TYPE), descriptor, caller, arguments); - } - - public ValueNode getDescriptor() { - return descriptor; - } - - public ValueNode getCaller() { - return caller; - } - - public ValueNode getArguments() { - return arguments; - } - - private FrameDescriptor getConstantFrameDescriptor() { - assert descriptor.isConstant() && !descriptor.isNullConstant(); - return (FrameDescriptor) descriptor.asConstant().asObject(); - } - - private int getFrameSize() { - return getConstantFrameDescriptor().getSize(); - } - - private static ResolvedJavaField findField(ResolvedJavaField[] fields, String fieldName) { - for (ResolvedJavaField field : fields) { - if (field.getName().equals(fieldName)) { - return field; - } - } - throw new RuntimeException("Frame field not found: " + fieldName); - } - - public static class VirtualOnlyInstanceNode extends VirtualInstanceNode implements Node.IterableNodeType { - - private boolean allowMaterialization; - - public VirtualOnlyInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields) { - super(type, fields); - } - - @Override - public ValueNode getMaterializedRepresentation(FixedNode fixed, ValueNode[] entries, int[] locks) { - if (allowMaterialization) { - return super.getMaterializedRepresentation(fixed, entries, locks); - } - return getMaterializedRepresentationHelper(this, fixed); - } - - public void setAllowMaterialization(boolean b) { - this.allowMaterialization = b; - } - } - - public static ValueNode getMaterializedRepresentationHelper(VirtualObjectNode virtualNode, FixedNode fixed) { - if (fixed instanceof MaterializeFrameNode || fixed instanceof AbstractEndNode) { - // We need to conservatively assume that a materialization of a virtual frame can also - // happen at a merge point. - return new AllocatedObjectNode(virtualNode); - } - String escapeReason; - if (fixed instanceof StoreFieldNode) { - escapeReason = "Must not store virtual frame object into a field."; - } else if (fixed instanceof Invoke) { - escapeReason = "Must not pass virtual frame object into an invoke that cannot be inlined."; - } else { - escapeReason = "Must not let virtual frame object escape at node " + fixed + "."; - } - - Throwable exception = new GraalInternalError(escapeReason + - " Insert a call to VirtualFrame.materialize() to convert the instance to a materialized frame object (source position of following stack trace is approximate)"); - throw GraphUtil.approxSourceException(fixed, exception); - } - - @Override - public void virtualize(VirtualizerTool tool) { - int frameSize = getFrameSize(); - - ResolvedJavaType frameType = stamp().javaType(tool.getMetaAccessProvider()); - ResolvedJavaField[] frameFields = frameType.getInstanceFields(true); - - ResolvedJavaField descriptorField = findField(frameFields, "descriptor"); - ResolvedJavaField callerField = findField(frameFields, "caller"); - ResolvedJavaField argumentsField = findField(frameFields, "arguments"); - ResolvedJavaField localsField = findField(frameFields, "locals"); - ResolvedJavaField primitiveLocalsField = findField(frameFields, "primitiveLocals"); - ResolvedJavaField tagsField = findField(frameFields, "tags"); - - VirtualObjectNode virtualFrame = new VirtualOnlyInstanceNode(frameType, frameFields); - VirtualObjectNode virtualFrameObjectArray = new VirtualArrayNode((ResolvedJavaType) localsField.getType().getComponentType(), frameSize); - VirtualObjectNode virtualFramePrimitiveArray = new VirtualArrayNode((ResolvedJavaType) primitiveLocalsField.getType().getComponentType(), frameSize); - VirtualObjectNode virtualFrameTagArray = new VirtualArrayNode((ResolvedJavaType) tagsField.getType().getComponentType(), frameSize); - - ValueNode[] objectArrayEntryState = new ValueNode[frameSize]; - ValueNode[] primitiveArrayEntryState = new ValueNode[frameSize]; - ValueNode[] tagArrayEntryState = new ValueNode[frameSize]; - - if (frameSize > 0) { - FrameDescriptor frameDescriptor = getConstantFrameDescriptor(); - ConstantNode objectDefault = ConstantNode.forObject(frameDescriptor.getTypeConversion().getDefaultValue(), tool.getMetaAccessProvider(), graph()); - ConstantNode tagDefault = ConstantNode.forByte((byte) 0, graph()); - for (int i = 0; i < frameSize; i++) { - objectArrayEntryState[i] = objectDefault; - primitiveArrayEntryState[i] = initialValue(frameDescriptor.getSlots().get(i).getKind()); - tagArrayEntryState[i] = tagDefault; - } - tool.getAssumptions().record(new AssumptionValidAssumption((OptimizedAssumption) frameDescriptor.getVersion())); - } - - tool.createVirtualObject(virtualFrameObjectArray, objectArrayEntryState, null); - tool.createVirtualObject(virtualFramePrimitiveArray, primitiveArrayEntryState, null); - tool.createVirtualObject(virtualFrameTagArray, tagArrayEntryState, null); - - assert frameFields.length == 6; - ValueNode[] frameEntryState = new ValueNode[frameFields.length]; - List frameFieldList = Arrays.asList(frameFields); - frameEntryState[frameFieldList.indexOf(descriptorField)] = getDescriptor(); - frameEntryState[frameFieldList.indexOf(callerField)] = getCaller(); - frameEntryState[frameFieldList.indexOf(argumentsField)] = getArguments(); - frameEntryState[frameFieldList.indexOf(localsField)] = virtualFrameObjectArray; - frameEntryState[frameFieldList.indexOf(primitiveLocalsField)] = virtualFramePrimitiveArray; - frameEntryState[frameFieldList.indexOf(tagsField)] = virtualFrameTagArray; - tool.createVirtualObject(virtualFrame, frameEntryState, null); - tool.replaceWithVirtual(virtualFrame); - } - - private ValueNode initialValue(FrameSlotKind kind) { - Kind graalKind = Kind.Long; - switch (kind) { - case Int: - graalKind = Kind.Int; - break; - case Double: - graalKind = Kind.Double; - break; - case Float: - graalKind = Kind.Float; - break; - case Boolean: - graalKind = Kind.Boolean; - break; - } - - return ConstantNode.defaultForKind(graalKind, graph()); - } - - @Override - public ValueNode canonical(CanonicalizerTool tool) { - if (usages().isEmpty()) { - return null; - } else { - return this; - } - } - - @NodeIntrinsic - public static native FrameWithoutBoxing allocate(FrameDescriptor descriptor, PackedFrame caller, Arguments args); -} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/UnsafeCastMacroNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/UnsafeCastMacroNode.java Fri Aug 16 14:00:17 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.truffle.nodes; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -public class UnsafeCastMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { - - public UnsafeCastMacroNode(Invoke invoke) { - super(invoke, "The class of the unsafe cast could not be reduced to a compile time constant."); - assert arguments.size() == 2; - } - - @Override - public ValueNode canonical(CanonicalizerTool tool) { - if (arguments.get(1).isConstant()) { - Class c = (Class) arguments.get(1).asConstant().asObject(); - ResolvedJavaType lookupJavaType = tool.runtime().lookupJavaType(c); - Stamp s = StampFactory.declaredNonNull(lookupJavaType); - ValueAnchorNode valueAnchorNode = graph().add(new ValueAnchorNode()); - UnsafeCastNode unsafeCast = graph().unique(new UnsafeCastNode(arguments.get(0), s, (GuardingNode) valueAnchorNode)); - this.replaceAtUsages(unsafeCast); - return valueAnchorNode; - } - return this; - } -} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.arithmetic; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.truffle.api.*; + +/** + * Node representing an exact integer addition that will throw an {@link ArithmeticException} in + * case the addition would overflow the 32 bit range. + */ +public class IntegerAddExactNode extends IntegerAddNode implements Canonicalizable, IntegerExactArithmeticNode { + + public IntegerAddExactNode(ValueNode x, ValueNode y) { + super(x.kind(), x, y); + assert x.kind() == y.kind() && (x.kind() == Kind.Int || x.kind() == Kind.Long); + } + + @Override + public boolean inferStamp() { + // TODO Should probably use a specialised version which understands that it can't overflow + return updateStamp(StampTool.add(x().stamp(), y().stamp())); + } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + if (x().isConstant() && !y().isConstant()) { + return graph().unique(new IntegerAddExactNode(y(), x())); + } + if (x().isConstant()) { + try { + if (kind() == Kind.Int) { + return ConstantNode.forInt(ExactMath.addExact(x().asConstant().asInt(), y().asConstant().asInt()), graph()); + } else { + assert kind() == Kind.Long; + return ConstantNode.forLong(ExactMath.addExact(x().asConstant().asLong(), y().asConstant().asLong()), graph()); + } + } catch (ArithmeticException ex) { + // The operation will result in an overflow exception, so do not canonicalize. + } + } else if (y().isConstant()) { + long c = y().asConstant().asLong(); + if (c == 0) { + return x(); + } + } + return this; + } + + @Override + public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) { + return graph().add(new IntegerAddExactSplitNode(stamp(), x(), y(), next, deopt)); + } + + @Override + public void lower(LoweringTool tool, LoweringType loweringType) { + IntegerExactArithmeticSplitNode.lower(tool, this); + } + + @NodeIntrinsic + public static native int addExact(int a, int b); + + @NodeIntrinsic + public static native long addExact(long a, long b); +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactSplitNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactSplitNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.arithmetic; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +public class IntegerAddExactSplitNode extends IntegerExactArithmeticSplitNode { + + public IntegerAddExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) { + super(stamp, x, y, next, overflowSuccessor); + } + + @Override + protected Value generateArithmetic(LIRGeneratorTool gen) { + return gen.emitAdd(gen.operand(getX()), gen.operand(getY())); + } +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.arithmetic; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; + +interface IntegerExactArithmeticNode extends Lowerable { + + IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt); +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.arithmetic; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.spi.Lowerable.*; +import com.oracle.graal.nodes.type.*; + +public abstract class IntegerExactArithmeticSplitNode extends ControlSplitNode implements LIRGenLowerable { + + @Successor private AbstractBeginNode overflowSuccessor; + @Successor private AbstractBeginNode next; + @Input private ValueNode x; + @Input private ValueNode y; + + public IntegerExactArithmeticSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) { + super(stamp); + this.x = x; + this.y = y; + this.overflowSuccessor = overflowSuccessor; + this.next = next; + } + + @Override + public double probability(AbstractBeginNode successor) { + return successor == next ? 1 : 0; + } + + @Override + public void setProbability(AbstractBeginNode successor, double value) { + assert probability(successor) == value; + } + + public AbstractBeginNode getNext() { + return next; + } + + public AbstractBeginNode getOverflowSuccessor() { + return overflowSuccessor; + } + + public ValueNode getX() { + return x; + } + + public ValueNode getY() { + return y; + } + + @Override + public void generate(LIRGenerator generator) { + generator.setResult(this, generateArithmetic(generator)); + generator.emitOverflowCheckBranch(generator.getLIRBlock(getNext()), generator.getLIRBlock(getOverflowSuccessor())); + } + + protected abstract Value generateArithmetic(LIRGeneratorTool generator); + + static void lower(LoweringTool tool, IntegerExactArithmeticNode node) { + if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { + FloatingNode floatingNode = (FloatingNode) node; + FixedWithNextNode previous = tool.lastFixedNode(); + FixedNode next = previous.next(); + previous.setNext(null); + DeoptimizeNode deopt = floatingNode.graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.ArithmeticException)); + BeginNode normalBegin = floatingNode.graph().add(new BeginNode()); + normalBegin.setNext(next); + IntegerExactArithmeticSplitNode split = node.createSplit(normalBegin, BeginNode.begin(deopt)); + previous.setNext(split); + floatingNode.replaceAndDelete(split); + } + } +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.arithmetic; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.truffle.api.*; + +/** + * Node representing an exact integer multiplication that will throw an {@link ArithmeticException} + * in case the addition would overflow the 32 bit range. + */ +public class IntegerMulExactNode extends IntegerMulNode implements Canonicalizable, IntegerExactArithmeticNode { + + public IntegerMulExactNode(ValueNode x, ValueNode y) { + super(x.kind(), x, y); + assert x.kind() == y.kind() && (x.kind() == Kind.Int || x.kind() == Kind.Long); + } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + if (x().isConstant() && !y().isConstant()) { + return graph().unique(new IntegerMulExactNode(y(), x())); + } + if (x().isConstant()) { + try { + if (kind() == Kind.Int) { + return ConstantNode.forInt(ExactMath.multiplyExact(x().asConstant().asInt(), y().asConstant().asInt()), graph()); + } else { + assert kind() == Kind.Long; + return ConstantNode.forLong(ExactMath.multiplyExact(x().asConstant().asLong(), y().asConstant().asLong()), graph()); + } + } catch (ArithmeticException ex) { + // The operation will result in an overflow exception, so do not canonicalize. + } + } else if (y().isConstant()) { + long c = y().asConstant().asLong(); + if (c == 1) { + return x(); + } + if (c == 0) { + return ConstantNode.defaultForKind(kind(), graph()); + } + } + return this; + } + + @Override + public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) { + return graph().add(new IntegerMulExactSplitNode(stamp(), x(), y(), next, deopt)); + } + + @Override + public void lower(LoweringTool tool, LoweringType loweringType) { + IntegerExactArithmeticSplitNode.lower(tool, this); + } + + @NodeIntrinsic + public static native int multiplyExact(int a, int b); + + @NodeIntrinsic + public static native long multiplyExact(long a, long b); +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactSplitNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactSplitNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.arithmetic; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +public class IntegerMulExactSplitNode extends IntegerExactArithmeticSplitNode { + + public IntegerMulExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) { + super(stamp, x, y, next, overflowSuccessor); + } + + @Override + protected Value generateArithmetic(LIRGeneratorTool gen) { + return gen.emitMul(gen.operand(getX()), gen.operand(getY())); + } +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.arithmetic; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.truffle.api.*; + +/** + * Node representing an exact integer substraction that will throw an {@link ArithmeticException} in + * case the addition would overflow the 32 bit range. + */ +public class IntegerSubExactNode extends IntegerSubNode implements Canonicalizable, IntegerExactArithmeticNode { + + public IntegerSubExactNode(ValueNode x, ValueNode y) { + super(x.kind(), x, y); + assert x.kind() == y.kind() && (x.kind() == Kind.Int || x.kind() == Kind.Long); + } + + @Override + public boolean inferStamp() { + // TODO Should probably use a specialised version which understands that it can't overflow + return updateStamp(StampTool.sub(x().stamp(), y().stamp())); + } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + if (x() == y()) { + return ConstantNode.forIntegerKind(kind(), 0, graph()); + } + if (x().isConstant() && y().isConstant()) { + try { + if (kind() == Kind.Int) { + return ConstantNode.forInt(ExactMath.subtractExact(x().asConstant().asInt(), y().asConstant().asInt()), graph()); + } else { + assert kind() == Kind.Long; + return ConstantNode.forLong(ExactMath.subtractExact(x().asConstant().asLong(), y().asConstant().asLong()), graph()); + } + } catch (ArithmeticException ex) { + // The operation will result in an overflow exception, so do not canonicalize. + } + } else if (y().isConstant()) { + long c = y().asConstant().asLong(); + if (c == 0) { + return x(); + } + } + return this; + } + + @Override + public IntegerExactArithmeticSplitNode createSplit(AbstractBeginNode next, AbstractBeginNode deopt) { + return graph().add(new IntegerSubExactSplitNode(stamp(), x(), y(), next, deopt)); + } + + @Override + public void lower(LoweringTool tool, LoweringType loweringType) { + IntegerExactArithmeticSplitNode.lower(tool, this); + } + + @NodeIntrinsic + public static native int subtractExact(int a, int b); + + @NodeIntrinsic + public static native long subtractExact(long a, long b); +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactSplitNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactSplitNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.arithmetic; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +public class IntegerSubExactSplitNode extends IntegerExactArithmeticSplitNode { + + public IntegerSubExactSplitNode(Stamp stamp, ValueNode x, ValueNode y, AbstractBeginNode next, AbstractBeginNode overflowSuccessor) { + super(stamp, x, y, next, overflowSuccessor); + } + + @Override + protected Value generateArithmetic(LIRGeneratorTool gen) { + return gen.emitSub(gen.operand(getX()), gen.operand(getY())); + } +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/CompilationConstantNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/CompilationConstantNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.asserts; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; + +public class CompilationConstantNode extends NeverPartOfCompilationNode implements Canonicalizable { + + public CompilationConstantNode(Invoke invoke) { + super(invoke, "The value could not be reduced to a compile time constant."); + assert arguments.size() == 1; + } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + if (arguments.get(0).isConstant()) { + return arguments.get(0); + } + return this; + } +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverInlineMacroNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.asserts; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.replacements.nodes.*; + +public class NeverInlineMacroNode extends MacroNode implements com.oracle.graal.graph.Node.IterableNodeType { + + public NeverInlineMacroNode(Invoke invoke) { + super(invoke); + } + + @Override + public void lower(LoweringTool tool, LoweringType loweringType) { + InvokeNode invoke = createInvoke(); + graph().replaceFixedWithFixed(this, invoke); + invoke.setUseForInlining(false); + } +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/NeverPartOfCompilationNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.asserts; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.replacements.nodes.*; + +public class NeverPartOfCompilationNode extends MacroNode implements com.oracle.graal.graph.Node.IterableNodeType { + + private final String message; + + public NeverPartOfCompilationNode(Invoke invoke) { + this(invoke, "This code path should never be part of a compilation."); + } + + public NeverPartOfCompilationNode(Invoke invoke, String message) { + super(invoke); + this.message = message; + } + + public final String getMessage() { + return message; + } +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.frame; + +import java.lang.reflect.*; +import java.util.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.truffle.*; +import com.oracle.graal.truffle.nodes.*; +import com.oracle.truffle.api.frame.*; + +/** + * Base node class for the intrinsic nodes for read and write access to a Truffle frame. + */ +public abstract class FrameAccessNode extends FixedWithNextNode implements Simplifiable { + + @Input private ValueNode frame; + @Input private ValueNode slot; + protected final ResolvedJavaField field; + protected final Kind slotKind; + + public FrameAccessNode(Stamp stamp, Kind slotKind, ValueNode frame, ValueNode slot, ResolvedJavaField field) { + super(stamp); + this.slotKind = slotKind; + this.frame = frame; + this.slot = slot; + this.field = field; + } + + public ValueNode getFrame() { + return frame; + } + + public ValueNode getSlot() { + return slot; + } + + public Kind getSlotKind() { + return slotKind; + } + + protected int getSlotIndex() { + return getConstantFrameSlot().getIndex(); + } + + protected boolean isConstantFrameSlot() { + return slot.isConstant() && !slot.isNullConstant(); + } + + protected FrameSlot getConstantFrameSlot() { + assert isConstantFrameSlot() : slot; + return (FrameSlot) slot.asConstant().asObject(); + } + + protected final void insertDeoptimization(VirtualizerTool tool) { + LogicNode contradiction = LogicConstantNode.contradiction(graph()); + FixedGuardNode fixedGuard = new FixedGuardNode(contradiction, DeoptimizationReason.UnreachedCode, DeoptimizationAction.InvalidateReprofile); + tool.addNode(fixedGuard); + } + + @Override + public String toString(Verbosity verbosity) { + if (verbosity == Verbosity.Name) { + return super.toString(verbosity) + getSlotKind().name() + (isConstantFrameSlot() ? " " + getConstantFrameSlot() : ""); + } else { + return super.toString(verbosity); + } + } + + protected final ValueNode getSlotOffset(int scale, MetaAccessProvider metaAccessProvider) { + if (isConstantFrameSlot()) { + return ConstantNode.forInt(getSlotIndex() * scale, graph()); + } else { + LoadFieldNode loadFrameSlotIndex = graph().add(new LoadFieldNode(getSlot(), metaAccessProvider.lookupJavaField(getFrameSlotIndexField()))); + graph().addBeforeFixed(this, loadFrameSlotIndex); + return scale == 1 ? loadFrameSlotIndex : IntegerArithmeticNode.mul(loadFrameSlotIndex, ConstantNode.forInt(scale, graph())); + } + } + + private static Field getFrameSlotIndexField() { + try { + return FrameSlotImpl.class.getDeclaredField("index"); + } catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } + } + + protected final boolean isValidAccessKind() { + if (getSlotKind() == Kind.Byte) { + // tag access + return true; + } + + return getSlotKind() == getGraalKind(getConstantFrameSlot().getKind()); + } + + private static Kind getGraalKind(FrameSlotKind kind) { + switch (kind) { + case Object: + return Kind.Object; + case Long: + return Kind.Long; + case Int: + return Kind.Int; + case Double: + return Kind.Double; + case Float: + return Kind.Float; + case Boolean: + return Kind.Boolean; + case Illegal: + default: + return Kind.Illegal; + } + } + + @Override + public final void simplify(SimplifierTool tool) { + if (isConstantFrameSlot()) { + if (!isValidAccessKind()) { + tool.deleteBranch(this.next()); + this.replaceAndDelete(graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.UnreachedCode))); + } else { + tool.assumptions().record(new AssumptionValidAssumption((OptimizedAssumption) getConstantFrameSlot().getFrameDescriptor().getVersion())); + } + } + } + + @Override + public Map getDebugProperties(Map map) { + Map properties = super.getDebugProperties(map); + if (isConstantFrameSlot()) { + properties.put("frameSlot", getConstantFrameSlot().toString()); + } + return properties; + } +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.frame; + +import sun.misc.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.Node.IterableNodeType; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; +import com.oracle.graal.truffle.*; +import com.oracle.truffle.api.frame.*; + +/** + * Intrinsic node for read access to a Truffle frame. + */ +@NodeInfo(nameTemplate = "FrameGet{p#slotKind/s}{p#frameSlot/s}") +public class FrameGetNode extends FrameAccessNode implements IterableNodeType, Virtualizable, Lowerable { + + public FrameGetNode(Kind kind, ValueNode frame, ValueNode slot, ResolvedJavaField field) { + super(StampFactory.forKind(kind), kind, frame, slot, field); + } + + @Override + public void virtualize(VirtualizerTool tool) { + if (!isConstantFrameSlot()) { + return; + } + assert isValidAccessKind(); + State virtualFrame = tool.getObjectState(getFrame()); + if (virtualFrame == null || virtualFrame.getState() != EscapeState.Virtual) { + return; + } + assert virtualFrame.getVirtualObject().type() == NewFrameNode.FRAME_TYPE : virtualFrame; + VirtualInstanceNode virtualFrameObject = (VirtualInstanceNode) virtualFrame.getVirtualObject(); + int arrayFieldIndex = virtualFrameObject.fieldIndex(field); + State virtualArray = tool.getObjectState(virtualFrame.getEntry(arrayFieldIndex)); + assert virtualArray != null; + ValueNode result = virtualArray.getEntry(getSlotIndex()); + State virtualResult = tool.getObjectState(result); + if (virtualResult != null) { + tool.replaceWithVirtual(virtualResult.getVirtualObject()); + } else { + tool.replaceWithValue(result); + } + } + + @Override + public void lower(LoweringTool tool, LoweringType loweringType) { + assert !(getFrame() instanceof NewFrameNode); + StructuredGraph structuredGraph = graph(); + + LoadFieldNode loadFieldNode = graph().add(new LoadFieldNode(getFrame(), field)); + structuredGraph.addBeforeFixed(this, loadFieldNode); + FixedWithNextNode loadNode; + if (!getSlotKind().isPrimitive()) { + ValueNode slotIndex = getSlotOffset(1, tool.getRuntime()); + loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, Kind.Object)); + } else if (getSlotKind() == Kind.Byte) { + ValueNode slotIndex = getSlotOffset(1, tool.getRuntime()); + loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, Kind.Byte)); + } else { + ValueNode slotOffset = getSlotOffset(Unsafe.ARRAY_LONG_INDEX_SCALE, tool.getRuntime()); + loadNode = graph().add(new UnsafeLoadNode(loadFieldNode, Unsafe.ARRAY_LONG_BASE_OFFSET, slotOffset, getSlotKind())); + } + structuredGraph.replaceFixedWithFixed(this, loadNode); + } + + @NodeIntrinsic + public static native T get(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, @ConstantNodeParameter ResolvedJavaField field); +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameSetNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameSetNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.frame; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.Node.IterableNodeType; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; +import com.oracle.graal.truffle.*; +import com.oracle.truffle.api.frame.*; + +/** + * Intrinsic node for write access to a Truffle frame. + */ +@NodeInfo(nameTemplate = "FrameSet{p#slotKind/s}{p#frameSlot/s}") +public class FrameSetNode extends FrameAccessNode implements IterableNodeType, Virtualizable, Lowerable { + + @Input private ValueNode value; + + public FrameSetNode(Kind kind, ValueNode frame, ValueNode frameSlot, ValueNode value, ResolvedJavaField field) { + super(StampFactory.forVoid(), kind, frame, frameSlot, field); + this.value = value; + } + + public ValueNode getValue() { + return value; + } + + @Override + public void virtualize(VirtualizerTool tool) { + if (!isConstantFrameSlot()) { + return; + } + assert isValidAccessKind(); + State virtualFrame = tool.getObjectState(getFrame()); + if (virtualFrame == null || virtualFrame.getState() != EscapeState.Virtual) { + return; + } + assert virtualFrame.getVirtualObject().type() == NewFrameNode.FRAME_TYPE : virtualFrame; + VirtualInstanceNode virtualFrameObject = (VirtualInstanceNode) virtualFrame.getVirtualObject(); + int arrayFieldIndex = virtualFrameObject.fieldIndex(field); + State virtualArray = tool.getObjectState(virtualFrame.getEntry(arrayFieldIndex)); + assert virtualArray != null; + ValueNode storedValue = value; + tool.setVirtualEntry(virtualArray, getSlotIndex(), storedValue); + tool.delete(); + } + + @Override + public void lower(LoweringTool tool, LoweringType loweringType) { + assert !(getFrame() instanceof NewFrameNode); + StructuredGraph structuredGraph = graph(); + + LoadFieldNode loadFieldNode = graph().add(new LoadFieldNode(getFrame(), field)); + structuredGraph.addBeforeFixed(this, loadFieldNode); + FixedWithNextNode storeNode; + ValueNode slotIndex = getSlotOffset(1, tool.getRuntime()); + if (!getSlotKind().isPrimitive()) { + storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, Kind.Object, value)); + } else if (getSlotKind() == Kind.Byte) { + storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, Kind.Byte, value)); + } else { + storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, Kind.Long, value)); + } + structuredGraph.replaceFixedWithFixed(this, storeNode); + } + + @NodeIntrinsic + public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, Object value, @ConstantNodeParameter ResolvedJavaField field); + + @NodeIntrinsic + public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, byte value, @ConstantNodeParameter ResolvedJavaField field); + + @NodeIntrinsic + public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, boolean value, @ConstantNodeParameter ResolvedJavaField field); + + @NodeIntrinsic + public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, int value, @ConstantNodeParameter ResolvedJavaField field); + + @NodeIntrinsic + public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, long value, @ConstantNodeParameter ResolvedJavaField field); + + @NodeIntrinsic + public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, double value, @ConstantNodeParameter ResolvedJavaField field); + + @NodeIntrinsic + public static native void set(@ConstantNodeParameter Kind kind, FrameWithoutBoxing frame, FrameSlot slot, float value, @ConstantNodeParameter ResolvedJavaField field); +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/MaterializeFrameNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/MaterializeFrameNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.frame; + +import com.oracle.graal.graph.Node.IterableNodeType; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.truffle.*; + +/** + * Intrinsic node for materializing a Truffle frame. + */ +@NodeInfo(nameTemplate = "MaterializeFrame{p#frame/s}") +public class MaterializeFrameNode extends FixedWithNextNode implements IterableNodeType { + + @Input private ValueNode frame; + + public MaterializeFrameNode(ValueNode frame) { + super(frame.stamp()); + this.frame = frame; + } + + public ValueNode getFrame() { + return frame; + } + + @NodeIntrinsic + public static native T materialize(FrameWithoutBoxing frame); +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.frame; + +import java.util.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.runtime.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.Node.IterableNodeType; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.util.*; +import com.oracle.graal.nodes.virtual.*; +import com.oracle.graal.truffle.*; +import com.oracle.graal.truffle.nodes.*; +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.frame.*; + +/** + * Intrinsic node representing the call for creating a frame in the {@link OptimizedCallTarget} + * class. + */ +public class NewFrameNode extends FixedWithNextNode implements IterableNodeType, VirtualizableAllocation, Canonicalizable { + + static final ResolvedJavaType FRAME_TYPE = Graal.getRequiredCapability(MetaAccessProvider.class).lookupJavaType(FrameWithoutBoxing.class); + + @Input private ValueNode descriptor; + @Input private ValueNode caller; + @Input private ValueNode arguments; + + public NewFrameNode(Stamp stamp, ValueNode descriptor, ValueNode caller, ValueNode arguments) { + super(stamp); + this.descriptor = descriptor; + this.caller = caller; + this.arguments = arguments; + } + + public NewFrameNode(ValueNode descriptor, ValueNode caller, ValueNode arguments) { + this(StampFactory.declaredNonNull(FRAME_TYPE), descriptor, caller, arguments); + } + + public ValueNode getDescriptor() { + return descriptor; + } + + public ValueNode getCaller() { + return caller; + } + + public ValueNode getArguments() { + return arguments; + } + + private FrameDescriptor getConstantFrameDescriptor() { + assert descriptor.isConstant() && !descriptor.isNullConstant(); + return (FrameDescriptor) descriptor.asConstant().asObject(); + } + + private int getFrameSize() { + return getConstantFrameDescriptor().getSize(); + } + + private static ResolvedJavaField findField(ResolvedJavaField[] fields, String fieldName) { + for (ResolvedJavaField field : fields) { + if (field.getName().equals(fieldName)) { + return field; + } + } + throw new RuntimeException("Frame field not found: " + fieldName); + } + + public static class VirtualOnlyInstanceNode extends VirtualInstanceNode implements Node.IterableNodeType { + + private boolean allowMaterialization; + + public VirtualOnlyInstanceNode(ResolvedJavaType type, ResolvedJavaField[] fields) { + super(type, fields); + } + + @Override + public ValueNode getMaterializedRepresentation(FixedNode fixed, ValueNode[] entries, int[] locks) { + if (allowMaterialization) { + return super.getMaterializedRepresentation(fixed, entries, locks); + } + return getMaterializedRepresentationHelper(this, fixed); + } + + public void setAllowMaterialization(boolean b) { + this.allowMaterialization = b; + } + } + + public static ValueNode getMaterializedRepresentationHelper(VirtualObjectNode virtualNode, FixedNode fixed) { + if (fixed instanceof MaterializeFrameNode || fixed instanceof AbstractEndNode) { + // We need to conservatively assume that a materialization of a virtual frame can also + // happen at a merge point. + return new AllocatedObjectNode(virtualNode); + } + String escapeReason; + if (fixed instanceof StoreFieldNode) { + escapeReason = "Must not store virtual frame object into a field."; + } else if (fixed instanceof Invoke) { + escapeReason = "Must not pass virtual frame object into an invoke that cannot be inlined."; + } else { + escapeReason = "Must not let virtual frame object escape at node " + fixed + "."; + } + + Throwable exception = new GraalInternalError(escapeReason + + " Insert a call to VirtualFrame.materialize() to convert the instance to a materialized frame object (source position of following stack trace is approximate)"); + throw GraphUtil.approxSourceException(fixed, exception); + } + + @Override + public void virtualize(VirtualizerTool tool) { + int frameSize = getFrameSize(); + + ResolvedJavaType frameType = stamp().javaType(tool.getMetaAccessProvider()); + ResolvedJavaField[] frameFields = frameType.getInstanceFields(true); + + ResolvedJavaField descriptorField = findField(frameFields, "descriptor"); + ResolvedJavaField callerField = findField(frameFields, "caller"); + ResolvedJavaField argumentsField = findField(frameFields, "arguments"); + ResolvedJavaField localsField = findField(frameFields, "locals"); + ResolvedJavaField primitiveLocalsField = findField(frameFields, "primitiveLocals"); + ResolvedJavaField tagsField = findField(frameFields, "tags"); + + VirtualObjectNode virtualFrame = new VirtualOnlyInstanceNode(frameType, frameFields); + VirtualObjectNode virtualFrameObjectArray = new VirtualArrayNode((ResolvedJavaType) localsField.getType().getComponentType(), frameSize); + VirtualObjectNode virtualFramePrimitiveArray = new VirtualArrayNode((ResolvedJavaType) primitiveLocalsField.getType().getComponentType(), frameSize); + VirtualObjectNode virtualFrameTagArray = new VirtualArrayNode((ResolvedJavaType) tagsField.getType().getComponentType(), frameSize); + + ValueNode[] objectArrayEntryState = new ValueNode[frameSize]; + ValueNode[] primitiveArrayEntryState = new ValueNode[frameSize]; + ValueNode[] tagArrayEntryState = new ValueNode[frameSize]; + + if (frameSize > 0) { + FrameDescriptor frameDescriptor = getConstantFrameDescriptor(); + ConstantNode objectDefault = ConstantNode.forObject(frameDescriptor.getTypeConversion().getDefaultValue(), tool.getMetaAccessProvider(), graph()); + ConstantNode tagDefault = ConstantNode.forByte((byte) 0, graph()); + for (int i = 0; i < frameSize; i++) { + objectArrayEntryState[i] = objectDefault; + primitiveArrayEntryState[i] = initialValue(frameDescriptor.getSlots().get(i).getKind()); + tagArrayEntryState[i] = tagDefault; + } + tool.getAssumptions().record(new AssumptionValidAssumption((OptimizedAssumption) frameDescriptor.getVersion())); + } + + tool.createVirtualObject(virtualFrameObjectArray, objectArrayEntryState, null); + tool.createVirtualObject(virtualFramePrimitiveArray, primitiveArrayEntryState, null); + tool.createVirtualObject(virtualFrameTagArray, tagArrayEntryState, null); + + assert frameFields.length == 6; + ValueNode[] frameEntryState = new ValueNode[frameFields.length]; + List frameFieldList = Arrays.asList(frameFields); + frameEntryState[frameFieldList.indexOf(descriptorField)] = getDescriptor(); + frameEntryState[frameFieldList.indexOf(callerField)] = getCaller(); + frameEntryState[frameFieldList.indexOf(argumentsField)] = getArguments(); + frameEntryState[frameFieldList.indexOf(localsField)] = virtualFrameObjectArray; + frameEntryState[frameFieldList.indexOf(primitiveLocalsField)] = virtualFramePrimitiveArray; + frameEntryState[frameFieldList.indexOf(tagsField)] = virtualFrameTagArray; + tool.createVirtualObject(virtualFrame, frameEntryState, null); + tool.replaceWithVirtual(virtualFrame); + } + + private ValueNode initialValue(FrameSlotKind kind) { + Kind graalKind = Kind.Long; + switch (kind) { + case Int: + graalKind = Kind.Int; + break; + case Double: + graalKind = Kind.Double; + break; + case Float: + graalKind = Kind.Float; + break; + case Boolean: + graalKind = Kind.Boolean; + break; + } + + return ConstantNode.defaultForKind(graalKind, graph()); + } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + if (usages().isEmpty()) { + return null; + } else { + return this; + } + } + + @NodeIntrinsic + public static native FrameWithoutBoxing allocate(FrameDescriptor descriptor, PackedFrame caller, Arguments args); +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckMacroNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckMacroNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.typesystem; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.truffle.nodes.asserts.*; +import com.oracle.truffle.api.*; + +/** + * Macro node for method {@link CompilerDirectives#customTypeCheck(boolean, Object, Object)}. + */ +public class CustomTypeCheckMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { + + private static final int ARGUMENT_COUNT = 3; + private static final int CONDITION_ARGUMENT_INDEX = 0; + private static final int OBJECT_ARGUMENT_INDEX = 1; + private static final int CUSTOM_TYPE_ARGUMENT_INDEX = 2; + + public CustomTypeCheckMacroNode(Invoke invoke) { + super(invoke, "The custom type parameter could not be reduced to a compile time constant."); + assert arguments.size() == ARGUMENT_COUNT; + } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + ValueNode customTypeArgument = arguments.get(CUSTOM_TYPE_ARGUMENT_INDEX); + if (customTypeArgument.isConstant()) { + Object typeToken = customTypeArgument.asConstant().asObject(); + ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX); + ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX); + return graph().unique(new ConditionalNode(graph().unique(new CustomTypeCheckNode(conditionArgument, objectArgument, typeToken)))); + } + return this; + } +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.typesystem; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; + +public final class CustomTypeCheckNode extends LogicNode implements Lowerable, com.oracle.graal.graph.Node.IterableNodeType { + + @Input private ValueNode condition; + @Input private ValueNode object; + private final Object customType; + + public CustomTypeCheckNode(ValueNode condition, ValueNode object, Object customType) { + this.condition = condition; + this.object = object; + this.customType = customType; + } + + public ValueNode getObject() { + return object; + } + + public ValueNode getCondition() { + return condition; + } + + public Object getCustomType() { + return customType; + } + + public void lower(LoweringTool tool, LoweringType loweringType) { + if (loweringType == LoweringType.BEFORE_GUARDS) { + this.replaceAtUsages(graph().unique(new IntegerEqualsNode(condition, ConstantNode.forInt(1, graph())))); + this.safeDelete(); + } + } + + @Override + public LogicNode canonical(CanonicalizerTool tool) { + return this; + } +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastMacroNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastMacroNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.typesystem; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.truffle.nodes.asserts.*; +import com.oracle.truffle.api.*; + +/** + * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class)} and + * {@link CompilerDirectives#unsafeCast(Object, Class, Object)}. + */ +public class TypeCastMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { + + private static final int ARGUMENT_COUNT = 3; + private static final int OBJECT_ARGUMENT_INDEX = 0; + private static final int CLASS_ARGUMENT_INDEX = 1; + private static final int CUSTOM_TYPE_ARGUMENT_INDEX = 2; + + public TypeCastMacroNode(Invoke invoke) { + super(invoke, "The class of the unsafe cast could not be reduced to a compile time constant."); + assert arguments.size() == ARGUMENT_COUNT; + } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + ValueNode classArgument = arguments.get(CLASS_ARGUMENT_INDEX); + ValueNode customTypeArgument = arguments.get(CUSTOM_TYPE_ARGUMENT_INDEX); + if (classArgument.isConstant() && customTypeArgument.isConstant()) { + Class c = (Class) classArgument.asConstant().asObject(); + ResolvedJavaType lookupJavaType = tool.runtime().lookupJavaType(c); + Stamp s = StampFactory.declaredNonNull(lookupJavaType); + ValueAnchorNode valueAnchorNode = graph().add(new ValueAnchorNode()); + ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX); + Object customType = customTypeArgument.asConstant().asObject(); + UnsafeCastNode unsafeCast = graph().unique(new UnsafeCastNode(objectArgument, s, valueAnchorNode, customType)); + this.replaceAtUsages(unsafeCast); + return valueAnchorNode; + } + return this; + } +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationMacroNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationMacroNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.typesystem; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.truffle.nodes.asserts.*; +import com.oracle.truffle.api.*; + +/** + * Macro node for method {@link CompilerDirectives#unsafeCustomization(Object, Object, Object)}. + */ +public class UnsafeCustomizationMacroNode extends NeverPartOfCompilationNode implements Canonicalizable { + + private static final int ARGUMENT_COUNT = 3; + private static final int RECEIVER_ARGUMENT_INDEX = 0; + private static final int CUSTOM_TYPE_ARGUMENT_INDEX = 1; + private static final int LOCATION_IDENTITY_ARGUMENT_INDEX = 2; + + public UnsafeCustomizationMacroNode(Invoke invoke) { + super(invoke, "The custom type parameter and/or the location identity could not be reduced to a compile time constant."); + assert arguments.size() == ARGUMENT_COUNT; + } + + @Override + public ValueNode canonical(CanonicalizerTool tool) { + ValueNode customTypeArgument = this.arguments.get(CUSTOM_TYPE_ARGUMENT_INDEX); + ValueNode locationIdentityArgument = this.arguments.get(LOCATION_IDENTITY_ARGUMENT_INDEX); + if (customTypeArgument.isConstant() && locationIdentityArgument.isConstant()) { + Object customType = customTypeArgument.asConstant().asObject(); + Object locationIdentity = locationIdentityArgument.asConstant().asObject(); + ValueNode receiverArgument = this.arguments.get(RECEIVER_ARGUMENT_INDEX); + return graph().unique(new UnsafeCustomizationNode(receiverArgument, customType, locationIdentity)); + } + return this; + } +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationNode.java Fri Aug 16 17:55:25 2013 +0200 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.truffle.nodes.typesystem; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +public final class UnsafeCustomizationNode extends FloatingNode implements LIRLowerable, com.oracle.graal.graph.Node.IterableNodeType { + + @Input private ValueNode receiver; + private final Object customType; + private final Object locationIdentity; + + public UnsafeCustomizationNode(ValueNode receiver, Object customType, Object locationIdentity) { + super(StampFactory.object()); + this.receiver = receiver; + this.customType = customType; + this.locationIdentity = locationIdentity; + } + + public ValueNode getReceiver() { + return receiver; + } + + public Object getCustomType() { + return customType; + } + + public Object getLocationIdentity() { + return locationIdentity; + } + + public void generate(LIRGeneratorTool generator) { + generator.setResult(this, generator.operand(receiver)); + } +} diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyFrameDoesNotEscapePhase.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyFrameDoesNotEscapePhase.java Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyFrameDoesNotEscapePhase.java Fri Aug 16 17:55:25 2013 +0200 @@ -27,7 +27,7 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; -import com.oracle.graal.truffle.nodes.*; +import com.oracle.graal.truffle.nodes.frame.*; /** * Compiler phase for verifying that the Truffle virtual frame does not escape and can therefore be diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyNoIntrinsicsLeftPhase.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyNoIntrinsicsLeftPhase.java Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/VerifyNoIntrinsicsLeftPhase.java Fri Aug 16 17:55:25 2013 +0200 @@ -27,7 +27,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; import com.oracle.graal.truffle.*; -import com.oracle.graal.truffle.nodes.*; +import com.oracle.graal.truffle.nodes.frame.*; /** * Verification phase for checking that no frame intrinsic nodes introduced by the diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerAssertsSubstitutions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerAssertsSubstitutions.java Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerAssertsSubstitutions.java Fri Aug 16 17:55:25 2013 +0200 @@ -24,7 +24,7 @@ import com.oracle.graal.api.replacements.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.truffle.nodes.*; +import com.oracle.graal.truffle.nodes.asserts.*; import com.oracle.truffle.api.*; @ClassSubstitution(CompilerAsserts.class) diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java Fri Aug 16 17:55:25 2013 +0200 @@ -31,6 +31,7 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.truffle.nodes.*; +import com.oracle.graal.truffle.nodes.typesystem.*; import com.oracle.truffle.api.*; @ClassSubstitution(CompilerDirectives.class) @@ -63,6 +64,12 @@ @MacroSubstitution(macro = BailoutNode.class, isStatic = true) public static native void bailout(String reason); - @MacroSubstitution(macro = UnsafeCastMacroNode.class, isStatic = true) - public static native Object unsafeCast(Object value, Class clazz); + @MacroSubstitution(macro = TypeCastMacroNode.class, isStatic = true) + public static native Object unsafeCast(Object value, Class clazz, Object customType); + + @MacroSubstitution(macro = CustomTypeCheckMacroNode.class, isStatic = true) + public static native boolean customTypeCheck(boolean condition, Object value, Object customType); + + @MacroSubstitution(macro = UnsafeCustomizationMacroNode.class, isStatic = true) + public static native Object unsafeCustomization(Object receiver, Object customType, Object locationIdentity); } diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/DefaultCallTargetSubstitutions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/DefaultCallTargetSubstitutions.java Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/DefaultCallTargetSubstitutions.java Fri Aug 16 17:55:25 2013 +0200 @@ -24,7 +24,7 @@ import com.oracle.graal.api.replacements.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.truffle.nodes.*; +import com.oracle.graal.truffle.nodes.asserts.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.impl.*; diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/ExactMathSubstitutions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/ExactMathSubstitutions.java Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/ExactMathSubstitutions.java Fri Aug 16 17:55:25 2013 +0200 @@ -23,7 +23,7 @@ package com.oracle.graal.truffle.substitutions; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.truffle.nodes.*; +import com.oracle.graal.truffle.nodes.arithmetic.*; import com.oracle.truffle.api.*; /** diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java Fri Aug 16 17:55:25 2013 +0200 @@ -28,7 +28,7 @@ import com.oracle.graal.api.runtime.*; import com.oracle.graal.nodes.*; import com.oracle.graal.truffle.*; -import com.oracle.graal.truffle.nodes.*; +import com.oracle.graal.truffle.nodes.frame.*; import com.oracle.truffle.api.frame.*; @ClassSubstitution(FrameWithoutBoxing.class) diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/OptimizedCallTargetSubstitutions.java Fri Aug 16 17:55:25 2013 +0200 @@ -25,7 +25,8 @@ import com.oracle.graal.api.replacements.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.truffle.*; -import com.oracle.graal.truffle.nodes.*; +import com.oracle.graal.truffle.nodes.asserts.*; +import com.oracle.graal.truffle.nodes.frame.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; diff -r 80de3bbfa8b9 -r 77bf4af4cc94 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java Fri Aug 16 14:00:17 2013 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java Fri Aug 16 17:55:25 2013 +0200 @@ -145,10 +145,9 @@ * @param clazz the specified type of the value * @return the value */ - @SuppressWarnings("unchecked") @Unsafe public static T unsafeCast(Object value, Class clazz) { - return (T) value; + return unsafeCast(value, clazz, null); } /** @@ -172,28 +171,30 @@ * @param customType the custom type that if present on a value makes this unsafe cast safe * @return the value */ + @SuppressWarnings("unchecked") @Unsafe public static T unsafeCast(Object value, Class clazz, Object customType) { - return unsafeCast(value, clazz); + return (T) value; } /** - * Proxies a sun.misc.Unsafe instance into an instance that adds a custom location identity on - * its accesses. This means that the accesses on these kind of location identities can only - * alias among themselves. It also allows to specify a custom type for the receiver values of - * follow-up unsafe accesses. Both the custom type and the location identity must evaluate to a - * constant. Furthermore, you should use the new sun.misc.Unsafe instance immediately for one - * read or write access via a sun.misc.Unsafe method and not store it anywhere. + * Proxies an object instance into an instance that adds a custom location identity on its + * accesses via sun.misc.Unsafe. This means that the accesses on these kind of location + * identities can only alias among themselves. It also allows to specify a custom type for the + * receiver values of follow-up unsafe accesses. Both the custom type and the location identity + * must evaluate to a constant. Furthermore, you should use the proxied receiver object + * immediately for one read or write access via a sun.misc.Unsafe method and not store it + * anywhere. * - * @param unsafe the instance of sun.misc.Unsafe + * @param receiver the object that is accessed via sun.misc.Unsafe * @param customType the expected type of the receiver object of follow-up unsafe accesses * @param locationIdentity the location identity token that can be used for improved global * value numbering or null * @return the accessed value */ @Unsafe - public static sun.misc.Unsafe unsafeCustomization(sun.misc.Unsafe unsafe, Object customType, Object locationIdentity) { - return unsafe; + public static Object unsafeCustomization(Object receiver, Object customType, Object locationIdentity) { + return receiver; } /** diff -r 80de3bbfa8b9 -r 77bf4af4cc94 mxtool/mx.py --- a/mxtool/mx.py Fri Aug 16 14:00:17 2013 +0200 +++ b/mxtool/mx.py Fri Aug 16 17:55:25 2013 +0200 @@ -3326,9 +3326,9 @@ Presents a command line interface for selecting one or more (if allowMultiple is true) items. """ - if len(items) == 0: - return [] - elif len(items) > 1: + if len(items) <= 1: + return items + else: if allowMultiple: log('[0] ') for i in range(0, len(items)):