Search in sources :

Example 1 with TruffleCompilationTask

use of org.graalvm.compiler.truffle.common.TruffleCompilationTask 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 TruffleCompilationTask

use of org.graalvm.compiler.truffle.common.TruffleCompilationTask in project graal by oracle.

the class TruffleBoundaryExceptionsTest method testExceptionOnTruffleBoundaryDeoptsOnce.

@Test
@SuppressWarnings("try")
public void testExceptionOnTruffleBoundaryDeoptsOnce() {
    class DeoptCountingExceptionOverBoundaryRootNode extends RootNode {

        protected DeoptCountingExceptionOverBoundaryRootNode() {
            super(null);
        }

        int deoptCounter = 0;

        int catchCounter = 0;

        int interpretCount = 0;

        @Override
        public Object execute(VirtualFrame frame) {
            boolean startedCompiled = CompilerDirectives.inCompiledCode();
            if (!startedCompiled) {
                interpretCount++;
            }
            try {
                throwExceptionBoundary();
            } catch (RuntimeException e) {
                catchCounter++;
            }
            if (startedCompiled && CompilerDirectives.inInterpreter()) {
                deoptCounter++;
            }
            return null;
        }

        @CompilerDirectives.TruffleBoundary
        public void throwExceptionBoundary() {
            throw new RuntimeException();
        }
    }
    final int[] compilationCount = { 0 };
    GraalTruffleRuntimeListener listener = new GraalTruffleRuntimeListener() {

        @Override
        public void onCompilationStarted(OptimizedCallTarget target, TruffleCompilationTask task) {
            compilationCount[0]++;
        }
    };
    setupContext("engine.InvalidationReprofileCount", "0", "engine.MultiTier", "false");
    DeoptCountingExceptionOverBoundaryRootNode rootNode = new DeoptCountingExceptionOverBoundaryRootNode();
    final OptimizedCallTarget outerTarget = (OptimizedCallTarget) rootNode.getCallTarget();
    final int compilationThreshold = outerTarget.getOptionValue(SingleTierCompilationThreshold);
    for (int i = 0; i < compilationThreshold; i++) {
        outerTarget.call();
    }
    // deoptimizes immediately due to the exception
    assertEquals("Incorrect number of deopts detected!", 1, rootNode.deoptCounter);
    assertNotCompiled(outerTarget);
    // recompile with exception branch
    outerTarget.call();
    assertCompiled(outerTarget);
    runtime.addListener(listener);
    try {
        final int execCount = 10;
        for (int i = 0; i < execCount; i++) {
            outerTarget.call();
        }
        final int totalExecutions = compilationThreshold + 1 + execCount;
        assertEquals("Incorrect number of catch block executions", totalExecutions, rootNode.catchCounter);
        assertEquals("Incorrect number of interpreted executions", compilationThreshold - 1, rootNode.interpretCount);
        assertEquals("Incorrect number of deopts detected!", 1, rootNode.deoptCounter);
        assertEquals("Compilation happened!", 0, compilationCount[0]);
    } finally {
        runtime.removeListener(listener);
    }
}
Also used : VirtualFrame(com.oracle.truffle.api.frame.VirtualFrame) RootNode(com.oracle.truffle.api.nodes.RootNode) GraalTruffleRuntimeListener(org.graalvm.compiler.truffle.runtime.GraalTruffleRuntimeListener) OptimizedCallTarget(org.graalvm.compiler.truffle.runtime.OptimizedCallTarget) TruffleCompilationTask(org.graalvm.compiler.truffle.common.TruffleCompilationTask) Test(org.junit.Test)

Example 3 with TruffleCompilationTask

use of org.graalvm.compiler.truffle.common.TruffleCompilationTask in project graal by oracle.

the class IsolateAwareTruffleCompiler method doCompile0.

@CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class)
@CEntryPointOptions(publishAs = CEntryPointOptions.Publish.NotPublished)
private static ClientHandle<String> doCompile0(@SuppressWarnings("unused") @CEntryPoint.IsolateThreadContext CompilerIsolateThread context, ClientIsolateThread client, ImageHeapRef<SubstrateTruffleCompiler> delegateRef, ClientHandle<TruffleCompilationIdentifier> compilationIdentifierHandle, ClientHandle<SubstrateCompilableTruffleAST> compilableHandle, ClientHandle<byte[]> encodedOptionsHandle, int encodedOptionsLength, ClientHandle<TruffleCompilationTask> taskHandle, ClientHandle<IsolatedEventContext> eventContextHandle, boolean firstCompilation) {
    IsolatedCompileContext.set(new IsolatedCompileContext(client));
    try {
        SubstrateTruffleCompiler delegate = ImageHeapObjects.deref(delegateRef);
        Map<String, Object> options = decodeOptions(client, encodedOptionsHandle, encodedOptionsLength);
        IsolatedCompilableTruffleAST compilable = new IsolatedCompilableTruffleAST(compilableHandle);
        delegate.initialize(options, compilable, firstCompilation);
        TruffleCompilation compilation = new IsolatedCompilationIdentifier(compilationIdentifierHandle, compilable);
        TruffleCompilationTask task = null;
        if (taskHandle.notEqual(IsolatedHandles.nullHandle())) {
            task = new IsolatedTruffleCompilationTask(taskHandle);
        }
        TruffleCompilerListener listener = null;
        if (eventContextHandle.notEqual(IsolatedHandles.nullHandle())) {
            listener = new IsolatedTruffleCompilerEventForwarder(eventContextHandle);
        }
        delegate.doCompile(null, compilation, options, task, listener);
        // no exception
        return IsolatedHandles.nullHandle();
    } catch (Throwable t) {
        StringWriter writer = new StringWriter();
        t.printStackTrace(new PrintWriter(writer));
        return IsolatedCompileContext.get().createStringInClient(writer.toString());
    } finally {
        /*
             * Compilation isolate do not use a dedicated reference handler thread, so we trigger
             * the reference handling manually when a compilation finishes.
             */
        Heap.getHeap().doReferenceHandling();
        IsolatedCompileContext.set(null);
    }
}
Also used : TruffleCompilation(org.graalvm.compiler.truffle.common.TruffleCompilation) IsolatedCompileContext(com.oracle.svm.graal.isolated.IsolatedCompileContext) TruffleCompilationTask(org.graalvm.compiler.truffle.common.TruffleCompilationTask) SubstrateTruffleCompiler(com.oracle.svm.truffle.api.SubstrateTruffleCompiler) StringWriter(java.io.StringWriter) PinnedObject(org.graalvm.nativeimage.PinnedObject) TruffleCompilerListener(org.graalvm.compiler.truffle.common.TruffleCompilerListener) PrintWriter(java.io.PrintWriter) CEntryPoint(org.graalvm.nativeimage.c.function.CEntryPoint) CEntryPointOptions(com.oracle.svm.core.c.function.CEntryPointOptions)

Example 4 with TruffleCompilationTask

use of org.graalvm.compiler.truffle.common.TruffleCompilationTask in project graal by oracle.

the class GraalTruffleRuntime method doCompile.

protected final void doCompile(TruffleDebugContext debug, OptimizedCallTarget callTarget, TruffleCompilationTask task) {
    Objects.requireNonNull(callTarget, "Cannot compile null call target.");
    Objects.requireNonNull(task, "Compilation task required.");
    List<OptimizedCallTarget> oldBlockCompilations = callTarget.blockCompilations;
    if (oldBlockCompilations != null) {
        for (OptimizedCallTarget blockTarget : oldBlockCompilations) {
            if (blockTarget.isValid()) {
                continue;
            }
            listeners.onCompilationQueued(blockTarget, task.tier());
            int nodeCount = blockTarget.getNonTrivialNodeCount();
            if (nodeCount > callTarget.engine.getEngineOptions().get(PolyglotCompilerOptions.PartialBlockMaximumSize)) {
                listeners.onCompilationDequeued(blockTarget, null, "Partial block is too big to be compiled.", task.tier());
                continue;
            }
            compileImpl(debug, blockTarget, task);
        }
    }
    compileImpl(debug, callTarget, task);
    if (oldBlockCompilations == null && callTarget.blockCompilations != null) {
        // retry with block compilations
        ((CompilationTask) task).reset();
        listeners.onCompilationQueued(callTarget, task.tier());
        doCompile(callTarget, task);
    }
}
Also used : TruffleSafepoint(com.oracle.truffle.api.TruffleSafepoint) TruffleCompilationTask(org.graalvm.compiler.truffle.common.TruffleCompilationTask)

