diff options
33 files changed, 95 insertions, 120 deletions
diff --git a/compiler/compiler.cc b/compiler/compiler.cc index 60977b6bd5..7c7ae71d77 100644 --- a/compiler/compiler.cc +++ b/compiler/compiler.cc @@ -47,7 +47,7 @@ bool Compiler::IsPathologicalCase(const DexFile::CodeItem& code_item, * Dalvik uses 16-bit uints for instruction and register counts. We'll limit to a quarter * of that, which also guarantees we cannot overflow our 16-bit internal Quick SSA name space. */ - CodeItemDataAccessor accessor(&dex_file, &code_item); + CodeItemDataAccessor accessor(dex_file, &code_item); if (accessor.InsnsSizeInCodeUnits() >= UINT16_MAX / 4) { LOG(INFO) << "Method exceeds compiler instruction limit: " << accessor.InsnsSizeInCodeUnits() diff --git a/compiler/debug/elf_debug_info_writer.h b/compiler/debug/elf_debug_info_writer.h index e2bea8e096..713f8eb05d 100644 --- a/compiler/debug/elf_debug_info_writer.h +++ b/compiler/debug/elf_debug_info_writer.h @@ -49,7 +49,7 @@ static void LocalInfoCallback(void* ctx, const DexFile::LocalInfo& entry) { static std::vector<const char*> GetParamNames(const MethodDebugInfo* mi) { std::vector<const char*> names; - CodeItemDebugInfoAccessor accessor(mi->dex_file, mi->code_item); + CodeItemDebugInfoAccessor accessor(*mi->dex_file, mi->code_item); if (accessor.HasCodeItem()) { DCHECK(mi->dex_file != nullptr); const uint8_t* stream = mi->dex_file->GetDebugInfoStream(accessor.DebugInfoOffset()); @@ -163,7 +163,7 @@ class ElfCompilationUnitWriter { for (auto mi : compilation_unit.methods) { DCHECK(mi->dex_file != nullptr); const DexFile* dex = mi->dex_file; - CodeItemDebugInfoAccessor accessor(dex, mi->code_item); + CodeItemDebugInfoAccessor accessor(*dex, mi->code_item); const DexFile::MethodId& dex_method = dex->GetMethodId(mi->dex_method_index); const DexFile::ProtoId& dex_proto = dex->GetMethodPrototype(dex_method); const DexFile::TypeList* dex_params = dex->GetProtoParameters(dex_proto); diff --git a/compiler/debug/elf_debug_line_writer.h b/compiler/debug/elf_debug_line_writer.h index 9910e7a4ce..4e37f4e4ba 100644 --- a/compiler/debug/elf_debug_line_writer.h +++ b/compiler/debug/elf_debug_line_writer.h @@ -159,7 +159,7 @@ class ElfDebugLineWriter { PositionInfos dex2line_map; DCHECK(mi->dex_file != nullptr); const DexFile* dex = mi->dex_file; - CodeItemDebugInfoAccessor accessor(dex, mi->code_item); + CodeItemDebugInfoAccessor accessor(*dex, mi->code_item); const uint32_t debug_info_offset = accessor.DebugInfoOffset(); if (!dex->DecodeDebugPositionInfo(debug_info_offset, PositionInfoCallback, &dex2line_map)) { continue; diff --git a/compiler/debug/elf_debug_loc_writer.h b/compiler/debug/elf_debug_loc_writer.h index 34c2919a21..9ea9f01cd9 100644 --- a/compiler/debug/elf_debug_loc_writer.h +++ b/compiler/debug/elf_debug_loc_writer.h @@ -149,7 +149,7 @@ static std::vector<VariableLocation> GetVariableLocations( DCHECK_LT(stack_map_index, dex_register_maps.size()); DexRegisterMap dex_register_map = dex_register_maps[stack_map_index]; DCHECK(dex_register_map.IsValid()); - CodeItemDataAccessor accessor(method_info->dex_file, method_info->code_item); + CodeItemDataAccessor accessor(*method_info->dex_file, method_info->code_item); reg_lo = dex_register_map.GetDexRegisterLocation( vreg, accessor.RegistersSize(), code_info, encoding); if (is64bitValue) { diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index fe83a66d0f..c0886d0185 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -711,7 +711,7 @@ static void ResolveConstStrings(Handle<mirror::DexCache> dex_cache, } ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); - for (const DexInstructionPcPair& inst : CodeItemInstructionAccessor(&dex_file, code_item)) { + for (const DexInstructionPcPair& inst : CodeItemInstructionAccessor(dex_file, code_item)) { switch (inst->Opcode()) { case Instruction::CONST_STRING: case Instruction::CONST_STRING_JUMBO: { diff --git a/compiler/driver/dex_compilation_unit.cc b/compiler/driver/dex_compilation_unit.cc index 1fe30de355..28e68c94df 100644 --- a/compiler/driver/dex_compilation_unit.cc +++ b/compiler/driver/dex_compilation_unit.cc @@ -40,8 +40,7 @@ DexCompilationUnit::DexCompilationUnit(Handle<mirror::ClassLoader> class_loader, access_flags_(access_flags), verified_method_(verified_method), dex_cache_(dex_cache), - code_item_accessor_(&dex_file, code_item) { -} + code_item_accessor_(dex_file, code_item) {} const std::string& DexCompilationUnit::GetSymbol() { if (symbol_.empty()) { diff --git a/compiler/exception_test.cc b/compiler/exception_test.cc index 8f7ab05791..7bacacf91d 100644 --- a/compiler/exception_test.cc +++ b/compiler/exception_test.cc @@ -130,7 +130,7 @@ class ExceptionTest : public CommonRuntimeTest { TEST_F(ExceptionTest, FindCatchHandler) { ScopedObjectAccess soa(Thread::Current()); - CodeItemDataAccessor accessor(dex_, dex_->GetCodeItem(method_f_->GetCodeItemOffset())); + CodeItemDataAccessor accessor(*dex_, dex_->GetCodeItem(method_f_->GetCodeItemOffset())); ASSERT_TRUE(accessor.HasCodeItem()); diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index 07894fd1b1..01155dcd37 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -911,7 +911,7 @@ static void CheckLoopEntriesCanBeUsedForOsr(const HGraph& graph, } ArenaVector<size_t> covered( loop_headers.size(), 0, graph.GetAllocator()->Adapter(kArenaAllocMisc)); - for (const DexInstructionPcPair& pair : CodeItemInstructionAccessor(&graph.GetDexFile(), + for (const DexInstructionPcPair& pair : CodeItemInstructionAccessor(graph.GetDexFile(), &code_item)) { const uint32_t dex_pc = pair.DexPc(); const Instruction& instruction = pair.Inst(); diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 7a66d807cf..b2ad8ec400 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -1660,7 +1660,7 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction, const DexFile::CodeItem* code_item = resolved_method->GetCodeItem(); const DexFile& callee_dex_file = *resolved_method->GetDexFile(); uint32_t method_index = resolved_method->GetDexMethodIndex(); - CodeItemDebugInfoAccessor code_item_accessor(&callee_dex_file, code_item); + CodeItemDebugInfoAccessor code_item_accessor(callee_dex_file, code_item); ClassLinker* class_linker = caller_compilation_unit_.GetClassLinker(); Handle<mirror::DexCache> dex_cache = NewHandleIfDifferent(resolved_method->GetDexCache(), caller_compilation_unit_.GetDexCache(), @@ -1968,7 +1968,7 @@ void HInliner::RunOptimizations(HGraph* callee_graph, return; } - CodeItemDataAccessor accessor(&callee_graph->GetDexFile(), code_item); + CodeItemDataAccessor accessor(callee_graph->GetDexFile(), code_item); HInliner inliner(callee_graph, outermost_graph_, codegen_, diff --git a/compiler/optimizing/optimization.cc b/compiler/optimizing/optimization.cc index 92b427cafa..57db7a634c 100644 --- a/compiler/optimizing/optimization.cc +++ b/compiler/optimizing/optimization.cc @@ -242,7 +242,7 @@ ArenaVector<HOptimization*> ConstructOptimizations( opt = new (allocator) HDeadCodeElimination(graph, stats, name); break; case OptimizationPass::kInliner: { - CodeItemDataAccessor accessor(dex_compilation_unit.GetDexFile(), + CodeItemDataAccessor accessor(*dex_compilation_unit.GetDexFile(), dex_compilation_unit.GetCodeItem()); opt = new (allocator) HInliner(graph, // outer_graph graph, // outermost_graph diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index b64f82caee..f4115f7e7b 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -766,13 +766,13 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* allocator, static constexpr size_t kSpaceFilterOptimizingThreshold = 128; const CompilerOptions& compiler_options = compiler_driver->GetCompilerOptions(); if ((compiler_options.GetCompilerFilter() == CompilerFilter::kSpace) - && (CodeItemInstructionAccessor(&dex_file, code_item).InsnsSizeInCodeUnits() > + && (CodeItemInstructionAccessor(dex_file, code_item).InsnsSizeInCodeUnits() > kSpaceFilterOptimizingThreshold)) { MaybeRecordStat(compilation_stats_.get(), MethodCompilationStat::kNotCompiledSpaceFilter); return nullptr; } - CodeItemDebugInfoAccessor code_item_accessor(&dex_file, code_item); + CodeItemDebugInfoAccessor code_item_accessor(dex_file, code_item); HGraph* graph = new (allocator) HGraph( allocator, arena_stack, diff --git a/compiler/optimizing/optimizing_unit_test.h b/compiler/optimizing/optimizing_unit_test.h index 661abb125c..8c97d57f4a 100644 --- a/compiler/optimizing/optimizing_unit_test.h +++ b/compiler/optimizing/optimizing_unit_test.h @@ -146,7 +146,7 @@ class OptimizingUnitTest : public CommonCompilerTest { /* access_flags */ 0u, /* verified_method */ nullptr, handles_->NewHandle<mirror::DexCache>(nullptr)); - CodeItemDebugInfoAccessor accessor(&graph->GetDexFile(), code_item); + CodeItemDebugInfoAccessor accessor(graph->GetDexFile(), code_item); HGraphBuilder builder(graph, dex_compilation_unit, accessor, handles_.get(), return_type); bool graph_built = (builder.BuildGraph() == kAnalysisSuccess); return graph_built ? graph : nullptr; diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc index c91240e19d..f817def4e1 100644 --- a/dex2oat/dex2oat_test.cc +++ b/dex2oat/dex2oat_test.cc @@ -944,7 +944,7 @@ class Dex2oatUnquickenTest : public Dex2oatTest { class_it.Next()) { if (class_it.IsAtMethod() && class_it.GetMethodCodeItem() != nullptr) { for (const DexInstructionPcPair& inst : - CodeItemInstructionAccessor(dex_file.get(), class_it.GetMethodCodeItem())) { + CodeItemInstructionAccessor(*dex_file, class_it.GetMethodCodeItem())) { ASSERT_FALSE(inst->IsQuickened()); } } diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc index cb1b80d590..16d70daddf 100644 --- a/dex2oat/linker/oat_writer.cc +++ b/dex2oat/linker/oat_writer.cc @@ -2696,7 +2696,7 @@ class OatWriter::WriteQuickeningIndicesMethodVisitor { CompiledMethod* compiled_method = driver.GetCompiledMethod(MethodReference(dex_file, method_idx)); const DexFile::CodeItem* code_item = class_it.GetMethodCodeItem(); - CodeItemDebugInfoAccessor accessor(dex_file, code_item); + CodeItemDebugInfoAccessor accessor(*dex_file, code_item); const uint32_t existing_debug_info_offset = accessor.DebugInfoOffset(); // If the existing offset is already out of bounds (and not magic marker 0xFFFFFFFF) // we will pretend the method has been quickened. diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc index 8a06f44628..2c98e12741 100644 --- a/dexdump/dexdump.cc +++ b/dexdump/dexdump.cc @@ -736,7 +736,7 @@ static void dumpInterface(const DexFile* pDexFile, const DexFile::TypeItem& pTyp * Dumps the catches table associated with the code. */ static void dumpCatches(const DexFile* pDexFile, const DexFile::CodeItem* pCode) { - CodeItemDataAccessor accessor(pDexFile, pCode); + CodeItemDataAccessor accessor(*pDexFile, pCode); const u4 triesSize = accessor.TriesSize(); // No catch table. @@ -951,7 +951,7 @@ static void dumpInstruction(const DexFile* pDexFile, fprintf(gOutFile, "%06x:", codeOffset + 0x10 + insnIdx * 2); // Dump (part of) raw bytes. - CodeItemInstructionAccessor accessor(pDexFile, pCode); + CodeItemInstructionAccessor accessor(*pDexFile, pCode); for (u4 i = 0; i < 8; i++) { if (i < insnWidth) { if (i == 7) { @@ -1169,7 +1169,7 @@ static void dumpBytecodes(const DexFile* pDexFile, u4 idx, codeOffset, codeOffset, dot.get(), name, signature.ToString().c_str()); // Iterate over all instructions. - CodeItemDataAccessor accessor(pDexFile, pCode); + CodeItemDataAccessor accessor(*pDexFile, pCode); for (const DexInstructionPcPair& pair : accessor) { const Instruction* instruction = &pair.Inst(); const u4 insnWidth = instruction->SizeInCodeUnits(); @@ -1186,7 +1186,7 @@ static void dumpBytecodes(const DexFile* pDexFile, u4 idx, */ static void dumpCode(const DexFile* pDexFile, u4 idx, u4 flags, const DexFile::CodeItem* pCode, u4 codeOffset) { - CodeItemDebugInfoAccessor accessor(pDexFile, pCode, pDexFile->GetDebugInfoOffset(pCode)); + CodeItemDebugInfoAccessor accessor(*pDexFile, pCode, pDexFile->GetDebugInfoOffset(pCode)); fprintf(gOutFile, " registers : %d\n", accessor.RegistersSize()); fprintf(gOutFile, " ins : %d\n", accessor.InsSize()); diff --git a/dexdump/dexdump_cfg.cc b/dexdump/dexdump_cfg.cc index f08ea746d3..0e313572bc 100644 --- a/dexdump/dexdump_cfg.cc +++ b/dexdump/dexdump_cfg.cc @@ -39,7 +39,7 @@ static void dumpMethodCFGImpl(const DexFile* dex_file, os << "digraph {\n"; os << " # /* " << dex_file->PrettyMethod(dex_method_idx, true) << " */\n"; - CodeItemDataAccessor accessor(dex_file, code_item); + CodeItemDataAccessor accessor(*dex_file, code_item); std::set<uint32_t> dex_pc_is_branch_target; { diff --git a/dexlayout/dex_ir.cc b/dexlayout/dex_ir.cc index 8ed3a79542..2191ea601f 100644 --- a/dexlayout/dex_ir.cc +++ b/dexlayout/dex_ir.cc @@ -567,7 +567,7 @@ ParameterAnnotation* Collections::GenerateParameterAnnotation( CodeItem* Collections::CreateCodeItem(const DexFile& dex_file, const DexFile::CodeItem& disk_code_item, uint32_t offset) { - CodeItemDebugInfoAccessor accessor(&dex_file, &disk_code_item); + CodeItemDebugInfoAccessor accessor(dex_file, &disk_code_item); const uint16_t registers_size = accessor.RegistersSize(); const uint16_t ins_size = accessor.InsSize(); const uint16_t outs_size = accessor.OutsSize(); diff --git a/dexlayout/dexlayout_test.cc b/dexlayout/dexlayout_test.cc index b8cff6dc59..5da3b1d366 100644 --- a/dexlayout/dexlayout_test.cc +++ b/dexlayout/dexlayout_test.cc @@ -699,7 +699,7 @@ TEST_F(DexLayoutTest, CodeItemOverrun) { while (it.HasNextMethod()) { DexFile::CodeItem* item = const_cast<DexFile::CodeItem*>(it.GetMethodCodeItem()); if (item != nullptr) { - CodeItemInstructionAccessor instructions(dex, item); + CodeItemInstructionAccessor instructions(*dex, item); if (instructions.begin() != instructions.end()) { DexInstructionIterator last_instruction = instructions.begin(); for (auto dex_it = instructions.begin(); dex_it != instructions.end(); ++dex_it) { diff --git a/dexlist/dexlist.cc b/dexlist/dexlist.cc index 348f501ef5..556938b563 100644 --- a/dexlist/dexlist.cc +++ b/dexlist/dexlist.cc @@ -100,7 +100,7 @@ static void dumpMethod(const DexFile* pDexFile, if (pCode == nullptr || codeOffset == 0) { return; } - CodeItemDebugInfoAccessor accessor(pDexFile, pCode, pDexFile->GetDebugInfoOffset(pCode)); + CodeItemDebugInfoAccessor accessor(*pDexFile, pCode, pDexFile->GetDebugInfoOffset(pCode)); // Method information. const DexFile::MethodId& pMethodId = pDexFile->GetMethodId(idx); diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 6a99c5ab2f..ca8077fea1 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -993,7 +993,7 @@ class OatDumper { if (code_item == nullptr) { return; } - CodeItemInstructionAccessor instructions(&dex_file, code_item); + CodeItemInstructionAccessor instructions(dex_file, code_item); // If we inserted a new dex code item pointer, add to total code bytes. const uint16_t* code_ptr = instructions.Insns(); @@ -1261,7 +1261,7 @@ class OatDumper { bool* addr_found) { bool success = true; - CodeItemDataAccessor code_item_accessor(&dex_file, code_item); + CodeItemDataAccessor code_item_accessor(dex_file, code_item); // TODO: Support regex std::string method_name = dex_file.GetMethodName(dex_file.GetMethodId(dex_method_idx)); diff --git a/profman/profman.cc b/profman/profman.cc index 71f7f9d669..c4216fab99 100644 --- a/profman/profman.cc +++ b/profman/profman.cc @@ -727,7 +727,7 @@ class ProfMan FINAL { const DexFile::CodeItem* code_item = dex_file->GetCodeItem(offset); bool found_invoke = false; - for (const DexInstructionPcPair& inst : CodeItemInstructionAccessor(dex_file, code_item)) { + for (const DexInstructionPcPair& inst : CodeItemInstructionAccessor(*dex_file, code_item)) { if (inst->Opcode() == Instruction::INVOKE_VIRTUAL) { if (found_invoke) { LOG(ERROR) << "Multiple invoke INVOKE_VIRTUAL found: " diff --git a/runtime/dex/code_item_accessors-inl.h b/runtime/dex/code_item_accessors-inl.h index 2fdf262b7d..2792dc0663 100644 --- a/runtime/dex/code_item_accessors-inl.h +++ b/runtime/dex/code_item_accessors-inl.h @@ -28,20 +28,20 @@ namespace art { inline CodeItemInstructionAccessor::CodeItemInstructionAccessor(ArtMethod* method) - : CodeItemInstructionAccessor(method->GetDexFile(), method->GetCodeItem()) {} + : CodeItemInstructionAccessor(*method->GetDexFile(), method->GetCodeItem()) {} inline CodeItemDataAccessor::CodeItemDataAccessor(ArtMethod* method) - : CodeItemDataAccessor(method->GetDexFile(), method->GetCodeItem()) {} + : CodeItemDataAccessor(*method->GetDexFile(), method->GetCodeItem()) {} inline CodeItemDebugInfoAccessor::CodeItemDebugInfoAccessor(ArtMethod* method) - : CodeItemDebugInfoAccessor(method->GetDexFile(), method->GetCodeItem()) {} + : CodeItemDebugInfoAccessor(*method->GetDexFile(), method->GetCodeItem()) {} -inline CodeItemDebugInfoAccessor::CodeItemDebugInfoAccessor(const DexFile* dex_file, +inline CodeItemDebugInfoAccessor::CodeItemDebugInfoAccessor(const DexFile& dex_file, const DexFile::CodeItem* code_item) { if (code_item == nullptr) { return; } - Init(dex_file, code_item, OatFile::GetDebugInfoOffset(*dex_file, code_item->debug_info_off_)); + Init(dex_file, code_item, OatFile::GetDebugInfoOffset(dex_file, code_item->debug_info_off_)); } } // namespace art diff --git a/runtime/dex/code_item_accessors-no_art-inl.h b/runtime/dex/code_item_accessors-no_art-inl.h index 016923d035..baea856e71 100644 --- a/runtime/dex/code_item_accessors-no_art-inl.h +++ b/runtime/dex/code_item_accessors-no_art-inl.h @@ -36,22 +36,21 @@ inline void CodeItemInstructionAccessor::Init(const StandardDexFile::CodeItem& c insns_ = code_item.insns_; } -inline void CodeItemInstructionAccessor::Init(const DexFile* dex_file, +inline void CodeItemInstructionAccessor::Init(const DexFile& dex_file, const DexFile::CodeItem* code_item) { if (code_item != nullptr) { - DCHECK(dex_file->HasAddress(code_item)); - DCHECK(dex_file != nullptr); - if (dex_file->IsCompactDexFile()) { + DCHECK(dex_file.HasAddress(code_item)); + if (dex_file.IsCompactDexFile()) { Init(down_cast<const CompactDexFile::CodeItem&>(*code_item)); } else { - DCHECK(dex_file->IsStandardDexFile()); + DCHECK(dex_file.IsStandardDexFile()); Init(down_cast<const StandardDexFile::CodeItem&>(*code_item)); } } } inline CodeItemInstructionAccessor::CodeItemInstructionAccessor( - const DexFile* dex_file, + const DexFile& dex_file, const DexFile::CodeItem* code_item) { Init(dex_file, code_item); } @@ -88,20 +87,19 @@ inline void CodeItemDataAccessor::Init(const StandardDexFile::CodeItem& code_ite tries_size_ = code_item.tries_size_; } -inline void CodeItemDataAccessor::Init(const DexFile* dex_file, +inline void CodeItemDataAccessor::Init(const DexFile& dex_file, const DexFile::CodeItem* code_item) { if (code_item != nullptr) { - DCHECK(dex_file != nullptr); - if (dex_file->IsCompactDexFile()) { + if (dex_file.IsCompactDexFile()) { CodeItemDataAccessor::Init(down_cast<const CompactDexFile::CodeItem&>(*code_item)); } else { - DCHECK(dex_file->IsStandardDexFile()); + DCHECK(dex_file.IsStandardDexFile()); CodeItemDataAccessor::Init(down_cast<const StandardDexFile::CodeItem&>(*code_item)); } } } -inline CodeItemDataAccessor::CodeItemDataAccessor(const DexFile* dex_file, +inline CodeItemDataAccessor::CodeItemDataAccessor(const DexFile& dex_file, const DexFile::CodeItem* code_item) { Init(dex_file, code_item); } @@ -125,15 +123,36 @@ inline const DexFile::TryItem* CodeItemDataAccessor::FindTryItem(uint32_t try_de return index != -1 ? &try_items.begin()[index] : nullptr; } -inline void CodeItemDebugInfoAccessor::Init(const DexFile* dex_file, +inline const void* CodeItemDataAccessor::CodeItemDataEnd() const { + const uint8_t* handler_data = GetCatchHandlerData(); + + if (TriesSize() == 0 || handler_data == nullptr) { + return &end().Inst(); + } + // Get the start of the handler data. + const 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<const void*>(handler_data); +} + +inline void CodeItemDebugInfoAccessor::Init(const DexFile& dex_file, const DexFile::CodeItem* code_item, uint32_t debug_info_offset) { - dex_file_ = dex_file; + dex_file_ = &dex_file; debug_info_offset_ = debug_info_offset; - if (dex_file->IsCompactDexFile()) { + if (dex_file.IsCompactDexFile()) { Init(down_cast<const CompactDexFile::CodeItem&>(*code_item)); } else { - DCHECK(dex_file->IsStandardDexFile()); + DCHECK(dex_file.IsStandardDexFile()); Init(down_cast<const StandardDexFile::CodeItem&>(*code_item)); } } diff --git a/runtime/dex/code_item_accessors.h b/runtime/dex/code_item_accessors.h index 65cc0bf996..b5a6957548 100644 --- a/runtime/dex/code_item_accessors.h +++ b/runtime/dex/code_item_accessors.h @@ -33,7 +33,7 @@ class ArtMethod; // StandardDexFile. class CodeItemInstructionAccessor { public: - ALWAYS_INLINE CodeItemInstructionAccessor(const DexFile* dex_file, + ALWAYS_INLINE CodeItemInstructionAccessor(const DexFile& dex_file, const DexFile::CodeItem* code_item); ALWAYS_INLINE explicit CodeItemInstructionAccessor(ArtMethod* method); @@ -68,7 +68,7 @@ class CodeItemInstructionAccessor { ALWAYS_INLINE void Init(const CompactDexFile::CodeItem& code_item); ALWAYS_INLINE void Init(const StandardDexFile::CodeItem& code_item); - ALWAYS_INLINE void Init(const DexFile* dex_file, const DexFile::CodeItem* code_item); + ALWAYS_INLINE void Init(const DexFile& dex_file, const DexFile::CodeItem* code_item); private: // size of the insns array, in 2 byte code units. 0 if there is no code item. @@ -82,7 +82,7 @@ class CodeItemInstructionAccessor { // StandardDexFile. class CodeItemDataAccessor : public CodeItemInstructionAccessor { public: - ALWAYS_INLINE CodeItemDataAccessor(const DexFile* dex_file, const DexFile::CodeItem* code_item); + ALWAYS_INLINE CodeItemDataAccessor(const DexFile& dex_file, const DexFile::CodeItem* code_item); ALWAYS_INLINE explicit CodeItemDataAccessor(ArtMethod* method); @@ -108,12 +108,14 @@ class CodeItemDataAccessor : public CodeItemInstructionAccessor { const DexFile::TryItem* FindTryItem(uint32_t try_dex_pc) const; + inline const void* CodeItemDataEnd() const; + protected: CodeItemDataAccessor() = default; ALWAYS_INLINE void Init(const CompactDexFile::CodeItem& code_item); ALWAYS_INLINE void Init(const StandardDexFile::CodeItem& code_item); - ALWAYS_INLINE void Init(const DexFile* dex_file, const DexFile::CodeItem* code_item); + ALWAYS_INLINE void Init(const DexFile& dex_file, const DexFile::CodeItem* code_item); private: // Fields mirrored from the dex/cdex code item. @@ -130,17 +132,17 @@ class CodeItemDebugInfoAccessor : public CodeItemDataAccessor { CodeItemDebugInfoAccessor() = default; // Handles null code items, but not null dex files. - ALWAYS_INLINE CodeItemDebugInfoAccessor(const DexFile* dex_file, + ALWAYS_INLINE CodeItemDebugInfoAccessor(const DexFile& dex_file, const DexFile::CodeItem* code_item); // Initialize with an existing offset. - ALWAYS_INLINE CodeItemDebugInfoAccessor(const DexFile* dex_file, + 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, + ALWAYS_INLINE void Init(const DexFile& dex_file, const DexFile::CodeItem* code_item, uint32_t debug_info_offset); diff --git a/runtime/dex/code_item_accessors_test.cc b/runtime/dex/code_item_accessors_test.cc index 57a5573d8d..b29d10b113 100644 --- a/runtime/dex/code_item_accessors_test.cc +++ b/runtime/dex/code_item_accessors_test.cc @@ -71,12 +71,12 @@ TEST(CodeItemAccessorsTest, TestDexInstructionsAccessor) { auto verify_code_item = [&](const DexFile* dex, const DexFile::CodeItem* item, const uint16_t* insns) { - CodeItemInstructionAccessor insns_accessor(dex, item); + CodeItemInstructionAccessor insns_accessor(*dex, item); EXPECT_TRUE(insns_accessor.HasCodeItem()); ASSERT_EQ(insns_accessor.InsnsSizeInCodeUnits(), kInsnsSizeInCodeUnits); EXPECT_EQ(insns_accessor.Insns(), insns); - CodeItemDataAccessor data_accessor(dex, item); + CodeItemDataAccessor data_accessor(*dex, item); EXPECT_TRUE(data_accessor.HasCodeItem()); EXPECT_EQ(data_accessor.InsnsSizeInCodeUnits(), kInsnsSizeInCodeUnits); EXPECT_EQ(data_accessor.Insns(), insns); diff --git a/runtime/dex/compact_dex_file.cc b/runtime/dex/compact_dex_file.cc index 8f90e098bb..2d1ee0420e 100644 --- a/runtime/dex/compact_dex_file.cc +++ b/runtime/dex/compact_dex_file.cc @@ -16,6 +16,7 @@ #include "compact_dex_file.h" +#include "code_item_accessors-no_art-inl.h" #include "dex_file-inl.h" #include "leb128.h" @@ -58,33 +59,8 @@ 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; - } + return reinterpret_cast<uintptr_t>(CodeItemDataAccessor(*this, &item).CodeItemDataEnd()) - + reinterpret_cast<uintptr_t>(&item); } } // namespace art diff --git a/runtime/dex/dex_file_test.cc b/runtime/dex/dex_file_test.cc index 87eec571f1..3ee115c01b 100644 --- a/runtime/dex/dex_file_test.cc +++ b/runtime/dex/dex_file_test.cc @@ -731,7 +731,7 @@ TEST_F(DexFileTest, OpenDexDebugInfoLocalNullType) { kRawDexDebugInfoLocalNullType, tmp.GetFilename().c_str(), 0xf25f2b38U, true); const DexFile::ClassDef& class_def = raw->GetClassDef(0); const DexFile::CodeItem* code_item = raw->GetCodeItem(raw->FindCodeItemOffset(class_def, 1)); - CodeItemDebugInfoAccessor accessor(raw.get(), code_item); + CodeItemDebugInfoAccessor accessor(*raw, code_item); ASSERT_TRUE(accessor.DecodeDebugLocalInfo(true, 1, Callback, nullptr)); } diff --git a/runtime/dex/dex_file_tracking_registrar.cc b/runtime/dex/dex_file_tracking_registrar.cc index bffca5599a..78ea9c16cb 100644 --- a/runtime/dex/dex_file_tracking_registrar.cc +++ b/runtime/dex/dex_file_tracking_registrar.cc @@ -185,7 +185,7 @@ void DexFileTrackingRegistrar::SetAllCodeItemStartRegistration(bool should_poiso if (code_item != nullptr) { const void* code_item_begin = reinterpret_cast<const void*>(code_item); size_t code_item_start = reinterpret_cast<size_t>(code_item); - CodeItemInstructionAccessor accessor(dex_file_, code_item); + CodeItemInstructionAccessor accessor(*dex_file_, code_item); size_t code_item_start_end = reinterpret_cast<size_t>(accessor.Insns()); size_t code_item_start_size = code_item_start_end - code_item_start; range_values_.push_back(std::make_tuple(code_item_begin, @@ -208,7 +208,7 @@ void DexFileTrackingRegistrar::SetAllInsnsRegistration(bool should_poison) { while (cdit.HasNextMethod()) { const DexFile::CodeItem* code_item = cdit.GetMethodCodeItem(); if (code_item != nullptr) { - CodeItemInstructionAccessor accessor(dex_file_, code_item); + CodeItemInstructionAccessor accessor(*dex_file_, code_item); const void* insns_begin = reinterpret_cast<const void*>(accessor.Insns()); // Member insns_size_in_code_units_ is in 2-byte units size_t insns_size = accessor.InsnsSizeInCodeUnits() * 2; diff --git a/runtime/dex/dex_file_verifier.cc b/runtime/dex/dex_file_verifier.cc index d6f685a595..c2f772ef25 100644 --- a/runtime/dex/dex_file_verifier.cc +++ b/runtime/dex/dex_file_verifier.cc @@ -580,7 +580,7 @@ uint32_t DexFileVerifier::ReadUnsignedLittleEndian(uint32_t size) { bool DexFileVerifier::CheckAndGetHandlerOffsets(const DexFile::CodeItem* code_item, uint32_t* handler_offsets, uint32_t handlers_size) { - CodeItemDataAccessor accessor(dex_file_, code_item); + CodeItemDataAccessor accessor(*dex_file_, code_item); const uint8_t* handlers_base = accessor.GetCatchHandlerData(); for (uint32_t i = 0; i < handlers_size; i++) { @@ -1233,7 +1233,7 @@ bool DexFileVerifier::CheckIntraCodeItem() { return false; } - CodeItemDataAccessor accessor(dex_file_, code_item); + CodeItemDataAccessor accessor(*dex_file_, code_item); if (UNLIKELY(accessor.InsSize() > accessor.RegistersSize())) { ErrorStringPrintf("ins_size (%ud) > registers_size (%ud)", accessor.InsSize(), accessor.RegistersSize()); diff --git a/runtime/dex/standard_dex_file.cc b/runtime/dex/standard_dex_file.cc index 843508d831..52fdff303b 100644 --- a/runtime/dex/standard_dex_file.cc +++ b/runtime/dex/standard_dex_file.cc @@ -17,6 +17,7 @@ #include "standard_dex_file.h" #include "base/casts.h" +#include "code_item_accessors-no_art-inl.h" #include "dex_file-inl.h" #include "leb128.h" @@ -73,33 +74,11 @@ bool StandardDexFile::SupportsDefaultMethods() const { 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; - } + // TODO: Clean up this temporary code duplication with StandardDexFile. Eventually the + // implementations will differ. + DCHECK(HasAddress(&item)); + return reinterpret_cast<uintptr_t>(CodeItemDataAccessor(*this, &item).CodeItemDataEnd()) - + reinterpret_cast<uintptr_t>(&item); } } // namespace art diff --git a/runtime/dex_to_dex_decompiler.cc b/runtime/dex_to_dex_decompiler.cc index f3f2d52cb4..e1c07baede 100644 --- a/runtime/dex_to_dex_decompiler.cc +++ b/runtime/dex_to_dex_decompiler.cc @@ -35,7 +35,7 @@ class DexDecompiler { 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) {} diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index 2183b60b1e..416ada84cd 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -569,7 +569,7 @@ MethodVerifier::MethodVerifier(Thread* self, dex_cache_(dex_cache), class_loader_(class_loader), class_def_(class_def), - code_item_accessor_(dex_file, code_item), + code_item_accessor_(*dex_file, code_item), declaring_class_(nullptr), interesting_dex_pc_(-1), monitor_enter_dex_pcs_(nullptr), diff --git a/test/983-source-transform-verify/source_transform.cc b/test/983-source-transform-verify/source_transform.cc index 55dc603c4f..e9cb35e944 100644 --- a/test/983-source-transform-verify/source_transform.cc +++ b/test/983-source-transform-verify/source_transform.cc @@ -90,7 +90,7 @@ void JNICALL CheckDexFileHook(jvmtiEnv* jvmti_env ATTRIBUTE_UNUSED, continue; } for (const DexInstructionPcPair& pair : - art::CodeItemInstructionAccessor(dex.get(), it.GetMethodCodeItem())) { + art::CodeItemInstructionAccessor(*dex, it.GetMethodCodeItem())) { const Instruction& inst = pair.Inst(); int forbiden_flags = (Instruction::kVerifyError | Instruction::kVerifyRuntimeOnly); if (inst.Opcode() == Instruction::RETURN_VOID_NO_BARRIER || |