summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/gc/collector/concurrent_copying.cc38
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_;