Move more Class annotations to native.
Art side of this change. There is also a corresponding Libcore change.
Seeing speedup in AnnotatedElementBenchmark.
GetDeclaredClasses 21.61x
GetDeclaringClass 108.73x
GetEnclosingClass 87.81x
GetEnclosingConstructor 23.35x
GetEnclosingMethod 22.71x
GetModifiers 152.47x
GetSimpleName 106.11x
IsAnonymousClass 91.28x
IsLocalClass 51.95x
Change-Id: I2b7f7eb7785fc20671fd7c338ffa9c7048a44a48
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index 213f25d..29413bf 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -1132,7 +1132,7 @@
return ProcessAnnotationSet(field_class, annotation_set, kDexVisibilityRuntime);
}
-mirror::ObjectArray<mirror::Object>* DexFile::GetSignatureAnnotationForField(ArtField* field)
+mirror::ObjectArray<mirror::String>* DexFile::GetSignatureAnnotationForField(ArtField* field)
const {
const AnnotationSetItem* annotation_set = FindAnnotationSetForField(field);
if (annotation_set == nullptr) {
@@ -1253,7 +1253,7 @@
return ProcessAnnotationSet(method_class, annotation_set, kDexVisibilityRuntime);
}
-mirror::ObjectArray<mirror::Object>* DexFile::GetExceptionTypesForMethod(ArtMethod* method) const {
+mirror::ObjectArray<mirror::Class>* DexFile::GetExceptionTypesForMethod(ArtMethod* method) const {
const AnnotationSetItem* annotation_set = FindAnnotationSetForMethod(method);
if (annotation_set == nullptr) {
return nullptr;
@@ -1289,7 +1289,7 @@
Handle<mirror::Class> method_class(hs.NewHandle(method->GetDeclaringClass()));
const AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet(
method_class, annotation_set, kDexVisibilityRuntime, annotation_class);
- return (annotation_item != nullptr);
+ return annotation_item != nullptr;
}
const DexFile::AnnotationSetItem* DexFile::FindAnnotationSetForClass(Handle<mirror::Class> klass)
@@ -1317,6 +1317,153 @@
return ProcessAnnotationSet(klass, annotation_set, kDexVisibilityRuntime);
}
+mirror::ObjectArray<mirror::Class>* DexFile::GetDeclaredClasses(Handle<mirror::Class> klass) const {
+ const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
+ if (annotation_set == nullptr) {
+ return nullptr;
+ }
+ const AnnotationItem* annotation_item = SearchAnnotationSet(
+ annotation_set, "Ldalvik/annotation/MemberClasses;", kDexVisibilitySystem);
+ if (annotation_item == nullptr) {
+ return nullptr;
+ }
+ StackHandleScope<1> hs(Thread::Current());
+ mirror::Class* class_class = mirror::Class::GetJavaLangClass();
+ Handle<mirror::Class> class_array_class(hs.NewHandle(
+ Runtime::Current()->GetClassLinker()->FindArrayClass(hs.Self(), &class_class)));
+ if (class_array_class.Get() == nullptr) {
+ return nullptr;
+ }
+ mirror::Object* obj = GetAnnotationValue(
+ klass, annotation_item, "value", class_array_class, kDexAnnotationArray);
+ if (obj == nullptr) {
+ return nullptr;
+ }
+ return obj->AsObjectArray<mirror::Class>();
+}
+
+mirror::Class* DexFile::GetDeclaringClass(Handle<mirror::Class> klass) const {
+ const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
+ if (annotation_set == nullptr) {
+ return nullptr;
+ }
+ const AnnotationItem* annotation_item = SearchAnnotationSet(
+ annotation_set, "Ldalvik/annotation/EnclosingClass;", kDexVisibilitySystem);
+ if (annotation_item == nullptr) {
+ return nullptr;
+ }
+ mirror::Object* obj = GetAnnotationValue(
+ klass, annotation_item, "value", NullHandle<mirror::Class>(), kDexAnnotationType);
+ if (obj == nullptr) {
+ return nullptr;
+ }
+ return obj->AsClass();
+}
+
+mirror::Class* DexFile::GetEnclosingClass(Handle<mirror::Class> klass) const {
+ mirror::Class* declaring_class = GetDeclaringClass(klass);
+ if (declaring_class != nullptr) {
+ return declaring_class;
+ }
+ const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
+ if (annotation_set == nullptr) {
+ return nullptr;
+ }
+ const AnnotationItem* annotation_item = SearchAnnotationSet(
+ annotation_set, "Ldalvik/annotation/EnclosingMethod;", kDexVisibilitySystem);
+ if (annotation_item == nullptr) {
+ return nullptr;
+ }
+ const uint8_t* annotation = SearchEncodedAnnotation(annotation_item->annotation_, "value");
+ if (annotation == nullptr) {
+ return nullptr;
+ }
+ AnnotationValue annotation_value;
+ if (!ProcessAnnotationValue(
+ klass, &annotation, &annotation_value, NullHandle<mirror::Class>(), kAllRaw)) {
+ return nullptr;
+ }
+ if (annotation_value.type_ != kDexAnnotationMethod) {
+ return nullptr;
+ }
+ StackHandleScope<2> hs(Thread::Current());
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
+ Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
+ ArtMethod* method = Runtime::Current()->GetClassLinker()->ResolveMethodWithoutInvokeType(
+ klass->GetDexFile(), annotation_value.value_.GetI(), dex_cache, class_loader);
+ if (method == nullptr) {
+ return nullptr;
+ }
+ return method->GetDeclaringClass();
+}
+
+mirror::Object* DexFile::GetEnclosingMethod(Handle<mirror::Class> klass) const {
+ const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
+ if (annotation_set == nullptr) {
+ return nullptr;
+ }
+ const AnnotationItem* annotation_item = SearchAnnotationSet(
+ annotation_set, "Ldalvik/annotation/EnclosingMethod;", kDexVisibilitySystem);
+ if (annotation_item == nullptr) {
+ return nullptr;
+ }
+ return GetAnnotationValue(
+ klass, annotation_item, "value", NullHandle<mirror::Class>(), kDexAnnotationMethod);
+}
+
+bool DexFile::GetInnerClass(Handle<mirror::Class> klass, mirror::String** name) const {
+ const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
+ if (annotation_set == nullptr) {
+ return false;
+ }
+ const AnnotationItem* annotation_item = SearchAnnotationSet(
+ annotation_set, "Ldalvik/annotation/InnerClass;", kDexVisibilitySystem);
+ if (annotation_item == nullptr) {
+ return false;
+ }
+ const uint8_t* annotation = SearchEncodedAnnotation(annotation_item->annotation_, "name");
+ if (annotation == nullptr) {
+ return false;
+ }
+ AnnotationValue annotation_value;
+ if (!ProcessAnnotationValue(
+ klass, &annotation, &annotation_value, NullHandle<mirror::Class>(), kAllObjects)) {
+ return false;
+ }
+ if (annotation_value.type_ != kDexAnnotationNull &&
+ annotation_value.type_ != kDexAnnotationString) {
+ return false;
+ }
+ *name = down_cast<mirror::String*>(annotation_value.value_.GetL());
+ return true;
+}
+
+bool DexFile::GetInnerClassFlags(Handle<mirror::Class> klass, uint32_t* flags) const {
+ const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
+ if (annotation_set == nullptr) {
+ return false;
+ }
+ const AnnotationItem* annotation_item = SearchAnnotationSet(
+ annotation_set, "Ldalvik/annotation/InnerClass;", kDexVisibilitySystem);
+ if (annotation_item == nullptr) {
+ return false;
+ }
+ const uint8_t* annotation = SearchEncodedAnnotation(annotation_item->annotation_, "accessFlags");
+ if (annotation == nullptr) {
+ return false;
+ }
+ AnnotationValue annotation_value;
+ if (!ProcessAnnotationValue(
+ klass, &annotation, &annotation_value, NullHandle<mirror::Class>(), kAllRaw)) {
+ return false;
+ }
+ if (annotation_value.type_ != kDexAnnotationInt) {
+ return false;
+ }
+ *flags = annotation_value.value_.GetI();
+ return true;
+}
+
bool DexFile::IsClassAnnotationPresent(Handle<mirror::Class> klass,
Handle<mirror::Class> annotation_class) const {
const AnnotationSetItem* annotation_set = FindAnnotationSetForClass(klass);
@@ -1325,7 +1472,7 @@
}
const AnnotationItem* annotation_item = GetAnnotationItemFromAnnotationSet(
klass, annotation_set, kDexVisibilityRuntime, annotation_class);
- return (annotation_item != nullptr);
+ return annotation_item != nullptr;
}
mirror::Object* DexFile::CreateAnnotationMember(Handle<mirror::Class> klass,
@@ -1440,7 +1587,7 @@
return annotation_value.value_.GetL();
}
-mirror::ObjectArray<mirror::Object>* DexFile::GetSignatureValue(Handle<mirror::Class> klass,
+mirror::ObjectArray<mirror::String>* DexFile::GetSignatureValue(Handle<mirror::Class> klass,
const AnnotationSetItem* annotation_set) const {
StackHandleScope<1> hs(Thread::Current());
const AnnotationItem* annotation_item =
@@ -1451,15 +1598,18 @@
mirror::Class* string_class = mirror::String::GetJavaLangString();
Handle<mirror::Class> string_array_class(hs.NewHandle(
Runtime::Current()->GetClassLinker()->FindArrayClass(Thread::Current(), &string_class)));
+ if (string_array_class.Get() == nullptr) {
+ return nullptr;
+ }
mirror::Object* obj =
GetAnnotationValue(klass, annotation_item, "value", string_array_class, kDexAnnotationArray);
if (obj == nullptr) {
return nullptr;
}
- return obj->AsObjectArray<mirror::Object>();
+ return obj->AsObjectArray<mirror::String>();
}
-mirror::ObjectArray<mirror::Object>* DexFile::GetThrowsValue(Handle<mirror::Class> klass,
+mirror::ObjectArray<mirror::Class>* DexFile::GetThrowsValue(Handle<mirror::Class> klass,
const AnnotationSetItem* annotation_set) const {
StackHandleScope<1> hs(Thread::Current());
const AnnotationItem* annotation_item =
@@ -1470,12 +1620,15 @@
mirror::Class* class_class = mirror::Class::GetJavaLangClass();
Handle<mirror::Class> class_array_class(hs.NewHandle(
Runtime::Current()->GetClassLinker()->FindArrayClass(Thread::Current(), &class_class)));
+ if (class_array_class.Get() == nullptr) {
+ return nullptr;
+ }
mirror::Object* obj =
GetAnnotationValue(klass, annotation_item, "value", class_array_class, kDexAnnotationArray);
if (obj == nullptr) {
return nullptr;
}
- return obj->AsObjectArray<mirror::Object>();
+ return obj->AsObjectArray<mirror::Class>();
}
mirror::ObjectArray<mirror::Object>* DexFile::ProcessAnnotationSet(Handle<mirror::Class> klass,
@@ -1507,6 +1660,8 @@
if (annotation_obj != nullptr) {
result->SetWithoutChecks<false>(dest_index, annotation_obj);
++dest_index;
+ } else if (self->IsExceptionPending()) {
+ return nullptr;
}
}
@@ -1516,6 +1671,10 @@
mirror::ObjectArray<mirror::Object>* trimmed_result =
mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_class.Get(), dest_index);
+ if (trimmed_result == nullptr) {
+ return nullptr;
+ }
+
for (uint32_t i = 0; i < dest_index; ++i) {
mirror::Object* obj = result->GetWithoutChecks(i);
trimmed_result->SetWithoutChecks<false>(i, obj);
@@ -1533,6 +1692,9 @@
soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_annotation_Annotation__array);
mirror::Class* annotation_array_array_class =
Runtime::Current()->GetClassLinker()->FindArrayClass(self, &annotation_array_class);
+ if (annotation_array_array_class == nullptr) {
+ return nullptr;
+ }
Handle<mirror::ObjectArray<mirror::Object>> annotation_array_array(hs.NewHandle(
mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_array_class, size)));
if (annotation_array_array.Get() == nullptr) {
@@ -1625,9 +1787,8 @@
klass->GetDexFile(), index, klass.Get());
set_object = true;
if (element_object == nullptr) {
- self->ClearException();
- const char* msg = StringByTypeIdx(index);
- self->ThrowNewException("Ljava/lang/TypeNotPresentException;", msg);
+ // TODO: Put a TypeNotFoundExceptionProxy instead of throwing here.
+ return false;
}
}
break;
@@ -1831,8 +1992,10 @@
soa.Decode<mirror::Class*>(WellKnownClasses::libcore_reflect_AnnotationMember);
mirror::Class* annotation_member_array_class =
class_linker->FindArrayClass(self, &annotation_member_class);
+ if (annotation_member_array_class == nullptr) {
+ return nullptr;
+ }
mirror::ObjectArray<mirror::Object>* element_array = nullptr;
-
if (size > 0) {
element_array =
mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_member_array_class, size);