diff options
author | 2017-09-23 16:11:06 -0700 | |
---|---|---|
committer | 2017-09-27 11:51:53 -0700 | |
commit | 1d2d4ff8570bb88d9d2d4633706fd7f6fb18d75e (patch) | |
tree | cbe67e8e9214828656314117121e8ce906a762ab /compiler | |
parent | e5b35ed787fbfb388d162361310bae5b0e7682a7 (diff) |
Add DexInstructionIterator and use it a few places
Motivation:
Want to start abstracting away dex specific functionality to enable
CompactDex. Adding an iterator will enable CompactDex iteration to
work differently than normal dex iteration.
Will eventually replace CodeItemIterator.
Bug: 63756964
Test: test-art-host
Change-Id: I90e67c1a994b7698aaac0523a82816b0a003fbdc
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/dex/dex_to_dex_compiler.cc | 4 | ||||
-rw-r--r-- | compiler/dex/inline_method_analyser.cc | 46 | ||||
-rw-r--r-- | compiler/dex/verified_method.cc | 17 | ||||
-rw-r--r-- | compiler/driver/compiler_driver.cc | 31 | ||||
-rw-r--r-- | compiler/optimizing/code_generator.cc | 12 | ||||
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 13 |
6 files changed, 52 insertions, 71 deletions
diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc index e49f83f943..7581962a86 100644 --- a/compiler/dex/dex_to_dex_compiler.cc +++ b/compiler/dex/dex_to_dex_compiler.cc @@ -374,8 +374,8 @@ CompiledMethod* ArtCompileDEX( // Dex pc is not serialized, only used for checking the instructions. Since we access the // array based on the index of the quickened instruction, the indexes must line up perfectly. // The reader side uses the NeedsIndexForInstruction function too. - const Instruction* inst = Instruction::At(code_item->insns_ + info.dex_pc); - CHECK(QuickenInfoTable::NeedsIndexForInstruction(inst)) << inst->Opcode(); + const Instruction& inst = code_item->InstructionAt(info.dex_pc); + CHECK(QuickenInfoTable::NeedsIndexForInstruction(&inst)) << inst.Opcode(); // Add the index. quicken_data.push_back(static_cast<uint8_t>(info.dex_member_index >> 0)); quicken_data.push_back(static_cast<uint8_t>(info.dex_member_index >> 8)); diff --git a/compiler/dex/inline_method_analyser.cc b/compiler/dex/inline_method_analyser.cc index c8e3d5edd8..925863ef0e 100644 --- a/compiler/dex/inline_method_analyser.cc +++ b/compiler/dex/inline_method_analyser.cc @@ -64,14 +64,14 @@ class Matcher { private: explicit Matcher(const DexFile::CodeItem* code_item) : code_item_(code_item), - instruction_(Instruction::At(code_item->insns_)), + instruction_(code_item->Instructions().begin()), pos_(0u), mark_(0u) { } static bool DoMatch(const DexFile::CodeItem* code_item, MatchFn* const* pattern, size_t size); const DexFile::CodeItem* const code_item_; - const Instruction* instruction_; + DexInstructionIterator instruction_; size_t pos_; size_t mark_; }; @@ -93,7 +93,7 @@ bool Matcher::Required(Matcher* matcher) { return false; } matcher->pos_ += 1u; - matcher->instruction_ = matcher->instruction_->Next(); + ++matcher->instruction_; return true; } @@ -105,7 +105,7 @@ bool Matcher::Repeated(Matcher* matcher) { return true; } matcher->pos_ = matcher->mark_; - matcher->instruction_ = matcher->instruction_->Next(); + ++matcher->instruction_; return true; } @@ -301,26 +301,27 @@ bool DoAnalyseConstructor(const DexFile::CodeItem* code_item, // Verify the invoke, prevent a few odd cases and collect IPUTs. uint16_t this_vreg = code_item->registers_size_ - code_item->ins_size_; uint16_t zero_vreg_mask = 0u; - for (const Instruction* instruction = Instruction::At(code_item->insns_); - instruction->Opcode() != Instruction::RETURN_VOID; - instruction = instruction->Next()) { - if (instruction->Opcode() == Instruction::INVOKE_DIRECT) { - ArtMethod* target_method = GetTargetConstructor(method, instruction); + + for (const Instruction& instruction : code_item->Instructions()) { + if (instruction.Opcode() == Instruction::RETURN_VOID) { + break; + } else if (instruction.Opcode() == Instruction::INVOKE_DIRECT) { + ArtMethod* target_method = GetTargetConstructor(method, &instruction); if (target_method == nullptr) { return false; } // We allow forwarding constructors only if they pass more arguments // to prevent infinite recursion. if (target_method->GetDeclaringClass() == method->GetDeclaringClass() && - instruction->VRegA_35c() <= code_item->ins_size_) { + instruction.VRegA_35c() <= code_item->ins_size_) { return false; } - size_t forwarded = CountForwardedConstructorArguments(code_item, instruction, zero_vreg_mask); + size_t forwarded = CountForwardedConstructorArguments(code_item, &instruction, zero_vreg_mask); if (forwarded == static_cast<size_t>(-1)) { return false; } if (target_method->GetDeclaringClass()->IsObjectClass()) { - DCHECK_EQ(Instruction::At(target_method->GetCodeItem()->insns_)->Opcode(), + DCHECK_EQ(target_method->GetCodeItem()->Instructions().begin()->Opcode(), Instruction::RETURN_VOID); } else { const DexFile::CodeItem* target_code_item = target_method->GetCodeItem(); @@ -345,15 +346,15 @@ bool DoAnalyseConstructor(const DexFile::CodeItem* code_item, return false; } } - } else if (IsInstructionDirectConst(instruction->Opcode())) { - zero_vreg_mask |= GetZeroVRegMask(instruction); + } else if (IsInstructionDirectConst(instruction.Opcode())) { + zero_vreg_mask |= GetZeroVRegMask(&instruction); if ((zero_vreg_mask & (1u << this_vreg)) != 0u) { return false; // Overwriting `this` is unsupported. } } else { - DCHECK(IsInstructionIPut(instruction->Opcode())); - DCHECK_EQ(instruction->VRegB_22c(), this_vreg); - if (!RecordConstructorIPut(method, instruction, this_vreg, zero_vreg_mask, iputs)) { + DCHECK(IsInstructionIPut(instruction.Opcode())); + DCHECK_EQ(instruction.VRegB_22c(), this_vreg); + if (!RecordConstructorIPut(method, &instruction, this_vreg, zero_vreg_mask, iputs)) { return false; } } @@ -447,8 +448,7 @@ bool InlineMethodAnalyser::AnalyseMethodCode(const DexFile::CodeItem* code_item, // We currently support only plain return or 2-instruction methods. DCHECK_NE(code_item->insns_size_in_code_units_, 0u); - const Instruction* instruction = Instruction::At(code_item->insns_); - Instruction::Code opcode = instruction->Opcode(); + Instruction::Code opcode = code_item->Instructions().begin()->Opcode(); switch (opcode) { case Instruction::RETURN_VOID: @@ -519,7 +519,7 @@ bool InlineMethodAnalyser::IsSyntheticAccessor(MethodReference ref) { bool InlineMethodAnalyser::AnalyseReturnMethod(const DexFile::CodeItem* code_item, InlineMethod* result) { - const Instruction* return_instruction = Instruction::At(code_item->insns_); + DexInstructionIterator return_instruction = code_item->Instructions().begin(); Instruction::Code return_opcode = return_instruction->Opcode(); uint32_t reg = return_instruction->VRegA_11x(); uint32_t arg_start = code_item->registers_size_ - code_item->ins_size_; @@ -541,7 +541,7 @@ bool InlineMethodAnalyser::AnalyseReturnMethod(const DexFile::CodeItem* code_ite bool InlineMethodAnalyser::AnalyseConstMethod(const DexFile::CodeItem* code_item, InlineMethod* result) { - const Instruction* instruction = Instruction::At(code_item->insns_); + DexInstructionIterator instruction = code_item->Instructions().begin(); const Instruction* return_instruction = instruction->Next(); Instruction::Code return_opcode = return_instruction->Opcode(); if (return_opcode != Instruction::RETURN && @@ -575,7 +575,7 @@ bool InlineMethodAnalyser::AnalyseIGetMethod(const DexFile::CodeItem* code_item, bool is_static, ArtMethod* method, InlineMethod* result) { - const Instruction* instruction = Instruction::At(code_item->insns_); + DexInstructionIterator instruction = code_item->Instructions().begin(); Instruction::Code opcode = instruction->Opcode(); DCHECK(IsInstructionIGet(opcode)); @@ -639,7 +639,7 @@ bool InlineMethodAnalyser::AnalyseIPutMethod(const DexFile::CodeItem* code_item, bool is_static, ArtMethod* method, InlineMethod* result) { - const Instruction* instruction = Instruction::At(code_item->insns_); + DexInstructionIterator instruction = code_item->Instructions().begin(); Instruction::Code opcode = instruction->Opcode(); DCHECK(IsInstructionIPut(opcode)); diff --git a/compiler/dex/verified_method.cc b/compiler/dex/verified_method.cc index e46dc597fa..9c5b63232e 100644 --- a/compiler/dex/verified_method.cc +++ b/compiler/dex/verified_method.cc @@ -64,24 +64,21 @@ void VerifiedMethod::GenerateSafeCastSet(verifier::MethodVerifier* method_verifi if (method_verifier->HasFailures()) { return; } - const DexFile::CodeItem* code_item = method_verifier->CodeItem(); - const Instruction* inst = Instruction::At(code_item->insns_); - const Instruction* end = Instruction::At(code_item->insns_ + - code_item->insns_size_in_code_units_); - - for (; inst < end; inst = inst->Next()) { - Instruction::Code code = inst->Opcode(); + IterationRange<DexInstructionIterator> instructions = method_verifier->CodeItem()->Instructions(); + for (auto it = instructions.begin(); it != instructions.end(); ++it) { + const Instruction& inst = *it; + const Instruction::Code code = inst.Opcode(); if (code == Instruction::CHECK_CAST) { - uint32_t dex_pc = inst->GetDexPc(code_item->insns_); + const uint32_t dex_pc = it.GetDexPC(instructions.begin()); if (!method_verifier->GetInstructionFlags(dex_pc).IsVisited()) { // Do not attempt to quicken this instruction, it's unreachable anyway. continue; } const verifier::RegisterLine* line = method_verifier->GetRegLine(dex_pc); const verifier::RegType& reg_type(line->GetRegisterType(method_verifier, - inst->VRegA_21c())); + inst.VRegA_21c())); const verifier::RegType& cast_type = - method_verifier->ResolveCheckedClass(dex::TypeIndex(inst->VRegB_21c())); + method_verifier->ResolveCheckedClass(dex::TypeIndex(inst.VRegB_21c())); // Pass null for the method verifier to not record the VerifierDeps dependency // if the types are not assignable. if (cast_type.IsStrictlyAssignableFrom(reg_type, /* method_verifier */ nullptr)) { diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 03d8ef5915..7573367788 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -762,18 +762,14 @@ static void ResolveConstStrings(Handle<mirror::DexCache> dex_cache, return; } - const uint16_t* code_ptr = code_item->insns_; - const uint16_t* code_end = code_item->insns_ + code_item->insns_size_in_code_units_; ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); - - while (code_ptr < code_end) { - const Instruction* inst = Instruction::At(code_ptr); - switch (inst->Opcode()) { + for (const Instruction& 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; @@ -782,8 +778,6 @@ static void ResolveConstStrings(Handle<mirror::DexCache> dex_cache, default: break; } - - code_ptr += inst->SizeInCodeUnits(); } } @@ -2439,21 +2433,16 @@ class InitializeClassVisitor : public CompilationVisitor { if (clinit != nullptr) { const DexFile::CodeItem* code_item = clinit->GetCodeItem(); DCHECK(code_item != nullptr); - const Instruction* inst = Instruction::At(code_item->insns_); - - const uint32_t insns_size = code_item->insns_size_in_code_units_; - for (uint32_t dex_pc = 0; dex_pc < insns_size;) { - if (inst->Opcode() == Instruction::CONST_STRING) { + for (const Instruction& 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); } - dex_pc += inst->SizeInCodeUnits(); - inst = inst->Next(); } } } diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index b8e4f326c8..3cb37926af 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -722,12 +722,10 @@ static void CheckLoopEntriesCanBeUsedForOsr(const HGraph& graph, } } ArenaVector<size_t> covered(loop_headers.size(), 0, graph.GetArena()->Adapter(kArenaAllocMisc)); - const uint16_t* code_ptr = code_item.insns_; - const uint16_t* code_end = code_item.insns_ + code_item.insns_size_in_code_units_; - - size_t dex_pc = 0; - while (code_ptr < code_end) { - const Instruction& instruction = *Instruction::At(code_ptr); + 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; if (instruction.IsBranch()) { uint32_t target = dex_pc + instruction.GetTargetOffset(); CheckCovers(target, graph, code_info, loop_headers, &covered); @@ -743,8 +741,6 @@ static void CheckLoopEntriesCanBeUsedForOsr(const HGraph& graph, CheckCovers(target, graph, code_info, loop_headers, &covered); } } - dex_pc += instruction.SizeInCodeUnits(); - code_ptr += instruction.SizeInCodeUnits(); } for (size_t i = 0; i < covered.size(); ++i) { diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index e832b10b79..6ad8036870 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -368,17 +368,16 @@ void HInstructionBuilder::FindNativeDebugInfoLocations(ArenaBitVector* locations }; dex_file_->DecodeDebugPositionInfo(&code_item_, Callback::Position, locations); // Instruction-specific tweaks. - const Instruction* const begin = Instruction::At(code_item_.insns_); - const Instruction* const end = begin->RelativeAt(code_item_.insns_size_in_code_units_); - for (const Instruction* inst = begin; inst < end; inst = inst->Next()) { - switch (inst->Opcode()) { + IterationRange<DexInstructionIterator> instructions = code_item_.Instructions(); + for (const Instruction& 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(inst->GetDexPc(code_item_.insns_)); - const Instruction* next = inst->Next(); - if (next < end) { + locations->ClearBit(inst.GetDexPc(code_item_.insns_)); + const Instruction* next = inst.Next(); + if (DexInstructionIterator(next) != instructions.end()) { locations->SetBit(next->GetDexPc(code_item_.insns_)); } break; |