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
diff --git a/dex/src/main/java/com/android/dex/Dex.java b/dex/src/main/java/com/android/dex/Dex.java
index 116a33c..78ee574 100644
--- a/dex/src/main/java/com/android/dex/Dex.java
+++ b/dex/src/main/java/com/android/dex/Dex.java
@@ -882,7 +882,7 @@
         /**
          * Returns the number of bytes used by this section.
          */
-        public int used () {
+        public int used() {
             return data.position() - initialPosition;
         }
     }
@@ -896,7 +896,7 @@
         @Override public int size() {
             return tableOfContents.stringIds.size;
         }
-    };
+    }
 
     private final class TypeIndexToDescriptorIndexTable extends AbstractList<Integer>
             implements RandomAccess {
@@ -906,7 +906,7 @@
         @Override public int size() {
             return tableOfContents.typeIds.size;
         }
-    };
+    }
 
     private final class TypeIndexToDescriptorTable extends AbstractList<String>
             implements RandomAccess {
@@ -916,7 +916,7 @@
         @Override public int size() {
             return tableOfContents.typeIds.size;
         }
-    };
+    }
 
     private final class ProtoIdTable extends AbstractList<ProtoId> implements RandomAccess {
         @Override public ProtoId get(int index) {
@@ -927,7 +927,7 @@
         @Override public int size() {
             return tableOfContents.protoIds.size;
         }
-    };
+    }
 
     private final class FieldIdTable extends AbstractList<FieldId> implements RandomAccess {
         @Override public FieldId get(int index) {
@@ -938,7 +938,7 @@
         @Override public int size() {
             return tableOfContents.fieldIds.size;
         }
-    };
+    }
 
     private final class MethodIdTable extends AbstractList<MethodId> implements RandomAccess {
         @Override public MethodId get(int index) {
@@ -949,7 +949,7 @@
         @Override public int size() {
             return tableOfContents.methodIds.size;
         }
-    };
+    }
 
     private final class ClassDefIterator implements Iterator<ClassDef> {
         private final Dex.Section in = open(tableOfContents.classDefs.off);
@@ -971,7 +971,7 @@
             public void remove() {
             throw new UnsupportedOperationException();
         }
-    };
+    }
 
     private final class ClassDefIterable implements Iterable<ClassDef> {
         public Iterator<ClassDef> iterator() {
@@ -979,5 +979,5 @@
                ? Collections.<ClassDef>emptySet().iterator()
                : new ClassDefIterator();
         }
-    };
+    }
 }
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 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 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 @@
 
         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 @@
                 : ((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 @@
          */
 
         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 @@
         }
 
         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 @@
      * 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);