Search in sources :

Example 1 with RequiredInlineOnlyInvocationPlugin

use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin in project graal by oracle.

the class TruffleGraphBuilderPlugins method registerCompilerDirectivesPlugins.

public static void registerCompilerDirectivesPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, boolean canDelayIntrinsification) {
    final ResolvedJavaType compilerDirectivesType = getRuntime().resolveType(metaAccess, "com.oracle.truffle.api.CompilerDirectives");
    Registration r = new Registration(plugins, new ResolvedJavaSymbol(compilerDirectivesType));
    r.register(new RequiredInvocationPlugin("inInterpreter") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(false));
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("hasNextTier") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            if (!canDelayIntrinsification && b.getGraph().getCancellable() instanceof TruffleCompilationTask) {
                TruffleCompilationTask task = (TruffleCompilationTask) b.getGraph().getCancellable();
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(task.hasNextTier()));
                return true;
            }
            return false;
        }
    });
    r.register(new RequiredInvocationPlugin("inCompiledCode") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("inCompilationRoot") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            GraphBuilderContext.ExternalInliningContext inliningContext = b.getExternalInliningContext();
            if (inliningContext != null) {
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(inliningContext.getInlinedDepth() == 0));
                return true;
            }
            return false;
        }
    });
    r.register(new RequiredInvocationPlugin("transferToInterpreter") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter));
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("transferToInterpreterAndInvalidate") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter));
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("interpreterOnly", Runnable.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("interpreterOnly", Callable.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("injectBranchProbability", double.class, boolean.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode probability, ValueNode condition) {
            b.addPush(JavaKind.Boolean, new BranchProbabilityNode(probability, condition));
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("bailout", String.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode message) {
            if (canDelayIntrinsification) {
                /*
                     * We do not want to bailout yet, since we are still parsing individual methods
                     * and constant folding could still eliminate the call to bailout(). However, we
                     * also want to stop parsing, since we are sure that we will never need the
                     * graph beyond the bailout point.
                     *
                     * Therefore, we manually emit the call to bailout, which will be intrinsified
                     * later when intrinsifications can no longer be delayed. The call is followed
                     * by a NeverPartOfCompilationNode, which is a control sink and therefore stops
                     * any further parsing.
                     */
                StampPair returnStamp = b.getInvokeReturnStamp(b.getAssumptions());
                CallTargetNode callTarget = b.add(new MethodCallTargetNode(InvokeKind.Static, targetMethod, new ValueNode[] { message }, returnStamp, null));
                b.add(new InvokeNode(callTarget, b.bci()));
                b.add(new NeverPartOfCompilationNode("intrinsification of call to bailout() will abort entire compilation"));
                return true;
            }
            if (message.isConstant()) {
                throw b.bailout(message.asConstant().toValueString());
            }
            throw b.bailout("bailout (message is not compile-time constant, so no additional information is available)");
        }
    });
    r.register(new RequiredInvocationPlugin("isCompilationConstant", Object.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            if ((value instanceof BoxNode ? ((BoxNode) value).getValue() : value).isConstant()) {
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
            } else {
                b.addPush(JavaKind.Boolean, new IsCompilationConstantNode(value));
            }
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("isPartialEvaluationConstant", Object.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            if ((value instanceof BoxNode ? ((BoxNode) value).getValue() : value).isConstant()) {
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
            } else if (canDelayIntrinsification) {
                return false;
            } else {
                b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(false));
            }
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("materialize", Object.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            AllowMaterializeNode materializedValue = b.append(new AllowMaterializeNode(value));
            b.add(new ForceMaterializeNode(materializedValue));
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("ensureVirtualized", Object.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
            b.add(new EnsureVirtualizedNode(object, false));
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("ensureVirtualizedHere", Object.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
            b.add(new EnsureVirtualizedNode(object, true));
            return true;
        }
    });
    for (JavaKind kind : JavaKind.values()) {
        if ((kind.isPrimitive() && kind != JavaKind.Void) || kind == JavaKind.Object) {
            Class<?> javaClass = getJavaClass(kind);
            r.register(new RequiredInlineOnlyInvocationPlugin("blackhole", javaClass) {

                @Override
                public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
                    b.add(new BlackholeNode(value));
                    return true;
                }
            });
        }
    }
    r.register(new RequiredInvocationPlugin("castExact", Object.class, Class.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object, ValueNode javaClass) {
            ValueNode nullCheckedClass = b.addNonNullCast(javaClass);
            LogicNode condition = b.append(InstanceOfDynamicNode.create(b.getAssumptions(), b.getConstantReflection(), nullCheckedClass, object, true, true));
            if (condition.isTautology()) {
                b.addPush(JavaKind.Object, object);
            } else {
                FixedGuardNode fixedGuard = b.add(new FixedGuardNode(condition, DeoptimizationReason.ClassCastException, DeoptimizationAction.InvalidateReprofile, false));
                b.addPush(JavaKind.Object, DynamicPiNode.create(b.getAssumptions(), b.getConstantReflection(), object, fixedGuard, nullCheckedClass, true, true));
            }
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("isExact", Object.class, Class.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object, ValueNode javaClass) {
            ValueNode nullCheckedClass = b.addNonNullCast(javaClass);
            LogicNode condition = b.append(InstanceOfDynamicNode.create(b.getAssumptions(), b.getConstantReflection(), nullCheckedClass, object, false, true));
            b.addPush(JavaKind.Boolean, b.append(new ConditionalNode(condition)));
            return true;
        }
    });
}
Also used : EnsureVirtualizedNode(org.graalvm.compiler.nodes.virtual.EnsureVirtualizedNode) RequiredInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin) BoxNode(org.graalvm.compiler.nodes.extended.BoxNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) Callable(java.util.concurrent.Callable) IsCompilationConstantNode(org.graalvm.compiler.truffle.compiler.nodes.IsCompilationConstantNode) ConditionalNode(org.graalvm.compiler.nodes.calc.ConditionalNode) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) StampPair(org.graalvm.compiler.core.common.type.StampPair) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) JavaKind(jdk.vm.ci.meta.JavaKind) RequiredInlineOnlyInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) BranchProbabilityNode(org.graalvm.compiler.nodes.extended.BranchProbabilityNode) AllowMaterializeNode(org.graalvm.compiler.truffle.compiler.nodes.frame.AllowMaterializeNode) ResolvedJavaSymbol(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.ResolvedJavaSymbol) NeverPartOfCompilationNode(org.graalvm.compiler.truffle.compiler.nodes.asserts.NeverPartOfCompilationNode) ForceMaterializeNode(org.graalvm.compiler.truffle.compiler.nodes.frame.ForceMaterializeNode) TruffleCompilationTask(org.graalvm.compiler.truffle.common.TruffleCompilationTask) BlackholeNode(org.graalvm.compiler.nodes.debug.BlackholeNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) ValueNode(org.graalvm.compiler.nodes.ValueNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode)

