[vm] Avoid holding canonical hashes at rest.
Canonical hashes are only stored during a round of canonicalization to avoid expontential time in cases such as those in tests/language_2/canonicalization_hasing_*. Clearing them avoids the GC spending time to visit them.
Bug: https://github.com/dart-lang/sdk/issues/37523
Change-Id: Icad1fad30dcb7eb95864bea8a26991aeccd7adc6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/125760
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc
index 7b451bd..d6dad68 100644
--- a/runtime/vm/heap/marker.cc
+++ b/runtime/vm/heap/marker.cc
@@ -497,6 +497,8 @@
}
void GCMarker::ProcessWeakTables(PageSpace* page_space) {
+ TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "ProcessWeakTables");
+
for (int sel = 0; sel < Heap::kNumWeakSelectors; sel++) {
WeakTable* table =
heap_->GetWeakTable(Heap::kOld, static_cast<Heap::WeakSelector>(sel));
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index 01a8a96..20ffb82 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -831,6 +831,8 @@
}
void Scavenger::ProcessWeakReferences() {
+ TIMELINE_FUNCTION_GC_DURATION(Thread::Current(), "ProcessWeakReferences");
+
auto rehash_weak_table = [](WeakTable* table, WeakTable* replacement_new,
WeakTable* replacement_old) {
intptr_t size = table->size();
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index a63c300..ad59f52 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -540,6 +540,7 @@
StackZone stack_zone(thread);
Zone* zone = stack_zone.GetZone();
+ // Clear any old hashes, which may have become invalid.
thread->heap()->ResetCanonicalHashTable();
Class& cls = Class::Handle(zone);
@@ -557,6 +558,12 @@
cls = class_table()->At(cid);
cls.RehashConstants(zone);
}
+
+ // Canonical hashes are only stored during a round of canonicalization to
+ // avoid expontential time in cases such as those in
+ // tests/language_2/canonicalization_hasing_*. Clear them after
+ // canonicalization is done so the GC won't need to update them.
+ thread->heap()->ResetCanonicalHashTable();
}
#if defined(DEBUG)
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index b03021b..27dd9ac 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -3766,6 +3766,11 @@
UNREACHABLE();
}
}
+ // Canonical hashes are only stored during a round of canonicalization to
+ // avoid expontential time in cases such as those in
+ // tests/language_2/canonicalization_hasing_*. Clear them after
+ // canonicalization is done so the GC won't need to update them.
+ thread->heap()->ResetCanonicalHashTable();
return error.raw();
}