Fix race in root marking.
There was a race which caused the class linker / intern table to not
become dirty after adding a root. We now guard the is dirty flag by
the corresponding locks to prevent this from occuring. This was
causing roots to be occasionally missed.
Also fixes the bug where we occasionally scan more cards than
needed.
Bug: 10626133
Change-Id: I0f6e72d92035ff463954d66988ef610ea0df61be
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index c5fb72c..20efbb4 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -231,7 +231,7 @@
LOCKS_EXCLUDED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void VisitRoots(RootVisitor* visitor, void* arg, bool clean_dirty)
+ void VisitRoots(RootVisitor* visitor, void* arg, bool only_dirty, bool clean_dirty)
LOCKS_EXCLUDED(Locks::classlinker_classes_lock_, dex_lock_);
mirror::DexCache* FindDexCache(const DexFile& dex_file) const
@@ -335,14 +335,6 @@
pid_t GetClassesLockOwner(); // For SignalCatcher.
pid_t GetDexLockOwner(); // For SignalCatcher.
- bool IsDirty() const {
- return is_dirty_;
- }
-
- void Dirty() {
- is_dirty_ = true;
- }
-
const void* GetPortableResolutionTrampoline() const {
return portable_resolution_trampoline_;
}
@@ -617,7 +609,8 @@
mirror::IfTable* array_iftable_;
bool init_done_;
- bool is_dirty_;
+ bool dex_caches_dirty_ GUARDED_BY(dex_lock_);
+ bool class_table_dirty_ GUARDED_BY(Locks::classlinker_classes_lock_);
InternTable* intern_table_;