From 2f117ba43c63d68bd1a13c20a90bb1fd75d7a34e Mon Sep 17 00:00:00 2001 From: Vyacheslav Egorov Date: Tue, 13 Dec 2022 19:46:41 +0000 Subject: [PATCH] [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 Auto-Submit: Slava Egorov Commit-Queue: Slava Egorov --- runtime/vm/compiler/aot/precompiler.cc | 10 ++++++++++ runtime/vm/compiler/aot/precompiler.h | 10 +++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc index 4b946311145..06994edce99 100644 --- a/runtime/vm/compiler/aot/precompiler.cc +++ b/runtime/vm/compiler/aot/precompiler.cc @@ -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) diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h index 243d246f5e4..cf44656abb5 100644 --- a/runtime/vm/compiler/aot/precompiler.h +++ b/runtime/vm/compiler/aot/precompiler.h @@ -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()); }