diff options
| -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 155e032aba..d2d2f234ab 100644 --- a/runtime/gc/collector/concurrent_copying.cc +++ b/runtime/gc/collector/concurrent_copying.cc @@ -214,7 +214,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) { @@ -241,10 +241,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_; |