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