• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 /*
18  * Copyright (C) 2012 The Android Open Source Project
19  *
20  * Licensed under the Apache License, Version 2.0 (the "License");
21  * you may not use this file except in compliance with the License.
22  * You may obtain a copy of the License at
23  *
24  *      http://www.apache.org/licenses/LICENSE-2.0
25  *
26  * Unless required by applicable law or agreed to in writing, software
27  * distributed under the License is distributed on an "AS IS" BASIS,
28  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29  * See the License for the specific language governing permissions and
30  * limitations under the License.
31  */
32 
33 package java.lang.reflect;
34 
35 import com.android.dex.Dex;
36 import java.lang.annotation.Annotation;
37 import libcore.reflect.AnnotationAccess;
38 import libcore.util.EmptyArray;
39 
40 /**
41  * This class represents methods and constructors.
42  * @hide
43  */
44 public final class ArtMethod {
45     /* A note on the field order here, it reflects the same field order as laid out by ART. */
46 
47     /** Method's declaring class */
48     private Class<?> declaringClass;
49 
50     /** Short-cut to declaringClass.dexCache.resolvedMethods */
51     private ArtMethod[] dexCacheResolvedMethods;
52 
53     /** Short-cut to declaringClass.dexCache.resolvedTypes */
54     /* package */ Class<?>[] dexCacheResolvedTypes;
55 
56     /** Short-cut to declaringClass.dexCache.strings */
57     private String[] dexCacheStrings;
58 
59     /**
60      * Method dispatch from the interpreter invokes this pointer which may cause a bridge into
61      * compiled code.
62      */
63     private long entryPointFromInterpreter;
64 
65     /**
66      * Pointer to JNI function registered to this method, or a function to resolve the JNI function.
67      */
68     private long entryPointFromJni;
69 
70     /**
71      * Method dispatch from portable compiled code invokes this pointer which may cause bridging
72      * into quick compiled code or the interpreter.
73      * Uncomment to enable.
74      */
75     // private long entryPointFromPortableCompiledCode;
76 
77     /**
78      * Method dispatch from quick compiled code invokes this pointer which may cause bridging
79      * into portable compiled code or the interpreter.
80      */
81     private long entryPointFromQuickCompiledCode;
82 
83     /**
84      * Pointer to a data structure created by the compiler and used by the garbage collector to
85      * determine which registers hold live references to objects within the heap.
86      */
87     private long gcMap;
88 
89     /** Bits encoding access (e.g. public, private) as well as other runtime specific flags */
90     private int accessFlags;
91 
92     /* Dex file fields. The defining dex file is available via declaringClass.dexCache */
93 
94     /** The offset of the code item associated with this method within its defining dex file */
95     private int dexCodeItemOffset;
96 
97     /** The method index of this method within its defining dex file */
98     private int dexMethodIndex;
99 
100     /* End of dex file fields. */
101 
102     /**
103      * Entry within a dispatch table for this method. For static/direct methods the index is
104      * into the declaringClass.directMethods, for virtual methods the vtable and for
105      * interface methods the ifTable.
106      */
107     private int methodIndex;
108 
109     /** Only created by ART directly. */
ArtMethod()110     private ArtMethod() {}
111 
getDeclaringClass()112     Class getDeclaringClass() {
113         return declaringClass;
114     }
115 
getAccessFlags()116     public int getAccessFlags() {
117         return accessFlags;
118     }
119 
getDexMethodIndex()120     int getDexMethodIndex() {
121         return dexMethodIndex;
122     }
123 
getMethodName(ArtMethod artMethod)124     public static String getMethodName(ArtMethod artMethod) {
125         artMethod = artMethod.findOverriddenMethodIfProxy();
126         Dex dex = artMethod.getDeclaringClass().getDex();
127         int nameIndex = dex.nameIndexFromMethodIndex(artMethod.getDexMethodIndex());
128         // Note, in the case of a Proxy the dex cache strings are equal.
129         return artMethod.getDexCacheString(dex, nameIndex);
130     }
131 
132     /**
133      * Returns true if the given parameters match those of the method in the given order.
134      *
135      * @hide
136      */
equalConstructorParameters(ArtMethod artMethod, Class<?>[] params)137     public static boolean equalConstructorParameters(ArtMethod artMethod, Class<?>[] params) {
138         Dex dex = artMethod.getDeclaringClass().getDex();
139         short[] types = dex.parameterTypeIndicesFromMethodIndex(artMethod.getDexMethodIndex());
140         if (types.length != params.length) {
141             return false;
142         }
143         for (int i = 0; i < types.length; i++) {
144             if (artMethod.getDexCacheType(dex, types[i]) != params[i]) {
145                 return false;
146             }
147         }
148         return true;
149     }
150 
151     /**
152      * Returns true if the given parameters match those of this method in the given order.
153      *
154      * @hide
155      */
equalMethodParameters(ArtMethod artMethod, Class<?>[] params)156     public static boolean equalMethodParameters(ArtMethod artMethod, Class<?>[] params) {
157         return equalConstructorParameters(artMethod.findOverriddenMethodIfProxy(), params);
158     }
159 
getParameterTypes()160     Class<?>[] getParameterTypes() {
161         Dex dex = getDeclaringClass().getDex();
162         short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
163         if (types.length == 0) {
164             return EmptyArray.CLASS;
165         }
166         Class<?>[] parametersArray = new Class[types.length];
167         for (int i = 0; i < types.length; i++) {
168             // Note, in the case of a Proxy the dex cache types are equal.
169             parametersArray[i] = getDexCacheType(dex, types[i]);
170         }
171         return parametersArray;
172     }
173 
getReturnType()174     Class<?> getReturnType() {
175         Dex dex = declaringClass.getDex();
176         int returnTypeIndex = dex.returnTypeIndexFromMethodIndex(dexMethodIndex);
177         // Note, in the case of a Proxy the dex cache types are equal.
178         return getDexCacheType(dex, returnTypeIndex);
179     }
180 
181     /**
182      * Performs a comparison of the parameters to this method with the given parameters.
183      *
184      * @hide
185      */
compareParameters(Class<?>[] params)186     int compareParameters(Class<?>[] params) {
187         Dex dex = getDeclaringClass().getDex();
188         short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
189         int length = Math.min(types.length, params.length);
190         for (int i = 0; i < length; i++) {
191             Class<?> aType = getDexCacheType(dex, types[i]);
192             Class<?> bType = params[i];
193             if (aType != bType) {
194                 int comparison = aType.getName().compareTo(bType.getName());
195                 if (comparison != 0) {
196                     return comparison;
197                 }
198             }
199         }
200         return types.length - params.length;
201     }
202 
getParameterAnnotations()203     Annotation[][] getParameterAnnotations() {
204         return AnnotationAccess.getParameterAnnotations(declaringClass, dexMethodIndex);
205     }
206 
207     /**
208      * Returns a string from the dex cache, computing the string from the dex file if necessary.
209      * Note this method replicates {@link java.lang.Class#getDexCacheString(Dex, int)}, but in
210      * Method we can avoid one indirection.
211      */
getDexCacheString(Dex dex, int dexStringIndex)212     private String getDexCacheString(Dex dex, int dexStringIndex) {
213         String s = (String) dexCacheStrings[dexStringIndex];
214         if (s == null) {
215             s = dex.strings().get(dexStringIndex).intern();
216             dexCacheStrings[dexStringIndex] = s;
217         }
218         return s;
219     }
220 
221     /**
222      * Returns a resolved type from the dex cache, computing the string from the dex file if
223      * necessary. Note this method delegates to {@link java.lang.Class#getDexCacheType(Dex, int)},
224      * but in Method we can avoid one indirection.
225      */
getDexCacheType(Dex dex, int dexTypeIndex)226     private Class<?> getDexCacheType(Dex dex, int dexTypeIndex) {
227         Class<?> resolvedType = dexCacheResolvedTypes[dexTypeIndex];
228         if (resolvedType == null) {
229             resolvedType = declaringClass.getDexCacheType(dex, dexTypeIndex);
230         }
231         return resolvedType;
232     }
233 
234     /**
235      * Returns the {@code ArtMethod} that this method overrides for
236      * proxy methods, otherwise returns this method. Used to determine
237      * the interface method overridden by a proxy method (as the proxy
238      * method doesn't directly support operations such as {@link
239      * Method#getName}).
240      */
findOverriddenMethodIfProxy()241     ArtMethod findOverriddenMethodIfProxy() {
242         if (declaringClass.isProxy()) {
243             // Proxy method's declaring class' dex cache refers to that of Proxy. The local cache in
244             // Method refers to the original interface's dex cache and is ensured to be resolved by
245             // proxy generation.
246             return dexCacheResolvedMethods[dexMethodIndex];
247         }
248         return this;
249     }
250 }
251