diff options
Diffstat (limited to 'runtime/class_linker.cc')
-rw-r--r-- | runtime/class_linker.cc | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index d4666e5f9c..9d175cdba5 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -2426,9 +2426,17 @@ void ClassLinker::VisitClassRoots(RootVisitor* visitor, VisitRootFlags flags) { boot_class_table_->VisitRoots(root_visitor); // If tracing is enabled, then mark all the class loaders to prevent unloading. if ((flags & kVisitRootFlagClassLoader) != 0 || tracing_enabled) { - for (const ClassLoaderData& data : class_loaders_) { - GcRoot<mirror::Object> root(GcRoot<mirror::Object>(self->DecodeJObject(data.weak_root))); - root.VisitRoot(visitor, RootInfo(kRootVMInternal)); + gc::Heap* const heap = Runtime::Current()->GetHeap(); + // Don't visit class-loaders if compacting with userfaultfd GC as these + // weaks are updated using Runtime::SweepSystemWeaks() and the GC doesn't + // tolerate double updates. + if (!heap->IsPerformingUffdCompaction()) { + for (const ClassLoaderData& data : class_loaders_) { + GcRoot<mirror::Object> root(GcRoot<mirror::Object>(self->DecodeJObject(data.weak_root))); + root.VisitRoot(visitor, RootInfo(kRootVMInternal)); + } + } else { + DCHECK_EQ(heap->CurrentCollectorType(), gc::CollectorType::kCollectorTypeCMC); } } } else if (!gUseReadBarrier && (flags & kVisitRootFlagNewRoots) != 0) { @@ -2468,11 +2476,9 @@ void ClassLinker::VisitClassRoots(RootVisitor* visitor, VisitRootFlags flags) { // Keep in sync with InitCallback. Anything we visit, we need to // reinit references to when reinitializing a ClassLinker from a // mapped image. -void ClassLinker::VisitRoots(RootVisitor* visitor, VisitRootFlags flags, bool visit_class_roots) { +void ClassLinker::VisitRoots(RootVisitor* visitor, VisitRootFlags flags) { class_roots_.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal)); - if (visit_class_roots) { - VisitClassRoots(visitor, flags); - } + VisitClassRoots(visitor, flags); // Instead of visiting the find_array_class_cache_ drop it so that it doesn't prevent class // unloading if we are marking roots. DropFindArrayClassCache(); |