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  */
  23 package org.graalvm.compiler.phases.common.inlining.walker;
  24 
  25 import java.util.BitSet;
  26 
  27 import org.graalvm.compiler.nodes.CallTargetNode;
  28 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
  29 import org.graalvm.compiler.phases.common.inlining.info.InlineInfo;
  30 import org.graalvm.compiler.phases.common.inlining.info.elem.Inlineable;
  31 import org.graalvm.compiler.phases.common.inlining.info.elem.InlineableGraph;
  32 
  33 import 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  */
  46 public 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);
 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 }