Search in sources :

Example 1 with Assumptions

use of jdk.vm.ci.meta.Assumptions in project graal by oracle.

the class MethodCallTargetNode method simplify.

@Override
public void simplify(SimplifierTool tool) {
    // attempt to devirtualize the call
    if (invoke().getContextMethod() == null) {
        // avoid invokes that have placeholder bcis: they do not have a valid contextType
        assert (invoke().stateAfter() != null && BytecodeFrame.isPlaceholderBci(invoke().stateAfter().bci)) || BytecodeFrame.isPlaceholderBci(invoke().stateDuring().bci);
        return;
    }
    ResolvedJavaType contextType = (invoke().stateAfter() == null && invoke().stateDuring() == null) ? null : invoke().getContextType();
    ResolvedJavaMethod specialCallTarget = findSpecialCallTarget(invokeKind, receiver(), targetMethod, contextType);
    if (specialCallTarget != null) {
        this.setTargetMethod(specialCallTarget);
        setInvokeKind(InvokeKind.Special);
        return;
    }
    Assumptions assumptions = graph().getAssumptions();
    /*
         * Even though we are not registering an assumption (see comment below), the optimization is
         * only valid when speculative optimizations are enabled.
         */
    if (invokeKind().isIndirect() && invokeKind().isInterface() && assumptions != null) {
        // check if the type of the receiver can narrow the result
        ValueNode receiver = receiver();
        // try to turn a interface call into a virtual call
        ResolvedJavaType declaredReceiverType = targetMethod().getDeclaringClass();
        /*
             * We need to check the invoke kind to avoid recursive simplification for virtual
             * interface methods calls.
             */
        if (declaredReceiverType.isInterface()) {
            ResolvedJavaType singleImplementor = declaredReceiverType.getSingleImplementor();
            if (singleImplementor != null && !singleImplementor.equals(declaredReceiverType)) {
                TypeReference speculatedType = TypeReference.createTrusted(assumptions, singleImplementor);
                if (tryCheckCastSingleImplementor(receiver, speculatedType)) {
                    return;
                }
            }
        }
        if (receiver instanceof UncheckedInterfaceProvider) {
            UncheckedInterfaceProvider uncheckedInterfaceProvider = (UncheckedInterfaceProvider) receiver;
            Stamp uncheckedStamp = uncheckedInterfaceProvider.uncheckedStamp();
            if (uncheckedStamp != null) {
                TypeReference speculatedType = StampTool.typeReferenceOrNull(uncheckedStamp);
                if (speculatedType != null) {
                    tryCheckCastSingleImplementor(receiver, speculatedType);
                }
            }
        }
    }
}
Also used : Stamp(org.graalvm.compiler.core.common.type.Stamp) Assumptions(jdk.vm.ci.meta.Assumptions) ValueNode(org.graalvm.compiler.nodes.ValueNode) UncheckedInterfaceProvider(org.graalvm.compiler.nodes.spi.UncheckedInterfaceProvider) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 2 with Assumptions

use of jdk.vm.ci.meta.Assumptions in project graal by oracle.

the class ObjectCloneNode method getLoweredSnippetGraph.

