Refactor DexInstructionIterator
Add a way to get the dex PC for the "for each" use case.
Bug: 67104794
Test: test-art-host
Change-Id: I144c459c9a2a03ec8d56842280338d1f7ce1caf0
diff --git a/compiler/dex/inline_method_analyser.cc b/compiler/dex/inline_method_analyser.cc
index 925863e..518b0ec 100644
--- a/compiler/dex/inline_method_analyser.cc
+++ b/compiler/dex/inline_method_analyser.cc
@@ -302,7 +302,8 @@
uint16_t this_vreg = code_item->registers_size_ - code_item->ins_size_;
uint16_t zero_vreg_mask = 0u;
- for (const Instruction& instruction : code_item->Instructions()) {
+ for (const DexInstructionPcPair& pair : code_item->Instructions()) {
+ const Instruction& instruction = pair.Inst();
if (instruction.Opcode() == Instruction::RETURN_VOID) {
break;
} else if (instruction.Opcode() == Instruction::INVOKE_DIRECT) {
diff --git a/compiler/dex/verified_method.cc b/compiler/dex/verified_method.cc
index 9c5b632..df75e07 100644
--- a/compiler/dex/verified_method.cc
+++ b/compiler/dex/verified_method.cc
@@ -64,12 +64,11 @@
if (method_verifier->HasFailures()) {
return;
}
- IterationRange<DexInstructionIterator> instructions = method_verifier->CodeItem()->Instructions();
- for (auto it = instructions.begin(); it != instructions.end(); ++it) {
- const Instruction& inst = *it;
+ for (const DexInstructionPcPair& pair : method_verifier->CodeItem()->Instructions()) {
+ const Instruction& inst = pair.Inst();
const Instruction::Code code = inst.Opcode();
if (code == Instruction::CHECK_CAST) {
- const uint32_t dex_pc = it.GetDexPC(instructions.begin());
+ const uint32_t dex_pc = pair.DexPc();
if (!method_verifier->GetInstructionFlags(dex_pc).IsVisited()) {
// Do not attempt to quicken this instruction, it's unreachable anyway.
continue;
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 135f9c7..ed3f0d2 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -736,13 +736,13 @@
}
ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
- for (const Instruction& inst : code_item->Instructions()) {
- switch (inst.Opcode()) {
+ for (const DexInstructionPcPair& inst : code_item->Instructions()) {
+ switch (inst->Opcode()) {
case Instruction::CONST_STRING:
case Instruction::CONST_STRING_JUMBO: {
- dex::StringIndex string_index((inst.Opcode() == Instruction::CONST_STRING)
- ? inst.VRegB_21c()
- : inst.VRegB_31c());
+ dex::StringIndex string_index((inst->Opcode() == Instruction::CONST_STRING)
+ ? inst->VRegB_21c()
+ : inst->VRegB_31c());
mirror::String* string = class_linker->ResolveString(dex_file, string_index, dex_cache);
CHECK(string != nullptr) << "Could not allocate a string when forcing determinism";
break;
@@ -2416,14 +2416,14 @@
if (clinit != nullptr) {
const DexFile::CodeItem* code_item = clinit->GetCodeItem();
DCHECK(code_item != nullptr);
- for (const Instruction& inst : code_item->Instructions()) {
- if (inst.Opcode() == Instruction::CONST_STRING) {
+ for (const DexInstructionPcPair& inst : code_item->Instructions()) {
+ if (inst->Opcode() == Instruction::CONST_STRING) {
ObjPtr<mirror::String> s = class_linker->ResolveString(
- *dex_file, dex::StringIndex(inst.VRegB_21c()), h_dex_cache);
+ *dex_file, dex::StringIndex(inst->VRegB_21c()), h_dex_cache);
CHECK(s != nullptr);
- } else if (inst.Opcode() == Instruction::CONST_STRING_JUMBO) {
+ } else if (inst->Opcode() == Instruction::CONST_STRING_JUMBO) {
ObjPtr<mirror::String> s = class_linker->ResolveString(
- *dex_file, dex::StringIndex(inst.VRegB_31c()), h_dex_cache);
+ *dex_file, dex::StringIndex(inst->VRegB_31c()), h_dex_cache);
CHECK(s != nullptr);
}
}
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index b8d1f52..2314251 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -919,10 +919,9 @@
}
ArenaVector<size_t> covered(
loop_headers.size(), 0, graph.GetAllocator()->Adapter(kArenaAllocMisc));
- IterationRange<DexInstructionIterator> instructions = code_item.Instructions();
- for (auto it = instructions.begin(); it != instructions.end(); ++it) {
- const uint32_t dex_pc = it.GetDexPC(instructions.begin());
- const Instruction& instruction = *it;
+ for (const DexInstructionPcPair& pair : code_item.Instructions()) {
+ const uint32_t dex_pc = pair.DexPc();
+ const Instruction& instruction = pair.Inst();
if (instruction.IsBranch()) {
uint32_t target = dex_pc + instruction.GetTargetOffset();
CheckCovers(target, graph, code_info, loop_headers, &covered);
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index 902985e..0f0be20 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -382,16 +382,18 @@
dex_file_->DecodeDebugPositionInfo(&code_item_, Callback::Position, locations);
// Instruction-specific tweaks.
IterationRange<DexInstructionIterator> instructions = code_item_.Instructions();
- for (const Instruction& inst : instructions) {
- switch (inst.Opcode()) {
+ for (DexInstructionIterator it = instructions.begin(); it != instructions.end(); ++it) {
+ switch (it->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(inst.GetDexPc(code_item_.insns_));
- const Instruction* next = inst.Next();
- if (DexInstructionIterator(next) != instructions.end()) {
- locations->SetBit(next->GetDexPc(code_item_.insns_));
+ locations->ClearBit(it.DexPc());
+ DexInstructionIterator next = it;
+ ++next;
+ DCHECK(next != it);
+ if (next != instructions.end()) {
+ locations->SetBit(next.DexPc());
}
break;
}