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);
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 8928321..98d4e59 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -931,7 +931,7 @@
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
+ mirror::ObjectArray<mirror::String>* GetSignatureAnnotationForField(ArtField* field) const
SHARED_REQUIRES(Locks::mutator_lock_);
bool IsFieldAnnotationPresent(ArtField* field, Handle<mirror::Class> annotation_class) const
SHARED_REQUIRES(Locks::mutator_lock_);
@@ -946,7 +946,7 @@
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
+ mirror::ObjectArray<mirror::Class>* GetExceptionTypesForMethod(ArtMethod* method) const
SHARED_REQUIRES(Locks::mutator_lock_);
mirror::ObjectArray<mirror::Object>* GetParameterAnnotations(ArtMethod* method) const
SHARED_REQUIRES(Locks::mutator_lock_);
@@ -960,6 +960,18 @@
SHARED_REQUIRES(Locks::mutator_lock_);
mirror::ObjectArray<mirror::Object>* GetAnnotationsForClass(Handle<mirror::Class> klass) const
SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::ObjectArray<mirror::Class>* GetDeclaredClasses(Handle<mirror::Class> klass) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::Class* GetDeclaringClass(Handle<mirror::Class> klass) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::Class* GetEnclosingClass(Handle<mirror::Class> klass) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ mirror::Object* GetEnclosingMethod(Handle<mirror::Class> klass) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ bool GetInnerClass(Handle<mirror::Class> klass, mirror::String** name) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
+ bool GetInnerClassFlags(Handle<mirror::Class> klass, uint32_t* flags) const
+ SHARED_REQUIRES(Locks::mutator_lock_);
bool IsClassAnnotationPresent(Handle<mirror::Class> klass, Handle<mirror::Class> annotation_class)
const SHARED_REQUIRES(Locks::mutator_lock_);
@@ -983,11 +995,11 @@
Handle<mirror::Class> array_class,
uint32_t expected_type) const
SHARED_REQUIRES(Locks::mutator_lock_);
- mirror::ObjectArray<mirror::Object>* GetSignatureValue(Handle<mirror::Class> klass,
+ mirror::ObjectArray<mirror::String>* 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
+ mirror::ObjectArray<mirror::Class>* 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,
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index 7e464e9..8fd6849 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -430,7 +430,7 @@
ScopedFastNativeObjectAccess soa(env);
StackHandleScope<2> hs(soa.Self());
Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
- if (klass->IsProxyClass()) {
+ if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
return nullptr;
}
Handle<mirror::Class> annotation_class(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType)));
@@ -442,7 +442,7 @@
ScopedFastNativeObjectAccess soa(env);
StackHandleScope<1> hs(soa.Self());
Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
- if (klass->IsProxyClass()) {
+ if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
// Return an empty array instead of a null pointer.
mirror::Class* annotation_array_class =
soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_annotation_Annotation__array);
@@ -453,18 +453,141 @@
return soa.AddLocalReference<jobjectArray>(klass->GetDexFile().GetAnnotationsForClass(klass));
}
+static jobjectArray Class_getDeclaredClasses(JNIEnv* env, jobject javaThis) {
+ ScopedFastNativeObjectAccess soa(env);
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
+ mirror::ObjectArray<mirror::Class>* classes = nullptr;
+ if (!klass->IsProxyClass() && klass->GetDexCache() != nullptr) {
+ classes = klass->GetDexFile().GetDeclaredClasses(klass);
+ }
+ if (classes == nullptr) {
+ // Return an empty array instead of a null pointer.
+ mirror::Class* class_class = mirror::Class::GetJavaLangClass();
+ mirror::Class* class_array_class =
+ Runtime::Current()->GetClassLinker()->FindArrayClass(soa.Self(), &class_class);
+ if (class_array_class == nullptr) {
+ return nullptr;
+ }
+ mirror::ObjectArray<mirror::Class>* empty_array =
+ mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class, 0);
+ return soa.AddLocalReference<jobjectArray>(empty_array);
+ }
+ return soa.AddLocalReference<jobjectArray>(classes);
+}
+
+static jclass Class_getEnclosingClass(JNIEnv* env, jobject javaThis) {
+ ScopedFastNativeObjectAccess soa(env);
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
+ if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
+ return nullptr;
+ }
+ return soa.AddLocalReference<jclass>(klass->GetDexFile().GetEnclosingClass(klass));
+}
+
+static jobject Class_getEnclosingConstructorNative(JNIEnv* env, jobject javaThis) {
+ ScopedFastNativeObjectAccess soa(env);
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
+ if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
+ return nullptr;
+ }
+ mirror::Object* method = klass->GetDexFile().GetEnclosingMethod(klass);
+ if (method != nullptr) {
+ if (method->GetClass() ==
+ soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_reflect_Constructor)) {
+ return soa.AddLocalReference<jobject>(method);
+ }
+ }
+ return nullptr;
+}
+
+static jobject Class_getEnclosingMethodNative(JNIEnv* env, jobject javaThis) {
+ ScopedFastNativeObjectAccess soa(env);
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
+ if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
+ return nullptr;
+ }
+ mirror::Object* method = klass->GetDexFile().GetEnclosingMethod(klass);
+ if (method != nullptr) {
+ if (method->GetClass() ==
+ soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_reflect_Method)) {
+ return soa.AddLocalReference<jobject>(method);
+ }
+ }
+ return nullptr;
+}
+
+static jint Class_getInnerClassFlags(JNIEnv* env, jobject javaThis, jint defaultValue) {
+ ScopedFastNativeObjectAccess soa(env);
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
+ if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
+ return defaultValue;
+ }
+ uint32_t flags;
+ if (!klass->GetDexFile().GetInnerClassFlags(klass, &flags)) {
+ return defaultValue;
+ }
+ return flags;
+}
+
+static jstring Class_getInnerClassName(JNIEnv* env, jobject javaThis) {
+ ScopedFastNativeObjectAccess soa(env);
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
+ if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
+ return nullptr;
+ }
+ mirror::String* class_name = nullptr;
+ if (!klass->GetDexFile().GetInnerClass(klass, &class_name)) {
+ return nullptr;
+ }
+ return soa.AddLocalReference<jstring>(class_name);
+}
+
+static jboolean Class_isAnonymousClass(JNIEnv* env, jobject javaThis) {
+ ScopedFastNativeObjectAccess soa(env);
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
+ if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
+ return false;
+ }
+ mirror::String* class_name = nullptr;
+ if (!klass->GetDexFile().GetInnerClass(klass, &class_name)) {
+ return false;
+ }
+ return class_name == nullptr;
+}
+
static jboolean Class_isDeclaredAnnotationPresent(JNIEnv* env, jobject javaThis,
jclass annotationType) {
ScopedFastNativeObjectAccess soa(env);
StackHandleScope<2> hs(soa.Self());
Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
- if (klass->IsProxyClass()) {
+ if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
return false;
}
Handle<mirror::Class> annotation_class(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType)));
return klass->GetDexFile().IsClassAnnotationPresent(klass, annotation_class);
}
+static jclass Class_getDeclaringClass(JNIEnv* env, jobject javaThis) {
+ ScopedFastNativeObjectAccess soa(env);
+ StackHandleScope<1> hs(soa.Self());
+ Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis)));
+ if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) {
+ return nullptr;
+ }
+ // Return null for anonymous classes.
+ if (Class_isAnonymousClass(env, javaThis)) {
+ return nullptr;
+ }
+ return soa.AddLocalReference<jclass>(klass->GetDexFile().GetDeclaringClass(klass));
+}
+
static jobject Class_newInstance(JNIEnv* env, jobject javaThis) {
ScopedFastNativeObjectAccess soa(env);
StackHandleScope<4> hs(soa.Self());
@@ -550,6 +673,7 @@
NATIVE_METHOD(Class, getDeclaredAnnotation,
"!(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;"),
NATIVE_METHOD(Class, getDeclaredAnnotations, "!()[Ljava/lang/annotation/Annotation;"),
+ NATIVE_METHOD(Class, getDeclaredClasses, "!()[Ljava/lang/Class;"),
NATIVE_METHOD(Class, getDeclaredConstructorInternal,
"!([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;"),
NATIVE_METHOD(Class, getDeclaredConstructorsInternal, "!(Z)[Ljava/lang/reflect/Constructor;"),
@@ -561,9 +685,16 @@
"!(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"),
NATIVE_METHOD(Class, getDeclaredMethodsUnchecked,
"!(Z)[Ljava/lang/reflect/Method;"),
+ NATIVE_METHOD(Class, getDeclaringClass, "!()Ljava/lang/Class;"),
+ NATIVE_METHOD(Class, getEnclosingClass, "!()Ljava/lang/Class;"),
+ NATIVE_METHOD(Class, getEnclosingConstructorNative, "!()Ljava/lang/reflect/Constructor;"),
+ NATIVE_METHOD(Class, getEnclosingMethodNative, "!()Ljava/lang/reflect/Method;"),
+ NATIVE_METHOD(Class, getInnerClassFlags, "!(I)I"),
+ NATIVE_METHOD(Class, getInnerClassName, "!()Ljava/lang/String;"),
NATIVE_METHOD(Class, getNameNative, "!()Ljava/lang/String;"),
NATIVE_METHOD(Class, getProxyInterfaces, "!()[Ljava/lang/Class;"),
NATIVE_METHOD(Class, getPublicDeclaredFields, "!()[Ljava/lang/reflect/Field;"),
+ NATIVE_METHOD(Class, isAnonymousClass, "!()Z"),
NATIVE_METHOD(Class, isDeclaredAnnotationPresent, "!(Ljava/lang/Class;)Z"),
NATIVE_METHOD(Class, newInstance, "!()Ljava/lang/Object;"),
};
diff --git a/runtime/native/java_lang_reflect_Constructor.cc b/runtime/native/java_lang_reflect_Constructor.cc
index b4b77e7..e1e9ceb 100644
--- a/runtime/native/java_lang_reflect_Constructor.cc
+++ b/runtime/native/java_lang_reflect_Constructor.cc
@@ -48,15 +48,18 @@
static jobjectArray Constructor_getExceptionTypes(JNIEnv* env, jobject javaMethod) {
ScopedFastNativeObjectAccess soa(env);
ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod);
- mirror::ObjectArray<mirror::Object>* result_array =
+ mirror::ObjectArray<mirror::Class>* result_array =
method->GetDexFile()->GetExceptionTypesForMethod(method);
if (result_array == nullptr) {
// Return an empty array instead of a null pointer.
mirror::Class* class_class = mirror::Class::GetJavaLangClass();
mirror::Class* class_array_class =
Runtime::Current()->GetClassLinker()->FindArrayClass(soa.Self(), &class_class);
- mirror::ObjectArray<mirror::Object>* empty_array =
- mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), class_array_class, 0);
+ if (class_array_class == nullptr) {
+ return nullptr;
+ }
+ mirror::ObjectArray<mirror::Class>* empty_array =
+ mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class, 0);
return soa.AddLocalReference<jobjectArray>(empty_array);
} else {
return soa.AddLocalReference<jobjectArray>(result_array);
diff --git a/runtime/native/java_lang_reflect_Method.cc b/runtime/native/java_lang_reflect_Method.cc
index 1219f85..caacba6 100644
--- a/runtime/native/java_lang_reflect_Method.cc
+++ b/runtime/native/java_lang_reflect_Method.cc
@@ -82,15 +82,18 @@
mirror::ObjectArray<mirror::Class>* declared_exceptions = klass->GetThrows()->Get(throws_index);
return soa.AddLocalReference<jobjectArray>(declared_exceptions->Clone(soa.Self()));
} else {
- mirror::ObjectArray<mirror::Object>* result_array =
+ mirror::ObjectArray<mirror::Class>* result_array =
method->GetDexFile()->GetExceptionTypesForMethod(method);
if (result_array == nullptr) {
// Return an empty array instead of a null pointer
mirror::Class* class_class = mirror::Class::GetJavaLangClass();
mirror::Class* class_array_class =
Runtime::Current()->GetClassLinker()->FindArrayClass(soa.Self(), &class_class);
- mirror::ObjectArray<mirror::Object>* empty_array =
- mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), class_array_class, 0);
+ if (class_array_class == nullptr) {
+ return nullptr;
+ }
+ mirror::ObjectArray<mirror::Class>* empty_array =
+ mirror::ObjectArray<mirror::Class>::Alloc(soa.Self(), class_array_class, 0);
return soa.AddLocalReference<jobjectArray>(empty_array);
} else {
return soa.AddLocalReference<jobjectArray>(result_array);