1 /*
   2  * Copyright (c) 2011, 2018, 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 
  24 
  25 package org.graalvm.compiler.nodes;
  26 
  27 import org.graalvm.compiler.graph.Node;
  28 import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
  29 import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
  30 import org.graalvm.compiler.nodes.memory.MemoryCheckpoint;
  31 import org.graalvm.compiler.nodes.spi.Lowerable;
  32 import org.graalvm.compiler.nodes.type.StampTool;
  33 
  34 import jdk.vm.ci.meta.ResolvedJavaMethod;
  35 import jdk.vm.ci.meta.ResolvedJavaType;
  36 
  37 public interface Invoke extends StateSplit, Lowerable, MemoryCheckpoint.Single, DeoptimizingNode.DeoptDuring, FixedNodeInterface, Invokable {
  38 
  39     FixedNode next();
  40 
  41     void setNext(FixedNode x);
  42 
  43     CallTargetNode callTarget();
  44 
  45     @Override
  46     int bci();
  47 
  48     Node predecessor();
  49 
  50     ValueNode classInit();
  51 
  52     void setClassInit(ValueNode node);
  53 
  54     boolean useForInlining();
  55 
  56     void setUseForInlining(boolean value);
  57 
  58     /**
  59      * True if this invocation is almost certainly polymorphic, false when in doubt.
  60      */
  61     boolean isPolymorphic();
  62 
  63     void setPolymorphic(boolean value);
  64 
  65     @Override
  66     default ResolvedJavaMethod getTargetMethod() {
  67         return callTarget() != null ? callTarget().targetMethod() : null;
  68     }
  69 
  70     /**
  71      * Returns the {@linkplain ResolvedJavaMethod method} from which this invoke is executed. This
  72      * is the caller method and in the case of inlining may be different from the method of the
  73      * graph this node is in.
  74      *
  75      * @return the method from which this invoke is executed.
  76      */
  77     default ResolvedJavaMethod getContextMethod() {
  78         FrameState state = stateAfter();
  79         if (state == null) {
  80             state = stateDuring();
  81         }
  82         return state.getMethod();
  83     }
  84 
  85     /**
  86      * Returns the {@linkplain ResolvedJavaType type} from which this invoke is executed. This is
  87      * the declaring type of the caller method.
  88      *
  89      * @return the type from which this invoke is executed.
  90      */
  91     default ResolvedJavaType getContextType() {
  92         ResolvedJavaMethod contextMethod = getContextMethod();
  93         if (contextMethod == null) {
  94             return null;
  95         }
  96         return contextMethod.getDeclaringClass();
  97     }
  98 
  99     @Override
 100     default void computeStateDuring(FrameState stateAfter) {
 101         FrameState newStateDuring = stateAfter.duplicateModifiedDuringCall(bci(), asNode().getStackKind());
 102         setStateDuring(newStateDuring);
 103     }
 104 
 105     default ValueNode getReceiver() {
 106         assert getInvokeKind().hasReceiver();
 107         return callTarget().arguments().get(0);
 108     }
 109 
 110     default ResolvedJavaType getReceiverType() {
 111         ResolvedJavaType receiverType = StampTool.typeOrNull(getReceiver());
 112         if (receiverType == null) {
 113             receiverType = ((MethodCallTargetNode) callTarget()).targetMethod().getDeclaringClass();
 114         }
 115         return receiverType;
 116     }
 117 
 118     default InvokeKind getInvokeKind() {
 119         return callTarget().invokeKind();
 120     }
 121 
 122     void replaceBci(int newBci);
 123 }