diff options
-rw-r--r-- | dexdump/dexdump.cc | 40 | ||||
-rw-r--r-- | dexlist/dexlist.cc | 7 | ||||
-rw-r--r-- | runtime/code_item_accessors-inl.h | 118 | ||||
-rw-r--r-- | runtime/code_item_accessors-no_art-inl.h | 169 | ||||
-rw-r--r-- | runtime/code_item_accessors.h | 18 |
5 files changed, 210 insertions, 142 deletions
diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc index 527a5b993c..f64c89a5b0 100644 --- a/dexdump/dexdump.cc +++ b/dexdump/dexdump.cc @@ -44,6 +44,7 @@ #include "android-base/stringprintf.h" +#include "code_item_accessors-no_art-inl.h" #include "dex_file-inl.h" #include "dex_file_loader.h" #include "dex_file_types.h" @@ -949,14 +950,14 @@ static void dumpInstruction(const DexFile* pDexFile, fprintf(gOutFile, "%06x:", codeOffset + 0x10 + insnIdx * 2); // Dump (part of) raw bytes. - const u2* insns = pCode->insns_; + CodeItemInstructionAccessor accessor(pDexFile, pCode); for (u4 i = 0; i < 8; i++) { if (i < insnWidth) { if (i == 7) { fprintf(gOutFile, " ... "); } else { // Print 16-bit value in little-endian order. - const u1* bytePtr = (const u1*) &insns[insnIdx + i]; + const u1* bytePtr = (const u1*) &accessor.Insns()[insnIdx + i]; fprintf(gOutFile, " %02x%02x", bytePtr[0], bytePtr[1]); } } else { @@ -966,7 +967,7 @@ static void dumpInstruction(const DexFile* pDexFile, // Dump pseudo-instruction or opcode. if (pDecInsn->Opcode() == Instruction::NOP) { - const u2 instr = get2LE((const u1*) &insns[insnIdx]); + const u2 instr = get2LE((const u1*) &accessor.Insns()[insnIdx]); if (instr == Instruction::kPackedSwitchSignature) { fprintf(gOutFile, "|%04x: packed-switch-data (%d units)", insnIdx, insnWidth); } else if (instr == Instruction::kSparseSwitchSignature) { @@ -1167,16 +1168,15 @@ static void dumpBytecodes(const DexFile* pDexFile, u4 idx, codeOffset, codeOffset, dot.get(), name, signature.ToString().c_str()); // Iterate over all instructions. - const u2* insns = pCode->insns_; - for (u4 insnIdx = 0; insnIdx < pCode->insns_size_in_code_units_;) { - const Instruction* instruction = Instruction::At(&insns[insnIdx]); + CodeItemDataAccessor accessor(pDexFile, pCode); + for (const DexInstructionPcPair& pair : accessor) { + const Instruction* instruction = &pair.Inst(); const u4 insnWidth = instruction->SizeInCodeUnits(); if (insnWidth == 0) { - fprintf(stderr, "GLITCH: zero-width instruction at idx=0x%04x\n", insnIdx); + fprintf(stderr, "GLITCH: zero-width instruction at idx=0x%04x\n", pair.DexPc()); break; } - dumpInstruction(pDexFile, pCode, codeOffset, insnIdx, insnWidth, instruction); - insnIdx += insnWidth; + dumpInstruction(pDexFile, pCode, codeOffset, pair.DexPc(), insnWidth, instruction); } // for } @@ -1185,11 +1185,13 @@ static void dumpBytecodes(const DexFile* pDexFile, u4 idx, */ static void dumpCode(const DexFile* pDexFile, u4 idx, u4 flags, const DexFile::CodeItem* pCode, u4 codeOffset) { - fprintf(gOutFile, " registers : %d\n", pCode->registers_size_); - fprintf(gOutFile, " ins : %d\n", pCode->ins_size_); - fprintf(gOutFile, " outs : %d\n", pCode->outs_size_); + CodeItemDebugInfoAccessor accessor(pDexFile, pCode, pDexFile->GetDebugInfoOffset(pCode)); + + fprintf(gOutFile, " registers : %d\n", accessor.RegistersSize()); + fprintf(gOutFile, " ins : %d\n", accessor.InsSize()); + fprintf(gOutFile, " outs : %d\n", accessor.OutsSize()); fprintf(gOutFile, " insns size : %d 16-bit code units\n", - pCode->insns_size_in_code_units_); + accessor.InsnsSizeInCodeUnits()); // Bytecode disassembly, if requested. if (gOptions.disassemble) { @@ -1202,17 +1204,9 @@ static void dumpCode(const DexFile* pDexFile, u4 idx, u4 flags, // Positions and locals table in the debug info. bool is_static = (flags & kAccStatic) != 0; fprintf(gOutFile, " positions : \n"); - uint32_t debug_info_offset = pDexFile->GetDebugInfoOffset(pCode); - pDexFile->DecodeDebugPositionInfo(debug_info_offset, dumpPositionsCb, nullptr); + pDexFile->DecodeDebugPositionInfo(accessor.DebugInfoOffset(), dumpPositionsCb, nullptr); fprintf(gOutFile, " locals : \n"); - pDexFile->DecodeDebugLocalInfo(pCode->registers_size_, - pCode->ins_size_, - pCode->insns_size_in_code_units_, - debug_info_offset, - is_static, - idx, - dumpLocalsCb, - nullptr); + accessor.DecodeDebugLocalInfo(is_static, idx, dumpLocalsCb, nullptr); } /* diff --git a/dexlist/dexlist.cc b/dexlist/dexlist.cc index 4c13ed6410..2c910d4018 100644 --- a/dexlist/dexlist.cc +++ b/dexlist/dexlist.cc @@ -27,6 +27,7 @@ #include <stdlib.h> #include "base/logging.h" // For InitLogging. +#include "code_item_accessors-no_art-inl.h" #include "dex_file-inl.h" #include "dex_file_loader.h" #include "mem_map.h" @@ -99,6 +100,7 @@ static void dumpMethod(const DexFile* pDexFile, if (pCode == nullptr || codeOffset == 0) { return; } + CodeItemDebugInfoAccessor accessor(pDexFile, pCode, pDexFile->GetDebugInfoOffset(pCode)); // Method information. const DexFile::MethodId& pMethodId = pDexFile->GetMethodId(idx); @@ -121,8 +123,7 @@ static void dumpMethod(const DexFile* pDexFile, // Find the first line. int firstLine = -1; - uint32_t debug_info_offset = pDexFile->GetDebugInfoOffset(pCode); - pDexFile->DecodeDebugPositionInfo(debug_info_offset, positionsCb, &firstLine); + pDexFile->DecodeDebugPositionInfo(accessor.DebugInfoOffset(), positionsCb, &firstLine); // Method signature. const Signature signature = pDexFile->GetMethodSignature(pMethodId); @@ -130,7 +131,7 @@ static void dumpMethod(const DexFile* pDexFile, // Dump actual method information. fprintf(gOutFile, "0x%08x %d %s %s %s %s %d\n", - insnsOff, pCode->insns_size_in_code_units_ * 2, + insnsOff, accessor.InsnsSizeInCodeUnits() * 2, className.get(), methodName, typeDesc, fileName, firstLine); free(typeDesc); diff --git a/runtime/code_item_accessors-inl.h b/runtime/code_item_accessors-inl.h index 4f4d8cc86e..1ba3c55f77 100644 --- a/runtime/code_item_accessors-inl.h +++ b/runtime/code_item_accessors-inl.h @@ -17,7 +17,7 @@ #ifndef ART_RUNTIME_CODE_ITEM_ACCESSORS_INL_H_ #define ART_RUNTIME_CODE_ITEM_ACCESSORS_INL_H_ -#include "code_item_accessors.h" +#include "code_item_accessors-no_art-inl.h" #include "art_method-inl.h" #include "cdex/compact_dex_file.h" @@ -27,45 +27,9 @@ namespace art { -inline void CodeItemInstructionAccessor::Init(const CompactDexFile::CodeItem& code_item) { - insns_size_in_code_units_ = code_item.insns_size_in_code_units_; - insns_ = code_item.insns_; -} - -inline void CodeItemInstructionAccessor::Init(const StandardDexFile::CodeItem& code_item) { - insns_size_in_code_units_ = code_item.insns_size_in_code_units_; - insns_ = code_item.insns_; -} - -inline void CodeItemInstructionAccessor::Init(const DexFile* dex_file, - const DexFile::CodeItem* code_item) { - DCHECK(dex_file != nullptr); - DCHECK(code_item != nullptr); - if (dex_file->IsCompactDexFile()) { - Init(down_cast<const CompactDexFile::CodeItem&>(*code_item)); - } else { - DCHECK(dex_file->IsStandardDexFile()); - Init(down_cast<const StandardDexFile::CodeItem&>(*code_item)); - } -} - -inline CodeItemInstructionAccessor::CodeItemInstructionAccessor( - const DexFile* dex_file, - const DexFile::CodeItem* code_item) { - Init(dex_file, code_item); -} - inline CodeItemInstructionAccessor::CodeItemInstructionAccessor(ArtMethod* method) : CodeItemInstructionAccessor(method->GetDexFile(), method->GetCodeItem()) {} -inline DexInstructionIterator CodeItemInstructionAccessor::begin() const { - return DexInstructionIterator(insns_, 0u); -} - -inline DexInstructionIterator CodeItemInstructionAccessor::end() const { - return DexInstructionIterator(insns_, insns_size_in_code_units_); -} - inline CodeItemInstructionAccessor CodeItemInstructionAccessor::CreateNullable( ArtMethod* method) { DCHECK(method != nullptr); @@ -79,78 +43,14 @@ inline CodeItemInstructionAccessor CodeItemInstructionAccessor::CreateNullable( return ret; } -inline void CodeItemDataAccessor::Init(const CompactDexFile::CodeItem& code_item) { - CodeItemInstructionAccessor::Init(code_item); - registers_size_ = code_item.registers_size_; - ins_size_ = code_item.ins_size_; - outs_size_ = code_item.outs_size_; - tries_size_ = code_item.tries_size_; -} - -inline void CodeItemDataAccessor::Init(const StandardDexFile::CodeItem& code_item) { - CodeItemInstructionAccessor::Init(code_item); - registers_size_ = code_item.registers_size_; - ins_size_ = code_item.ins_size_; - outs_size_ = code_item.outs_size_; - tries_size_ = code_item.tries_size_; -} - -inline void CodeItemDataAccessor::Init(const DexFile* dex_file, - const DexFile::CodeItem* code_item) { - DCHECK(dex_file != nullptr); - DCHECK(code_item != nullptr); - if (dex_file->IsCompactDexFile()) { - CodeItemDataAccessor::Init(down_cast<const CompactDexFile::CodeItem&>(*code_item)); - } else { - DCHECK(dex_file->IsStandardDexFile()); - CodeItemDataAccessor::Init(down_cast<const StandardDexFile::CodeItem&>(*code_item)); - } -} - -inline CodeItemDataAccessor::CodeItemDataAccessor(const DexFile* dex_file, - const DexFile::CodeItem* code_item) { - Init(dex_file, code_item); -} - inline CodeItemDataAccessor::CodeItemDataAccessor(ArtMethod* method) : CodeItemDataAccessor(method->GetDexFile(), method->GetCodeItem()) {} -inline CodeItemDataAccessor CodeItemDataAccessor::CreateNullable( - const DexFile* dex_file, - const DexFile::CodeItem* code_item) { - CodeItemDataAccessor ret; - if (code_item != nullptr) { - ret.Init(dex_file, code_item); - } else { - DCHECK(!ret.HasCodeItem()) << "Should be null initialized"; - } - return ret; -} - inline CodeItemDataAccessor CodeItemDataAccessor::CreateNullable(ArtMethod* method) { DCHECK(method != nullptr); return CreateNullable(method->GetDexFile(), method->GetCodeItem()); } -inline IterationRange<const DexFile::TryItem*> CodeItemDataAccessor::TryItems() const { - const DexFile::TryItem* try_items = DexFile::GetTryItems(end(), 0u); - return { - try_items, - try_items + TriesSize() }; -} - -inline const uint8_t* CodeItemDataAccessor::GetCatchHandlerData(size_t offset) const { - return DexFile::GetCatchHandlerData(end(), TriesSize(), offset); -} - -inline const DexFile::TryItem* CodeItemDataAccessor::FindTryItem(uint32_t try_dex_pc) const { - IterationRange<const DexFile::TryItem*> try_items(TryItems()); - int32_t index = DexFile::FindTryItem(try_items.begin(), - try_items.end() - try_items.begin(), - try_dex_pc); - return index != -1 ? &try_items.begin()[index] : nullptr; -} - inline CodeItemDebugInfoAccessor::CodeItemDebugInfoAccessor(ArtMethod* method) : CodeItemDebugInfoAccessor(method->GetDexFile(), method->GetCodeItem()) {} @@ -159,21 +59,7 @@ inline CodeItemDebugInfoAccessor::CodeItemDebugInfoAccessor(const DexFile* dex_f if (code_item == nullptr) { return; } - debug_info_offset_ = OatFile::GetDebugInfoOffset(*dex_file, code_item); - if (dex_file->IsCompactDexFile()) { - Init(down_cast<const CompactDexFile::CodeItem&>(*code_item)); - } else { - DCHECK(dex_file->IsStandardDexFile()); - Init(down_cast<const StandardDexFile::CodeItem&>(*code_item)); - } -} - -inline void CodeItemDebugInfoAccessor::Init(const CompactDexFile::CodeItem& code_item) { - CodeItemDataAccessor::Init(code_item); -} - -inline void CodeItemDebugInfoAccessor::Init(const StandardDexFile::CodeItem& code_item) { - CodeItemDataAccessor::Init(code_item); + Init(dex_file, code_item, OatFile::GetDebugInfoOffset(*dex_file, code_item)); } } // namespace art diff --git a/runtime/code_item_accessors-no_art-inl.h b/runtime/code_item_accessors-no_art-inl.h new file mode 100644 index 0000000000..96321b54f5 --- /dev/null +++ b/runtime/code_item_accessors-no_art-inl.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_RUNTIME_CODE_ITEM_ACCESSORS_NO_ART_INL_H_ +#define ART_RUNTIME_CODE_ITEM_ACCESSORS_NO_ART_INL_H_ + +#include "code_item_accessors.h" + +#include "cdex/compact_dex_file.h" +#include "dex_file-inl.h" +#include "standard_dex_file.h" + +// The no ART version is used by binaries that don't include the whole runtime. + +namespace art { + +inline void CodeItemInstructionAccessor::Init(const CompactDexFile::CodeItem& code_item) { + insns_size_in_code_units_ = code_item.insns_size_in_code_units_; + insns_ = code_item.insns_; +} + +inline void CodeItemInstructionAccessor::Init(const StandardDexFile::CodeItem& code_item) { + insns_size_in_code_units_ = code_item.insns_size_in_code_units_; + insns_ = code_item.insns_; +} + +inline void CodeItemInstructionAccessor::Init(const DexFile* dex_file, + const DexFile::CodeItem* code_item) { + DCHECK(dex_file != nullptr); + DCHECK(code_item != nullptr); + if (dex_file->IsCompactDexFile()) { + Init(down_cast<const CompactDexFile::CodeItem&>(*code_item)); + } else { + DCHECK(dex_file->IsStandardDexFile()); + Init(down_cast<const StandardDexFile::CodeItem&>(*code_item)); + } +} + +inline CodeItemInstructionAccessor::CodeItemInstructionAccessor( + const DexFile* dex_file, + const DexFile::CodeItem* code_item) { + Init(dex_file, code_item); +} + +inline DexInstructionIterator CodeItemInstructionAccessor::begin() const { + return DexInstructionIterator(insns_, 0u); +} + +inline DexInstructionIterator CodeItemInstructionAccessor::end() const { + return DexInstructionIterator(insns_, insns_size_in_code_units_); +} + +inline void CodeItemDataAccessor::Init(const CompactDexFile::CodeItem& code_item) { + CodeItemInstructionAccessor::Init(code_item); + registers_size_ = code_item.registers_size_; + ins_size_ = code_item.ins_size_; + outs_size_ = code_item.outs_size_; + tries_size_ = code_item.tries_size_; +} + +inline void CodeItemDataAccessor::Init(const StandardDexFile::CodeItem& code_item) { + CodeItemInstructionAccessor::Init(code_item); + registers_size_ = code_item.registers_size_; + ins_size_ = code_item.ins_size_; + outs_size_ = code_item.outs_size_; + tries_size_ = code_item.tries_size_; +} + +inline void CodeItemDataAccessor::Init(const DexFile* dex_file, + const DexFile::CodeItem* code_item) { + DCHECK(dex_file != nullptr); + DCHECK(code_item != nullptr); + if (dex_file->IsCompactDexFile()) { + CodeItemDataAccessor::Init(down_cast<const CompactDexFile::CodeItem&>(*code_item)); + } else { + DCHECK(dex_file->IsStandardDexFile()); + CodeItemDataAccessor::Init(down_cast<const StandardDexFile::CodeItem&>(*code_item)); + } +} + +inline CodeItemDataAccessor::CodeItemDataAccessor(const DexFile* dex_file, + const DexFile::CodeItem* code_item) { + Init(dex_file, code_item); +} + +inline CodeItemDataAccessor CodeItemDataAccessor::CreateNullable( + const DexFile* dex_file, + const DexFile::CodeItem* code_item) { + CodeItemDataAccessor ret; + if (code_item != nullptr) { + ret.Init(dex_file, code_item); + } else { + DCHECK(!ret.HasCodeItem()) << "Should be null initialized"; + } + return ret; +} + +inline IterationRange<const DexFile::TryItem*> CodeItemDataAccessor::TryItems() const { + const DexFile::TryItem* try_items = DexFile::GetTryItems(end(), 0u); + return { + try_items, + try_items + TriesSize() }; +} + +inline const uint8_t* CodeItemDataAccessor::GetCatchHandlerData(size_t offset) const { + return DexFile::GetCatchHandlerData(end(), TriesSize(), offset); +} + +inline const DexFile::TryItem* CodeItemDataAccessor::FindTryItem(uint32_t try_dex_pc) const { + IterationRange<const DexFile::TryItem*> try_items(TryItems()); + int32_t index = DexFile::FindTryItem(try_items.begin(), + try_items.end() - try_items.begin(), + try_dex_pc); + return index != -1 ? &try_items.begin()[index] : nullptr; +} + +inline void CodeItemDebugInfoAccessor::Init(const DexFile* dex_file, + const DexFile::CodeItem* code_item, + uint32_t debug_info_offset) { + dex_file_ = dex_file; + debug_info_offset_ = debug_info_offset; + if (dex_file->IsCompactDexFile()) { + Init(down_cast<const CompactDexFile::CodeItem&>(*code_item)); + } else { + DCHECK(dex_file->IsStandardDexFile()); + Init(down_cast<const StandardDexFile::CodeItem&>(*code_item)); + } +} + +inline void CodeItemDebugInfoAccessor::Init(const CompactDexFile::CodeItem& code_item) { + CodeItemDataAccessor::Init(code_item); +} + +inline void CodeItemDebugInfoAccessor::Init(const StandardDexFile::CodeItem& code_item) { + CodeItemDataAccessor::Init(code_item); +} + +template<typename NewLocalCallback> +inline bool CodeItemDebugInfoAccessor::DecodeDebugLocalInfo(bool is_static, + uint32_t method_idx, + NewLocalCallback new_local, + void* context) const { + return dex_file_->DecodeDebugLocalInfo(RegistersSize(), + InsSize(), + InsnsSizeInCodeUnits(), + DebugInfoOffset(), + is_static, + method_idx, + new_local, + context); +} + + +} // namespace art + +#endif // ART_RUNTIME_CODE_ITEM_ACCESSORS_NO_ART_INL_H_ diff --git a/runtime/code_item_accessors.h b/runtime/code_item_accessors.h index a089a276de..9f40114438 100644 --- a/runtime/code_item_accessors.h +++ b/runtime/code_item_accessors.h @@ -142,17 +142,35 @@ class CodeItemDebugInfoAccessor : public CodeItemDataAccessor { ALWAYS_INLINE CodeItemDebugInfoAccessor(const DexFile* dex_file, const DexFile::CodeItem* code_item); + // Initialize with an existing offset. + ALWAYS_INLINE CodeItemDebugInfoAccessor(const DexFile* dex_file, + const DexFile::CodeItem* code_item, + uint32_t debug_info_offset) { + Init(dex_file, code_item, debug_info_offset); + } + + ALWAYS_INLINE void Init(const DexFile* dex_file, + const DexFile::CodeItem* code_item, + uint32_t debug_info_offset); + ALWAYS_INLINE explicit CodeItemDebugInfoAccessor(ArtMethod* method); uint32_t DebugInfoOffset() const { return debug_info_offset_; } + template<typename NewLocalCallback> + bool DecodeDebugLocalInfo(bool is_static, + uint32_t method_idx, + NewLocalCallback new_local, + void* context) const; + protected: ALWAYS_INLINE void Init(const CompactDexFile::CodeItem& code_item); ALWAYS_INLINE void Init(const StandardDexFile::CodeItem& code_item); private: + const DexFile* dex_file_ = nullptr; uint32_t debug_info_offset_ = 0u; }; |