001/*
002 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.nodes.spi;
024
025import java.lang.reflect.*;
026import java.util.*;
027
028import jdk.internal.jvmci.meta.*;
029
030import com.oracle.graal.api.replacements.*;
031import com.oracle.graal.nodes.*;
032
033/**
034 * Interface for managing replacements.
035 */
036public interface Replacements {
037
038    /**
039     * Gets the snippet graph derived from a given method.
040     *
041     * @param args arguments to the snippet if available, otherwise {@code null}
042     * @return the snippet graph, if any, that is derived from {@code method}
043     */
044    StructuredGraph getSnippet(ResolvedJavaMethod method, Object[] args);
045
046    /**
047     * Gets the snippet graph derived from a given method.
048     *
049     * @param recursiveEntry if the snippet contains a call to this method, it's considered as
050     *            recursive call and won't be processed for {@linkplain MethodSubstitution
051     *            substitutions}.
052     * @param args arguments to the snippet if available, otherwise {@code null}
053     * @return the snippet graph, if any, that is derived from {@code method}
054     */
055    StructuredGraph getSnippet(ResolvedJavaMethod method, ResolvedJavaMethod recursiveEntry, Object[] args);
056
057    /**
058     * Registers a method as snippet.
059     */
060    void registerSnippet(ResolvedJavaMethod method);
061
062    /**
063     * Gets a graph that is a substitution for a given method.
064     *
065     * @param invokeBci the call site BCI if this request is made for inlining a substitute
066     *            otherwise {@code -1}
067     * @return the graph, if any, that is a substitution for {@code method}
068     */
069    default StructuredGraph getSubstitution(ResolvedJavaMethod method, int invokeBci) {
070        return getSubstitution(method, false, invokeBci);
071    }
072
073    /**
074     * Gets a graph that is a substitution for a given method.
075     *
076     * @param fromBytecodeOnly only return a graph created by parsing the bytecode of another method
077     * @param invokeBci the call site BCI if this request is made for inlining a substitute
078     *            otherwise {@code -1}
079     * @return the graph, if any, that is a substitution for {@code method}
080     */
081    StructuredGraph getSubstitution(ResolvedJavaMethod method, boolean fromBytecodeOnly, int invokeBci);
082
083    /**
084     * Gets a method that is a substitution for a given method.
085     *
086     * @return the method, if any, whose bytecode are a substitution for {@code method}
087     */
088    ResolvedJavaMethod getSubstitutionMethod(ResolvedJavaMethod method);
089
090    /**
091     * Determines if there is a {@linkplain #getSubstitution(ResolvedJavaMethod, int) substitution
092     * graph} for a given method.
093     *
094     * @param invokeBci the call site BCI if this request is made for inlining a substitute
095     *            otherwise {@code -1}
096     * @return true iff there is a substitution graph available for {@code method}
097     */
098    default boolean hasSubstitution(ResolvedJavaMethod method, int invokeBci) {
099        return hasSubstitution(method, false, invokeBci);
100    }
101
102    /**
103     * Determines if there is a {@linkplain #getSubstitution(ResolvedJavaMethod, int) substitution
104     * graph} for a given method.
105     *
106     * @param fromBytecodeOnly only consider graphs created by parsing the bytecode of another
107     *            method
108     * @param invokeBci the call site BCI if this request is made for inlining a substitute
109     *            otherwise {@code -1}
110     * @return true iff there is a substitution graph available for {@code method}
111     */
112    boolean hasSubstitution(ResolvedJavaMethod method, boolean fromBytecodeOnly, int invokeBci);
113
114    /**
115     * Registers all the {@linkplain MethodSubstitution method} substitutions defined by a given
116     * class.
117     *
118     * @param original the original class for which substitutions are being registered. This must be
119     *            the same type denoted by the {@link ClassSubstitution} annotation on
120     *            {@code substitutions}. It is required here so that an implementation is not forced
121     *            to read annotations during registration.
122     * @param substitutions the class defining substitutions for {@code original}. This class must
123     *            be annotated with {@link ClassSubstitution}.
124     */
125    void registerSubstitutions(Type original, Class<?> substitutions);
126
127    /**
128     * Returns all methods that are currently registered as method/macro substitution or as a
129     * snippet.
130     */
131    Collection<ResolvedJavaMethod> getAllReplacements();
132
133    /**
134     * Register snippet templates.
135     */
136    void registerSnippetTemplateCache(SnippetTemplateCache snippetTemplates);
137
138    /**
139     * Get snippet templates that were registered with
140     * {@link Replacements#registerSnippetTemplateCache(SnippetTemplateCache)}.
141     */
142    <T extends SnippetTemplateCache> T getSnippetTemplateCache(Class<T> templatesClass);
143}