diff options
| author | 2016-07-20 20:25:27 -0700 | |
|---|---|---|
| committer | 2016-07-21 12:28:50 -0700 | |
| commit | 7e9b257f10ddcb61a169d34b9aabc4b9bc066ed8 (patch) | |
| tree | a67563d72ccaec4319cd946e8fe48881314d036b | |
| parent | e4b1c86d13c3f60362708f4a128b62db156f5fde (diff) | |
Use non-CAS thread flip root visitor.
We don't need to use CAS to update the thread-local GC roots for the
thread flip.
Bug: 12687968
Bug: 29517059
Test: libartd.so boot. ART tests. Ritzperf EAAC.
Change-Id: Ia2acab824f756bd7d2ad501b2040233e0d394356
| -rw-r--r-- | runtime/gc/collector/concurrent_copying.cc | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc index b7b5aa0059..78eed9ec25 100644 --- a/runtime/gc/collector/concurrent_copying.cc +++ b/runtime/gc/collector/concurrent_copying.cc @@ -194,7 +194,7 @@ void ConcurrentCopying::InitializePhase() { } // Used to switch the thread roots of a thread from from-space refs to to-space refs. -class ConcurrentCopying::ThreadFlipVisitor : public Closure { +class ConcurrentCopying::ThreadFlipVisitor : public Closure, public RootVisitor { public: ThreadFlipVisitor(ConcurrentCopying* concurrent_copying, bool use_tlab) : concurrent_copying_(concurrent_copying), use_tlab_(use_tlab) { @@ -221,10 +221,44 @@ class ConcurrentCopying::ThreadFlipVisitor : public Closure { thread->RevokeThreadLocalAllocationStack(); } ReaderMutexLock mu(self, *Locks::heap_bitmap_lock_); - thread->VisitRoots(concurrent_copying_); + // We can use the non-CAS VisitRoots functions below because we update thread-local GC roots + // only. + thread->VisitRoots(this); concurrent_copying_->GetBarrier().Pass(self); } + void VisitRoots(mirror::Object*** roots, + size_t count, + const RootInfo& info ATTRIBUTE_UNUSED) + SHARED_REQUIRES(Locks::mutator_lock_) { + for (size_t i = 0; i < count; ++i) { + mirror::Object** root = roots[i]; + mirror::Object* ref = *root; + if (ref != nullptr) { + mirror::Object* to_ref = concurrent_copying_->Mark(ref); + if (to_ref != ref) { + *root = to_ref; + } + } + } + } + + void VisitRoots(mirror::CompressedReference<mirror::Object>** roots, + size_t count, + const RootInfo& info ATTRIBUTE_UNUSED) + SHARED_REQUIRES(Locks::mutator_lock_) { + for (size_t i = 0; i < count; ++i) { + mirror::CompressedReference<mirror::Object>* const root = roots[i]; + if (!root->IsNull()) { + mirror::Object* ref = root->AsMirrorPtr(); + mirror::Object* to_ref = concurrent_copying_->Mark(ref); + if (to_ref != ref) { + root->Assign(to_ref); + } + } + } + } + private: ConcurrentCopying* const concurrent_copying_; const bool use_tlab_; |