diff options
author | 2021-02-05 13:33:28 +0000 | |
---|---|---|
committer | 2021-02-08 10:49:38 +0000 | |
commit | eae6a7121925b95477b92b404d85645e665bc948 (patch) | |
tree | 1a2155272c19c5aa60ad5eebe27e881f87e63088 | |
parent | 1ee12675375f97790f2ad2bbd0196c1847f858fb (diff) |
Avoid an unnecessary ComputeModifiedUtf8Hash().
The DescriptorHashPair already has the hash as the member
`second`, so avoid recalculating it in release mode.
Also split "HashEquals" classes into separate "Hash" and
"Equals" classes to disambiguate their operators in traces.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 175869411
Change-Id: I87cbe613778c7d310ba5c2bf437729244780472c
-rw-r--r-- | runtime/class_table.cc | 18 | ||||
-rw-r--r-- | runtime/class_table.h | 14 | ||||
-rw-r--r-- | runtime/intern_table.cc | 10 | ||||
-rw-r--r-- | runtime/intern_table.h | 15 |
4 files changed, 33 insertions, 24 deletions
diff --git a/runtime/class_table.cc b/runtime/class_table.cc index 65d976828d..fc2640c2cc 100644 --- a/runtime/class_table.cc +++ b/runtime/class_table.cc @@ -164,7 +164,7 @@ bool ClassTable::Remove(const char* descriptor) { return false; } -uint32_t ClassTable::ClassDescriptorHashEquals::operator()(const TableSlot& slot) +uint32_t ClassTable::ClassDescriptorHash::operator()(const TableSlot& slot) const { std::string temp; // No read barrier needed, we're reading a chain of constant references for comparison @@ -172,8 +172,12 @@ uint32_t ClassTable::ClassDescriptorHashEquals::operator()(const TableSlot& slot return ComputeModifiedUtf8Hash(slot.Read<kWithoutReadBarrier>()->GetDescriptor(&temp)); } -bool ClassTable::ClassDescriptorHashEquals::operator()(const TableSlot& a, - const TableSlot& b) const { +uint32_t ClassTable::ClassDescriptorHash::operator()(const DescriptorHashPair& pair) const { + DCHECK_EQ(ComputeModifiedUtf8Hash(pair.first), pair.second); + return pair.second; +} + +bool ClassTable::ClassDescriptorEquals::operator()(const TableSlot& a, const TableSlot& b) const { // No read barrier needed, we're reading a chain of constant references for comparison // with null and retrieval of constant primitive data. See ReadBarrierOption. if (a.Hash() != b.Hash()) { @@ -187,8 +191,8 @@ bool ClassTable::ClassDescriptorHashEquals::operator()(const TableSlot& a, b.Read<kWithoutReadBarrier>()->GetDescriptor(&temp)); } -bool ClassTable::ClassDescriptorHashEquals::operator()(const TableSlot& a, - const DescriptorHashPair& b) const { +bool ClassTable::ClassDescriptorEquals::operator()(const TableSlot& a, + const DescriptorHashPair& b) const { // No read barrier needed, we're reading a chain of constant references for comparison // with null and retrieval of constant primitive data. See ReadBarrierOption. if (!a.MaskedHashEquals(b.second)) { @@ -198,10 +202,6 @@ bool ClassTable::ClassDescriptorHashEquals::operator()(const TableSlot& a, return a.Read<kWithoutReadBarrier>()->DescriptorEquals(b.first); } -uint32_t ClassTable::ClassDescriptorHashEquals::operator()(const DescriptorHashPair& pair) const { - return ComputeModifiedUtf8Hash(pair.first); -} - bool ClassTable::InsertStrongRoot(ObjPtr<mirror::Object> obj) { WriterMutexLock mu(Thread::Current(), lock_); DCHECK(obj != nullptr); diff --git a/runtime/class_table.h b/runtime/class_table.h index 544a26b992..375954ac18 100644 --- a/runtime/class_table.h +++ b/runtime/class_table.h @@ -103,18 +103,22 @@ class ClassTable { using DescriptorHashPair = std::pair<const char*, uint32_t>; - class ClassDescriptorHashEquals { + class ClassDescriptorHash { public: // uint32_t for cross compilation. uint32_t operator()(const TableSlot& slot) const NO_THREAD_SAFETY_ANALYSIS; + // uint32_t for cross compilation. + uint32_t operator()(const DescriptorHashPair& pair) const NO_THREAD_SAFETY_ANALYSIS; + }; + + class ClassDescriptorEquals { + public: // Same class loader and descriptor. bool operator()(const TableSlot& a, const TableSlot& b) const NO_THREAD_SAFETY_ANALYSIS; // Same descriptor. bool operator()(const TableSlot& a, const DescriptorHashPair& b) const NO_THREAD_SAFETY_ANALYSIS; - // uint32_t for cross compilation. - uint32_t operator()(const DescriptorHashPair& pair) const NO_THREAD_SAFETY_ANALYSIS; }; class TableSlotEmptyFn { @@ -132,8 +136,8 @@ class ClassTable { // should be compared for a matching class descriptor and class loader. typedef HashSet<TableSlot, TableSlotEmptyFn, - ClassDescriptorHashEquals, - ClassDescriptorHashEquals, + ClassDescriptorHash, + ClassDescriptorEquals, TrackingAllocator<TableSlot, kAllocatorTagClassTable>> ClassSet; ClassTable(); diff --git a/runtime/intern_table.cc b/runtime/intern_table.cc index abcc2178af..b11de51eb4 100644 --- a/runtime/intern_table.cc +++ b/runtime/intern_table.cc @@ -307,7 +307,7 @@ void InternTable::SweepInternTableWeaks(IsMarkedVisitor* visitor) { weak_interns_.SweepWeaks(visitor); } -std::size_t InternTable::StringHashEquals::operator()(const GcRoot<mirror::String>& root) const { +std::size_t InternTable::StringHash::operator()(const GcRoot<mirror::String>& root) const { if (kIsDebugBuild) { Locks::mutator_lock_->AssertSharedHeld(Thread::Current()); } @@ -316,16 +316,16 @@ std::size_t InternTable::StringHashEquals::operator()(const GcRoot<mirror::Strin static_cast<uint32_t>(root.Read<kWithoutReadBarrier>()->GetHashCode())); } -bool InternTable::StringHashEquals::operator()(const GcRoot<mirror::String>& a, - const GcRoot<mirror::String>& b) const { +bool InternTable::StringEquals::operator()(const GcRoot<mirror::String>& a, + const GcRoot<mirror::String>& b) const { if (kIsDebugBuild) { Locks::mutator_lock_->AssertSharedHeld(Thread::Current()); } return a.Read<kWithoutReadBarrier>()->Equals(b.Read<kWithoutReadBarrier>()); } -bool InternTable::StringHashEquals::operator()(const GcRoot<mirror::String>& a, - const Utf8String& b) const { +bool InternTable::StringEquals::operator()(const GcRoot<mirror::String>& a, + const Utf8String& b) const { if (kIsDebugBuild) { Locks::mutator_lock_->AssertSharedHeld(Thread::Current()); } diff --git a/runtime/intern_table.h b/runtime/intern_table.h index 5ed6aac28f..db6016eba7 100644 --- a/runtime/intern_table.h +++ b/runtime/intern_table.h @@ -72,18 +72,23 @@ class InternTable { const char* utf8_data_; }; - class StringHashEquals { + class StringHash { public: std::size_t operator()(const GcRoot<mirror::String>& root) const NO_THREAD_SAFETY_ANALYSIS; - bool operator()(const GcRoot<mirror::String>& a, const GcRoot<mirror::String>& b) const - NO_THREAD_SAFETY_ANALYSIS; // Utf8String can be used for lookup. std::size_t operator()(const Utf8String& key) const { // A cast to prevent undesired sign extension. return static_cast<uint32_t>(key.GetHash()); } + }; + + class StringEquals { + public: + bool operator()(const GcRoot<mirror::String>& a, const GcRoot<mirror::String>& b) const + NO_THREAD_SAFETY_ANALYSIS; + // Utf8String can be used for lookup. bool operator()(const GcRoot<mirror::String>& a, const Utf8String& b) const NO_THREAD_SAFETY_ANALYSIS; }; @@ -100,8 +105,8 @@ class InternTable { using UnorderedSet = HashSet<GcRoot<mirror::String>, GcRootEmptyFn, - StringHashEquals, - StringHashEquals, + StringHash, + StringEquals, TrackingAllocator<GcRoot<mirror::String>, kAllocatorTagInternTable>>; InternTable(); |