Visit class native roots from VisitReferences
Visit class roots when we call Class::VisitReferences instead of in
the class linker. This makes it easier to implement class unloading
since unmarked classes won't have their roots visited by the class
linker.
Bug: 22181835
Change-Id: I63f31e5ebef7b2a0b764b3ba3cb038b3f561b379
diff --git a/runtime/gc/collector/semi_space.cc b/runtime/gc/collector/semi_space.cc
index e93ff05..acc1d9b 100644
--- a/runtime/gc/collector/semi_space.cc
+++ b/runtime/gc/collector/semi_space.cc
@@ -295,8 +295,26 @@
LOG(FATAL) << ref << " found in from space";
}
}
+
+ // TODO: Remove NO_THREAD_SAFETY_ANALYSIS when clang better understands visitors.
+ void VisitRootIfNonNull(mirror::CompressedReference<mirror::Object>* root) const
+ NO_THREAD_SAFETY_ANALYSIS {
+ if (!root->IsNull()) {
+ VisitRoot(root);
+ }
+ }
+
+ void VisitRoot(mirror::CompressedReference<mirror::Object>* root) const
+ NO_THREAD_SAFETY_ANALYSIS {
+ if (kIsDebugBuild) {
+ Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
+ Locks::heap_bitmap_lock_->AssertExclusiveHeld(Thread::Current());
+ }
+ CHECK(!from_space_->HasAddress(root->AsMirrorPtr()));
+ }
+
private:
- space::ContinuousMemMapAllocSpace* from_space_;
+ space::ContinuousMemMapAllocSpace* const from_space_;
};
void SemiSpace::VerifyNoFromSpaceReferences(Object* obj) {
@@ -313,6 +331,7 @@
DCHECK(obj != nullptr);
semi_space_->VerifyNoFromSpaceReferences(obj);
}
+
private:
SemiSpace* const semi_space_;
};
@@ -670,11 +689,27 @@
}
void operator()(mirror::Class* klass, mirror::Reference* ref) const
- SHARED_REQUIRES(Locks::mutator_lock_)
- REQUIRES(Locks::heap_bitmap_lock_) {
+ REQUIRES(Locks::mutator_lock_, Locks::heap_bitmap_lock_) {
collector_->DelayReferenceReferent(klass, ref);
}
+ // TODO: Remove NO_THREAD_SAFETY_ANALYSIS when clang better understands visitors.
+ void VisitRootIfNonNull(mirror::CompressedReference<mirror::Object>* root) const
+ NO_THREAD_SAFETY_ANALYSIS {
+ if (!root->IsNull()) {
+ VisitRoot(root);
+ }
+ }
+
+ void VisitRoot(mirror::CompressedReference<mirror::Object>* root) const
+ NO_THREAD_SAFETY_ANALYSIS {
+ if (kIsDebugBuild) {
+ Locks::mutator_lock_->AssertExclusiveHeld(Thread::Current());
+ Locks::heap_bitmap_lock_->AssertExclusiveHeld(Thread::Current());
+ }
+ collector_->MarkObject(root);
+ }
+
private:
SemiSpace* const collector_;
};