diff options
author | Neil Fuller <nfuller@google.com> | 2014-03-25 12:38:18 +0000 |
---|---|---|
committer | Neil Fuller <nfuller@google.com> | 2014-03-26 14:06:16 +0000 |
commit | 457745fd303079b2ccea1963794a9383f9770ee7 (patch) | |
tree | c2772e3b616a2aaaf9a94e61847a7e2778410983 /luni/src | |
parent | 217c7c93cc461d174aec997fc89c4ed37e2cd989 (diff) | |
download | libcore-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.java | 31 |
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++) { |