Use ClassStatus::kVisiblyInitialized in interpreter.
Test: m test-art-host-gtest
Test: testrunner.py --host --interpreter --interp-ac
Test: aosp_taimen-userdebug boots.
Test: run-gtests.sh
Test: testrunner.py --target --interpreter --interp-ac
Bug: 36692143
Change-Id: Ic081c3fab8fb98ba2667bc851fb2b7dd746e7020
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index 01fb4dd..2556079 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -377,7 +377,7 @@
return resolved_field;
} else {
// If the class is initialized we're done.
- if (LIKELY(fields_class->IsInitialized())) {
+ if (LIKELY(fields_class->IsVisiblyInitialized())) {
return resolved_field;
} else {
StackHandleScope<1> hs(self);
@@ -619,7 +619,7 @@
if (is_static) {
// Check class is initialized else fail so that we can contend to initialize the class with
// other threads that may be racing to do this.
- if (UNLIKELY(!fields_class->IsInitialized())) {
+ if (UNLIKELY(!fields_class->IsVisiblyInitialized())) {
return nullptr;
}
}
diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc
index 5f176db..0e5fdd4 100644
--- a/runtime/interpreter/interpreter.cc
+++ b/runtime/interpreter/interpreter.cc
@@ -496,14 +496,18 @@
}
self->EndAssertNoThreadSuspension(old_cause);
// Do this after populating the shadow frame in case EnsureInitialized causes a GC.
- if (method->IsStatic() && UNLIKELY(!method->GetDeclaringClass()->IsInitialized())) {
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- StackHandleScope<1> hs(self);
- Handle<mirror::Class> h_class(hs.NewHandle(method->GetDeclaringClass()));
- if (UNLIKELY(!class_linker->EnsureInitialized(self, h_class, true, true))) {
- CHECK(self->IsExceptionPending());
- self->PopShadowFrame();
- return;
+ if (method->IsStatic()) {
+ ObjPtr<mirror::Class> declaring_class = method->GetDeclaringClass();
+ if (UNLIKELY(!declaring_class->IsVisiblyInitialized())) {
+ StackHandleScope<1> hs(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))) {
+ CHECK(self->IsExceptionPending());
+ self->PopShadowFrame();
+ return;
+ }
+ DCHECK(h_class->IsInitializing());
}
}
if (LIKELY(!method->IsNative())) {
@@ -676,16 +680,16 @@
const bool is_static = method->IsStatic();
if (is_static) {
ObjPtr<mirror::Class> declaring_class = method->GetDeclaringClass();
- if (UNLIKELY(!declaring_class->IsInitialized())) {
+ if (UNLIKELY(!declaring_class->IsVisiblyInitialized())) {
StackHandleScope<1> hs(self);
- HandleWrapperObjPtr<mirror::Class> h_declaring_class(hs.NewHandleWrapper(&declaring_class));
+ Handle<mirror::Class> h_class(hs.NewHandle(declaring_class));
if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(
- self, h_declaring_class, true, true))) {
+ self, h_class, /*can_init_fields=*/ true, /*can_init_parents=*/ true))) {
DCHECK(self->IsExceptionPending());
self->PopShadowFrame();
return;
}
- CHECK(h_declaring_class->IsInitializing());
+ DCHECK(h_class->IsInitializing());
}
}
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index e017b17..4e80a61 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -82,7 +82,7 @@
if (method->GetDeclaringClass()->IsStringClass() && method->IsConstructor()) {
return false;
}
- if (method->IsStatic() && !method->GetDeclaringClass()->IsInitialized()) {
+ if (method->IsStatic() && !method->GetDeclaringClass()->IsVisiblyInitialized()) {
return false;
}
ProfilingInfo* profiling_info = method->GetProfilingInfo(kRuntimePointerSize);
@@ -650,18 +650,18 @@
// Ensure static methods are initialized.
if (method->IsStatic()) {
ObjPtr<mirror::Class> declaringClass = method->GetDeclaringClass();
- if (UNLIKELY(!declaringClass->IsInitialized())) {
+ if (UNLIKELY(!declaringClass->IsVisiblyInitialized())) {
self->PushShadowFrame(shadow_frame);
StackHandleScope<1> hs(self);
Handle<mirror::Class> h_class(hs.NewHandle(declaringClass));
- if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_class, true,
- true))) {
+ if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(
+ self, h_class, /*can_init_fields=*/ true, /*can_init_parents=*/ true))) {
self->PopShadowFrame();
DCHECK(self->IsExceptionPending());
return;
}
self->PopShadowFrame();
- CHECK(h_class->IsInitializing());
+ DCHECK(h_class->IsInitializing());
// Reload from shadow frame in case the method moved, this is faster than adding a handle.
method = shadow_frame->GetMethod();
}
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index 0846b17..421befb 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -332,7 +332,7 @@
DCHECK(!called_method->IsIntrinsic());
DCHECK(!(called_method->GetDeclaringClass()->IsStringClass() &&
called_method->IsConstructor()));
- DCHECK(type != kStatic || called_method->GetDeclaringClass()->IsInitialized());
+ DCHECK(type != kStatic || called_method->GetDeclaringClass()->IsVisiblyInitialized());
const uint16_t number_of_inputs =
(is_range) ? inst->VRegA_3rc(inst_data) : inst->VRegA_35c(inst_data);
@@ -498,14 +498,15 @@
dex::StringIndex string_idx)
REQUIRES_SHARED(Locks::mutator_lock_) {
ObjPtr<mirror::Class> java_lang_string_class = GetClassRoot<mirror::String>();
- if (UNLIKELY(!java_lang_string_class->IsInitialized())) {
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ if (UNLIKELY(!java_lang_string_class->IsVisiblyInitialized())) {
StackHandleScope<1> hs(self);
Handle<mirror::Class> h_class(hs.NewHandle(java_lang_string_class));
- if (UNLIKELY(!class_linker->EnsureInitialized(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());
}
ArtMethod* method = shadow_frame.GetMethod();
ObjPtr<mirror::String> string_ptr =
diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc
index 80ebf21..f38b69f 100644
--- a/runtime/interpreter/mterp/mterp.cc
+++ b/runtime/interpreter/mterp/mterp.cc
@@ -793,8 +793,8 @@
uint32_t field_idx = kIsStatic ? inst->VRegB_21c() : inst->VRegC_22c();
ArtField* field = dex_cache->GetResolvedField(field_idx, kRuntimePointerSize);
if (LIKELY(field != nullptr)) {
- bool initialized = !kIsStatic || field->GetDeclaringClass()->IsInitialized();
- if (LIKELY(initialized)) {
+ bool visibly_initialized = !kIsStatic || field->GetDeclaringClass()->IsVisiblyInitialized();
+ if (LIKELY(visibly_initialized)) {
DCHECK_EQ(field, (FindFieldFromCode<kAccessType, /* access_checks= */ false>(
field_idx, referrer, self, sizeof(PrimType))));
ObjPtr<mirror::Object> obj = kIsStatic