summaryrefslogtreecommitdiffstats
path: root/luni/src
diff options
context:
space:
mode:
authorNeil Fuller <nfuller@google.com>2014-03-25 12:38:18 +0000
committerNeil Fuller <nfuller@google.com>2014-03-26 14:06:16 +0000
commit457745fd303079b2ccea1963794a9383f9770ee7 (patch)
treec2772e3b616a2aaaf9a94e61847a7e2778410983 /luni/src
parent217c7c93cc461d174aec997fc89c4ed37e2cd989 (diff)
downloadlibcore-457745fd303079b2ccea1963794a9383f9770ee7.zip
libcore-457745fd303079b2ccea1963794a9383f9770ee7.tar.gz
libcore-457745fd303079b2ccea1963794a9383f9770ee7.tar.bz2
Speed-up for apps that use Dagger on ART
This is more of a harm-free heuristic improvement than a fix. It rearranges the algorithm for determining whether a Field (or Constructor/Method) is annotated. A cheap check (does the Field/Method/Constructor has any annotations at all?) is pushed ahead of a more expensive one (If the annotation were to be present, what would its type index be?). This happens to work well in practice in sample apps because the cheap check often fails, allowing the algorithm to terminate earlier. The second change is to skip() the field information rather than to read each field in turn when looking for Method or Constructor annotation information. The second change is not a hotspot but looks like an easy optimization that avoids many small method calls and a for loop for little additional complexity. Change-Id: I2118d650f2f1db4e103384483684306e42809093
Diffstat (limited to 'luni/src')
-rw-r--r--luni/src/main/java/libcore/reflect/AnnotationAccess.java31
1 files changed, 17 insertions, 14 deletions
diff --git a/luni/src/main/java/libcore/reflect/AnnotationAccess.java b/luni/src/main/java/libcore/reflect/AnnotationAccess.java
index 6ff82c4..d63ad30 100644
--- a/luni/src/main/java/libcore/reflect/AnnotationAccess.java
+++ b/luni/src/main/java/libcore/reflect/AnnotationAccess.java
@@ -183,6 +183,11 @@ public final class AnnotationAccess {
private static com.android.dex.Annotation getMethodAnnotation(
AnnotatedElement element, Class<? extends Annotation> annotationClass) {
+ int annotationSetOffset = getAnnotationSetOffset(element);
+ if (annotationSetOffset == 0) {
+ return null; // no annotation
+ }
+
Class<?> dexClass = getDexClass(element);
Dex dex = dexClass.getDex();
int annotationTypeIndex = getTypeIndex(dex, annotationClass);
@@ -190,11 +195,6 @@ public final class AnnotationAccess {
return null; // The dex file doesn't use this annotation.
}
- int annotationSetOffset = getAnnotationSetOffset(element);
- if (annotationSetOffset == 0) {
- return null; // no annotation
- }
-
Dex.Section setIn = dex.open(annotationSetOffset); // annotation_set_item
for (int i = 0, size = setIn.readInt(); i < size; i++) {
int annotationOffset = setIn.readInt();
@@ -228,19 +228,22 @@ public final class AnnotationAccess {
int methodsSize = directoryIn.readInt();
directoryIn.readInt(); // parameters size
- int fieldIndex = element instanceof Field ? ((Field) element).getDexFieldIndex() : -1;
- for (int i = 0; i < fieldsSize; i++) {
- int candidateFieldIndex = directoryIn.readInt();
- int annotationSetOffset = directoryIn.readInt();
- if (candidateFieldIndex == fieldIndex) {
- return annotationSetOffset;
- }
- }
- // we must read all fields prior to methods, if we were searching for a field then we missed
if (element instanceof Field) {
+ int fieldIndex = ((Field) element).getDexFieldIndex();
+ for (int i = 0; i < fieldsSize; i++) {
+ int candidateFieldIndex = directoryIn.readInt();
+ int annotationSetOffset = directoryIn.readInt();
+ if (candidateFieldIndex == fieldIndex) {
+ return annotationSetOffset;
+ }
+ }
+ // if we were searching for a field then we missed
return 0;
}
+ // Skip through the fields without reading them and look for constructors or methods.
+ directoryIn.skip(8 * fieldsSize);
+
int methodIndex= element instanceof Method ? ((Method) element).getDexMethodIndex()
: ((Constructor<?>) element).getDexMethodIndex();
for (int i = 0; i < methodsSize; i++) {