@Override
@SuppressWarnings("try")
protected StructuredGraph getLoweredSnippetGraph(LoweringTool tool) {
    ResolvedJavaType type = StampTool.typeOrNull(getObject());
    if (type != null) {
        if (type.isArray()) {
            Method method = ObjectCloneSnippets.arrayCloneMethods.get(type.getComponentType().getJavaKind());
            if (method != null) {
                final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(method);
                final Replacements replacements = tool.getReplacements();
                StructuredGraph snippetGraph = null;
                DebugContext debug = getDebug();
                try (DebugContext.Scope s = debug.scope("ArrayCloneSnippet", snippetMethod)) {
                    snippetGraph = replacements.getSnippet(snippetMethod, null, graph().trackNodeSourcePosition(), this.getNodeSourcePosition());
                } catch (Throwable e) {
                    throw debug.handle(e);
                }
                assert snippetGraph != null : "ObjectCloneSnippets should be installed";
                assert getConcreteType(stamp(NodeView.DEFAULT)) != null;
                return lowerReplacement((StructuredGraph) snippetGraph.copy(getDebug()), tool);
            }
            assert false : "unhandled array type " + type.getComponentType().getJavaKind();
        } else {
            Assumptions assumptions = graph().getAssumptions();
            type = getConcreteType(getObject().stamp(NodeView.DEFAULT));
            if (type != null) {
                StructuredGraph newGraph = new StructuredGraph.Builder(graph().getOptions(), graph().getDebug(), AllowAssumptions.ifNonNull(assumptions)).build();
                ParameterNode param = newGraph.addWithoutUnique(new ParameterNode(0, StampPair.createSingle(getObject().stamp(NodeView.DEFAULT))));
                NewInstanceNode newInstance = newGraph.add(new NewInstanceNode(type, true));
                newGraph.addAfterFixed(newGraph.start(), newInstance);
                ReturnNode returnNode = newGraph.add(new ReturnNode(newInstance));
                newGraph.addAfterFixed(newInstance, returnNode);
                for (ResolvedJavaField field : type.getInstanceFields(true)) {
                    LoadFieldNode load = newGraph.add(LoadFieldNode.create(newGraph.getAssumptions(), param, field));
                    newGraph.addBeforeFixed(returnNode, load);
                    newGraph.addBeforeFixed(returnNode, newGraph.add(new StoreFieldNode(newInstance, field, load)));
                }
                assert getConcreteType(stamp(NodeView.DEFAULT)) != null;
                return lowerReplacement(newGraph, tool);
            }
        }
    }
    assert getConcreteType(stamp(NodeView.DEFAULT)) == null;
    return null;
}
Also used : StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) Replacements(org.graalvm.compiler.nodes.spi.Replacements) NewInstanceNode(org.graalvm.compiler.nodes.java.NewInstanceNode) Method(java.lang.reflect.Method) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) DebugContext(org.graalvm.compiler.debug.DebugContext) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaField(jdk.vm.ci.meta.ResolvedJavaField) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) AllowAssumptions(org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions) Assumptions(jdk.vm.ci.meta.Assumptions) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 3 with Assumptions

use of jdk.vm.ci.meta.Assumptions in project graal by oracle.

the class InliningUtil method finishInlining.

