[vm/aot] Fix ProgramElementKeyValueTrait::Hash.

It was returning library's index which is an unstable
value. This instability could cause `Precompiler::HasApiUse`
to stop returning `true` after `Precompiler::DropLibraries` even
if library was added to the `api_uses_` set. This in turn could cause
`Precompiler::PruneDictionaries` to drop library entries it should
not have dropped.

TEST=added assertion that verifies stability of the set

Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try
Change-Id: I0685bd75562f83e2b9d8b3a03fa410ba218df2ea
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/275241
Reviewed-by: Tess Strickland <sstrickl@google.com>
Auto-Submit: Slava Egorov <vegorov@google.com>
Commit-Queue: Slava Egorov <vegorov@google.com>
This commit is contained in:
Vyacheslav Egorov 2022-12-13 19:46:41 +00:00 committed by Commit Queue
parent c673119d9e
commit 2f117ba43c
2 changed files with 17 additions and 3 deletions

View file

@ -3087,6 +3087,16 @@ void Precompiler::DiscardCodeObjects() {
}
void Precompiler::PruneDictionaries() {
#if defined(DEBUG)
// Verify that api_uses_ is stable: any entry in it can be found. This
// check serves to catch bugs when ProgramElementSet::Hash is accidentally
// defined using unstable values.
ProgramElementSet::Iterator it = api_uses_.GetIterator();
while (auto entry = it.Next()) {
ASSERT(api_uses_.HasKey(*entry));
}
#endif
// PRODUCT-only: pruning interferes with various uses of the service protocol,
// including heap analysis tools.
#if defined(PRODUCT)

View file

@ -199,11 +199,15 @@ class ProgramElementKeyValueTrait {
if (key->IsFunction()) {
return Function::Cast(*key).Hash();
} else if (key->IsField()) {
return Field::Cast(*key).kernel_offset();
return Utils::WordHash(Field::Cast(*key).kernel_offset());
} else if (key->IsClass()) {
return Class::Cast(*key).kernel_offset();
return Utils::WordHash(Class::Cast(*key).kernel_offset());
} else if (key->IsLibrary()) {
return Library::Cast(*key).index();
// This must not use library's index or url hash because both
// of these might change during precompilation: urls are changed
// by |Precompiler::Obfuscate| and library index is changed by
// |Precompiler::DropLibraries|.
return Utils::WordHash(Library::Cast(*key).kernel_offset());
}
FATAL("Unexpected type: %s\n", key->ToCString());
}