Search in sources :

Example 1 with Speculation

use of jdk.vm.ci.meta.SpeculationLog.Speculation 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;
                    Speculation speculation = SpeculationLog.NO_SPECULATION;
                    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, null));
                        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) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) Speculation(jdk.vm.ci.meta.SpeculationLog.Speculation) 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 2 with Speculation

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

the class VirtualFrameAccessorNode method insertDeoptimization.

protected final void insertDeoptimization(VirtualizerTool tool) {
    /*
         * Escape analysis does not allow insertion of a DeoptimizeNode. We work around this
         * restriction by inserting an always-failing guard, which will be canonicalized to a
         * DeoptimizeNode later on.
         */
    LogicNode condition = LogicConstantNode.contradiction();
    tool.addNode(condition);
    Speculation speculation = graph().getSpeculationLog().speculate(frame.getIntrinsifyAccessorsSpeculation());
    tool.addNode(new FixedGuardNode(condition, DeoptimizationReason.RuntimeConstraint, DeoptimizationAction.InvalidateReprofile, speculation, false));
    if (getStackKind() == JavaKind.Void) {
        tool.delete();
    } else {
        /*
             * Even though all usages will be eventually dead, we need to provide a valid
             * replacement value for now.
             */
        ConstantNode unusedValue = ConstantNode.forConstant(JavaConstant.defaultForKind(getStackKind()), tool.getMetaAccess());
        tool.addNode(unusedValue);
        tool.replaceWith(unusedValue);
    }
}
Also used : FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) LogicConstantNode(org.graalvm.compiler.nodes.LogicConstantNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) Speculation(jdk.vm.ci.meta.SpeculationLog.Speculation)

Example 3 with Speculation

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

the class TruffleBoundaryPhase method addDeoptimizeNode.

private static void addDeoptimizeNode(StructuredGraph graph, FixedNode originalNext, ResolvedJavaMethod targetMethod) {
    SpeculationLog speculationLog = graph.getSpeculationLog();
    if (speculationLog != null) {
        SpeculationReason speculationReason = PartialEvaluator.createTruffleBoundaryExceptionSpeculation(targetMethod);
        if (speculationLog.maySpeculate(speculationReason)) {
            Speculation exceptionSpeculation = speculationLog.speculate(speculationReason);
            DeoptimizeNode deoptimize = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.TransferToInterpreter, exceptionSpeculation));
            originalNext.replaceAtPredecessor(deoptimize);
            GraphUtil.killCFG(originalNext);
        }
    }
}
Also used : SpeculationLog(jdk.vm.ci.meta.SpeculationLog) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) Speculation(jdk.vm.ci.meta.SpeculationLog.Speculation) SpeculationReason(jdk.vm.ci.meta.SpeculationLog.SpeculationReason)

Example 4 with Speculation

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

the class TruffleGraphBuilderPlugins method registerFrameMethods.