Example 5 with TruffleCompilationTask

use of org.graalvm.compiler.truffle.common.TruffleCompilationTask in project graal by oracle.

the class AgnosticInliningPhaseTest method runLanguageAgnosticInliningPhase.

protected StructuredGraph runLanguageAgnosticInliningPhase(OptimizedCallTarget callTarget) {
    final PartialEvaluator partialEvaluator = getTruffleCompiler(callTarget).getPartialEvaluator();
    final CompilationIdentifier compilationIdentifier = new CompilationIdentifier() {

        @Override
        public String toString(Verbosity verbosity) {
            return "";
        }
    };
    final PartialEvaluator.Request request = partialEvaluator.new Request(callTarget.getOptionValues(), getDebugContext(), callTarget, partialEvaluator.rootForCallTarget(callTarget), compilationIdentifier, getSpeculationLog(), new TruffleCompilerImpl.CancellableTruffleCompilationTask(new TruffleCompilationTask() {

        private TruffleInliningData inlining = new TruffleInlining();

        @Override
        public boolean isCancelled() {
            return false;
        }

        @Override
        public boolean isLastTier() {
            return true;
        }

        @Override
        public TruffleInliningData inliningData() {
            return inlining;
        }

        @Override
        public boolean hasNextTier() {
            return false;
        }
    }));
    final AgnosticInliningPhase agnosticInliningPhase = new AgnosticInliningPhase(partialEvaluator, request);
    agnosticInliningPhase.apply(request.graph, getTruffleCompiler(callTarget).getPartialEvaluator().getProviders());
    return request.graph;
}
Also used : PartialEvaluator(org.graalvm.compiler.truffle.compiler.PartialEvaluator) CompilationIdentifier(org.graalvm.compiler.core.common.CompilationIdentifier) TruffleCompilerImpl(org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl) TruffleInlining(org.graalvm.compiler.truffle.runtime.TruffleInlining) TruffleInliningData(org.graalvm.compiler.truffle.common.TruffleInliningData) TruffleCompilationTask(org.graalvm.compiler.truffle.common.TruffleCompilationTask) AgnosticInliningPhase(org.graalvm.compiler.truffle.compiler.phases.inlining.AgnosticInliningPhase)

Aggregations

TruffleCompilationTask (org.graalvm.compiler.truffle.common.TruffleCompilationTask)7 CompilationIdentifier (org.graalvm.compiler.core.common.CompilationIdentifier)2 TruffleCompilerListener (org.graalvm.compiler.truffle.common.TruffleCompilerListener)2 TruffleInliningData (org.graalvm.compiler.truffle.common.TruffleInliningData)2 TruffleCompilerImpl (org.graalvm.compiler.truffle.compiler.TruffleCompilerImpl)2 OptimizedCallTarget (org.graalvm.compiler.truffle.runtime.OptimizedCallTarget)2 TruffleInlining (org.graalvm.compiler.truffle.runtime.TruffleInlining)2 CEntryPointOptions (com.oracle.svm.core.c.function.CEntryPointOptions)1 IsolatedCompileContext (com.oracle.svm.graal.isolated.IsolatedCompileContext)1 SubstrateTruffleCompiler (com.oracle.svm.truffle.api.SubstrateTruffleCompiler)1 TruffleSafepoint (com.oracle.truffle.api.TruffleSafepoint)1 VirtualFrame (com.oracle.truffle.api.frame.VirtualFrame)1 RootNode (com.oracle.truffle.api.nodes.RootNode)1 PrintWriter (java.io.PrintWriter)1 StringWriter (java.io.StringWriter)1 Callable (java.util.concurrent.Callable)1 JavaKind (jdk.vm.ci.meta.JavaKind)1 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)1 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)1 StampPair (org.graalvm.compiler.core.common.type.StampPair)1