Example 2 with RequiredInlineOnlyInvocationPlugin

use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin in project graal by oracle.

the class SubstrateGraphBuilderPlugins method registerReflectionPlugins.

private static void registerReflectionPlugins(InvocationPlugins plugins, Replacements replacements) {
    Registration r = new Registration(plugins, "jdk.internal.reflect.Reflection", replacements);
    r.register(new RequiredInlineOnlyInvocationPlugin("getCallerClass") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Object, new SubstrateReflectionGetCallerClassNode(MacroParams.of(b, targetMethod)));
            return true;
        }
    });
}
Also used : SubstrateReflectionGetCallerClassNode(com.oracle.svm.core.graal.nodes.SubstrateReflectionGetCallerClassNode) RequiredInlineOnlyInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 3 with RequiredInlineOnlyInvocationPlugin

use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin in project graal by oracle.

the class ReflectionPlugins method registerMethodHandlesPlugins.

private void registerMethodHandlesPlugins(InvocationPlugins plugins) {
    registerFoldInvocationPlugins(plugins, MethodHandles.class, "publicLookup", "privateLookupIn", "arrayConstructor", "arrayLength", "arrayElementGetter", "arrayElementSetter", "arrayElementVarHandle", "byteArrayViewVarHandle", "byteBufferViewVarHandle");
    registerFoldInvocationPlugins(plugins, MethodHandles.Lookup.class, "in", "findStatic", "findVirtual", "findConstructor", "findClass", "accessClass", "findSpecial", "findGetter", "findSetter", "findVarHandle", "findStaticGetter", "findStaticSetter", "findStaticVarHandle", "unreflect", "unreflectSpecial", "unreflectConstructor", "unreflectGetter", "unreflectSetter", "unreflectVarHandle");
    registerFoldInvocationPlugins(plugins, MethodType.class, "methodType", "genericMethodType", "changeParameterType", "insertParameterTypes", "appendParameterTypes", "replaceParameterTypes", "dropParameterTypes", "changeReturnType", "erase", "generic", "wrap", "unwrap", "parameterType", "parameterCount", "returnType", "lastParameterType");
    Registration r = new Registration(plugins, MethodHandles.class);
    r.register(new RequiredInlineOnlyInvocationPlugin("lookup") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            return processMethodHandlesLookup(b, targetMethod);
        }
    });
}
Also used : MethodHandles(java.lang.invoke.MethodHandles) RequiredInlineOnlyInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 4 with RequiredInlineOnlyInvocationPlugin

