diff options
Diffstat (limited to 'runtime')
| -rw-r--r-- | runtime/cdex/compact_dex_file.cc | 36 | ||||
| -rw-r--r-- | runtime/cdex/compact_dex_file.h | 3 | ||||
| -rw-r--r-- | runtime/dex_file-inl.h | 9 | ||||
| -rw-r--r-- | runtime/dex_file.cc | 29 | ||||
| -rw-r--r-- | runtime/dex_file.h | 17 | ||||
| -rw-r--r-- | runtime/dex_file_tracking_registrar.cc | 4 | ||||
| -rw-r--r-- | runtime/dex_to_dex_decompiler.cc | 6 | ||||
| -rw-r--r-- | runtime/dex_to_dex_decompiler.h | 2 | ||||
| -rw-r--r-- | runtime/standard_dex_file.cc | 35 | ||||
| -rw-r--r-- | runtime/standard_dex_file.h | 3 | ||||
| -rw-r--r-- | runtime/vdex_file.cc | 2 |
11 files changed, 101 insertions, 45 deletions
diff --git a/runtime/cdex/compact_dex_file.cc b/runtime/cdex/compact_dex_file.cc index a92ab28a7a..8f90e098bb 100644 --- a/runtime/cdex/compact_dex_file.cc +++ b/runtime/cdex/compact_dex_file.cc @@ -16,6 +16,9 @@ #include "compact_dex_file.h" +#include "dex_file-inl.h" +#include "leb128.h" + namespace art { constexpr uint8_t CompactDexFile::kDexMagic[kDexMagicSize]; @@ -51,4 +54,37 @@ bool CompactDexFile::SupportsDefaultMethods() const { static_cast<uint32_t>(FeatureFlags::kDefaultMethods)) != 0; } +uint32_t CompactDexFile::GetCodeItemSize(const DexFile::CodeItem& item) const { + // TODO: Clean up this temporary code duplication with StandardDexFile. Eventually the + // implementations will differ. + DCHECK(HasAddress(&item)); + const CodeItem& code_item = down_cast<const CodeItem&>(item); + uintptr_t code_item_start = reinterpret_cast<uintptr_t>(&code_item); + uint32_t insns_size = code_item.insns_size_in_code_units_; + uint32_t tries_size = code_item.tries_size_; + const uint8_t* handler_data = GetCatchHandlerData( + DexInstructionIterator(code_item.insns_, code_item.insns_size_in_code_units_), + code_item.tries_size_, + 0); + + if (tries_size == 0 || handler_data == nullptr) { + uintptr_t insns_end = reinterpret_cast<uintptr_t>(&code_item.insns_[insns_size]); + return insns_end - code_item_start; + } else { + // Get the start of the handler data. + uint32_t handlers_size = DecodeUnsignedLeb128(&handler_data); + // Manually read each handler. + for (uint32_t i = 0; i < handlers_size; ++i) { + int32_t uleb128_count = DecodeSignedLeb128(&handler_data) * 2; + if (uleb128_count <= 0) { + uleb128_count = -uleb128_count + 1; + } + for (int32_t j = 0; j < uleb128_count; ++j) { + DecodeUnsignedLeb128(&handler_data); + } + } + return reinterpret_cast<uintptr_t>(handler_data) - code_item_start; + } +} + } // namespace art diff --git a/runtime/cdex/compact_dex_file.h b/runtime/cdex/compact_dex_file.h index e47f97e804..4343229962 100644 --- a/runtime/cdex/compact_dex_file.h +++ b/runtime/cdex/compact_dex_file.h @@ -47,6 +47,7 @@ class CompactDexFile : public DexFile { struct CodeItem : public DexFile::CodeItem { private: // TODO: Insert compact dex specific fields here. + friend class CompactDexFile; DISALLOW_COPY_AND_ASSIGN(CodeItem); }; @@ -70,6 +71,8 @@ class CompactDexFile : public DexFile { virtual bool SupportsDefaultMethods() const OVERRIDE; + uint32_t GetCodeItemSize(const DexFile::CodeItem& item) const OVERRIDE; + private: // Not supported yet. CompactDexFile(const uint8_t* base, diff --git a/runtime/dex_file-inl.h b/runtime/dex_file-inl.h index 7cc8b87f8c..90b3c8d34a 100644 --- a/runtime/dex_file-inl.h +++ b/runtime/dex_file-inl.h @@ -507,6 +507,15 @@ inline const StandardDexFile* DexFile::AsStandardDexFile() const { return down_cast<const StandardDexFile*>(this); } +// Get the base of the encoded data for the given DexCode. +inline const uint8_t* DexFile::GetCatchHandlerData(const DexInstructionIterator& code_item_end, + uint32_t tries_size, + uint32_t offset) { + const uint8_t* handler_data = + reinterpret_cast<const uint8_t*>(GetTryItems(code_item_end, tries_size)); + return handler_data + offset; +} + } // namespace art #endif // ART_RUNTIME_DEX_FILE_INL_H_ diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc index d6469c6c22..16325b83f6 100644 --- a/runtime/dex_file.cc +++ b/runtime/dex_file.cc @@ -217,35 +217,6 @@ uint32_t DexFile::FindCodeItemOffset(const DexFile::ClassDef& class_def, UNREACHABLE(); } -uint32_t DexFile::GetCodeItemSize(const DexFile::CodeItem& code_item) { - uintptr_t code_item_start = reinterpret_cast<uintptr_t>(&code_item); - uint32_t insns_size = code_item.insns_size_in_code_units_; - uint32_t tries_size = code_item.tries_size_; - const uint8_t* handler_data = GetCatchHandlerData( - DexInstructionIterator(code_item.insns_, code_item.insns_size_in_code_units_), - code_item.tries_size_, - 0); - - if (tries_size == 0 || handler_data == nullptr) { - uintptr_t insns_end = reinterpret_cast<uintptr_t>(&code_item.insns_[insns_size]); - return insns_end - code_item_start; - } else { - // Get the start of the handler data. - uint32_t handlers_size = DecodeUnsignedLeb128(&handler_data); - // Manually read each handler. - for (uint32_t i = 0; i < handlers_size; ++i) { - int32_t uleb128_count = DecodeSignedLeb128(&handler_data) * 2; - if (uleb128_count <= 0) { - uleb128_count = -uleb128_count + 1; - } - for (int32_t j = 0; j < uleb128_count; ++j) { - DecodeUnsignedLeb128(&handler_data); - } - } - return reinterpret_cast<uintptr_t>(handler_data) - code_item_start; - } -} - const DexFile::FieldId* DexFile::FindFieldId(const DexFile::TypeId& declaring_klass, const DexFile::StringId& name, const DexFile::TypeId& type) const { diff --git a/runtime/dex_file.h b/runtime/dex_file.h index b9bf119035..6e11f09549 100644 --- a/runtime/dex_file.h +++ b/runtime/dex_file.h @@ -308,7 +308,11 @@ class DexFile { debug_info_off_ = new_offset; } - private: + uint32_t GetDebugInfoOffset() const { + return debug_info_off_; + } + + protected: uint16_t registers_size_; // the number of registers used by this code // (locals + parameters) uint16_t ins_size_; // the number of words of incoming arguments to the method @@ -333,7 +337,6 @@ class DexFile { friend class CodeItemDataAccessor; friend class CodeItemDebugInfoAccessor; friend class CodeItemInstructionAccessor; - friend class DexFile; // TODO: Remove this one when it's cleaned up. friend class VdexFile; // TODO: Remove this one when it's cleaned up. DISALLOW_COPY_AND_ASSIGN(CodeItem); }; @@ -583,7 +586,7 @@ class DexFile { uint32_t FindCodeItemOffset(const DexFile::ClassDef& class_def, uint32_t dex_method_idx) const; - static uint32_t GetCodeItemSize(const DexFile::CodeItem& disk_code_item); + virtual uint32_t GetCodeItemSize(const DexFile::CodeItem& disk_code_item) const = 0; // Returns the declaring class descriptor string of a field id. const char* GetFieldDeclaringClassDescriptor(const FieldId& field_id) const { @@ -715,7 +718,7 @@ class DexFile { } CHECK(oat_dex_file_ == nullptr) << "Should only use GetDebugInfoOffset in a non runtime setup"; - return code_item->debug_info_off_; + return code_item->GetDebugInfoOffset(); } const char* GetReturnTypeDescriptor(const ProtoId& proto_id) const; @@ -778,11 +781,7 @@ class DexFile { // Get the base of the encoded data for the given DexCode. static const uint8_t* GetCatchHandlerData(const DexInstructionIterator& code_item_end, uint32_t tries_size, - uint32_t offset) { - const uint8_t* handler_data = - reinterpret_cast<const uint8_t*>(GetTryItems(code_item_end, tries_size)); - return handler_data + offset; - } + uint32_t offset); // Find which try region is associated with the given address (ie dex pc). Returns -1 if none. static int32_t FindTryItem(const TryItem* try_items, uint32_t tries_size, uint32_t address); diff --git a/runtime/dex_file_tracking_registrar.cc b/runtime/dex_file_tracking_registrar.cc index c157ddc790..bffca5599a 100644 --- a/runtime/dex_file_tracking_registrar.cc +++ b/runtime/dex_file_tracking_registrar.cc @@ -164,7 +164,7 @@ void DexFileTrackingRegistrar::SetAllCodeItemRegistration(bool should_poison) { const DexFile::CodeItem* code_item = cdit.GetMethodCodeItem(); if (code_item != nullptr) { const void* code_item_begin = reinterpret_cast<const void*>(code_item); - size_t code_item_size = DexFile::GetCodeItemSize(*code_item); + size_t code_item_size = dex_file_->GetCodeItemSize(*code_item); range_values_.push_back(std::make_tuple(code_item_begin, code_item_size, should_poison)); } cdit.Next(); @@ -233,7 +233,7 @@ void DexFileTrackingRegistrar::SetCodeItemRegistration(const char* class_name, b const DexFile::CodeItem* code_item = cdit.GetMethodCodeItem(); if (code_item != nullptr && strcmp(methodid_name, class_name) == 0) { const void* code_item_begin = reinterpret_cast<const void*>(code_item); - size_t code_item_size = DexFile::GetCodeItemSize(*code_item); + size_t code_item_size = dex_file_->GetCodeItemSize(*code_item); range_values_.push_back(std::make_tuple(code_item_begin, code_item_size, should_poison)); } cdit.Next(); diff --git a/runtime/dex_to_dex_decompiler.cc b/runtime/dex_to_dex_decompiler.cc index dc7e11bc19..7f36c4e1ce 100644 --- a/runtime/dex_to_dex_decompiler.cc +++ b/runtime/dex_to_dex_decompiler.cc @@ -31,11 +31,11 @@ namespace optimizer { class DexDecompiler { public: - DexDecompiler(const DexFile* dex_file, + DexDecompiler(const DexFile& dex_file, const DexFile::CodeItem& code_item, const ArrayRef<const uint8_t>& quickened_info, bool decompile_return_instruction) - : code_item_accessor_(dex_file, &code_item), + : code_item_accessor_(&dex_file, &code_item), quicken_info_(quickened_info.data()), quicken_info_number_of_indices_(QuickenInfoTable::NumberOfIndices(quickened_info.size())), decompile_return_instruction_(decompile_return_instruction) {} @@ -196,7 +196,7 @@ bool DexDecompiler::Decompile() { return true; } -bool ArtDecompileDEX(const DexFile* dex_file, +bool ArtDecompileDEX(const DexFile& dex_file, const DexFile::CodeItem& code_item, const ArrayRef<const uint8_t>& quickened_info, bool decompile_return_instruction) { diff --git a/runtime/dex_to_dex_decompiler.h b/runtime/dex_to_dex_decompiler.h index 804b7e830a..a2e3f28ce9 100644 --- a/runtime/dex_to_dex_decompiler.h +++ b/runtime/dex_to_dex_decompiler.h @@ -29,7 +29,7 @@ namespace optimizer { // to non-const has too many repercussions on the code base. We make it // consistent with DexToDexCompiler, but we should really change it to // DexFile::CodeItem*. -bool ArtDecompileDEX(const DexFile* dex_file, +bool ArtDecompileDEX(const DexFile& dex_file, const DexFile::CodeItem& code_item, const ArrayRef<const uint8_t>& quickened_data, bool decompile_return_instruction); diff --git a/runtime/standard_dex_file.cc b/runtime/standard_dex_file.cc index b608341a92..843508d831 100644 --- a/runtime/standard_dex_file.cc +++ b/runtime/standard_dex_file.cc @@ -16,6 +16,10 @@ #include "standard_dex_file.h" +#include "base/casts.h" +#include "dex_file-inl.h" +#include "leb128.h" + namespace art { const uint8_t StandardDexFile::kDexMagic[] = { 'd', 'e', 'x', '\n' }; @@ -67,4 +71,35 @@ bool StandardDexFile::SupportsDefaultMethods() const { return GetDexVersion() >= DexFile::kDefaultMethodsVersion; } +uint32_t StandardDexFile::GetCodeItemSize(const DexFile::CodeItem& item) const { + DCHECK(HasAddress(&item)); + const CodeItem& code_item = down_cast<const CodeItem&>(item); + uintptr_t code_item_start = reinterpret_cast<uintptr_t>(&code_item); + uint32_t insns_size = code_item.insns_size_in_code_units_; + uint32_t tries_size = code_item.tries_size_; + const uint8_t* handler_data = GetCatchHandlerData( + DexInstructionIterator(code_item.insns_, code_item.insns_size_in_code_units_), + code_item.tries_size_, + 0); + + if (tries_size == 0 || handler_data == nullptr) { + uintptr_t insns_end = reinterpret_cast<uintptr_t>(&code_item.insns_[insns_size]); + return insns_end - code_item_start; + } else { + // Get the start of the handler data. + uint32_t handlers_size = DecodeUnsignedLeb128(&handler_data); + // Manually read each handler. + for (uint32_t i = 0; i < handlers_size; ++i) { + int32_t uleb128_count = DecodeSignedLeb128(&handler_data) * 2; + if (uleb128_count <= 0) { + uleb128_count = -uleb128_count + 1; + } + for (int32_t j = 0; j < uleb128_count; ++j) { + DecodeUnsignedLeb128(&handler_data); + } + } + return reinterpret_cast<uintptr_t>(handler_data) - code_item_start; + } +} + } // namespace art diff --git a/runtime/standard_dex_file.h b/runtime/standard_dex_file.h index 80c406ebc7..74749d249b 100644 --- a/runtime/standard_dex_file.h +++ b/runtime/standard_dex_file.h @@ -35,6 +35,7 @@ class StandardDexFile : public DexFile { struct CodeItem : public DexFile::CodeItem { private: // TODO: Insert standard dex specific fields here. + friend class StandardDexFile; DISALLOW_COPY_AND_ASSIGN(CodeItem); }; @@ -58,6 +59,8 @@ class StandardDexFile : public DexFile { virtual bool SupportsDefaultMethods() const OVERRIDE; + uint32_t GetCodeItemSize(const DexFile::CodeItem& item) const OVERRIDE; + private: StandardDexFile(const uint8_t* base, size_t size, diff --git a/runtime/vdex_file.cc b/runtime/vdex_file.cc index a9af97df48..6d37d0604e 100644 --- a/runtime/vdex_file.cc +++ b/runtime/vdex_file.cc @@ -254,7 +254,7 @@ void VdexFile::UnquickenDexFile(const DexFile& target_dex_file, quickening_info)); } optimizer::ArtDecompileDEX( - &target_dex_file, + target_dex_file, *code_item, GetQuickeningInfoAt(quickening_info, quickening_offset), decompile_return_instruction); |