From c4621985bdfc2b27494087e5dee65a6d0cc5a632 Mon Sep 17 00:00:00 2001 From: Mathieu Chartier Date: Mon, 16 Sep 2013 19:43:47 -0700 Subject: 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 --- runtime/intern_table.cc | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'runtime/intern_table.cc') diff --git a/runtime/intern_table.cc b/runtime/intern_table.cc index e3a75cf..89c15f8 100644 --- a/runtime/intern_table.cc +++ b/runtime/intern_table.cc @@ -42,13 +42,15 @@ void InternTable::DumpForSigQuit(std::ostream& os) const { } void InternTable::VisitRoots(RootVisitor* visitor, void* arg, - bool clean_dirty) { + bool only_dirty, bool clean_dirty) { MutexLock mu(Thread::Current(), intern_table_lock_); - for (const auto& strong_intern : strong_interns_) { - visitor(strong_intern.second, arg); - } - if (clean_dirty) { - is_dirty_ = false; + if (!only_dirty || is_dirty_) { + for (const auto& strong_intern : strong_interns_) { + visitor(strong_intern.second, arg); + } + if (clean_dirty) { + is_dirty_ = false; + } } // Note: we deliberately don't visit the weak_interns_ table and the immutable // image roots. @@ -123,7 +125,7 @@ mirror::String* InternTable::Insert(mirror::String* s, bool is_strong) { } // Mark as dirty so that we rescan the roots. - Dirty(); + is_dirty_ = true; // Check the image for a match. mirror::String* image = LookupStringFromImage(s); -- cgit v1.1