private static ValueNode finishInlining(Invoke invoke, StructuredGraph graph, FixedNode firstNode, List<ReturnNode> returnNodes, UnwindNode unwindNode, Assumptions inlinedAssumptions, StructuredGraph inlineGraph) {
    FixedNode invokeNode = invoke.asNode();
    FrameState stateAfter = invoke.stateAfter();
    assert stateAfter == null || stateAfter.isAlive();
    invokeNode.replaceAtPredecessor(firstNode);
    if (invoke instanceof InvokeWithExceptionNode) {
        InvokeWithExceptionNode invokeWithException = ((InvokeWithExceptionNode) invoke);
        if (unwindNode != null && unwindNode.isAlive()) {
            assert unwindNode.predecessor() != null;
            assert invokeWithException.exceptionEdge().successors().count() == 1;
            ExceptionObjectNode obj = (ExceptionObjectNode) invokeWithException.exceptionEdge();
            obj.replaceAtUsages(unwindNode.exception());
            Node n = obj.next();
            obj.setNext(null);
            unwindNode.replaceAndDelete(n);
            obj.replaceAtPredecessor(null);
            obj.safeDelete();
        } else {
            invokeWithException.killExceptionEdge();
        }
        // get rid of memory kill
        AbstractBeginNode begin = invokeWithException.next();
        if (begin instanceof KillingBeginNode) {
            AbstractBeginNode newBegin = new BeginNode();
            graph.addAfterFixed(begin, graph.add(newBegin));
            begin.replaceAtUsages(newBegin);
            graph.removeFixed(begin);
        }
    } else {
        if (unwindNode != null && unwindNode.isAlive()) {
            DeoptimizeNode deoptimizeNode = addDeoptimizeNode(graph, DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler);
            unwindNode.replaceAndDelete(deoptimizeNode);
        }
    }
    ValueNode returnValue;
    if (!returnNodes.isEmpty()) {
        FixedNode n = invoke.next();
        invoke.setNext(null);
        if (returnNodes.size() == 1) {
            ReturnNode returnNode = returnNodes.get(0);
            returnValue = returnNode.result();
            invokeNode.replaceAtUsages(returnValue);
            returnNode.replaceAndDelete(n);
        } else {
            MergeNode merge = graph.add(new MergeNode());
            merge.setStateAfter(stateAfter);
            returnValue = mergeReturns(merge, returnNodes);
            invokeNode.replaceAtUsages(returnValue);
            if (merge.isPhiAtMerge(returnValue)) {
                fixFrameStates(graph, merge, (PhiNode) returnValue);
            }
            merge.setNext(n);
        }
    } else {
        returnValue = null;
        invokeNode.replaceAtUsages(null);
        GraphUtil.killCFG(invoke.next());
    }
    // Copy assumptions from inlinee to caller
    Assumptions assumptions = graph.getAssumptions();
    if (assumptions != null) {
        if (inlinedAssumptions != null) {
            assumptions.record(inlinedAssumptions);
        }
    } else {
        assert inlinedAssumptions == null : String.format("cannot inline graph (%s) which makes assumptions into a graph (%s) that doesn't", inlineGraph, graph);
    }
    // Copy inlined methods from inlinee to caller
    graph.updateMethods(inlineGraph);
    // Update the set of accessed fields
    if (GraalOptions.GeneratePIC.getValue(graph.getOptions())) {
        graph.updateFields(inlineGraph);
    }
    if (inlineGraph.hasUnsafeAccess()) {
        graph.markUnsafeAccess();
    }
    assert inlineGraph.getSpeculationLog() == null || inlineGraph.getSpeculationLog() == graph.getSpeculationLog() : "Only the root graph should have a speculation log";
    return returnValue;
}
Also used : AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) PiNode(org.graalvm.compiler.nodes.PiNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) MonitorExitNode(org.graalvm.compiler.nodes.java.MonitorExitNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) GuardingNode(org.graalvm.compiler.nodes.extended.GuardingNode) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) StartNode(org.graalvm.compiler.nodes.StartNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) UnwindNode(org.graalvm.compiler.nodes.UnwindNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) ForeignCallNode(org.graalvm.compiler.nodes.extended.ForeignCallNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) FrameState(org.graalvm.compiler.nodes.FrameState) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) Assumptions(jdk.vm.ci.meta.Assumptions) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode)

Example 4 with Assumptions

use of jdk.vm.ci.meta.Assumptions in project graal by oracle.

the class MethodHandleNode method maybeCastArgument.

/**
 * Inserts a node to cast the argument at index to the given type if the given type is more
 * concrete than the argument type.
 *
 * @param adder
 * @param index of the argument to be cast
 * @param type the type the argument should be cast to
 */
