1/*
2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package org.graalvm.compiler.phases.common.inlining.walker;
24
25import java.util.BitSet;
26
27import org.graalvm.compiler.nodes.CallTargetNode;
28import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
29import org.graalvm.compiler.phases.common.inlining.info.InlineInfo;
30import org.graalvm.compiler.phases.common.inlining.info.elem.Inlineable;
31import org.graalvm.compiler.phases.common.inlining.info.elem.InlineableGraph;
32
33import jdk.vm.ci.meta.ResolvedJavaMethod;
34
35/**
36 * <p>
37 * An instance of this class denotes a callsite being analyzed for inlining.
38 * </p>
39 * <p>
40 * Each element of the {@link InliningData} stack contains one such instance, the accompanying
41 * {@link CallsiteHolder}s in that element represent feasible targets for the callsite in question.
42 * </p>
43 *
44 * @see InliningData#moveForward()
45 */
46public class MethodInvocation {
47
48    private final InlineInfo callee;
49    private final double probability;
50    private final double relevance;
51
52    private int processedGraphs;
53
54    /**
55     * <p>
56     * The immutable positions of freshly instantiated arguments (ie, positions in
57     * <code>callee.invoke.callTarget.arguments</code>).
58     * </p>
59     *
60     * <p>
61     * A freshly instantiated argument is either:
62     * <uL>
63     * <li>an {@link InliningData#isFreshInstantiation(org.graalvm.compiler.nodes.ValueNode)}</li>
64     * <li>a fixed-param of the graph containing the callsite (ie, of <code>callee.graph()</code>
65     * that contains <code>callee.invoke</code>)</li>
66     * </uL>
67     * </p>
68     *
69     * <p>
70     * Given those positions, the
71     * {@link org.graalvm.compiler.phases.common.inlining.walker.CallsiteHolderExplorable}
72     * instantiated in {@link #buildCallsiteHolderForElement(int)} can determine which of <i>its</i>
73     * parameters are fixed.
74     * </p>
75     */
76    private final BitSet freshlyInstantiatedArguments;
77
78    private final int sizeFreshArgs;
79
80    public MethodInvocation(InlineInfo info, double probability, double relevance, BitSet freshlyInstantiatedArguments) {
81        this.callee = info;
82        this.probability = probability;
83        this.relevance = relevance;
84        this.freshlyInstantiatedArguments = freshlyInstantiatedArguments;
85        this.sizeFreshArgs = freshlyInstantiatedArguments == null ? 0 : freshlyInstantiatedArguments.cardinality();
86    }
87
88    public void incrementProcessedGraphs() {
89        processedGraphs++;
90        assert processedGraphs <= callee.numberOfMethods();
91    }
92
93    public int processedGraphs() {
94        assert processedGraphs <= callee.numberOfMethods();
95        return processedGraphs;
96    }
97
98    public int totalGraphs() {
99        return callee.numberOfMethods();
100    }
101
102    public InlineInfo callee() {
103        return callee;
104    }
105
106    public double probability() {
107        return probability;
108    }
109
110    public double relevance() {
111        return relevance;
112    }
113
114    public boolean isRoot() {
115        return callee == null;
116    }
117
118    public BitSet getFreshlyInstantiatedArguments() {
119        return freshlyInstantiatedArguments;
120    }
121
122    public int getSizeFreshArgs() {
123        return sizeFreshArgs;
124    }
125
126    public CallsiteHolder buildCallsiteHolderForElement(int index) {
127        Inlineable elem = callee.inlineableElementAt(index);
128        assert elem instanceof InlineableGraph;
129        InlineableGraph ig = (InlineableGraph) elem;
130        final double invokeProbability = probability * callee.probabilityAt(index);
131        final double invokeRelevance = relevance * callee.relevanceAt(index);
132        return new CallsiteHolderExplorable(ig.getGraph(), invokeProbability, invokeRelevance, freshlyInstantiatedArguments, null);
133    }
134
135    @Override
136    public String toString() {
137        if (isRoot()) {
138            return "<root>";
139        }
140        CallTargetNode callTarget = callee.invoke().callTarget();
141        if (callTarget instanceof MethodCallTargetNode) {
142            ResolvedJavaMethod calleeMethod = ((MethodCallTargetNode) callTarget).targetMethod();
143            return calleeMethod.format("Invoke#%H.%n(%p)");
144        } else {
145            return "Invoke#" + callTarget.targetName();
146        }
147    }
148}
149