OSDN Git Service

Improve VerifyNoFromSpaceRefsObjectVisitor logging
authorMathieu Chartier <mathieuc@google.com>
Thu, 20 Apr 2017 20:31:39 +0000 (13:31 -0700)
committerMathieu Chartier <mathieuc@google.com>
Thu, 20 Apr 2017 20:44:38 +0000 (13:44 -0700)
Remove read barriers in PrettyTypeOf to prevent recursive failures.

Pass down holder and offset information to
VerifyNoFromSpaceRefsFieldVisitor.

Test: test-art-host
Bug: 37531237
Change-Id: I704ec18ebecfc1ca2982b38f67a2f0788e59dfe9

runtime/gc/collector/concurrent_copying.cc
runtime/mirror/class-inl.h
runtime/mirror/object.cc

index bcf5008..792c191 100644 (file)
@@ -1031,13 +1031,15 @@ class ConcurrentCopying::VerifyNoFromSpaceRefsVisitor : public SingleRootVisitor
   explicit VerifyNoFromSpaceRefsVisitor(ConcurrentCopying* collector)
       : collector_(collector) {}
 
-  void operator()(mirror::Object* ref) const
+  void operator()(mirror::Object* ref,
+                  MemberOffset offset = MemberOffset(0),
+                  mirror::Object* holder = nullptr) const
       REQUIRES_SHARED(Locks::mutator_lock_) ALWAYS_INLINE {
     if (ref == nullptr) {
       // OK.
       return;
     }
-    collector_->AssertToSpaceInvariant(nullptr, MemberOffset(0), ref);
+    collector_->AssertToSpaceInvariant(holder, offset, ref);
     if (kUseBakerReadBarrier) {
       CHECK_EQ(ref->GetReadBarrierState(), ReadBarrier::WhiteState())
           << "Ref " << ref << " " << ref->PrettyTypeOf()
@@ -1067,7 +1069,7 @@ class ConcurrentCopying::VerifyNoFromSpaceRefsFieldVisitor {
     mirror::Object* ref =
         obj->GetFieldObject<mirror::Object, kDefaultVerifyFlags, kWithoutReadBarrier>(offset);
     VerifyNoFromSpaceRefsVisitor visitor(collector_);
-    visitor(ref);
+    visitor(ref, offset, obj.Ptr());
   }
   void operator()(ObjPtr<mirror::Class> klass,
                   ObjPtr<mirror::Reference> ref) const
index be3b937..9124a3a 100644 (file)
@@ -823,7 +823,10 @@ inline bool Class::IsClassClass() {
 }
 
 inline const DexFile& Class::GetDexFile() {
-  return *GetDexCache()->GetDexFile();
+  // From-space version is the same as the to-space version since the dex file never changes.
+  // Avoiding the read barrier here is important to prevent recursive AssertToSpaceInvariant issues
+  // from PrettyTypeOf.
+  return *GetDexCache<kDefaultVerifyFlags, kWithoutReadBarrier>()->GetDexFile();
 }
 
 inline bool Class::DescriptorEquals(const char* match) {
index f5b9ab3..eabc29a 100644 (file)
@@ -281,12 +281,16 @@ std::string Object::PrettyTypeOf(ObjPtr<mirror::Object> obj) {
 }
 
 std::string Object::PrettyTypeOf() {
-  if (GetClass() == nullptr) {
+  // From-space version is the same as the to-space version since the dex file never changes.
+  // Avoiding the read barrier here is important to prevent recursive AssertToSpaceInvariant
+  // issues.
+  ObjPtr<mirror::Class> klass = GetClass<kDefaultVerifyFlags, kWithoutReadBarrier>();
+  if (klass == nullptr) {
     return "(raw)";
   }
   std::string temp;
-  std::string result(PrettyDescriptor(GetClass()->GetDescriptor(&temp)));
-  if (IsClass()) {
+  std::string result(PrettyDescriptor(klass->GetDescriptor(&temp)));
+  if (klass->IsClassClass()) {
     result += "<" + PrettyDescriptor(AsClass()->GetDescriptor(&temp)) + ">";
   }
   return result;