private static void maybeCastArgument(GraphAdder adder, ValueNode[] arguments, int index, JavaType type) {
    ValueNode argument = arguments[index];
    if (type instanceof ResolvedJavaType && !((ResolvedJavaType) type).isJavaLangObject()) {
        Assumptions assumptions = adder.getAssumptions();
        TypeReference targetType = TypeReference.create(assumptions, (ResolvedJavaType) type);
        /*
             * When an argument is a Word type, we can have a mismatch of primitive/object types
             * here. Not inserting a PiNode is a safe fallback, and Word types need no additional
             * type information anyway.
             */
        if (targetType != null && !targetType.getType().isPrimitive() && !argument.getStackKind().isPrimitive()) {
            ResolvedJavaType argumentType = StampTool.typeOrNull(argument.stamp(NodeView.DEFAULT));
            if (argumentType == null || (argumentType.isAssignableFrom(targetType.getType()) && !argumentType.equals(targetType.getType()))) {
                LogicNode inst = InstanceOfNode.createAllowNull(targetType, argument, null, null);
                assert !inst.isAlive();
                if (!inst.isTautology()) {
                    inst = adder.add(inst);
                    AnchoringNode guardAnchor = adder.getGuardAnchor();
                    DeoptimizationReason reason = DeoptimizationReason.ClassCastException;
                    DeoptimizationAction action = DeoptimizationAction.InvalidateRecompile;
                    JavaConstant speculation = JavaConstant.NULL_POINTER;
                    GuardingNode guard;
                    if (guardAnchor == null) {
                        FixedGuardNode fixedGuard = adder.add(new FixedGuardNode(inst, reason, action, speculation, false));
                        guard = fixedGuard;
                    } else {
                        GuardNode newGuard = adder.add(new GuardNode(inst, guardAnchor, reason, action, false, speculation));
                        adder.add(new ValueAnchorNode(newGuard));
                        guard = newGuard;
                    }
                    ValueNode valueNode = adder.add(PiNode.create(argument, StampFactory.object(targetType), guard.asNode()));
                    arguments[index] = valueNode;
                }
            }
        }
    }
}
Also used : GuardNode(org.graalvm.compiler.nodes.GuardNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) AnchoringNode(org.graalvm.compiler.nodes.extended.AnchoringNode) JavaConstant(jdk.vm.ci.meta.JavaConstant) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) Assumptions(jdk.vm.ci.meta.Assumptions) ValueAnchorNode(org.graalvm.compiler.nodes.extended.ValueAnchorNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) DeoptimizationAction(jdk.vm.ci.meta.DeoptimizationAction) DeoptimizationReason(jdk.vm.ci.meta.DeoptimizationReason) GuardingNode(org.graalvm.compiler.nodes.extended.GuardingNode)

Example 5 with Assumptions

use of jdk.vm.ci.meta.Assumptions in project graal by oracle.

the class FinalizableSubclassTest method checkForRegisterFinalizeNode.

private void checkForRegisterFinalizeNode(Class<?> cl, boolean shouldContainFinalizer, AllowAssumptions allowAssumptions) {
    StructuredGraph graph = parseAndProcess(cl, allowAssumptions);
    Assert.assertTrue(graph.getNodes().filter(RegisterFinalizerNode.class).count() == (shouldContainFinalizer ? 1 : 0));
    int noFinalizerAssumption = 0;
    Assumptions assumptions = graph.getAssumptions();
    if (assumptions != null) {
        for (Assumption a : assumptions) {
            if (a instanceof NoFinalizableSubclass) {
                noFinalizerAssumption++;
            } else if (a instanceof LeafType) {
                // Need to also allow leaf type assumption instead of no finalizable subclass
                // assumption.
                noFinalizerAssumption++;
            }
        }
    }
    Assert.assertTrue(noFinalizerAssumption == (shouldContainFinalizer ? 0 : 1));
}
Also used : LeafType(jdk.vm.ci.meta.Assumptions.LeafType) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) AllowAssumptions(org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions) Assumptions(jdk.vm.ci.meta.Assumptions) NoFinalizableSubclass(jdk.vm.ci.meta.Assumptions.NoFinalizableSubclass) RegisterFinalizerNode(org.graalvm.compiler.nodes.java.RegisterFinalizerNode) Assumption(jdk.vm.ci.meta.Assumptions.Assumption)

Aggregations

Assumptions (jdk.vm.ci.meta.Assumptions)9 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)5 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)5 ValueNode (org.graalvm.compiler.nodes.ValueNode)5 TypeReference (org.graalvm.compiler.core.common.type.TypeReference)4 ResolvedJavaField (jdk.vm.ci.meta.ResolvedJavaField)2 DeoptimizeNode (org.graalvm.compiler.nodes.DeoptimizeNode)2 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)2 FixedNode (org.graalvm.compiler.nodes.FixedNode)2 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)2 InvokeNode (org.graalvm.compiler.nodes.InvokeNode)2 LogicNode (org.graalvm.compiler.nodes.LogicNode)2 ParameterNode (org.graalvm.compiler.nodes.ParameterNode)2 ReturnNode (org.graalvm.compiler.nodes.ReturnNode)2 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)2 AllowAssumptions (org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions)2 GuardingNode (org.graalvm.compiler.nodes.extended.GuardingNode)2 Method (java.lang.reflect.Method)1 Assumption (jdk.vm.ci.meta.Assumptions.Assumption)1 LeafType (jdk.vm.ci.meta.Assumptions.LeafType)1