From 94f7b49578b6aaa80de8ffed230648d601393905 Mon Sep 17 00:00:00 2001 From: Hiroshi Yamauchi Date: Tue, 22 Jul 2014 18:08:23 -0700 Subject: Add GcRoot to clean up and enforce read barriers. Introduce a value-type wrapper around Object* for GC roots so that 1) we won't have to directly add the read barrier code in many places and 2) we can avoid accidentally bypassing/missing read barriers on GC roots (the GcRoot interface ensures that the read barrier is executed on a read). The jdwp test passed. Bug: 12687968 Change-Id: Ib167c7c325b3c7e3900133578815f04d219972a1 --- runtime/reference_table.cc | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'runtime/reference_table.cc') diff --git a/runtime/reference_table.cc b/runtime/reference_table.cc index cd35863543..70aba9bbf1 100644 --- a/runtime/reference_table.cc +++ b/runtime/reference_table.cc @@ -24,7 +24,6 @@ #include "mirror/class-inl.h" #include "mirror/object-inl.h" #include "mirror/string-inl.h" -#include "read_barrier.h" #include "thread.h" #include "utils.h" @@ -46,14 +45,13 @@ void ReferenceTable::Add(mirror::Object* obj) { LOG(FATAL) << "ReferenceTable '" << name_ << "' " << "overflowed (" << max_size_ << " entries)"; } - entries_.push_back(obj); + entries_.push_back(GcRoot(obj)); } void ReferenceTable::Remove(mirror::Object* obj) { // We iterate backwards on the assumption that references are LIFO. for (int i = entries_.size() - 1; i >= 0; --i) { - mirror::Object* entry = - ReadBarrier::BarrierForRoot(&entries_[i]); + mirror::Object* entry = entries_[i].Read(); if (entry == obj) { entries_.erase(entries_.begin() + i); return; @@ -71,10 +69,12 @@ static size_t GetElementCount(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks:: } struct ObjectComparator { - bool operator()(mirror::Object* obj1, mirror::Object* obj2) + bool operator()(GcRoot root1, GcRoot root2) // TODO: enable analysis when analysis can work with the STL. NO_THREAD_SAFETY_ANALYSIS { Locks::mutator_lock_->AssertSharedHeld(Thread::Current()); + mirror::Object* obj1 = root1.Read(); + mirror::Object* obj2 = root2.Read(); // Ensure null references and cleared jweaks appear at the end. if (obj1 == NULL) { return true; @@ -163,8 +163,7 @@ void ReferenceTable::Dump(std::ostream& os, Table& entries) { } os << " Last " << (count - first) << " entries (of " << count << "):\n"; for (int idx = count - 1; idx >= first; --idx) { - mirror::Object* ref = - ReadBarrier::BarrierForRoot(&entries[idx]); + mirror::Object* ref = entries[idx].Read(); if (ref == NULL) { continue; } @@ -200,17 +199,17 @@ void ReferenceTable::Dump(std::ostream& os, Table& entries) { // Make a copy of the table and sort it. Table sorted_entries; for (size_t i = 0; i < entries.size(); ++i) { - mirror::Object* entry = - ReadBarrier::BarrierForRoot(&entries[i]); - sorted_entries.push_back(entry); + mirror::Object* entry = entries[i].Read(); + sorted_entries.push_back(GcRoot(entry)); } std::sort(sorted_entries.begin(), sorted_entries.end(), ObjectComparator()); // Remove any uninteresting stuff from the list. The sort moved them all to the end. - while (!sorted_entries.empty() && sorted_entries.back() == NULL) { + while (!sorted_entries.empty() && sorted_entries.back().IsNull()) { sorted_entries.pop_back(); } - while (!sorted_entries.empty() && sorted_entries.back() == kClearedJniWeakGlobal) { + while (!sorted_entries.empty() && + sorted_entries.back().Read() == kClearedJniWeakGlobal) { sorted_entries.pop_back(); } if (sorted_entries.empty()) { @@ -222,8 +221,8 @@ void ReferenceTable::Dump(std::ostream& os, Table& entries) { size_t equiv = 0; size_t identical = 0; for (size_t idx = 1; idx < count; idx++) { - mirror::Object* prev = sorted_entries[idx-1]; - mirror::Object* current = sorted_entries[idx]; + mirror::Object* prev = sorted_entries[idx-1].Read(); + mirror::Object* current = sorted_entries[idx].Read(); size_t element_count = GetElementCount(prev); if (current == prev) { // Same reference, added more than once. @@ -238,13 +237,15 @@ void ReferenceTable::Dump(std::ostream& os, Table& entries) { } } // Handle the last entry. - DumpSummaryLine(os, sorted_entries.back(), GetElementCount(sorted_entries.back()), identical, equiv); + DumpSummaryLine(os, sorted_entries.back().Read(), + GetElementCount(sorted_entries.back().Read()), + identical, equiv); } void ReferenceTable::VisitRoots(RootCallback* visitor, void* arg, uint32_t tid, RootType root_type) { - for (auto& ref : entries_) { - visitor(&ref, arg, tid, root_type); + for (GcRoot& root : entries_) { + root.VisitRoot(visitor, arg, tid, root_type); } } -- cgit v1.2.3-59-g8ed1b