use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin in project graal by oracle.

the class StandardGraphBuilderPlugins method registerGraalDirectivesPlugins.

private static void registerGraalDirectivesPlugins(InvocationPlugins plugins, SnippetReflectionProvider snippetReflection) {
    Registration r = new Registration(plugins, GraalDirectives.class);
    r.register(new DeoptimizePlugin(snippetReflection, None, TransferToInterpreter, false, "deoptimize"));
    r.register(new DeoptimizePlugin(snippetReflection, InvalidateReprofile, TransferToInterpreter, false, "deoptimizeAndInvalidate"));
    r.register(new DeoptimizePlugin(snippetReflection, null, null, null, "deoptimize", DeoptimizationAction.class, DeoptimizationReason.class, boolean.class));
    r.register(new DeoptimizePlugin(snippetReflection, null, null, null, "deoptimize", DeoptimizationAction.class, DeoptimizationReason.class, SpeculationReason.class));
    r.register(new RequiredInlineOnlyInvocationPlugin("inCompiledCode") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
            return true;
        }
    });
    r.register(new RequiredInlineOnlyInvocationPlugin("inIntrinsic") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(b.parsingIntrinsic()));
            return true;
        }
    });
    r.register(new RequiredInlineOnlyInvocationPlugin("controlFlowAnchor") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new ControlFlowAnchorNode());
            return true;
        }
    });
    r.register(new RequiredInlineOnlyInvocationPlugin("neverStripMine") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new NeverStripMineNode());
            return true;
        }
    });
    r.register(new RequiredInlineOnlyInvocationPlugin("sideEffect") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new SideEffectNode());
            return true;
        }
    });
    r.register(new RequiredInlineOnlyInvocationPlugin("sideEffect", int.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode a) {
            b.addPush(JavaKind.Int, new SideEffectNode(a));
            return true;
        }
    });
    r.register(new RequiredInlineOnlyInvocationPlugin("trustedBox", Object.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode a) {
            b.addPush(JavaKind.Object, new TrustedBoxedValue(a));
            return true;
        }
    });
    r.register(new RequiredInlineOnlyInvocationPlugin("assumeStableDimension", Object.class, int.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode array, ValueNode dimension) {
            if (array instanceof ConstantNode && b.getMetaAccess().lookupJavaType(array.asJavaConstant()).isArray()) {
                if (dimension instanceof ConstantNode && dimension.stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
                    int stableDim = dimension.asJavaConstant().asInt();
                    ConstantNode c = ConstantNode.forConstant(array.asJavaConstant(), stableDim, false, b.getMetaAccess());
                    b.addPush(JavaKind.Object, c);
                    return true;
                }
            }
            throw GraalError.shouldNotReachHere("Illegal usage of stable array intrinsic assumeStableDimension(array, dimension): " + "This compiler intrinsic can only be used iff array is a constant node (i.e., constant field) and iff " + "dimension is a constant int. It will replace the constant array with a new constant that additionally sets the stable" + "dimensions to the int parameter supplied.");
        }
    });
    r.register(new RequiredInlineOnlyInvocationPlugin("injectBranchProbability", double.class, boolean.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode probability, ValueNode condition) {
            b.addPush(JavaKind.Boolean, new BranchProbabilityNode(probability, condition));
            return true;
        }
    });
    r.register(new RequiredInlineOnlyInvocationPlugin("injectIterationCount", double.class, boolean.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode iterations, ValueNode condition) {
            // injectBranchProbability(1. - 1. / iterations, condition)
            if (iterations.isJavaConstant()) {
                double iterationsConstant;
                if (iterations.stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
                    iterationsConstant = iterations.asJavaConstant().asLong();
                } else if (iterations.stamp(NodeView.DEFAULT) instanceof FloatStamp) {
                    iterationsConstant = iterations.asJavaConstant().asDouble();
                } else {
                    return false;
                }
                double probability = 1. - 1. / iterationsConstant;
                ValueNode probabilityNode = b.add(ConstantNode.forDouble(probability));
                b.addPush(JavaKind.Boolean, new BranchProbabilityNode(probabilityNode, condition));
                return true;
            }
            return false;
        }
    });
    for (JavaKind kind : JavaKind.values()) {
        if ((kind.isPrimitive() && kind != JavaKind.Void) || kind == JavaKind.Object) {
            Class<?> javaClass = getJavaClass(kind);
            r.register(new RequiredInlineOnlyInvocationPlugin("blackhole", javaClass) {

                @Override
                public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
                    b.add(new BlackholeNode(value));
                    return true;
                }
            });
            r.register(new RequiredInlineOnlyInvocationPlugin("bindToRegister", javaClass) {

                @Override
                public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
                    b.add(new BindToRegisterNode(value));
                    return true;
                }
            });
            r.register(new RequiredInvocationPlugin("opaque", javaClass) {

                @Override
                public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
                    b.addPush(kind, new OpaqueNode(value));
                    return true;
                }
            });
        }
    }
    r.register(new RequiredInlineOnlyInvocationPlugin("spillRegisters") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new SpillRegistersNode());
            return true;
        }
    });
    r.register(new RequiredInlineOnlyInvocationPlugin("guardingNonNull", Object.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
            b.addPush(value.getStackKind(), b.nullCheckedValue(value));
            return true;
        }
    });
    r.register(new RequiredInlineOnlyInvocationPlugin("ensureVirtualized", Object.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
            b.add(new EnsureVirtualizedNode(object, false));
            return true;
        }
    });
    r.register(new RequiredInlineOnlyInvocationPlugin("ensureVirtualizedHere", Object.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
            b.add(new EnsureVirtualizedNode(object, true));
            return true;
        }
    });
    r.register(new RequiredInvocationPlugin("breakpoint") {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
            b.add(new BreakpointNode());
            return true;
        }
    });
    for (JavaKind kind : JavaKind.values()) {
        if ((kind.isPrimitive() && kind != JavaKind.Void) || kind == JavaKind.Object) {
            Class<?> javaClass = getJavaClass(kind);
            r.register(new RequiredInlineOnlyInvocationPlugin("isCompilationConstant", javaClass) {

                @Override
                public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
                    b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(value.isJavaConstant()));
                    return true;
                }
            });
        }
    }
}
Also used : EnsureVirtualizedNode(org.graalvm.compiler.nodes.virtual.EnsureVirtualizedNode) SpillRegistersNode(org.graalvm.compiler.nodes.debug.SpillRegistersNode) RequiredInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin) BreakpointNode(org.graalvm.compiler.nodes.BreakpointNode) OpaqueNode(org.graalvm.compiler.nodes.extended.OpaqueNode) SideEffectNode(org.graalvm.compiler.nodes.debug.SideEffectNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) DeoptimizationReason(jdk.vm.ci.meta.DeoptimizationReason) NeverStripMineNode(org.graalvm.compiler.nodes.debug.NeverStripMineNode) JavaKind(jdk.vm.ci.meta.JavaKind) BindToRegisterNode(org.graalvm.compiler.nodes.debug.BindToRegisterNode) RequiredInlineOnlyInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) BranchProbabilityNode(org.graalvm.compiler.nodes.extended.BranchProbabilityNode) FloatStamp(org.graalvm.compiler.core.common.type.FloatStamp) SpeculationReason(jdk.vm.ci.meta.SpeculationLog.SpeculationReason) TrustedBoxedValue(org.graalvm.compiler.nodes.extended.BoxNode.TrustedBoxedValue) BlackholeNode(org.graalvm.compiler.nodes.debug.BlackholeNode) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) IntegerStamp(org.graalvm.compiler.core.common.type.IntegerStamp) ControlFlowAnchorNode(org.graalvm.compiler.nodes.debug.ControlFlowAnchorNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) DeoptimizationAction(jdk.vm.ci.meta.DeoptimizationAction) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Example 5 with RequiredInlineOnlyInvocationPlugin

