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