private static void registerFrameMethods(Registration r, ConstantReflectionProvider constantReflection, KnownTruffleTypes types) {
    r.register(new RequiredInvocationPlugin("getArguments", Receiver.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver frame) {
            if (frame.get(false) instanceof NewFrameNode) {
                b.push(JavaKind.Object, ((NewFrameNode) frame.get()).getArguments());
                return true;
            }
            return false;
        }
    });
    r.register(new RequiredInvocationPlugin("getFrameDescriptor", Receiver.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver frame) {
            if (frame.get(false) instanceof NewFrameNode) {
                b.push(JavaKind.Object, ((NewFrameNode) frame.get()).getDescriptor());
                return true;
            }
            return false;
        }
    });
    r.register(new RequiredInvocationPlugin("materialize", Receiver.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            ValueNode frame = receiver.get();
            if (frame instanceof NewFrameNode && ((NewFrameNode) frame).getIntrinsifyAccessors()) {
                Speculation speculation = b.getGraph().getSpeculationLog().speculate(((NewFrameNode) frame).getIntrinsifyAccessorsSpeculation());
                b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.RuntimeConstraint, speculation));
                return true;
            }
            b.addPush(JavaKind.Object, new AllowMaterializeNode(frame));
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("clear", Receiver.class, new ResolvedJavaSymbol(types.classFrameSlot)) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode frameSlot) {
            int frameSlotIndex = maybeGetConstantFrameSlotIndex(receiver, frameSlot, constantReflection, types);
            if (frameSlotIndex >= 0) {
                TruffleCompilerRuntime runtime = getRuntime();
                b.add(new VirtualFrameClearNode(receiver, frameSlotIndex, runtime.getFrameSlotKindTagForJavaKind(JavaKind.Illegal), VirtualFrameAccessType.Legacy));
                return true;
            }
            return false;
        }
    });
    r.register(new RequiredInvocationPlugin("clear", Receiver.class, int.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode frameSlot) {
            int frameSlotIndex = maybeGetConstantNumberedFrameSlotIndex(receiver, frameSlot);
            if (frameSlotIndex >= 0) {
                TruffleCompilerRuntime runtime = getRuntime();
                b.add(new VirtualFrameClearNode(receiver, frameSlotIndex, runtime.getFrameSlotKindTagForJavaKind(JavaKind.Illegal), VirtualFrameAccessType.Indexed));
                return true;
            }
            return false;
        }
    });
    r.register(new RequiredInvocationPlugin("swap", Receiver.class, int.class, int.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode frameSlot1, ValueNode frameSlot2) {
            int frameSlot1Index = maybeGetConstantNumberedFrameSlotIndex(receiver, frameSlot1);
            int frameSlot2Index = maybeGetConstantNumberedFrameSlotIndex(receiver, frameSlot2);
            if (frameSlot1Index >= 0 && frameSlot2Index >= 0) {
                b.add(new VirtualFrameSwapNode(receiver, frameSlot1Index, frameSlot2Index, VirtualFrameAccessType.Indexed));
                return true;
            }
            return false;
        }
    });
    r.register(new RequiredInvocationPlugin("copy", Receiver.class, int.class, int.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode frameSlot1, ValueNode frameSlot2) {
            int frameSlot1Index = maybeGetConstantNumberedFrameSlotIndex(receiver, frameSlot1);
            int frameSlot2Index = maybeGetConstantNumberedFrameSlotIndex(receiver, frameSlot2);
            if (frameSlot1Index >= 0 && frameSlot2Index >= 0) {
                b.add(new VirtualFrameCopyNode(receiver, frameSlot1Index, frameSlot2Index, VirtualFrameAccessType.Indexed));
                return true;
            }
            return false;
        }
    });
}
Also used : VirtualFrameCopyNode(org.graalvm.compiler.truffle.compiler.nodes.frame.VirtualFrameCopyNode) VirtualFrameClearNode(org.graalvm.compiler.truffle.compiler.nodes.frame.VirtualFrameClearNode) NewFrameNode(org.graalvm.compiler.truffle.compiler.nodes.frame.NewFrameNode) RequiredInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin) TruffleCompilerRuntime(org.graalvm.compiler.truffle.common.TruffleCompilerRuntime) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) AllowMaterializeNode(org.graalvm.compiler.truffle.compiler.nodes.frame.AllowMaterializeNode) ResolvedJavaSymbol(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.ResolvedJavaSymbol) Speculation(jdk.vm.ci.meta.SpeculationLog.Speculation) VirtualFrameSwapNode(org.graalvm.compiler.truffle.compiler.nodes.frame.VirtualFrameSwapNode) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) ValueNode(org.graalvm.compiler.nodes.ValueNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 5 with Speculation

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

the class UseTrappingNullChecksPhase method tryUseTrappingNullCheck.

private static void tryUseTrappingNullCheck(MetaAccessProvider metaAccessProvider, DynamicDeoptimizeNode deopt, long implicitNullCheckLimit) {
    Node predecessor = deopt.predecessor();
    if (predecessor instanceof AbstractMergeNode) {
        AbstractMergeNode merge = (AbstractMergeNode) predecessor;
        // Process each predecessor at the merge, unpacking the reasons and speculations as
        // needed.
        ValueNode reason = deopt.getActionAndReason();
        ValuePhiNode reasonPhi = null;
        List<ValueNode> reasons = null;
        int expectedPhis = 0;
        if (reason instanceof ValuePhiNode) {
            reasonPhi = (ValuePhiNode) reason;
            if (reasonPhi.merge() != merge) {
                return;
            }
            reasons = reasonPhi.values().snapshot();
            expectedPhis++;
        } else if (!reason.isConstant()) {
            merge.getDebug().log("Non constant reason %s", merge);
            return;
        }
        ValueNode speculation = deopt.getSpeculation();
        ValuePhiNode speculationPhi = null;
        List<ValueNode> speculations = null;
        if (speculation instanceof ValuePhiNode) {
            speculationPhi = (ValuePhiNode) speculation;
            if (speculationPhi.merge() != merge) {
                return;
            }
            speculations = speculationPhi.values().snapshot();
            expectedPhis++;
        }
        if (merge.phis().count() != expectedPhis) {
            return;
        }
        int index = 0;
        List<EndNode> predecessors = merge.cfgPredecessors().snapshot();
        for (AbstractEndNode end : predecessors) {
            Node endPredecesssor = end.predecessor();
            ValueNode thisReason = reasons != null ? reasons.get(index) : reason;
            ValueNode thisSpeculation = speculations != null ? speculations.get(index) : speculation;
            if (!merge.isAlive()) {
                // must be handled specially.
                assert predecessors.get(predecessors.size() - 1) == end : "must be last end";
                endPredecesssor = deopt.predecessor();
                thisSpeculation = deopt.getSpeculation();
                thisReason = deopt.getActionAndReason();
            }
            index++;
            if (!thisReason.isConstant() || !thisSpeculation.isConstant()) {
                end.getDebug().log("Non constant deopt %s", end);
                continue;
            }
            DeoptimizationReason deoptimizationReason = metaAccessProvider.decodeDeoptReason(thisReason.asJavaConstant());
            Speculation speculationConstant = metaAccessProvider.decodeSpeculation(thisSpeculation.asJavaConstant(), deopt.graph().getSpeculationLog());
            tryUseTrappingNullCheck(deopt, endPredecesssor, deoptimizationReason, speculationConstant, implicitNullCheckLimit, thisReason.asJavaConstant(), thisSpeculation.asJavaConstant());
        }
    }
}
Also used : AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) DynamicDeoptimizeNode(org.graalvm.compiler.nodes.DynamicDeoptimizeNode) FixedAccessNode(org.graalvm.compiler.nodes.memory.FixedAccessNode) DeoptimizingFixedWithNextNode(org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IfNode(org.graalvm.compiler.nodes.IfNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) CompressionNode(org.graalvm.compiler.nodes.CompressionNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) AbstractDeoptimizeNode(org.graalvm.compiler.nodes.AbstractDeoptimizeNode) AddressNode(org.graalvm.compiler.nodes.memory.address.AddressNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) NullCheckNode(org.graalvm.compiler.nodes.extended.NullCheckNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) DeoptimizationReason(jdk.vm.ci.meta.DeoptimizationReason) Speculation(jdk.vm.ci.meta.SpeculationLog.Speculation)

Aggregations

Speculation (jdk.vm.ci.meta.SpeculationLog.Speculation)5 DeoptimizeNode (org.graalvm.compiler.nodes.DeoptimizeNode)3 LogicNode (org.graalvm.compiler.nodes.LogicNode)3 ValueNode (org.graalvm.compiler.nodes.ValueNode)3 DeoptimizationReason (jdk.vm.ci.meta.DeoptimizationReason)2 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)2 Assumptions (jdk.vm.ci.meta.Assumptions)1 DeoptimizationAction (jdk.vm.ci.meta.DeoptimizationAction)1 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)1 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)1 SpeculationLog (jdk.vm.ci.meta.SpeculationLog)1 SpeculationReason (jdk.vm.ci.meta.SpeculationLog.SpeculationReason)1 TypeReference (org.graalvm.compiler.core.common.type.TypeReference)1 Node (org.graalvm.compiler.graph.Node)1 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)1 AbstractDeoptimizeNode (org.graalvm.compiler.nodes.AbstractDeoptimizeNode)1 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)1 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)1 BeginNode (org.graalvm.compiler.nodes.BeginNode)1 CompressionNode (org.graalvm.compiler.nodes.CompressionNode)1