Use ClassStatus::kVisiblyInitialized in reflection.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: aosp_taimen-userdebug boots.
Test: run-gtests.sh
Test: testrunner.py --target --optimizing
Bug: 36692143
Change-Id: I53342f5bb6285c9ca95445791dd10e04c6d8f962
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index 4516d1b..49e37fe 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -932,9 +932,9 @@
caller.Assign(GetCallingClass(soa.Self(), 1));
}
if (UNLIKELY(caller != nullptr && !VerifyAccess(receiver.Get(),
- declaring_class,
- constructor->GetAccessFlags(),
- caller.Get()))) {
+ declaring_class,
+ constructor->GetAccessFlags(),
+ caller.Get()))) {
soa.Self()->ThrowNewExceptionF(
"Ljava/lang/IllegalAccessException;", "%s is not accessible from %s",
constructor->PrettyMethod().c_str(), caller->PrettyClass().c_str());
@@ -942,12 +942,15 @@
}
}
// Ensure that we are initialized.
- if (UNLIKELY(!declaring_class->IsInitialized())) {
- if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(
- soa.Self(), hs.NewHandle(declaring_class), true, true)) {
- soa.Self()->AssertPendingException();
+ if (UNLIKELY(!declaring_class->IsVisiblyInitialized())) {
+ Thread* self = soa.Self();
+ Handle<mirror::Class> h_class = hs.NewHandle(declaring_class);
+ if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(
+ self, h_class, /*can_init_fields=*/ true, /*can_init_parents=*/ true))) {
+ DCHECK(self->IsExceptionPending());
return nullptr;
}
+ DCHECK(h_class->IsInitializing());
}
// Invoke the constructor.
JValue result;
diff --git a/runtime/native/java_lang_reflect_Field.cc b/runtime/native/java_lang_reflect_Field.cc
index 31734a4..42b6c22 100644
--- a/runtime/native/java_lang_reflect_Field.cc
+++ b/runtime/native/java_lang_reflect_Field.cc
@@ -129,15 +129,17 @@
soa.Self()->AssertThreadSuspensionIsAllowable();
ObjPtr<mirror::Class> declaring_class = (*f)->GetDeclaringClass();
if ((*f)->IsStatic()) {
- if (UNLIKELY(!declaring_class->IsInitialized())) {
- StackHandleScope<2> hs(soa.Self());
+ if (UNLIKELY(!declaring_class->IsVisiblyInitialized())) {
+ Thread* self = soa.Self();
+ StackHandleScope<2> hs(self);
HandleWrapperObjPtr<mirror::Field> h_f(hs.NewHandleWrapper(f));
HandleWrapperObjPtr<mirror::Class> h_klass(hs.NewHandleWrapper(&declaring_class));
- ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
- if (UNLIKELY(!class_linker->EnsureInitialized(soa.Self(), h_klass, true, true))) {
- DCHECK(soa.Self()->IsExceptionPending());
+ if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(
+ self, h_klass, /*can_init_fields=*/ true, /*can_init_parents=*/ true))) {
+ DCHECK(self->IsExceptionPending());
return false;
}
+ DCHECK(h_klass->IsInitializing());
}
*class_or_rcvr = declaring_class;
return true;
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index 4700e33..469d329 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -699,12 +699,16 @@
ArtMethod* m = executable->GetArtMethod();
ObjPtr<mirror::Class> declaring_class = m->GetDeclaringClass();
- if (UNLIKELY(!declaring_class->IsInitialized())) {
- StackHandleScope<1> hs(soa.Self());
+ if (UNLIKELY(!declaring_class->IsVisiblyInitialized())) {
+ Thread* self = soa.Self();
+ StackHandleScope<1> hs(self);
HandleWrapperObjPtr<mirror::Class> h_class(hs.NewHandleWrapper(&declaring_class));
- if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(soa.Self(), h_class, true, true)) {
+ if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(
+ self, h_class, /*can_init_fields=*/ true, /*can_init_parents=*/ true))) {
+ DCHECK(self->IsExceptionPending());
return nullptr;
}
+ DCHECK(h_class->IsInitializing());
}
ObjPtr<mirror::Object> receiver;