use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin in project graal by oracle.

the class StandardGraphBuilderPlugins method registerMethodHandleImplPlugins.

private static void registerMethodHandleImplPlugins(InvocationPlugins plugins, Replacements replacements) {
    Registration r = new Registration(plugins, "java.lang.invoke.MethodHandleImpl", replacements);
    // In later JDKs this no longer exists and the usage is replace by Class.cast which is
    // already an intrinsic
    r.register(new OptionalInvocationPlugin("castReference", Class.class, Object.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode javaClass, ValueNode object) {
            b.genCheckcastDynamic(object, javaClass);
            return true;
        }

        @Override
        public boolean inlineOnly() {
            return true;
        }
    });
    r.register(new InlineOnlyInvocationPlugin("profileBoolean", boolean.class, int[].class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode result, ValueNode counters) {
            if (b.needsExplicitException()) {
                return false;
            }
            if (result.isConstant()) {
                b.push(JavaKind.Boolean, result);
                return true;
            }
            if (counters.isConstant()) {
                ValueNode newResult = result;
                int[] ctrs = ConstantReflectionUtil.loadIntArrayConstant(b.getConstantReflection(), (JavaConstant) counters.asConstant(), 2);
                if (ctrs != null && ctrs.length == 2) {
                    int falseCount = ctrs[0];
                    int trueCount = ctrs[1];
                    int totalCount = trueCount + falseCount;
                    if (totalCount == 0) {
                        b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter));
                    } else if (falseCount == 0 || trueCount == 0) {
                        boolean expected = falseCount == 0;
                        LogicNode condition = b.add(IntegerEqualsNode.create(b.getConstantReflection(), b.getMetaAccess(), b.getOptions(), null, result, b.add(ConstantNode.forBoolean(!expected)), NodeView.DEFAULT));
                        b.append(new FixedGuardNode(condition, DeoptimizationReason.UnreachedCode, DeoptimizationAction.InvalidateReprofile, true));
                        newResult = b.add(ConstantNode.forBoolean(expected));
                    } else {
                    // We cannot use BranchProbabilityNode here since there's no guarantee
                    // the result of MethodHandleImpl.profileBoolean() is used as the
                    // test in an `if` statement (as required by BranchProbabilityNode).
                    }
                }
                b.addPush(JavaKind.Boolean, newResult);
                return true;
            }
            b.addPush(JavaKind.Boolean, new ProfileBooleanNode(b.getConstantReflection(), MacroParams.of(b, targetMethod, result, counters)));
            return true;
        }
    });
    r.register(new RequiredInlineOnlyInvocationPlugin("isCompileConstant", Object.class) {

        @Override
        public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode obj) {
            b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(obj.isConstant()));
            return true;
        }
    });
}
Also used : ProfileBooleanNode(org.graalvm.compiler.replacements.nodes.ProfileBooleanNode) RequiredInlineOnlyInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin) Receiver(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver) JavaConstant(jdk.vm.ci.meta.JavaConstant) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) OptionalInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.OptionalInvocationPlugin) GraphBuilderContext(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext) Registration(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration) RequiredInlineOnlyInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin) InlineOnlyInvocationPlugin(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.InlineOnlyInvocationPlugin) ValueNode(org.graalvm.compiler.nodes.ValueNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod)

