Move annotations to native.
Art side of this change. There is also a corresponding Libcore change.
Seeing ~2-3x speedup over dalvik KK MR1 in AnnotatedElementBenchmark.
Benchmark Speedup of Art AOSP to Dalvik KK MR1
GetAllReturnsLargeAnnotation 2.99
GetAllReturnsMarkerAnnotation 2.20
GetAllReturnsNoAnnotation 2.43
GetAllReturnsSmallAnnotation 2.52
GetAllReturnsThreeAnnotations 2.87
GetAnnotationsOnSubclass 2.42
GetDeclaredAnnotationsOnSubclass 2.49
GetFieldAnnotation 2.68
GetFieldAnnotations 2.60
GetMethodAnnotation 2.66
GetMethodAnnotations 2.61
GetParameterAnnotations 2.52
GetTypeAnnotation 2.56
GetTypeAnnotations 2.17
IsFieldAnnotationPresent 3.26
IsMethodAnnotationPresent 4.99
IsTypeAnnotationPresent 1.34
Change-Id: Ibdbb6d23b17eaab6e83c8774b1bb9401e8227941
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index fc805f8..8928321 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -28,6 +28,8 @@
#include "globals.h"
#include "invoke_type.h"
#include "jni.h"
+#include "jvalue.h"
+#include "mirror/object_array.h"
#include "modifiers.h"
#include "utf.h"
@@ -384,6 +386,17 @@
DISALLOW_COPY_AND_ASSIGN(AnnotationItem);
};
+ struct AnnotationValue {
+ JValue value_;
+ uint8_t type_;
+ };
+
+ enum AnnotationResultStyle { // private
+ kAllObjects,
+ kPrimitivesOrObjects,
+ kAllRaw
+ };
+
// Returns the checksum of a file for comparison with GetLocationChecksum().
// For .dex files, this is the header checksum.
// For zip files, this is the classes.dex zip entry CRC32 checksum.
@@ -817,6 +830,187 @@
static bool LineNumForPcCb(void* context, uint32_t address, uint32_t line_num);
+ const AnnotationsDirectoryItem* GetAnnotationsDirectory(const ClassDef& class_def) const {
+ if (class_def.annotations_off_ == 0) {
+ return nullptr;
+ } else {
+ return reinterpret_cast<const AnnotationsDirectoryItem*>(begin_ + class_def.annotations_off_);
+ }
+ }
+
+ const AnnotationSetItem* GetClassAnnotationSet(const AnnotationsDirectoryItem* anno_dir) const {
+ if (anno_dir->class_annotations_off_ == 0) {
+ return nullptr;
+ } else {
+ return reinterpret_cast<const AnnotationSetItem*>(begin_ + anno_dir->class_annotations_off_);
+ }
+ }
+
+ const FieldAnnotationsItem* GetFieldAnnotations(const AnnotationsDirectoryItem* anno_dir) const {
+ if (anno_dir->fields_size_ == 0) {
+ return nullptr;
+ } else {
+ return reinterpret_cast<const FieldAnnotationsItem*>(&anno_dir[1]);
+ }
+ }
+
+ const MethodAnnotationsItem* GetMethodAnnotations(const AnnotationsDirectoryItem* anno_dir)
+ const {
+ if (anno_dir->methods_size_ == 0) {
+ return nullptr;
+ } else {
+ // Skip past the header and field annotations.
+ const uint8_t* addr = reinterpret_cast<const uint8_t*>(&anno_dir[1]);
+ addr += anno_dir->fields_size_ * sizeof(FieldAnnotationsItem);
+ return reinterpret_cast<const MethodAnnotationsItem*>(addr);
+ }
+ }
+
+ const ParameterAnnotationsItem* GetParameterAnnotations(const AnnotationsDirectoryItem* anno_dir)
+ const {
+ if (anno_dir->parameters_size_ == 0) {
+ return nullptr;
+ } else {
+ // Skip past the header, field annotations, and method annotations.
+ const uint8_t* addr = reinterpret_cast<const uint8_t*>(&anno_dir[1]);
+ addr += anno_dir->fields_size_ * sizeof(FieldAnnotationsItem);
+ addr += anno_dir->methods_size_ * sizeof(MethodAnnotationsItem);
+ return reinterpret_cast<const ParameterAnnotationsItem*>(addr);
+ }
+ }
+
+ const AnnotationSetItem* GetFieldAnnotationSetItem(const FieldAnnotationsItem& anno_item) const {
+ uint32_t offset = anno_item.annotations_off_;
+ if (offset == 0) {
+ return nullptr;
+ } else {
+ return reinterpret_cast<const AnnotationSetItem*>(begin_ + offset);
+ }
+ }
+
+ const AnnotationSetItem* GetMethodAnnotationSetItem(const MethodAnnotationsItem& anno_item)
+ const {
+ uint32_t offset = anno_item.annotations_off_;
+ if (offset == 0) {
+ return nullptr;
+ } else {
+ return reinterpret_cast<const AnnotationSetItem*>(begin_ + offset);
+ }
+ }
+
+ const AnnotationSetRefList* GetParameterAnnotationSetRefList(
+ const ParameterAnnotationsItem* anno_item) const {
+ uint32_t offset = anno_item->annotations_off_;
+ if (offset == 0) {
+ return nullptr;
+ }
+ return reinterpret_cast<const AnnotationSetRefList*>(begin_ + offset);
+ }
+
+ const AnnotationItem* GetAnnotationItem(const AnnotationSetItem* set_item, uint32_t index) const {
+ DCHECK_LE(index, set_item->size_);
+ uint32_t offset = set_item->entries_[index];
+ if (offset == 0) {
+ return nullptr;
+ } else {
+ return reinterpret_cast<const AnnotationItem*>(begin_ + offset);
+ }
+ }
+
+ const AnnotationSetItem* GetSetRefItemItem(const AnnotationSetRefItem* anno_item) const {
+ uint32_t offset = anno_item->annotations_off_;
+ if (offset == 0) {
+ return nullptr;
+ }
+ return reinterpret_cast<const AnnotationSetItem*>(begin_ + offset);
+ }
+
+ const AnnotationSetItem* FindAnnotationSetForField(ArtField* field) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::Object* GetAnnotationForField(ArtField* field, Handle<mirror::Class> annotation_class)
+ const SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::ObjectArray<mirror::Object>* GetAnnotationsForField(ArtField* field) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::ObjectArray<mirror::Object>* GetSignatureAnnotationForField(ArtField* field) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ bool IsFieldAnnotationPresent(ArtField* field, Handle<mirror::Class> annotation_class) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+
+ const AnnotationSetItem* FindAnnotationSetForMethod(ArtMethod* method) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ const ParameterAnnotationsItem* FindAnnotationsItemForMethod(ArtMethod* method) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::Object* GetAnnotationDefaultValue(ArtMethod* method) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::Object* GetAnnotationForMethod(ArtMethod* method, Handle<mirror::Class> annotation_class)
+ const SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::ObjectArray<mirror::Object>* GetAnnotationsForMethod(ArtMethod* method) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::ObjectArray<mirror::Object>* GetExceptionTypesForMethod(ArtMethod* method) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::ObjectArray<mirror::Object>* GetParameterAnnotations(ArtMethod* method) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ bool IsMethodAnnotationPresent(ArtMethod* method, Handle<mirror::Class> annotation_class) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+
+ const AnnotationSetItem* FindAnnotationSetForClass(Handle<mirror::Class> klass) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::Object* GetAnnotationForClass(Handle<mirror::Class> klass,
+ Handle<mirror::Class> annotation_class) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::ObjectArray<mirror::Object>* GetAnnotationsForClass(Handle<mirror::Class> klass) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ bool IsClassAnnotationPresent(Handle<mirror::Class> klass, Handle<mirror::Class> annotation_class)
+ const SHARED_REQUIRES(Locks::mutator_lock_);
+
+ mirror::Object* CreateAnnotationMember(Handle<mirror::Class> klass,
+ Handle<mirror::Class> annotation_class,
+ const uint8_t** annotation) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ const AnnotationItem* GetAnnotationItemFromAnnotationSet(Handle<mirror::Class> klass,
+ const AnnotationSetItem* annotation_set,
+ uint32_t visibility,
+ Handle<mirror::Class> annotation_class)
+ const SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::Object* GetAnnotationObjectFromAnnotationSet(Handle<mirror::Class> klass,
+ const AnnotationSetItem* annotation_set,
+ uint32_t visibility,
+ Handle<mirror::Class> annotation_class) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::Object* GetAnnotationValue(Handle<mirror::Class> klass,
+ const AnnotationItem* annotation_item,
+ const char* annotation_name,
+ Handle<mirror::Class> array_class,
+ uint32_t expected_type) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::ObjectArray<mirror::Object>* GetSignatureValue(Handle<mirror::Class> klass,
+ const AnnotationSetItem* annotation_set)
+ const SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::ObjectArray<mirror::Object>* GetThrowsValue(Handle<mirror::Class> klass,
+ const AnnotationSetItem* annotation_set) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::ObjectArray<mirror::Object>* ProcessAnnotationSet(Handle<mirror::Class> klass,
+ const AnnotationSetItem* annotation_set,
+ uint32_t visibility) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::ObjectArray<mirror::Object>* ProcessAnnotationSetRefList(Handle<mirror::Class> klass,
+ const AnnotationSetRefList* set_ref_list, uint32_t size) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ bool ProcessAnnotationValue(Handle<mirror::Class> klass, const uint8_t** annotation_ptr,
+ AnnotationValue* annotation_value, Handle<mirror::Class> return_class,
+ DexFile::AnnotationResultStyle result_style) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::Object* ProcessEncodedAnnotation(Handle<mirror::Class> klass,
+ const uint8_t** annotation) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ const AnnotationItem* SearchAnnotationSet(const AnnotationSetItem* annotation_set,
+ const char* descriptor, uint32_t visibility) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ const uint8_t* SearchEncodedAnnotation(const uint8_t* annotation, const char* name) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ bool SkipAnnotationValue(const uint8_t** annotation_ptr) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+
// Debug info opcodes and constants
enum {
DBG_END_SEQUENCE = 0x00,