summaryrefslogtreecommitdiffstats
path: root/luni/src
diff options
context:
space:
mode:
authorNeil Fuller <nfuller@google.com>2014-03-26 16:59:44 +0000
committerNeil Fuller <nfuller@google.com>2014-03-28 11:19:46 +0000
commit08da684abe6d5515a9c760a3a33af4f8b426095d (patch)
treeab1d757261bc97a6b64cb68c4d6c232ec901b4b4 /luni/src
parentf9901b2d274fdc2aab890c1e51e09042605b1370 (diff)
downloadlibcore-08da684abe6d5515a9c760a3a33af4f8b426095d.zip
libcore-08da684abe6d5515a9c760a3a33af4f8b426095d.tar.gz
libcore-08da684abe6d5515a9c760a3a33af4f8b426095d.tar.bz2
Improve the performance of Annotation checks
In the circumstance where the annotated element (field/ method/constructor/class) was loaded from a different Dex file than the annotation: The previous code would perform a binary search to determine the type ID of the annotation in the Dex file of the annotated element. That type ID would then be compared against the type IDs of annotations present on the annotated element. The binary search was quite expensive: it involved various indirections, many small native method calls and temporary String creation. Instead, the code now compares the names of the annotations on the annotated element with the name of the annotation being searched for. The name of the annotation is known and cached on the class and is therefore cheap to get. The name was previously being used to binary search for the type ID so this appears to be no less correct. Also removed some unused methods in order to delete the getFieldIndex() method. Change-Id: Ib8fb021ddf1221e3eac983aa87e7aea8174720ef
Diffstat (limited to 'luni/src')
-rw-r--r--luni/src/main/java/libcore/reflect/AnnotationAccess.java56
1 files changed, 12 insertions, 44 deletions
diff --git a/luni/src/main/java/libcore/reflect/AnnotationAccess.java b/luni/src/main/java/libcore/reflect/AnnotationAccess.java
index d63ad30..2a72c18 100644
--- a/luni/src/main/java/libcore/reflect/AnnotationAccess.java
+++ b/luni/src/main/java/libcore/reflect/AnnotationAccess.java
@@ -16,7 +16,6 @@
package libcore.reflect;
-import com.android.dex.ClassDef;
import com.android.dex.Dex;
import com.android.dex.EncodedValueReader;
import com.android.dex.FieldId;
@@ -167,7 +166,7 @@ public final class AnnotationAccess {
*/
public static <A extends Annotation> A getDeclaredAnnotation(
AnnotatedElement element, Class<A> annotationClass) {
- com.android.dex.Annotation a = getMethodAnnotation(element, annotationClass);
+ com.android.dex.Annotation a = getAnnotation(element, annotationClass);
return a != null
? toAnnotationInstance(getDexClass(element), annotationClass, a)
: null;
@@ -178,10 +177,10 @@ public final class AnnotationAccess {
*/
public static boolean isDeclaredAnnotationPresent(
AnnotatedElement element, Class<? extends Annotation> annotationClass) {
- return getMethodAnnotation(element, annotationClass) != null;
+ return getAnnotation(element, annotationClass) != null;
}
- private static com.android.dex.Annotation getMethodAnnotation(
+ private static com.android.dex.Annotation getAnnotation(
AnnotatedElement element, Class<? extends Annotation> annotationClass) {
int annotationSetOffset = getAnnotationSetOffset(element);
if (annotationSetOffset == 0) {
@@ -190,17 +189,17 @@ public final class AnnotationAccess {
Class<?> dexClass = getDexClass(element);
Dex dex = dexClass.getDex();
- int annotationTypeIndex = getTypeIndex(dex, annotationClass);
- if (annotationTypeIndex == -1) {
- return null; // The dex file doesn't use this annotation.
- }
-
Dex.Section setIn = dex.open(annotationSetOffset); // annotation_set_item
+ String annotationInternalName = InternalNames.getInternalName(annotationClass);
for (int i = 0, size = setIn.readInt(); i < size; i++) {
int annotationOffset = setIn.readInt();
Dex.Section annotationIn = dex.open(annotationOffset); // annotation_item
+ // The internal string name of the annotation is compared here and deliberately not
+ // the value of annotationClass.getTypeIndex(). The annotationClass may have been
+ // defined by a different dex file, which would make the indexes incomparable.
com.android.dex.Annotation candidate = annotationIn.readAnnotation();
- if (candidate.getTypeIndex() == annotationTypeIndex) {
+ String candidateInternalName = dex.typeNames().get(candidate.getTypeIndex());
+ if (candidateInternalName.equals(annotationInternalName)) {
return candidate;
}
}
@@ -268,23 +267,6 @@ public final class AnnotationAccess {
: ((Member) element).getDeclaringClass();
}
- public static int getFieldIndex(Class<?> declaringClass, Class<?> type, String name) {
- Dex dex = declaringClass.getDex();
- int declaringClassIndex = getTypeIndex(dex, declaringClass);
- int typeIndex = getTypeIndex(dex, type);
- int nameIndex = dex.findStringIndex(name);
- FieldId fieldId = new FieldId(dex, declaringClassIndex, typeIndex, nameIndex);
- return dex.findFieldIndex(fieldId);
- }
-
- public static int getMethodIndex(Class<?> declaringClass, String name, int protoIndex) {
- Dex dex = declaringClass.getDex();
- int declaringClassIndex = getTypeIndex(dex, declaringClass);
- int nameIndex = dex.findStringIndex(name);
- MethodId methodId = new MethodId(dex, declaringClassIndex, protoIndex, nameIndex);
- return dex.findMethodIndex(methodId);
- }
-
/**
* Returns the parameter annotations on {@code member}.
*/
@@ -357,6 +339,8 @@ public final class AnnotationAccess {
*/
Class<?> annotationClass = method.getDeclaringClass();
+ // All lookups of type and string indexes are within the Dex that declares the annotation so
+ // the indexes can be compared directly.
Dex dex = annotationClass.getDex();
EncodedValueReader reader = getOnlyAnnotationValue(
dex, annotationClass, "Ldalvik/annotation/AnnotationDefault;");
@@ -365,7 +349,7 @@ public final class AnnotationAccess {
}
int fieldCount = reader.readAnnotation();
- if (reader.getAnnotationType() != getTypeIndex(dex, annotationClass)) {
+ if (reader.getAnnotationType() != annotationClass.getDexTypeIndex()) {
throw new AssertionError("annotation value type != annotation class");
}
@@ -540,22 +524,6 @@ public final class AnnotationAccess {
* was derived.
*/
- /** Find dex's type index for the class c */
- private static int getTypeIndex(Dex dex, Class<?> c) {
- if (dex == c.getDex()) {
- return c.getDexTypeIndex();
- }
- if (dex == null) {
- return -1;
- }
- int typeIndex = dex.findTypeIndex(InternalNames.getInternalName(c));
- if (typeIndex < 0) {
- typeIndex = -1;
- }
- return typeIndex;
- }
-
-
private static EncodedValueReader getAnnotationReader(
Dex dex, AnnotatedElement element, String annotationName, int expectedFieldCount) {
int annotationSetOffset = getAnnotationSetOffset(element);