diff options
author | 2017-11-07 00:08:52 -0800 | |
---|---|---|
committer | 2017-11-07 13:15:41 -0800 | |
commit | 0021feb36ca7021e2c255e6eaf16b967180290c6 (patch) | |
tree | 43f1ce8f6d91630a831d03b51a465d57c2a47119 | |
parent | 550c0aee52bf8981dfe1d22d3b661d61e80cc7ee (diff) |
Delete CodeItemIterator
Replace uses with DexInstructionIterator.
Bug: 63756964
Test: test-art-host-gtest
Change-Id: I28c839c372edcb60583867355d46b14f8752d41b
-rw-r--r-- | compiler/dex/dex_to_dex_compiler.cc | 13 | ||||
-rw-r--r-- | compiler/optimizing/block_builder.cc | 28 | ||||
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 21 | ||||
-rw-r--r-- | dex2oat/dex2oat_test.cc | 4 | ||||
-rw-r--r-- | profman/profman.cc | 6 | ||||
-rw-r--r-- | runtime/bytecode_utils.h | 33 | ||||
-rw-r--r-- | runtime/dex_file.h | 5 | ||||
-rw-r--r-- | runtime/dex_instruction_iterator.h | 3 | ||||
-rw-r--r-- | runtime/dex_to_dex_decompiler.cc | 4 | ||||
-rw-r--r-- | test/983-source-transform-verify/source_transform.cc | 6 |
10 files changed, 47 insertions, 76 deletions
diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc index a94dbe94ff..cc452fc1ae 100644 --- a/compiler/dex/dex_to_dex_compiler.cc +++ b/compiler/dex/dex_to_dex_compiler.cc @@ -112,9 +112,10 @@ class DexCompiler { void DexCompiler::Compile() { DCHECK_EQ(dex_to_dex_compilation_level_, DexToDexCompilationLevel::kOptimize); - for (CodeItemIterator it(*unit_.GetCodeItem()); !it.Done(); it.Advance()) { - Instruction* inst = const_cast<Instruction*>(&it.CurrentInstruction()); - const uint32_t dex_pc = it.CurrentDexPc(); + IterationRange<DexInstructionIterator> instructions = unit_.GetCodeItem()->Instructions(); + for (DexInstructionIterator it = instructions.begin(); it != instructions.end(); ++it) { + const uint32_t dex_pc = it.DexPc(); + Instruction* inst = const_cast<Instruction*>(&it.Inst()); switch (inst->Opcode()) { case Instruction::RETURN_VOID: CompileReturnVoid(inst, dex_pc); @@ -125,7 +126,7 @@ void DexCompiler::Compile() { if (inst->Opcode() == Instruction::NOP) { // We turned the CHECK_CAST into two NOPs, avoid visiting the second NOP twice since this // would add 2 quickening info entries. - it.Advance(); + ++it; } break; @@ -362,8 +363,8 @@ CompiledMethod* ArtCompileDEX( if (kIsDebugBuild) { // Double check that the counts line up with the size of the quicken info. size_t quicken_count = 0; - for (CodeItemIterator it(*code_item); !it.Done(); it.Advance()) { - if (QuickenInfoTable::NeedsIndexForInstruction(&it.CurrentInstruction())) { + for (const DexInstructionPcPair& pair : code_item->Instructions()) { + if (QuickenInfoTable::NeedsIndexForInstruction(&pair.Inst())) { ++quicken_count; } } diff --git a/compiler/optimizing/block_builder.cc b/compiler/optimizing/block_builder.cc index d7def774fd..595dd4d226 100644 --- a/compiler/optimizing/block_builder.cc +++ b/compiler/optimizing/block_builder.cc @@ -76,9 +76,10 @@ bool HBasicBlockBuilder::CreateBranchTargets() { // Iterate over all instructions and find branching instructions. Create blocks for // the locations these instructions branch to. - for (CodeItemIterator it(code_item_); !it.Done(); it.Advance()) { - uint32_t dex_pc = it.CurrentDexPc(); - const Instruction& instruction = it.CurrentInstruction(); + IterationRange<DexInstructionIterator> instructions = code_item_.Instructions(); + for (const DexInstructionPcPair& pair : instructions) { + const uint32_t dex_pc = pair.DexPc(); + const Instruction& instruction = pair.Inst(); if (instruction.IsBranch()) { number_of_branches_++; @@ -105,13 +106,13 @@ bool HBasicBlockBuilder::CreateBranchTargets() { } if (instruction.CanFlowThrough()) { - if (it.IsLast()) { + DexInstructionIterator next(std::next(DexInstructionIterator(pair))); + if (next == instructions.end()) { // In the normal case we should never hit this but someone can artificially forge a dex // file to fall-through out the method code. In this case we bail out compilation. return false; - } else { - MaybeCreateBlockAt(dex_pc + it.CurrentInstruction().SizeInCodeUnits()); } + MaybeCreateBlockAt(next.DexPc()); } } @@ -126,8 +127,9 @@ void HBasicBlockBuilder::ConnectBasicBlocks() { bool is_throwing_block = false; // Calculate the qucikening index here instead of CreateBranchTargets since it's easier to // calculate in dex_pc order. - for (CodeItemIterator it(code_item_); !it.Done(); it.Advance()) { - uint32_t dex_pc = it.CurrentDexPc(); + for (const DexInstructionPcPair& pair : code_item_.Instructions()) { + const uint32_t dex_pc = pair.DexPc(); + const Instruction& instruction = pair.Inst(); // Check if this dex_pc address starts a new basic block. HBasicBlock* next_block = GetBlockAt(dex_pc); @@ -144,7 +146,7 @@ void HBasicBlockBuilder::ConnectBasicBlocks() { graph_->AddBlock(block); } // Make sure to increment this before the continues. - if (QuickenInfoTable::NeedsIndexForInstruction(&it.CurrentInstruction())) { + if (QuickenInfoTable::NeedsIndexForInstruction(&instruction)) { ++quicken_index; } @@ -153,8 +155,6 @@ void HBasicBlockBuilder::ConnectBasicBlocks() { continue; } - const Instruction& instruction = it.CurrentInstruction(); - if (!is_throwing_block && IsThrowingDexInstruction(instruction)) { DCHECK(!ContainsElement(throwing_blocks_, block)); is_throwing_block = true; @@ -185,9 +185,9 @@ void HBasicBlockBuilder::ConnectBasicBlocks() { continue; } + // Go to the next instruction in case we read dex PC below. if (instruction.CanFlowThrough()) { - uint32_t next_dex_pc = dex_pc + instruction.SizeInCodeUnits(); - block->AddSuccessor(GetBlockAt(next_dex_pc)); + block->AddSuccessor(GetBlockAt(std::next(DexInstructionIterator(pair)).DexPc())); } // The basic block ends here. Do not add any more instructions. @@ -229,7 +229,7 @@ bool HBasicBlockBuilder::MightHaveLiveNormalPredecessors(HBasicBlock* catch_bloc } } - const Instruction& first = GetDexInstructionAt(code_item_, catch_block->GetDexPc()); + const Instruction& first = code_item_.InstructionAt(catch_block->GetDexPc()); if (first.Opcode() == Instruction::MOVE_EXCEPTION) { // Verifier guarantees that if a catch block begins with MOVE_EXCEPTION then // it has no live normal predecessors. diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 0f0be20961..8e9b818722 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -321,19 +321,19 @@ bool HInstructionBuilder::Build() { quicken_index = block_builder_->GetQuickenIndex(block_dex_pc); } - for (CodeItemIterator it(code_item_, block_dex_pc); !it.Done(); it.Advance()) { + for (const DexInstructionPcPair& pair : code_item_.Instructions(block_dex_pc)) { if (current_block_ == nullptr) { // The previous instruction ended this block. break; } - uint32_t dex_pc = it.CurrentDexPc(); + const uint32_t dex_pc = pair.DexPc(); if (dex_pc != block_dex_pc && FindBlockStartingAt(dex_pc) != nullptr) { // This dex_pc starts a new basic block. break; } - if (current_block_->IsTryBlock() && IsThrowingDexInstruction(it.CurrentInstruction())) { + if (current_block_->IsTryBlock() && IsThrowingDexInstruction(pair.Inst())) { PropagateLocalsToCatchBlocks(); } @@ -341,11 +341,11 @@ bool HInstructionBuilder::Build() { AppendInstruction(new (allocator_) HNativeDebugInfo(dex_pc)); } - if (!ProcessDexInstruction(it.CurrentInstruction(), dex_pc, quicken_index)) { + if (!ProcessDexInstruction(pair.Inst(), dex_pc, quicken_index)) { return false; } - if (QuickenInfoTable::NeedsIndexForInstruction(&it.CurrentInstruction())) { + if (QuickenInfoTable::NeedsIndexForInstruction(&pair.Inst())) { ++quicken_index; } } @@ -382,16 +382,15 @@ ArenaBitVector* HInstructionBuilder::FindNativeDebugInfoLocations() { dex_file_->DecodeDebugPositionInfo(&code_item_, Callback::Position, locations); // Instruction-specific tweaks. IterationRange<DexInstructionIterator> instructions = code_item_.Instructions(); - for (DexInstructionIterator it = instructions.begin(); it != instructions.end(); ++it) { - switch (it->Opcode()) { + for (const DexInstructionPcPair& inst : instructions) { + switch (inst->Opcode()) { case Instruction::MOVE_EXCEPTION: { // Stop in native debugger after the exception has been moved. // The compiler also expects the move at the start of basic block so // we do not want to interfere by inserting native-debug-info before it. - locations->ClearBit(it.DexPc()); - DexInstructionIterator next = it; - ++next; - DCHECK(next != it); + locations->ClearBit(inst.DexPc()); + DexInstructionIterator next = std::next(DexInstructionIterator(inst)); + DCHECK(next.DexPc() != inst.DexPc()); if (next != instructions.end()) { locations->SetBit(next.DexPc()); } diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc index cb91978680..6a2ef1e7ca 100644 --- a/dex2oat/dex2oat_test.cc +++ b/dex2oat/dex2oat_test.cc @@ -940,8 +940,8 @@ class Dex2oatUnquickenTest : public Dex2oatTest { class_it.HasNext(); class_it.Next()) { if (class_it.IsAtMethod() && class_it.GetMethodCodeItem() != nullptr) { - for (CodeItemIterator it(*class_it.GetMethodCodeItem()); !it.Done(); it.Advance()) { - Instruction* inst = const_cast<Instruction*>(&it.CurrentInstruction()); + for (const DexInstructionPcPair& inst : + class_it.GetMethodCodeItem()->Instructions()) { ASSERT_FALSE(inst->IsQuickened()); } } diff --git a/profman/profman.cc b/profman/profman.cc index 4c4bb87e49..ea534f888f 100644 --- a/profman/profman.cc +++ b/profman/profman.cc @@ -725,15 +725,15 @@ class ProfMan FINAL { const DexFile::CodeItem* code_item = dex_file->GetCodeItem(offset); bool found_invoke = false; - for (CodeItemIterator it(*code_item); !it.Done(); it.Advance()) { - if (it.CurrentInstruction().Opcode() == Instruction::INVOKE_VIRTUAL) { + for (const DexInstructionPcPair& inst : code_item->Instructions()) { + if (inst->Opcode() == Instruction::INVOKE_VIRTUAL) { if (found_invoke) { LOG(ERROR) << "Multiple invoke INVOKE_VIRTUAL found: " << dex_file->PrettyMethod(method_index); return false; } found_invoke = true; - *dex_pc = it.CurrentDexPc(); + *dex_pc = inst.DexPc(); } } if (!found_invoke) { diff --git a/runtime/bytecode_utils.h b/runtime/bytecode_utils.h index b6a3c03191..815e0baf27 100644 --- a/runtime/bytecode_utils.h +++ b/runtime/bytecode_utils.h @@ -24,35 +24,6 @@ namespace art { -class CodeItemIterator : public ValueObject { - public: - explicit CodeItemIterator(const DexFile::CodeItem& code_item) : CodeItemIterator(code_item, 0u) {} - CodeItemIterator(const DexFile::CodeItem& code_item, uint32_t start_dex_pc) - : code_ptr_(code_item.insns_ + start_dex_pc), - code_end_(code_item.insns_ + code_item.insns_size_in_code_units_), - dex_pc_(start_dex_pc) {} - - bool Done() const { return code_ptr_ >= code_end_; } - bool IsLast() const { return code_ptr_ + CurrentInstruction().SizeInCodeUnits() >= code_end_; } - - const Instruction& CurrentInstruction() const { return *Instruction::At(code_ptr_); } - uint32_t CurrentDexPc() const { return dex_pc_; } - - void Advance() { - DCHECK(!Done()); - size_t instruction_size = CurrentInstruction().SizeInCodeUnits(); - code_ptr_ += instruction_size; - dex_pc_ += instruction_size; - } - - private: - const uint16_t* code_ptr_; - const uint16_t* const code_end_; - uint32_t dex_pc_; - - DISALLOW_COPY_AND_ASSIGN(CodeItemIterator); -}; - class DexSwitchTable : public ValueObject { public: DexSwitchTable(const Instruction& instruction, uint32_t dex_pc) @@ -164,10 +135,6 @@ class DexSwitchTableIterator { size_t index_; }; -inline const Instruction& GetDexInstructionAt(const DexFile::CodeItem& code_item, uint32_t dex_pc) { - return CodeItemIterator(code_item, dex_pc).CurrentInstruction(); -} - inline bool IsThrowingDexInstruction(const Instruction& instruction) { // Special-case MONITOR_EXIT which is a throwing instruction but the verifier // guarantees that it will never throw. This is necessary to avoid rejecting diff --git a/runtime/dex_file.h b/runtime/dex_file.h index f239edc064..5c9b2585eb 100644 --- a/runtime/dex_file.h +++ b/runtime/dex_file.h @@ -301,8 +301,9 @@ class DexFile { // Raw code_item. struct CodeItem { - IterationRange<DexInstructionIterator> Instructions() const { - return { DexInstructionIterator(insns_, 0u), + IterationRange<DexInstructionIterator> Instructions(uint32_t start_dex_pc = 0u) const { + DCHECK_LE(start_dex_pc, insns_size_in_code_units_); + return { DexInstructionIterator(insns_, start_dex_pc), DexInstructionIterator(insns_, insns_size_in_code_units_) }; } diff --git a/runtime/dex_instruction_iterator.h b/runtime/dex_instruction_iterator.h index f77908cffc..be583a2533 100644 --- a/runtime/dex_instruction_iterator.h +++ b/runtime/dex_instruction_iterator.h @@ -123,6 +123,9 @@ class DexInstructionIterator : public DexInstructionIteratorBase { explicit DexInstructionIterator(const uint16_t* inst, uint32_t dex_pc) : DexInstructionIteratorBase(Instruction::At(inst), dex_pc) {} + explicit DexInstructionIterator(const DexInstructionPcPair& pair) + : DexInstructionIterator(pair.Instructions(), pair.DexPc()) {} + // Value after modification. DexInstructionIterator& operator++() { data_.dex_pc_ += Inst().SizeInCodeUnits(); diff --git a/runtime/dex_to_dex_decompiler.cc b/runtime/dex_to_dex_decompiler.cc index 908405b7ca..a5ebaded5f 100644 --- a/runtime/dex_to_dex_decompiler.cc +++ b/runtime/dex_to_dex_decompiler.cc @@ -89,8 +89,8 @@ bool DexDecompiler::Decompile() { // because the RETURN_VOID quickening is not encoded in the quickening data. Because // unquickening is a rare need and not performance sensitive, it is not worth the // added storage to also add the RETURN_VOID quickening in the quickened data. - for (CodeItemIterator it(code_item_); !it.Done(); it.Advance()) { - Instruction* inst = const_cast<Instruction*>(&it.CurrentInstruction()); + for (const DexInstructionPcPair& pair : code_item_.Instructions()) { + Instruction* inst = const_cast<Instruction*>(&pair.Inst()); switch (inst->Opcode()) { case Instruction::RETURN_VOID_NO_BARRIER: diff --git a/test/983-source-transform-verify/source_transform.cc b/test/983-source-transform-verify/source_transform.cc index ef67acec98..ca3f88b347 100644 --- a/test/983-source-transform-verify/source_transform.cc +++ b/test/983-source-transform-verify/source_transform.cc @@ -89,13 +89,13 @@ void JNICALL CheckDexFileHook(jvmtiEnv* jvmti_env ATTRIBUTE_UNUSED, if (!it.IsAtMethod() || it.GetMethodCodeItem() == nullptr) { continue; } - for (CodeItemIterator code_it(*it.GetMethodCodeItem()); !code_it.Done(); code_it.Advance()) { - const Instruction& inst = code_it.CurrentInstruction(); + for (const DexInstructionPcPair& pair : it.GetMethodCodeItem()->Instructions()) { + const Instruction& inst = pair.Inst(); int forbiden_flags = (Instruction::kVerifyError | Instruction::kVerifyRuntimeOnly); if (inst.Opcode() == Instruction::RETURN_VOID_NO_BARRIER || (inst.GetVerifyExtraFlags() & forbiden_flags) != 0) { std::cout << "Unexpected instruction found in " << dex->PrettyMethod(it.GetMemberIndex()) - << " [Dex PC: 0x" << std::hex << code_it.CurrentDexPc() << std::dec << "] : " + << " [Dex PC: 0x" << std::hex << pair.DexPc() << std::dec << "] : " << inst.DumpString(dex.get()) << std::endl; continue; } |