Aggregations

ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)5 GraphBuilderContext (org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext)5 Receiver (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver)5 RequiredInlineOnlyInvocationPlugin (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInlineOnlyInvocationPlugin)5 Registration (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration)5 ValueNode (org.graalvm.compiler.nodes.ValueNode)3 JavaKind (jdk.vm.ci.meta.JavaKind)2 DeoptimizeNode (org.graalvm.compiler.nodes.DeoptimizeNode)2 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)2 LogicNode (org.graalvm.compiler.nodes.LogicNode)2 BlackholeNode (org.graalvm.compiler.nodes.debug.BlackholeNode)2 BranchProbabilityNode (org.graalvm.compiler.nodes.extended.BranchProbabilityNode)2 RequiredInvocationPlugin (org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin)2 EnsureVirtualizedNode (org.graalvm.compiler.nodes.virtual.EnsureVirtualizedNode)2 SubstrateReflectionGetCallerClassNode (com.oracle.svm.core.graal.nodes.SubstrateReflectionGetCallerClassNode)1 MethodHandles (java.lang.invoke.MethodHandles)1 Callable (java.util.concurrent.Callable)1 DeoptimizationAction (jdk.vm.ci.meta.DeoptimizationAction)1 DeoptimizationReason (jdk.vm.ci.meta.DeoptimizationReason)1 JavaConstant (jdk.vm.ci.meta.JavaConstant)1