diff truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/DirectCallNode.java @ 21951:9c8c0937da41

Moving all sources into truffle subdirectory
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Wed, 17 Jun 2015 10:58:08 +0200
parents graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/DirectCallNode.java@57f3498a51a4
children dc83cc1f94f2
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/DirectCallNode.java	Wed Jun 17 10:58:08 2015 +0200
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.nodes;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.frame.*;
+
+/**
+ * Represents a direct call to a {@link CallTarget}. Direct calls are calls for which the
+ * {@link CallTarget} remains the same for each consecutive call. This part of the Truffle API
+ * enables the runtime system to perform additional optimizations on direct calls.
+ *
+ * Optimizations that can be applied to a {@link DirectCallNode} are inlining and call site
+ * sensitive AST duplication. Inlining inlines this call site into the call graph of the parent
+ * {@link CallTarget}. Call site sensitive AST duplication duplicates the {@link CallTarget} in an
+ * uninitialized state to collect call site sensitive profiling information.
+ *
+ * Please note: This class is not intended to be subclassed by guest language implementations.
+ *
+ * @see IndirectCallNode for calls with a non-constant target
+ * @see TruffleRuntime#createDirectCallNode(CallTarget)
+ * @see #forceInlining()
+ * @see #cloneCallTarget()
+ */
+public abstract class DirectCallNode extends Node {
+
+    protected final CallTarget callTarget;
+
+    protected DirectCallNode(CallTarget callTarget) {
+        this.callTarget = callTarget;
+    }
+
+    /**
+     * Calls the inner {@link CallTarget} returned by {@link #getCurrentCallTarget()}.
+     *
+     * @param arguments the arguments that should be passed to the callee
+     * @return the return result of the call
+     */
+    public abstract Object call(VirtualFrame frame, Object[] arguments);
+
+    /**
+     * Returns the originally supplied {@link CallTarget} when this call node was created. Please
+     * note that the returned {@link CallTarget} is not necessarily the {@link CallTarget} that is
+     * called. For that use {@link #getCurrentCallTarget()} instead.
+     *
+     * @return the {@link CallTarget} provided.
+     */
+    public CallTarget getCallTarget() {
+        return callTarget;
+    }
+
+    /**
+     * Returns <code>true</code> if the underlying runtime system supports inlining for the
+     * {@link CallTarget} in this {@link DirectCallNode}.
+     *
+     * @return true if inlining is supported.
+     */
+    public abstract boolean isInlinable();
+
+    /**
+     * Returns <code>true</code> if the {@link CallTarget} is forced to be inlined. A
+     * {@link DirectCallNode} can either be inlined manually by invoking {@link #forceInlining()} or
+     * by the runtime system which may at any point decide to inline.
+     *
+     * @return true if this method was inlined else false.
+     */
+    public abstract boolean isInliningForced();
+
+    /**
+     * Enforces the runtime system to inline the {@link CallTarget} at this call site. If the
+     * runtime system does not support inlining or it is already inlined this method has no effect.
+     * The runtime system may decide to not inline calls which were forced to inline.
+     */
+    public abstract void forceInlining();
+
+    /**
+     * Returns true if the runtime system has decided to inline this call-site. If the
+     * {@link DirectCallNode} was forced to inline then this does not necessarily mean that the
+     * {@link DirectCallNode} is really going to be inlined. This depends on whether or not the
+     * runtime system supports inlining. The runtime system may also decide to not inline calls
+     * which were forced to inline.
+     *
+     * @deprecated we do not expose this information any longer. returns always false.
+     */
+    @SuppressWarnings("static-method")
+    @Deprecated
+    public final boolean isInlined() {
+        return false;
+    }
+
+    /**
+     * Returns <code>true</code> if the runtime system supports cloning and the {@link RootNode}
+     * returns <code>true</code> in {@link RootNode#isCloningAllowed()}.
+     *
+     * @return <code>true</code> if the target is allowed to be cloned.
+     */
+    public abstract boolean isCallTargetCloningAllowed();
+
+    /**
+     * Clones the {@link CallTarget} instance returned by {@link #getCallTarget()} in an
+     * uninitialized state for this {@link DirectCallNode}. This can be sensible to gather call site
+     * sensitive profiling information for this {@link DirectCallNode}. If
+     * {@link #isCallTargetCloningAllowed()} returns <code>false</code> this method has no effect
+     * and returns <code>false</code>.
+     */
+    public abstract boolean cloneCallTarget();
+
+    /**
+     * Returns <code>true</code> if the target of the {@link DirectCallNode} was cloned by the
+     * runtime system or by the guest language implementation.
+     *
+     * @return if the target was split
+     */
+    public final boolean isCallTargetCloned() {
+        return getClonedCallTarget() != null;
+    }
+
+    /**
+     * Returns the split {@link CallTarget} if this call site's {@link CallTarget} is cloned.
+     *
+     * @return the split {@link CallTarget}
+     */
+    public abstract CallTarget getClonedCallTarget();
+
+    /**
+     * Returns the used call target when {@link #call(VirtualFrame, Object[])} is invoked. If the
+     * {@link CallTarget} was split this method returns the {@link CallTarget} returned by
+     * {@link #getClonedCallTarget()}.
+     *
+     * @return the used {@link CallTarget} when node is called
+     */
+    public CallTarget getCurrentCallTarget() {
+        CallTarget split = getClonedCallTarget();
+        if (split != null) {
+            return split;
+        } else {
+            return getCallTarget();
+        }
+    }
+
+    /**
+     * Returns the {@link RootNode} associated with {@link CallTarget} returned by
+     * {@link #getCurrentCallTarget()}. If the stored {@link CallTarget} does not contain a
+     * {@link RootNode} this method returns <code>null</code>.
+     *
+     * @see #getCurrentCallTarget()
+     * @return the root node of the used call target
+     */
+    public final RootNode getCurrentRootNode() {
+        CallTarget target = getCurrentCallTarget();
+        if (target instanceof RootCallTarget) {
+            return ((RootCallTarget) target).getRootNode();
+        }
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s(target=%s)", getClass().getSimpleName(), getCurrentCallTarget());
+    }
+
+    public static DirectCallNode create(CallTarget target) {
+        return Truffle.getRuntime().createDirectCallNode(target);
+    }
+
+}