diff options
| author | 2015-10-27 21:10:08 +0000 | |
|---|---|---|
| committer | 2015-10-27 21:10:08 +0000 | |
| commit | 3dca4c04170bb4c7b26609e55f3f4966d46b681a (patch) | |
| tree | bcdd800831f98a896b2b712932e769f46fbeefab | |
| parent | 9e1b56f0e77aa5b6c72374b86d0cef58484ddcaa (diff) | |
| parent | 0f8e0723d67bd75125705b2707c36927beabd886 (diff) | |
Merge "Use HashMap for DexFileVerifier"
| -rw-r--r-- | runtime/base/allocator.h | 9 | ||||
| -rw-r--r-- | runtime/dex_file_verifier.cc | 10 | ||||
| -rw-r--r-- | runtime/dex_file_verifier.h | 30 |
3 files changed, 46 insertions, 3 deletions
diff --git a/runtime/base/allocator.h b/runtime/base/allocator.h index ad255b8694..969f5b953f 100644 --- a/runtime/base/allocator.h +++ b/runtime/base/allocator.h @@ -22,6 +22,7 @@ #include <unordered_map> #include "atomic.h" +#include "base/hash_map.h" #include "base/macros.h" #include "base/mutex.h" #include "base/type_static_if.h" @@ -170,6 +171,14 @@ template<class Key, using AllocationTrackingUnorderedMap = std::unordered_map< Key, T, Hash, Pred, TrackingAllocator<std::pair<const Key, T>, kTag>>; +template<class Key, + class T, + class EmptyFn, + AllocatorTag kTag, + class Hash = std::hash<Key>, + class Pred = std::equal_to<Key>> +using AllocationTrackingHashMap = HashMap< + Key, T, EmptyFn, Hash, Pred, TrackingAllocator<std::pair<Key, T>, kTag>>; } // namespace art #endif // ART_RUNTIME_BASE_ALLOCATOR_H_ diff --git a/runtime/dex_file_verifier.cc b/runtime/dex_file_verifier.cc index a5f9d09900..440d696ea9 100644 --- a/runtime/dex_file_verifier.cc +++ b/runtime/dex_file_verifier.cc @@ -1416,7 +1416,12 @@ bool DexFileVerifier::CheckIntraSectionIterate(size_t offset, uint32_t section_c } if (IsDataSectionType(type)) { - offset_to_type_map_.Put(aligned_offset, type); + if (aligned_offset == 0u) { + ErrorStringPrintf("Item %d offset is 0", i); + return false; + } + DCHECK(offset_to_type_map_.Find(aligned_offset) == offset_to_type_map_.end()); + offset_to_type_map_.Insert(std::pair<uint32_t, uint16_t>(aligned_offset, type)); } aligned_offset = ptr_ - begin_; @@ -1589,7 +1594,8 @@ bool DexFileVerifier::CheckIntraSection() { } bool DexFileVerifier::CheckOffsetToTypeMap(size_t offset, uint16_t type) { - auto it = offset_to_type_map_.find(offset); + DCHECK_NE(offset, 0u); + auto it = offset_to_type_map_.Find(offset); if (UNLIKELY(it == offset_to_type_map_.end())) { ErrorStringPrintf("No data map entry found @ %zx; expected %x", offset, type); return false; diff --git a/runtime/dex_file_verifier.h b/runtime/dex_file_verifier.h index 4f15357ea0..6c63749f04 100644 --- a/runtime/dex_file_verifier.h +++ b/runtime/dex_file_verifier.h @@ -175,7 +175,35 @@ class DexFileVerifier { const char* const location_; const DexFile::Header* const header_; - AllocationTrackingSafeMap<uint32_t, uint16_t, kAllocatorTagDexFileVerifier> offset_to_type_map_; + struct OffsetTypeMapEmptyFn { + // Make a hash map slot empty by making the offset 0. Offset 0 is a valid dex file offset that + // is in the offset of the dex file header. However, we only store data section items in the + // map, and these are after the header. + void MakeEmpty(std::pair<uint32_t, uint16_t>& pair) const { + pair.first = 0u; + } + // Check if a hash map slot is empty. + bool IsEmpty(const std::pair<uint32_t, uint16_t>& pair) const { + return pair.first == 0; + } + }; + struct OffsetTypeMapHashCompareFn { + // Hash function for offset. + size_t operator()(const uint32_t key) const { + return key; + } + // std::equal function for offset. + bool operator()(const uint32_t a, const uint32_t b) const { + return a == b; + } + }; + // Map from offset to dex file type, HashMap for performance reasons. + AllocationTrackingHashMap<uint32_t, + uint16_t, + OffsetTypeMapEmptyFn, + kAllocatorTagDexFileVerifier, + OffsetTypeMapHashCompareFn, + OffsetTypeMapHashCompareFn> offset_to_type_map_; const uint8_t* ptr_; const void* previous_item_; |