diff options
| author | 2022-10-05 10:43:49 -0700 | |
|---|---|---|
| committer | 2022-10-05 23:20:25 +0000 | |
| commit | f3c44b410967761680e7285641ba6e15ab45c660 (patch) | |
| tree | a2f96114f6af01f3cfda6ce9f8ae1215f63c077d | |
| parent | 0b325abb397452b69cf259d193c840b1242d8371 (diff) | |
Avoid updating class loaders outside system weaks
We update all system weaks using Runtime::SweepSystemWeaks(). But when
we are tracing, we attempt to update them again via
ClassLinker::VisitRoots, which results in double updation of GC-root.
This is not tolerated by userfaultfd-GC as we do in-place sliding
compaction.
Bug: 250480435
Test: art/test/testrunner/testrunner.py --host --gcstres -t
2240-tracing-non-invokable-method
Change-Id: I970f2d47270837f7b02f34d34ae434ba8a4edd2b
| -rw-r--r-- | runtime/class_linker.cc | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index f487e561a4..67a20a854e 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -2146,9 +2146,18 @@ 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 (!gUseUserfaultfd + || !heap->MarkCompactCollector()->IsCompacting(self)) { + 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) { |