1 /* 2 * Copyright (c) 2009, 2014, 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 25 import java.lang.annotation.*; 26 import java.lang.invoke.*; 27 import java.lang.reflect.*; 28 import java.util.*; 29 30 /** 31 * Represents a resolved Java method. Methods, like fields and types, are resolved through 32 * {@link ConstantPool constant pools}. 33 */ 34 public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersProvider { 35 36 /** 37 * Returns the bytecode of this method, if the method has code. The returned byte array does not 38 * contain breakpoints or non-Java bytecodes. This may return null if the 39 * {@link #getDeclaringClass() holder} is not {@link ResolvedJavaType#isLinked() linked}. 40 * 41 * The contained constant pool indices may not be the ones found in the original class file but 42 * they can be used with the JVMCI API (e.g. methods in {@link ConstantPool}). 43 * 44 * @return the bytecode of the method, or {@code null} if {@code getCodeSize() == 0} or if the 45 * code is not ready. 46 */ 47 byte[] getCode(); 48 49 /** 50 * Returns the size of the bytecode of this method, if the method has code. This is equivalent 51 * to {@link #getCode()}. {@code length} if the method has code. 52 * 53 * @return the size of the bytecode in bytes, or 0 if no bytecode is available 54 */ 55 int getCodeSize(); 56 57 /** 58 * Returns the {@link ResolvedJavaType} object representing the class or interface that declares 59 * this method. 60 */ 61 ResolvedJavaType getDeclaringClass(); 62 63 /** 64 * Returns the maximum number of locals used in this method's bytecodes. 65 */ 66 int getMaxLocals(); 67 68 /** 69 * Returns the maximum number of stack slots used in this method's bytecodes. 70 */ 71 int getMaxStackSize(); 72 73 /** 74 * {@inheritDoc} 75 * <p> 76 * Only the {@linkplain Modifier#methodModifiers() method flags} specified in the JVM 77 * specification will be included in the returned mask. 78 */ 79 int getModifiers(); 80 81 default boolean isFinal() { 82 return ModifiersProvider.super.isFinalFlagSet(); 83 } 84 85 /** 86 * Determines if this method is a synthetic method as defined by the Java Language 87 * Specification. 88 */ 89 default boolean isSynthetic() { 90 return (SYNTHETIC & getModifiers()) == SYNTHETIC; 91 } 92 93 /** 94 * Checks that the method is a <a 95 * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6">varargs</a> 96 * method. 97 * 98 * @return whether the method is a varargs method 99 */ 100 default boolean isVarArgs() { 101 return (VARARGS & getModifiers()) == VARARGS; 102 } 103 104 /** 105 * Checks that the method is a <a 106 * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6">bridge</a> 107 * method. 108 * 109 * @return whether the method is a bridge method 110 */ 111 default boolean isBridge() { 112 return (BRIDGE & getModifiers()) == BRIDGE; 113 } 114 115 /** 116 * Returns {@code true} if this method is a default method; returns {@code false} otherwise. 117 * 118 * A default method is a public non-abstract instance method, that is, a non-static method with 119 * a body, declared in an interface type. 120 * 121 * @return true if and only if this method is a default method as defined by the Java Language 122 * Specification. 123 */ 124 boolean isDefault(); 125 126 /** 127 * Checks whether this method is a class initializer. 128 * 129 * @return {@code true} if the method is a class initializer 130 */ 131 boolean isClassInitializer(); 132 133 /** 134 * Checks whether this method is a constructor. 135 * 136 * @return {@code true} if the method is a constructor 137 */ 138 boolean isConstructor(); 139 140 /** 141 * Checks whether this method can be statically bound (usually, that means it is final or 142 * private or static, but not abstract, or the declaring class is final). 143 * 144 * @return {@code true} if this method can be statically bound 145 */ 146 boolean canBeStaticallyBound(); 147 148 /** 149 * Returns the list of exception handlers for this method. 150 */ 151 ExceptionHandler[] getExceptionHandlers(); 152 153 /** 154 * Returns a stack trace element for this method and a given bytecode index. 155 */ 156 StackTraceElement asStackTraceElement(int bci); 157 158 /** 159 * Returns an object that provides access to the profiling information recorded for this method. 160 */ 161 default ProfilingInfo getProfilingInfo() { 162 return getProfilingInfo(true, true); 163 } 164 165 /** 166 * Returns an object that provides access to the profiling information recorded for this method. 167 * 168 * @param includeNormal if true, 169 * {@linkplain ProfilingInfo#getDeoptimizationCount(DeoptimizationReason) 170 * deoptimization counts} will include deoptimization that happened during execution 171 * of standard non-osr methods. 172 * @param includeOSR if true, 173 * {@linkplain ProfilingInfo#getDeoptimizationCount(DeoptimizationReason) 174 * deoptimization counts} will include deoptimization that happened during execution 175 * of on-stack-replacement methods. 176 */ 177 ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR); 178 179 /** 180 * Invalidates the profiling information and restarts profiling upon the next invocation. 181 */ 182 void reprofile(); 183 184 /** 185 * Returns the constant pool of this method. 186 */ 187 ConstantPool getConstantPool(); 188 189 /** 190 * Returns all annotations of this method. If no annotations are present, an array of length 0 191 * is returned. 192 */ 193 Annotation[] getAnnotations(); 194 195 /** 196 * Returns the annotation for the specified type of this method, if such an annotation is 197 * present. 198 * 199 * @param annotationClass the Class object corresponding to the annotation type 200 * @return this element's annotation for the specified annotation type if present on this 201 * method, else {@code null} 202 */ 203 <T extends Annotation> T getAnnotation(Class<T> annotationClass); 204 205 /** 206 * Returns an array of arrays that represent the annotations on the formal parameters, in 207 * declaration order, of this method. 208 * 209 * @see Method#getParameterAnnotations() 210 */ 211 Annotation[][] getParameterAnnotations(); 212 213 /** 214 * Returns an array of {@link Type} objects that represent the formal parameter types, in 215 * declaration order, of this method. 216 * 217 * @see Method#getGenericParameterTypes() 218 */ 219 Type[] getGenericParameterTypes(); 220 221 /** 222 * Returns {@code true} if this method is not excluded from inlining and has associated Java 223 * bytecodes (@see {@link ResolvedJavaMethod#hasBytecodes()}). 224 */ 225 boolean canBeInlined(); 226 227 /** 228 * Returns {@code true} if the inlining of this method should be forced. 229 */ 230 boolean shouldBeInlined(); 231 232 /** 233 * Returns the LineNumberTable of this method or null if this method does not have a line 234 * numbers table. 235 */ 236 LineNumberTable getLineNumberTable(); 237 238 /** 239 * Returns the local variable table of this method or null if this method does not have a local 240 * variable table. 241 */ 242 LocalVariableTable getLocalVariableTable(); 243 244 /** 245 * Invokes the underlying method represented by this object, on the specified object with the 246 * specified parameters. This method is similar to a reflective method invocation by 247 * {@link Method#invoke}. 248 * 249 * @param receiver The receiver for the invocation, or {@code null} if it is a static method. 250 * @param arguments The arguments for the invocation. 251 * @return The value returned by the method invocation, or {@code null} if the return type is 252 * {@code void}. 253 */ 254 JavaConstant invoke(JavaConstant receiver, JavaConstant[] arguments); 255 256 /** 257 * Gets the encoding of (that is, a constant representing the value of) this method. 258 * 259 * @return a constant representing a reference to this method 260 */ 261 Constant getEncoding(); 262 263 /** 264 * Checks if this method is present in the virtual table for subtypes of the specified 265 * {@linkplain ResolvedJavaType type}. 266 * 267 * @return true is this method is present in the virtual table for subtypes of this type. 268 */ 269 boolean isInVirtualMethodTable(ResolvedJavaType resolved); 270 271 /** 272 * Gets the annotation of a particular type for a formal parameter of this method. 273 * 274 * @param annotationClass the Class object corresponding to the annotation type 275 * @param parameterIndex the index of a formal parameter of {@code method} 276 * @return the annotation of type {@code annotationClass} for the formal parameter present, else 277 * null 278 * @throws IndexOutOfBoundsException if {@code parameterIndex} does not denote a formal 279 * parameter 280 */ 281 default <T extends Annotation> T getParameterAnnotation(Class<T> annotationClass, int parameterIndex) { 282 if (parameterIndex >= 0) { 283 Annotation[][] parameterAnnotations = getParameterAnnotations(); 284 for (Annotation a : parameterAnnotations[parameterIndex]) { 285 if (a.annotationType() == annotationClass) { 286 return annotationClass.cast(a); 287 } 288 } 289 } 290 return null; 291 } 292 293 default JavaType[] toParameterTypes() { 294 JavaType receiver = isStatic() || isConstructor() ? null : getDeclaringClass(); 295 return getSignature().toParameterTypes(receiver); 296 } 297 298 /** 299 * Gets the annotations of a particular type for the formal parameters of this method. 300 * 301 * @param annotationClass the Class object corresponding to the annotation type 302 * @return the annotation of type {@code annotationClass} (if any) for each formal parameter 303 * present 304 */ 305 @SuppressWarnings("unchecked") 306 default <T extends Annotation> T[] getParameterAnnotations(Class<T> annotationClass) { 307 Annotation[][] parameterAnnotations = getParameterAnnotations(); 308 T[] result = (T[]) Array.newInstance(annotationClass, parameterAnnotations.length); 309 for (int i = 0; i < parameterAnnotations.length; i++) { 310 for (Annotation a : parameterAnnotations[i]) { 311 if (a.annotationType() == annotationClass) { 312 result[i] = annotationClass.cast(a); 313 } 314 } 315 } 316 return result; 317 } 318 319 /** 320 * Checks whether the method has bytecodes associated with it. Methods without bytecodes are 321 * either abstract or native methods. 322 * 323 * @return whether the definition of this method is Java bytecodes 324 */ 325 default boolean hasBytecodes() { 326 return isConcrete() && !isNative(); 327 } 328 329 /** 330 * Checks whether the method has a receiver parameter - i.e., whether it is not static. 331 * 332 * @return whether the method has a receiver parameter 333 */ 334 default boolean hasReceiver() { 335 return !isStatic(); 336 } 337 338 /** 339 * Determines if this method is {@link java.lang.Object#Object()}. 340 */ 341 default boolean isJavaLangObjectInit() { 342 return getDeclaringClass().isJavaLangObject() && getName().equals("<init>"); 343 } 344 345 SpeculationLog getSpeculationLog(); 346 347 /** 348 * Determines if the method identified by its holder and name is a <a 349 * href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.9">signature 350 * polymorphic</a> method. 351 */ 352 static boolean isSignaturePolymorphic(JavaType holder, String name, MetaAccessProvider metaAccess) { 353 if (!holder.getName().equals("Ljava/lang/invoke/MethodHandle;")) { 354 return false; 355 } 356 ResolvedJavaType methodHandleType = metaAccess.lookupJavaType(MethodHandle.class); 357 Signature signature = metaAccess.parseMethodDescriptor("([Ljava/lang/Object;)Ljava/lang/Object;"); 358 ResolvedJavaMethod method = methodHandleType.findMethod(name, signature); 359 if (method == null) { 360 return false; 361 } 362 return method.isNative() && method.isVarArgs(); 363 } 364 }