author | never |
Wed, 27 Apr 2016 16:20:49 -0700 | |
changeset 38139 | cf6f5c1b7205 |
parent 35824 | d3958ca72bf9 |
child 38231 | 38b7e4a90f6a |
permissions | -rw-r--r-- |
33160 | 1 |
/* |
2 |
* Copyright (c) 2009, 2015, 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 jdk.vm.ci.meta; |
|
24 |
||
33632 | 25 |
import java.lang.annotation.Annotation; |
33160 | 26 |
|
33632 | 27 |
import jdk.vm.ci.meta.Assumptions.AssumptionResult; |
33160 | 28 |
|
29 |
/** |
|
30 |
* Represents a resolved Java type. Types include primitives, objects, {@code void}, and arrays |
|
31 |
* thereof. Types, like fields and methods, are resolved through {@link ConstantPool constant pools} |
|
32 |
* . |
|
33 |
*/ |
|
34 |
public interface ResolvedJavaType extends JavaType, ModifiersProvider { |
|
35 |
/** |
|
36 |
* Checks whether this type has a finalizer method. |
|
37 |
* |
|
38 |
* @return {@code true} if this class has a finalizer |
|
39 |
*/ |
|
40 |
boolean hasFinalizer(); |
|
41 |
||
42 |
/** |
|
43 |
* Checks whether this type has any finalizable subclasses so far. Any decisions based on this |
|
44 |
* information require the registration of a dependency, since this information may change. |
|
45 |
* |
|
46 |
* @return {@code true} if this class has any subclasses with finalizers |
|
47 |
*/ |
|
48 |
AssumptionResult<Boolean> hasFinalizableSubclass(); |
|
49 |
||
50 |
/** |
|
51 |
* Checks whether this type is an interface. |
|
52 |
* |
|
53 |
* @return {@code true} if this type is an interface |
|
54 |
*/ |
|
55 |
boolean isInterface(); |
|
56 |
||
57 |
/** |
|
58 |
* Checks whether this type is an instance class. |
|
59 |
* |
|
60 |
* @return {@code true} if this type is an instance class |
|
61 |
*/ |
|
62 |
boolean isInstanceClass(); |
|
63 |
||
64 |
/** |
|
65 |
* Checks whether this type is an array class. |
|
66 |
* |
|
67 |
* @return {@code true} if this type is an array class |
|
68 |
*/ |
|
69 |
boolean isArray(); |
|
70 |
||
71 |
/** |
|
72 |
* Checks whether this type is primitive. |
|
73 |
* |
|
74 |
* @return {@code true} if this type is primitive |
|
75 |
*/ |
|
76 |
boolean isPrimitive(); |
|
77 |
||
78 |
/** |
|
79 |
* {@inheritDoc} |
|
80 |
* <p> |
|
81 |
* Only the flags specified in the JVM specification will be included in the returned mask. This |
|
82 |
* method is identical to {@link Class#getModifiers()} in terms of the value return for this |
|
83 |
* type. |
|
84 |
*/ |
|
85 |
int getModifiers(); |
|
86 |
||
87 |
/* |
|
88 |
* The setting of the final bit for types is a bit confusing since arrays are marked as final. |
|
89 |
* This method provides a semantically equivalent test that appropriate for types. |
|
90 |
*/ |
|
91 |
default boolean isLeaf() { |
|
92 |
return getElementalType().isFinalFlagSet(); |
|
93 |
} |
|
94 |
||
95 |
/** |
|
96 |
* Checks whether this type is initialized. If a type is initialized it implies that it was |
|
97 |
* {@link #isLinked() linked} and that the static initializer has run. |
|
98 |
* |
|
99 |
* @return {@code true} if this type is initialized |
|
100 |
*/ |
|
101 |
boolean isInitialized(); |
|
102 |
||
103 |
/** |
|
104 |
* Initializes this type. |
|
105 |
*/ |
|
106 |
void initialize(); |
|
107 |
||
108 |
/** |
|
109 |
* Checks whether this type is linked and verified. When a type is linked the static initializer |
|
110 |
* has not necessarily run. An {@link #isInitialized() initialized} type is always linked. |
|
111 |
* |
|
112 |
* @return {@code true} if this type is linked |
|
113 |
*/ |
|
114 |
boolean isLinked(); |
|
115 |
||
116 |
/** |
|
117 |
* Determines if this type is either the same as, or is a superclass or superinterface of, the |
|
118 |
* type represented by the specified parameter. This method is identical to |
|
119 |
* {@link Class#isAssignableFrom(Class)} in terms of the value return for this type. |
|
120 |
*/ |
|
121 |
boolean isAssignableFrom(ResolvedJavaType other); |
|
122 |
||
123 |
/** |
|
124 |
* Returns true if this type is exactly the type {@link java.lang.Object}. |
|
125 |
*/ |
|
126 |
default boolean isJavaLangObject() { |
|
127 |
// Removed assertion due to https://bugs.eclipse.org/bugs/show_bug.cgi?id=434442 |
|
128 |
return getSuperclass() == null && !isInterface() && getJavaKind() == JavaKind.Object; |
|
129 |
} |
|
130 |
||
131 |
/** |
|
132 |
* Checks whether the specified object is an instance of this type. |
|
133 |
* |
|
134 |
* @param obj the object to test |
|
135 |
* @return {@code true} if the object is an instance of this type |
|
136 |
*/ |
|
137 |
boolean isInstance(JavaConstant obj); |
|
138 |
||
139 |
/** |
|
140 |
* Returns this type if it is an exact type otherwise returns null. This type is exact if it is |
|
141 |
* void, primitive, final, or an array of a final or primitive type. |
|
142 |
* |
|
143 |
* @return this type if it is exact; {@code null} otherwise |
|
144 |
*/ |
|
145 |
ResolvedJavaType asExactType(); |
|
146 |
||
147 |
/** |
|
148 |
* Gets the super class of this type. If this type represents either the {@code Object} class, |
|
149 |
* an interface, a primitive type, or void, then null is returned. If this object represents an |
|
150 |
* array class then the type object representing the {@code Object} class is returned. |
|
151 |
*/ |
|
152 |
ResolvedJavaType getSuperclass(); |
|
153 |
||
154 |
/** |
|
155 |
* Gets the interfaces implemented or extended by this type. This method is analogous to |
|
156 |
* {@link Class#getInterfaces()} and as such, only returns the interfaces directly implemented |
|
157 |
* or extended by this type. |
|
158 |
*/ |
|
159 |
ResolvedJavaType[] getInterfaces(); |
|
160 |
||
161 |
/** |
|
162 |
* Gets the single implementor of this type. Calling this method on a non-interface type causes |
|
163 |
* an exception. |
|
164 |
* <p> |
|
165 |
* If the compiler uses the result of this method for its compilation, the usage must be guarded |
|
166 |
* because the verifier can not guarantee that the assigned type really implements this |
|
167 |
* interface. Additionally, class loading can invalidate the result of this method. |
|
168 |
* |
|
169 |
* @return {@code null} if there is no implementor, the implementor if there is only one, or |
|
170 |
* {@code this} if there are more than one. |
|
171 |
*/ |
|
172 |
ResolvedJavaType getSingleImplementor(); |
|
173 |
||
174 |
/** |
|
175 |
* Walks the class hierarchy upwards and returns the least common class that is a superclass of |
|
176 |
* both the current and the given type. |
|
177 |
* |
|
178 |
* @return the least common type that is a super type of both the current and the given type, or |
|
179 |
* {@code null} if primitive types are involved. |
|
180 |
*/ |
|
181 |
ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType); |
|
182 |
||
183 |
/** |
|
184 |
* Attempts to get a leaf concrete subclass of this type. |
|
185 |
* <p> |
|
186 |
* For an {@linkplain #isArray() array} type A, the leaf concrete subclass is A if the |
|
187 |
* {@linkplain #getElementalType() elemental} type of A is final (which includes primitive |
|
188 |
* types). Otherwise {@code null} is returned for A. |
|
189 |
* <p> |
|
190 |
* For a non-array type T, the result is the leaf concrete type in the current hierarchy of T. |
|
191 |
* <p> |
|
192 |
* A runtime may decide not to manage or walk a large hierarchy and so the result is |
|
193 |
* conservative. That is, a non-null result is guaranteed to be the leaf concrete class in T's |
|
194 |
* hierarchy <b>at the current point in time</b> but a null result does not necessarily imply |
|
195 |
* that there is no leaf concrete class in T's hierarchy. |
|
196 |
* <p> |
|
197 |
* If the compiler uses the result of this method for its compilation, it must register the |
|
198 |
* {@link AssumptionResult} in its {@link Assumptions} because dynamic class loading can |
|
199 |
* invalidate the result of this method. |
|
200 |
* |
|
201 |
* @return an {@link AssumptionResult} containing the leaf concrete subclass for this type as |
|
202 |
* described above |
|
203 |
*/ |
|
204 |
AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype(); |
|
205 |
||
206 |
ResolvedJavaType getComponentType(); |
|
207 |
||
208 |
default ResolvedJavaType getElementalType() { |
|
209 |
ResolvedJavaType t = this; |
|
210 |
while (t.isArray()) { |
|
211 |
t = t.getComponentType(); |
|
212 |
} |
|
213 |
return t; |
|
214 |
} |
|
215 |
||
216 |
ResolvedJavaType getArrayClass(); |
|
217 |
||
218 |
/** |
|
219 |
* Resolves the method implementation for virtual dispatches on objects of this dynamic type. |
|
38139
cf6f5c1b7205
8152903: [JVMCI] CompilerToVM::resolveMethod should correctly handle private methods in interfaces
never
parents:
35824
diff
changeset
|
220 |
* This resolution process only searches "up" the class hierarchy of this type. A broader search |
cf6f5c1b7205
8152903: [JVMCI] CompilerToVM::resolveMethod should correctly handle private methods in interfaces
never
parents:
35824
diff
changeset
|
221 |
* that also walks "down" the hierarchy is implemented by |
cf6f5c1b7205
8152903: [JVMCI] CompilerToVM::resolveMethod should correctly handle private methods in interfaces
never
parents:
35824
diff
changeset
|
222 |
* {@link #findUniqueConcreteMethod(ResolvedJavaMethod)}. For interface types it returns null |
cf6f5c1b7205
8152903: [JVMCI] CompilerToVM::resolveMethod should correctly handle private methods in interfaces
never
parents:
35824
diff
changeset
|
223 |
* since no concrete object can be an interface. |
33160 | 224 |
* |
225 |
* @param method the method to select the implementation of |
|
226 |
* @param callerType the caller or context type used to perform access checks |
|
38139
cf6f5c1b7205
8152903: [JVMCI] CompilerToVM::resolveMethod should correctly handle private methods in interfaces
never
parents:
35824
diff
changeset
|
227 |
* @return the method that would be selected at runtime (might be abstract) or {@code null} if |
cf6f5c1b7205
8152903: [JVMCI] CompilerToVM::resolveMethod should correctly handle private methods in interfaces
never
parents:
35824
diff
changeset
|
228 |
* it can not be resolved |
33160 | 229 |
*/ |
230 |
ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method, ResolvedJavaType callerType); |
|
231 |
||
232 |
/** |
|
38139
cf6f5c1b7205
8152903: [JVMCI] CompilerToVM::resolveMethod should correctly handle private methods in interfaces
never
parents:
35824
diff
changeset
|
233 |
* A convenience wrapper for {@link #resolveMethod(ResolvedJavaMethod, ResolvedJavaType)} that |
cf6f5c1b7205
8152903: [JVMCI] CompilerToVM::resolveMethod should correctly handle private methods in interfaces
never
parents:
35824
diff
changeset
|
234 |
* only returns non-abstract methods. |
33160 | 235 |
* |
236 |
* @param method the method to select the implementation of |
|
237 |
* @param callerType the caller or context type used to perform access checks |
|
238 |
* @return the concrete method that would be selected at runtime, or {@code null} if there is no |
|
239 |
* concrete implementation of {@code method} in this type or any of its superclasses |
|
240 |
*/ |
|
38139
cf6f5c1b7205
8152903: [JVMCI] CompilerToVM::resolveMethod should correctly handle private methods in interfaces
never
parents:
35824
diff
changeset
|
241 |
default ResolvedJavaMethod resolveConcreteMethod(ResolvedJavaMethod method, ResolvedJavaType callerType) { |
cf6f5c1b7205
8152903: [JVMCI] CompilerToVM::resolveMethod should correctly handle private methods in interfaces
never
parents:
35824
diff
changeset
|
242 |
ResolvedJavaMethod resolvedMethod = resolveMethod(method, callerType); |
cf6f5c1b7205
8152903: [JVMCI] CompilerToVM::resolveMethod should correctly handle private methods in interfaces
never
parents:
35824
diff
changeset
|
243 |
if (resolvedMethod == null || resolvedMethod.isAbstract()) { |
cf6f5c1b7205
8152903: [JVMCI] CompilerToVM::resolveMethod should correctly handle private methods in interfaces
never
parents:
35824
diff
changeset
|
244 |
return null; |
cf6f5c1b7205
8152903: [JVMCI] CompilerToVM::resolveMethod should correctly handle private methods in interfaces
never
parents:
35824
diff
changeset
|
245 |
} |
cf6f5c1b7205
8152903: [JVMCI] CompilerToVM::resolveMethod should correctly handle private methods in interfaces
never
parents:
35824
diff
changeset
|
246 |
return resolvedMethod; |
cf6f5c1b7205
8152903: [JVMCI] CompilerToVM::resolveMethod should correctly handle private methods in interfaces
never
parents:
35824
diff
changeset
|
247 |
} |
33160 | 248 |
|
249 |
/** |
|
250 |
* Given a {@link ResolvedJavaMethod} A, returns a concrete {@link ResolvedJavaMethod} B that is |
|
251 |
* the only possible unique target for a virtual call on A(). Returns {@code null} if either no |
|
252 |
* such concrete method or more than one such method exists. Returns the method A if A is a |
|
253 |
* concrete method that is not overridden. |
|
254 |
* <p> |
|
255 |
* If the compiler uses the result of this method for its compilation, it must register an |
|
256 |
* assumption because dynamic class loading can invalidate the result of this method. |
|
257 |
* |
|
258 |
* @param method the method A for which a unique concrete target is searched |
|
259 |
* @return the unique concrete target or {@code null} if no such target exists or assumptions |
|
260 |
* are not supported by this runtime |
|
261 |
*/ |
|
262 |
AssumptionResult<ResolvedJavaMethod> findUniqueConcreteMethod(ResolvedJavaMethod method); |
|
263 |
||
264 |
/** |
|
265 |
* Returns the instance fields of this class, including |
|
266 |
* {@linkplain ResolvedJavaField#isInternal() internal} fields. A zero-length array is returned |
|
267 |
* for array and primitive types. The order of fields returned by this method is stable. That |
|
268 |
* is, for a single JVM execution the same order is returned each time this method is called. It |
|
269 |
* is also the "natural" order, which means that the JVM would expect the fields in this order |
|
270 |
* if no specific order is given. |
|
271 |
* |
|
272 |
* @param includeSuperclasses if true, then instance fields for the complete hierarchy of this |
|
273 |
* type are included in the result |
|
274 |
* @return an array of instance fields |
|
275 |
*/ |
|
276 |
ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses); |
|
277 |
||
278 |
/** |
|
279 |
* Returns the static fields of this class, including |
|
280 |
* {@linkplain ResolvedJavaField#isInternal() internal} fields. A zero-length array is returned |
|
281 |
* for array and primitive types. The order of fields returned by this method is stable. That |
|
282 |
* is, for a single JVM execution the same order is returned each time this method is called. |
|
283 |
*/ |
|
284 |
ResolvedJavaField[] getStaticFields(); |
|
285 |
||
286 |
/** |
|
287 |
* Returns all annotations of this class. If no annotations are present, an array of length 0 is |
|
288 |
* returned. |
|
289 |
*/ |
|
290 |
Annotation[] getAnnotations(); |
|
291 |
||
292 |
/** |
|
293 |
* Returns the annotation for the specified type of this class, if such an annotation is |
|
294 |
* present. |
|
295 |
* |
|
296 |
* @param annotationClass the Class object corresponding to the annotation type |
|
297 |
* @return this element's annotation for the specified annotation type if present on this class, |
|
298 |
* else {@code null} |
|
299 |
*/ |
|
300 |
<T extends Annotation> T getAnnotation(Class<T> annotationClass); |
|
301 |
||
302 |
/** |
|
303 |
* Returns the instance field of this class (or one of its super classes) at the given offset, |
|
304 |
* or {@code null} if there is no such field. |
|
305 |
* |
|
306 |
* @param offset the offset of the field to look for |
|
307 |
* @return the field with the given offset, or {@code null} if there is no such field. |
|
308 |
*/ |
|
309 |
ResolvedJavaField findInstanceFieldWithOffset(long offset, JavaKind expectedKind); |
|
310 |
||
311 |
/** |
|
312 |
* Returns name of source file of this type. |
|
313 |
*/ |
|
314 |
String getSourceFileName(); |
|
315 |
||
316 |
/** |
|
317 |
* Returns {@code true} if the type is a local type. |
|
318 |
*/ |
|
319 |
boolean isLocal(); |
|
320 |
||
321 |
/** |
|
322 |
* Returns {@code true} if the type is a member type. |
|
323 |
*/ |
|
324 |
boolean isMember(); |
|
325 |
||
326 |
/** |
|
327 |
* Returns the enclosing type of this type, if it exists, or {@code null}. |
|
328 |
*/ |
|
329 |
ResolvedJavaType getEnclosingType(); |
|
330 |
||
331 |
/** |
|
332 |
* Returns an array reflecting all the constructors declared by this type. This method is |
|
333 |
* similar to {@link Class#getDeclaredConstructors()} in terms of returned constructors. |
|
334 |
*/ |
|
335 |
ResolvedJavaMethod[] getDeclaredConstructors(); |
|
336 |
||
337 |
/** |
|
338 |
* Returns an array reflecting all the methods declared by this type. This method is similar to |
|
339 |
* {@link Class#getDeclaredMethods()} in terms of returned methods. |
|
340 |
*/ |
|
341 |
ResolvedJavaMethod[] getDeclaredMethods(); |
|
342 |
||
343 |
/** |
|
344 |
* Returns the {@code <clinit>} method for this class if there is one. |
|
345 |
*/ |
|
346 |
ResolvedJavaMethod getClassInitializer(); |
|
347 |
||
348 |
/** |
|
349 |
* Returns true if this type represents an interface and it should be trusted even in places |
|
350 |
* where the JVM verifier would not give any guarantees other than {@link Object}. |
|
351 |
*/ |
|
352 |
boolean isTrustedInterfaceType(); |
|
353 |
||
354 |
default ResolvedJavaMethod findMethod(String name, Signature signature) { |
|
355 |
for (ResolvedJavaMethod method : getDeclaredMethods()) { |
|
356 |
if (method.getName().equals(name) && method.getSignature().equals(signature)) { |
|
357 |
return method; |
|
358 |
} |
|
359 |
} |
|
360 |
return null; |
|
361 |
} |
|
362 |
} |