1 /*
   2  * Copyright (c) 2015, 2019, 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.graphbuilderconf;
  26 
  27 import org.graalvm.compiler.graph.Node.ValueNumberable;
  28 import org.graalvm.compiler.nodes.FixedWithNextNode;
  29 import org.graalvm.compiler.nodes.StructuredGraph;
  30 import org.graalvm.compiler.nodes.ValueNode;
  31 import org.graalvm.compiler.nodes.extended.GuardingNode;
  32 
  33 import jdk.vm.ci.meta.JavaKind;
  34 import jdk.vm.ci.meta.JavaTypeProfile;
  35 import jdk.vm.ci.meta.ResolvedJavaField;
  36 import jdk.vm.ci.meta.ResolvedJavaMethod;
  37 import jdk.vm.ci.meta.ResolvedJavaType;
  38 import jdk.vm.ci.meta.Signature;
  39 
  40 public interface NodePlugin extends GraphBuilderPlugin {
  41     /**
  42      * Handle the parsing of a method invocation bytecode to a method that can be bound statically.
  43      * If the method returns true, it must {@link GraphBuilderContext#push push} a value as the
  44      * result of the method invocation using the {@link Signature#getReturnKind return kind} of the
  45      * method.
  46      *
  47      * @param b the context
  48      * @param method the statically bound, invoked method
  49      * @param args the arguments of the method invocation
  50      * @return true if the plugin handles the invocation, false otherwise
  51      */
  52     default boolean handleInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
  53         return false;
  54     }
  55 
  56     /**
  57      * Handle the parsing of a GETFIELD bytecode. If the method returns true, it must
  58      * {@link GraphBuilderContext#push push} a value using the
  59      * {@link ResolvedJavaField#getJavaKind() kind} of the field.
  60      *
  61      * @param b the context
  62      * @param object the receiver object for the field access
  63      * @param field the accessed field
  64      * @return true if the plugin handles the field access, false otherwise
  65      */
  66     default boolean handleLoadField(GraphBuilderContext b, ValueNode object, ResolvedJavaField field) {
  67         return false;
  68     }
  69 
  70     /**
  71      * Handle the parsing of a GETSTATIC bytecode. If the method returns true, it must
  72      * {@link GraphBuilderContext#push push} a value using the
  73      * {@link ResolvedJavaField#getJavaKind() kind} of the field.
  74      *
  75      * @param b the context
  76      * @param field the accessed field
  77      * @return true if the plugin handles the field access, false otherwise
  78      */
  79     default boolean handleLoadStaticField(GraphBuilderContext b, ResolvedJavaField field) {
  80         return false;
  81     }
  82 
  83     /**
  84      * Handle the parsing of a PUTFIELD bytecode.
  85      *
  86      * @param b the context
  87      * @param object the receiver object for the field access
  88      * @param field the accessed field
  89      * @param value the value to be stored into the field
  90      * @return true if the plugin handles the field access, false otherwise
  91      */
  92     default boolean handleStoreField(GraphBuilderContext b, ValueNode object, ResolvedJavaField field, ValueNode value) {
  93         return false;
  94     }
  95 
  96     /**
  97      * Handle the parsing of a PUTSTATIC bytecode.
  98      *
  99      * @param b the context
 100      * @param field the accessed field
 101      * @param value the value to be stored into the field
 102      * @return true if the plugin handles the field access, false otherwise.
 103      */
 104     default boolean handleStoreStaticField(GraphBuilderContext b, ResolvedJavaField field, ValueNode value) {
 105         return false;
 106     }
 107 
 108     /**
 109      * Handle the parsing of an array load bytecode. If the method returns true, it must
 110      * {@link GraphBuilderContext#push push} a value using the provided elementKind.
 111      *
 112      * @param b the context
 113      * @param array the accessed array
 114      * @param index the index for the array access
 115      * @param boundsCheck the explicit bounds check already emitted, or null if no bounds check was
 116      *            emitted yet
 117      * @param elementKind the element kind of the accessed array
 118      * @return true if the plugin handles the array access, false otherwise.
 119      */
 120     default boolean handleLoadIndexed(GraphBuilderContext b, ValueNode array, ValueNode index, GuardingNode boundsCheck, JavaKind elementKind) {
 121         return false;
 122     }
 123 
 124     /**
 125      * Handle the parsing of an array store bytecode.
 126      *
 127      * @param b the context
 128      * @param array the accessed array
 129      * @param index the index for the array access
 130      * @param boundsCheck the explicit array bounds check already emitted, or null if no array
 131      *            bounds check was emitted yet
 132      * @param storeCheck the explicit array store check already emitted, or null if no array store
 133      *            check was emitted yet
 134      * @param elementKind the element kind of the accessed array
 135      * @param value the value to be stored into the array
 136      * @return true if the plugin handles the array access, false otherwise.
 137      */
 138     default boolean handleStoreIndexed(GraphBuilderContext b, ValueNode array, ValueNode index, GuardingNode boundsCheck, GuardingNode storeCheck, JavaKind elementKind, ValueNode value) {
 139         return false;
 140     }
 141 
 142     /**
 143      * Handle the parsing of a CHECKCAST bytecode. If the method returns true, it must
 144      * {@link GraphBuilderContext#push push} a value with the result of the cast using
 145      * {@link JavaKind#Object}.
 146      *
 147      * @param b the context
 148      * @param object the object to be type checked
 149      * @param type the type that the object is checked against
 150      * @param profile the profiling information for the type check, or null if no profiling
 151      *            information is available
 152      * @return true if the plugin handles the cast, false otherwise
 153      */
 154     default boolean handleCheckCast(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) {
 155         return false;
 156     }
 157 
 158     /**
 159      * Handle the parsing of a INSTANCEOF bytecode. If the method returns true, it must
 160      * {@link GraphBuilderContext#push push} a value with the result of the instanceof using
 161      * {@link JavaKind#Int}.
 162      *
 163      * @param b the context
 164      * @param object the object to be type checked
 165      * @param type the type that the object is checked against
 166      * @param profile the profiling information for the type check, or null if no profiling
 167      *            information is available
 168      * @return true if the plugin handles the instanceof, false otherwise
 169      */
 170     default boolean handleInstanceOf(GraphBuilderContext b, ValueNode object, ResolvedJavaType type, JavaTypeProfile profile) {
 171         return false;
 172     }
 173 
 174     /**
 175      * Handle the parsing of a NEW bytecode. If the method returns true, it must
 176      * {@link GraphBuilderContext#push push} a value with the result of the allocation using
 177      * {@link JavaKind#Object}.
 178      *
 179      * @param b the context
 180      * @param type the type to be instantiated
 181      * @return true if the plugin handles the bytecode, false otherwise
 182      */
 183     default boolean handleNewInstance(GraphBuilderContext b, ResolvedJavaType type) {
 184         return false;
 185     }
 186 
 187     /**
 188      * Handle the parsing of a NEWARRAY and ANEWARRAY bytecode. If the method returns true, it must
 189      * {@link GraphBuilderContext#push push} a value with the result of the allocation using
 190      * {@link JavaKind#Object}.
 191      *
 192      * @param b the context
 193      * @param elementType the element type of the array to be instantiated
 194      * @param length the length of the new array
 195      * @return true if the plugin handles the bytecode, false otherwise
 196      */
 197     default boolean handleNewArray(GraphBuilderContext b, ResolvedJavaType elementType, ValueNode length) {
 198         return false;
 199     }
 200 
 201     /**
 202      * Handle the parsing of a MULTIANEWARRAY bytecode. If the method returns true, it must
 203      * {@link GraphBuilderContext#push push} a value with the result of the allocation using
 204      * {@link JavaKind#Object}.
 205      *
 206      * @param b the context
 207      * @param type the type of the outermost array to be instantiated
 208      * @param dimensions the array of lengths for all the dimensions to be instantiated
 209      * @return true if the plugin handles the bytecode, false otherwise
 210      */
 211     default boolean handleNewMultiArray(GraphBuilderContext b, ResolvedJavaType type, ValueNode[] dimensions) {
 212         return false;
 213     }
 214 
 215     /**
 216      * Allows this plugin to add nodes after the exception object has been loaded in the dispatch
 217      * sequence. Note that a {@link StructuredGraph} is provided to this call instead of a
 218      * {@link GraphBuilderContext} so that the caller has a guarantee that its current control flow
 219      * insertion point is not changed by this call. This means nodes must be added to the graph with
 220      * the appropriate method (e.g., {@link StructuredGraph#unique} for {@link ValueNumberable}
 221      * nodes) and fixed nodes must be manually {@linkplain FixedWithNextNode#setNext added} as
 222      * successors of {@code afterExceptionLoaded}.
 223      *
 224      * The reason for this constraint is that when this plugin runs, it's inserting instructions
 225      * into a different block than the one currently being parsed.
 226      *
 227      * @param graph the graph being parsed
 228      * @param afterExceptionLoaded the last fixed node after loading the exception
 229      * @return the last fixed node after instrumentation
 230      */
 231     default FixedWithNextNode instrumentExceptionDispatch(StructuredGraph graph, FixedWithNextNode afterExceptionLoaded) {
 232         return afterExceptionLoaded;
 233     }
 234 
 235     /**
 236      * If the plugin {@link GraphBuilderContext#push pushes} a value with a different
 237      * {@link JavaKind} than specified by the bytecode, it must override this method and return
 238      * {@code true}. This disables assertion checking for value kinds.
 239      *
 240      * @param b the context
 241      */
 242     default boolean canChangeStackKind(GraphBuilderContext b) {
 243         return false;
 244     }
 245 }