Mercurial > hg > graal-compiler
changeset 23019:e3bcc6af1bcc
Fix handling of FrameStates with intrinsic bcis during partial evaluation
author | Christian Wimmer <christian.wimmer@oracle.com> |
---|---|
date | Wed, 18 Nov 2015 12:01:29 -0800 |
parents | 31f1578ea3ab |
children | 4af472d10ad6 |
files | graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SimplePartialEvaluationTest.java graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/ObjectHashCodeNode.java |
diffstat | 5 files changed, 90 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Wed Nov 18 11:52:05 2015 -0800 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java Wed Nov 18 12:01:29 2015 -0800 @@ -137,11 +137,16 @@ this.stateDuring = stateDuring; } + public int getBci() { + return bci; + } + /** * Set the {@code bci} of the invoke bytecode for use when converting a stateAfter into a * stateDuring. */ public void setBci(int bci) { + assert this.bci == BytecodeFrame.UNKNOWN_BCI || this.bci == bci; this.bci = bci; }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java Wed Nov 18 11:52:05 2015 -0800 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java Wed Nov 18 12:01:29 2015 -0800 @@ -516,13 +516,14 @@ if (outerFrameState == null) { outerFrameState = stateAtReturn.duplicateModifiedDuringCall(invoke.bci(), invokeReturnKind); } - processFrameState(frameState, invoke, inlineGraph.method(), stateAtExceptionEdge, outerFrameState, alwaysDuplicateStateAfter); + processFrameState(frameState, invoke, inlineGraph.method(), stateAtExceptionEdge, outerFrameState, alwaysDuplicateStateAfter, invoke.callTarget().targetMethod(), + invoke.callTarget().arguments()); } } } public static FrameState processFrameState(FrameState frameState, Invoke invoke, ResolvedJavaMethod inlinedMethod, FrameState stateAtExceptionEdge, FrameState outerFrameState, - boolean alwaysDuplicateStateAfter) { + boolean alwaysDuplicateStateAfter, ResolvedJavaMethod invokeTargetMethod, List<ValueNode> invokeArgsList) { FrameState stateAtReturn = invoke.stateAfter(); JavaKind invokeReturnKind = invoke.asNode().getStackKind(); @@ -569,10 +570,9 @@ // This is an intrinsic. Deoptimizing within an intrinsic // must re-execute the intrinsified invocation assert frameState.outerFrameState() == null; - NodeInputList<ValueNode> invokeArgsList = invoke.callTarget().arguments(); ValueNode[] invokeArgs = invokeArgsList.isEmpty() ? NO_ARGS : invokeArgsList.toArray(new ValueNode[invokeArgsList.size()]); - ResolvedJavaMethod targetMethod = invoke.callTarget().targetMethod(); - FrameState stateBeforeCall = stateAtReturn.duplicateModifiedBeforeCall(invoke.bci(), invokeReturnKind, targetMethod.getSignature().toParameterKinds(!targetMethod.isStatic()), invokeArgs); + FrameState stateBeforeCall = stateAtReturn.duplicateModifiedBeforeCall(invoke.bci(), invokeReturnKind, invokeTargetMethod.getSignature().toParameterKinds(!invokeTargetMethod.isStatic()), + invokeArgs); frameState.replaceAndDelete(stateBeforeCall); return stateBeforeCall; } else {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java Wed Nov 18 11:52:05 2015 -0800 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java Wed Nov 18 12:01:29 2015 -0800 @@ -28,12 +28,14 @@ import static jdk.vm.ci.common.JVMCIError.unimplemented; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import jdk.vm.ci.code.Architecture; import jdk.vm.ci.code.BailoutException; +import jdk.vm.ci.code.BytecodeFrame; import jdk.vm.ci.code.BytecodePosition; import jdk.vm.ci.meta.ConstantReflectionProvider; import jdk.vm.ci.meta.DeoptimizationAction; @@ -83,6 +85,7 @@ import com.oracle.graal.nodes.StructuredGraph; import com.oracle.graal.nodes.UnwindNode; import com.oracle.graal.nodes.ValueNode; +import com.oracle.graal.nodes.extended.ForeignCallNode; import com.oracle.graal.nodes.extended.IntegerSwitchNode; import com.oracle.graal.nodes.java.MethodCallTargetNode; import com.oracle.graal.nodes.java.MonitorIdNode; @@ -630,6 +633,12 @@ PEMethodScope methodScope = (PEMethodScope) s; if (node instanceof SimpleInfopointNode && methodScope.isInlinedMethod()) { InliningUtil.addSimpleInfopointCaller((SimpleInfopointNode) node, methodScope.getBytecodePosition()); + + } else if (node instanceof ForeignCallNode) { + ForeignCallNode foreignCall = (ForeignCallNode) node; + if (foreignCall.getBci() == BytecodeFrame.UNKNOWN_BCI) { + foreignCall.setBci(methodScope.invokeData.invoke.bci()); + } } BytecodePosition pos = node.getNodeContext(BytecodePosition.class); @@ -734,7 +743,16 @@ if (frameState.bci < 0) { ensureExceptionStateDecoded(methodScope); } - return InliningUtil.processFrameState(frameState, methodScope.invokeData.invoke, methodScope.method, methodScope.exceptionState, methodScope.outerState, true); + List<ValueNode> invokeArgsList = null; + if (frameState.bci == BytecodeFrame.BEFORE_BCI) { + /* + * We know that the argument list is only used in this case, so avoid the List + * allocation for "normal" bcis. + */ + invokeArgsList = Arrays.asList(methodScope.arguments); + } + return InliningUtil.processFrameState(frameState, methodScope.invokeData.invoke, methodScope.method, methodScope.exceptionState, methodScope.outerState, true, methodScope.method, + invokeArgsList); } else if (node instanceof MonitorIdNode) { ensureOuterStateDecoded(methodScope);
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SimplePartialEvaluationTest.java Wed Nov 18 11:52:05 2015 -0800 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/SimplePartialEvaluationTest.java Wed Nov 18 12:01:29 2015 -0800 @@ -42,6 +42,7 @@ import com.oracle.graal.truffle.test.nodes.NestedExplodedLoopTestNode; import com.oracle.graal.truffle.test.nodes.NeverPartOfCompilationTestNode; import com.oracle.graal.truffle.test.nodes.ObjectEqualsNode; +import com.oracle.graal.truffle.test.nodes.ObjectHashCodeNode; import com.oracle.graal.truffle.test.nodes.RecursionTestNode; import com.oracle.graal.truffle.test.nodes.RootTestNode; import com.oracle.graal.truffle.test.nodes.StoreLocalTestNode; @@ -228,4 +229,22 @@ Assert.assertEquals(42, compilable.call(new Object[0])); } + + @Test + public void intrinsicHashCode() { + /* + * The intrinsic for Object.hashCode() is inlined late during Truffle partial evaluation, + * because we call hashCode() on a value whose exact type Object is only known during + * partial evaluation. + */ + FrameDescriptor fd = new FrameDescriptor(); + Object testObject = new Object(); + AbstractTestNode result = new ObjectHashCodeNode(testObject); + RootNode rootNode = new RootTestNode(fd, "intrinsicHashCode", result); + OptimizedCallTarget compilable = compileHelper("intrinsicHashCode", rootNode, new Object[0]); + + int actual = (Integer) compilable.call(new Object[0]); + int expected = testObject.hashCode(); + Assert.assertEquals(expected, actual); + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/ObjectHashCodeNode.java Wed Nov 18 12:01:29 2015 -0800 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2015, 2015, 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.test.nodes; + +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.NodeInfo; + +@NodeInfo +public class ObjectHashCodeNode extends AbstractTestNode { + + @CompilationFinal private Object o1; + + public ObjectHashCodeNode(Object o1) { + this.o1 = o1; + } + + @Override + public int execute(VirtualFrame frame) { + return o1.hashCode(); + } +}