summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Lokesh Gidra <lokeshgidra@google.com> 2022-10-05 10:43:49 -0700
committer Treehugger Robot <treehugger-gerrit@google.com> 2022-10-05 23:20:25 +0000
commitf3c44b410967761680e7285641ba6e15ab45c660 (patch)
treea2f96114f6af01f3cfda6ce9f8ae1215f63c077d
parent0b325abb397452b69cf259d193c840b1242d8371 (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.cc15
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) {