Store java_lang_Object_ in the flip callback
There was a race where the GC thread would not have is_marking =
true, and call
WellKnownClasses::ToClass(WellKnownClasses::java_lang_Object). This
meant that the returned class was maybe in the from-space for the
no image case. The fix was to move this decoding into the flip
callback since this callback is called before flipping any thread
roots.
Bug: 37531237
Bug: 12687968
Test: test-art-host
Change-Id: I9a09249e9c6ea2b3b124e957a9e4b61017869306
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index 792c191..bd81f47 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -374,6 +374,8 @@
cc->VerifyGrayImmuneObjects();
}
}
+ cc->java_lang_Object_ = down_cast<mirror::Class*>(cc->Mark(
+ WellKnownClasses::ToClass(WellKnownClasses::java_lang_Object).Ptr()));
}
private:
@@ -2067,11 +2069,9 @@
size_t data_offset = mirror::Array::DataOffset(component_size).SizeValue();
if (data_offset > byte_size) {
// An int array is too big. Use java.lang.Object.
- ObjPtr<mirror::Class> java_lang_Object =
- WellKnownClasses::ToClass(WellKnownClasses::java_lang_Object);
- AssertToSpaceInvariant(nullptr, MemberOffset(0), java_lang_Object.Ptr());
- CHECK_EQ(byte_size, (java_lang_Object->GetObjectSize<kVerifyNone, kWithoutReadBarrier>()));
- dummy_obj->SetClass(java_lang_Object.Ptr());
+ AssertToSpaceInvariant(nullptr, MemberOffset(0), java_lang_Object_);
+ CHECK_EQ(byte_size, (java_lang_Object_->GetObjectSize<kVerifyNone, kWithoutReadBarrier>()));
+ dummy_obj->SetClass(java_lang_Object_);
CHECK_EQ(byte_size, (dummy_obj->SizeOf<kVerifyNone>()));
} else {
// Use an int array.
diff --git a/runtime/gc/collector/concurrent_copying.h b/runtime/gc/collector/concurrent_copying.h
index a0da9fc..398a7e2 100644
--- a/runtime/gc/collector/concurrent_copying.h
+++ b/runtime/gc/collector/concurrent_copying.h
@@ -316,6 +316,11 @@
Mutex immune_gray_stack_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
std::vector<mirror::Object*> immune_gray_stack_ GUARDED_BY(immune_gray_stack_lock_);
+ // Class of java.lang.Object. Filled in from WellKnownClasses in FlipCallback. Must
+ // be filled in before flipping thread roots so that FillDummyObject can run. Not
+ // ObjPtr since the GC may transition to suspended and runnable between phases.
+ mirror::Class* java_lang_Object_;
+
class AssertToSpaceInvariantFieldVisitor;
class AssertToSpaceInvariantObjectVisitor;
class AssertToSpaceInvariantRefsVisitor;