diff options
49 files changed, 214 insertions, 774 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/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 7f8353312f..7c6a5fde40 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -5597,42 +5597,13 @@ Location LocationsBuilderARMVIXL::ArmEncodableConstantOrRegister(HInstruction* c return Location::RequiresRegister(); } -bool LocationsBuilderARMVIXL::CanEncodeConstantAsImmediate(HConstant* input_cst, - Opcode opcode) { - uint64_t value = static_cast<uint64_t>(Int64FromConstant(input_cst)); - if (DataType::Is64BitType(input_cst->GetType())) { - Opcode high_opcode = opcode; - SetCc low_set_cc = kCcDontCare; - switch (opcode) { - case SUB: - // Flip the operation to an ADD. - value = -value; - opcode = ADD; - FALLTHROUGH_INTENDED; - case ADD: - if (Low32Bits(value) == 0u) { - return CanEncodeConstantAsImmediate(High32Bits(value), opcode, kCcDontCare); - } - high_opcode = ADC; - low_set_cc = kCcSet; - break; - default: - break; - } - return CanEncodeConstantAsImmediate(Low32Bits(value), opcode, low_set_cc) && - CanEncodeConstantAsImmediate(High32Bits(value), high_opcode, kCcDontCare); - } else { - return CanEncodeConstantAsImmediate(Low32Bits(value), opcode); - } -} - -// TODO(VIXL): Replace art::arm::SetCc` with `vixl32::FlagsUpdate after flags set optimization -// enabled. -bool LocationsBuilderARMVIXL::CanEncodeConstantAsImmediate(uint32_t value, - Opcode opcode, - SetCc set_cc) { - ArmVIXLAssembler* assembler = codegen_->GetAssembler(); - if (assembler->ShifterOperandCanHold(opcode, value, set_cc)) { +static bool CanEncode32BitConstantAsImmediate( + CodeGeneratorARMVIXL* codegen, + uint32_t value, + Opcode opcode, + vixl32::FlagsUpdate flags_update = vixl32::FlagsUpdate::DontCare) { + ArmVIXLAssembler* assembler = codegen->GetAssembler(); + if (assembler->ShifterOperandCanHold(opcode, value, flags_update)) { return true; } Opcode neg_opcode = kNoOperand; @@ -5649,13 +5620,41 @@ bool LocationsBuilderARMVIXL::CanEncodeConstantAsImmediate(uint32_t value, return false; } - if (assembler->ShifterOperandCanHold(neg_opcode, neg_value, set_cc)) { + if (assembler->ShifterOperandCanHold(neg_opcode, neg_value, flags_update)) { return true; } return opcode == AND && IsPowerOfTwo(value + 1); } +bool LocationsBuilderARMVIXL::CanEncodeConstantAsImmediate(HConstant* input_cst, Opcode opcode) { + uint64_t value = static_cast<uint64_t>(Int64FromConstant(input_cst)); + if (DataType::Is64BitType(input_cst->GetType())) { + Opcode high_opcode = opcode; + vixl32::FlagsUpdate low_flags_update = vixl32::FlagsUpdate::DontCare; + switch (opcode) { + case SUB: + // Flip the operation to an ADD. + value = -value; + opcode = ADD; + FALLTHROUGH_INTENDED; + case ADD: + if (Low32Bits(value) == 0u) { + return CanEncode32BitConstantAsImmediate(codegen_, High32Bits(value), opcode); + } + high_opcode = ADC; + low_flags_update = vixl32::FlagsUpdate::SetFlags; + break; + default: + break; + } + return CanEncode32BitConstantAsImmediate(codegen_, High32Bits(value), high_opcode) && + CanEncode32BitConstantAsImmediate(codegen_, Low32Bits(value), opcode, low_flags_update); + } else { + return CanEncode32BitConstantAsImmediate(codegen_, Low32Bits(value), opcode); + } +} + void InstructionCodeGeneratorARMVIXL::HandleFieldGet(HInstruction* instruction, const FieldInfo& field_info) { DCHECK(instruction->IsInstanceFieldGet() || instruction->IsStaticFieldGet()); @@ -8131,13 +8130,11 @@ void InstructionCodeGeneratorARMVIXL::GenerateAddLongConst(Location out, return; } __ Adds(out_low, first_low, value_low); - if (GetAssembler()->ShifterOperandCanHold(ADC, value_high, kCcDontCare)) { + if (GetAssembler()->ShifterOperandCanHold(ADC, value_high)) { __ Adc(out_high, first_high, value_high); - } else if (GetAssembler()->ShifterOperandCanHold(SBC, ~value_high, kCcDontCare)) { - __ Sbc(out_high, first_high, ~value_high); } else { - LOG(FATAL) << "Unexpected constant " << value_high; - UNREACHABLE(); + DCHECK(GetAssembler()->ShifterOperandCanHold(SBC, ~value_high)); + __ Sbc(out_high, first_high, ~value_high); } } diff --git a/compiler/optimizing/code_generator_arm_vixl.h b/compiler/optimizing/code_generator_arm_vixl.h index c46d17ccec..38570bb0fe 100644 --- a/compiler/optimizing/code_generator_arm_vixl.h +++ b/compiler/optimizing/code_generator_arm_vixl.h @@ -287,7 +287,6 @@ class LocationsBuilderARMVIXL : public HGraphVisitor { Location ArithmeticZeroOrFpuRegister(HInstruction* input); Location ArmEncodableConstantOrRegister(HInstruction* constant, Opcode opcode); bool CanEncodeConstantAsImmediate(HConstant* input_cst, Opcode opcode); - bool CanEncodeConstantAsImmediate(uint32_t value, Opcode opcode, SetCc set_cc = kCcDontCare); CodeGeneratorARMVIXL* const codegen_; InvokeDexCallingConventionVisitorARMVIXL parameter_visitor_; 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/compiler/optimizing/scheduler_arm.cc b/compiler/optimizing/scheduler_arm.cc index b3c8f105d1..8dcadaad2e 100644 --- a/compiler/optimizing/scheduler_arm.cc +++ b/compiler/optimizing/scheduler_arm.cc @@ -330,10 +330,12 @@ bool SchedulingLatencyVisitorARM::CanGenerateTest(HCondition* condition) { } } else if (c == kCondLE || c == kCondGT) { if (value < std::numeric_limits<int64_t>::max() && - !codegen_->GetAssembler()->ShifterOperandCanHold(SBC, High32Bits(value + 1), kCcSet)) { + !codegen_->GetAssembler()->ShifterOperandCanHold( + SBC, High32Bits(value + 1), vixl32::FlagsUpdate::SetFlags)) { return false; } - } else if (!codegen_->GetAssembler()->ShifterOperandCanHold(SBC, High32Bits(value), kCcSet)) { + } else if (!codegen_->GetAssembler()->ShifterOperandCanHold( + SBC, High32Bits(value), vixl32::FlagsUpdate::SetFlags)) { return false; } } diff --git a/compiler/utils/arm/assembler_arm_shared.h b/compiler/utils/arm/assembler_arm_shared.h index 21f13eeab7..7464052d93 100644 --- a/compiler/utils/arm/assembler_arm_shared.h +++ b/compiler/utils/arm/assembler_arm_shared.h @@ -40,13 +40,6 @@ enum StoreOperandType { kStoreDWord }; -// Set condition codes request. -enum SetCc { - kCcDontCare, // Allows prioritizing 16-bit instructions on Thumb2 whether they set CCs or not. - kCcSet, - kCcKeep, -}; - } // namespace arm } // namespace art diff --git a/compiler/utils/arm/assembler_arm_test.h b/compiler/utils/arm/assembler_arm_test.h deleted file mode 100644 index 8c3a11f2cf..0000000000 --- a/compiler/utils/arm/assembler_arm_test.h +++ /dev/null @@ -1,555 +0,0 @@ -/* - * Copyright (C) 2014 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_COMPILER_UTILS_ARM_ASSEMBLER_ARM_TEST_H_ -#define ART_COMPILER_UTILS_ARM_ASSEMBLER_ARM_TEST_H_ - -#include "utils/assembler_test.h" - -namespace art { - -template<typename Ass, - typename Reg, - typename FPReg, - typename Imm, - typename SOp, - typename Cond, - typename SetCc> -class AssemblerArmTest : public AssemblerTest<Ass, Reg, FPReg, Imm> { - public: - typedef AssemblerTest<Ass, Reg, FPReg, Imm> Base; - - using Base::GetRegisters; - using Base::GetRegName; - using Base::CreateImmediate; - using Base::WarnOnCombinations; - - static constexpr int64_t kFullImmRangeThreshold = 32; - - virtual void FillImmediates(std::vector<Imm>& immediates, int64_t imm_min, int64_t imm_max) { - // Small range: do completely. - if (imm_max - imm_min <= kFullImmRangeThreshold) { - for (int64_t i = imm_min; i <= imm_max; ++i) { - immediates.push_back(CreateImmediate(i)); - } - } else { - immediates.push_back(CreateImmediate(imm_min)); - immediates.push_back(CreateImmediate(imm_max)); - if (imm_min < imm_max - 1) { - immediates.push_back(CreateImmediate(imm_min + 1)); - } - if (imm_min < imm_max - 2) { - immediates.push_back(CreateImmediate(imm_min + 2)); - } - if (imm_min < imm_max - 3) { - immediates.push_back(CreateImmediate(imm_max - 1)); - } - if (imm_min < imm_max - 4) { - immediates.push_back(CreateImmediate((imm_min + imm_max) / 2)); - } - } - } - - std::string RepeatRRIIC(void (Ass::*f)(Reg, Reg, Imm, Imm, Cond), - int64_t imm1_min, int64_t imm1_max, - int64_t imm2_min, int64_t imm2_max, - std::string fmt) { - return RepeatTemplatedRRIIC(f, GetRegisters(), GetRegisters(), - &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, - &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, - imm1_min, imm1_max, imm2_min, imm2_max, - fmt); - } - - template <typename Reg1, typename Reg2> - std::string RepeatTemplatedRRIIC(void (Ass::*f)(Reg1, Reg2, Imm, Imm, Cond), - const std::vector<Reg1*> reg1_registers, - const std::vector<Reg2*> reg2_registers, - std::string (AssemblerArmTest::*GetName1)(const Reg1&), - std::string (AssemblerArmTest::*GetName2)(const Reg2&), - int64_t imm1_min, int64_t imm1_max, - int64_t imm2_min, int64_t imm2_max, - std::string fmt) { - std::vector<Imm> immediates1; - FillImmediates(immediates1, imm1_min, imm1_max); - std::vector<Imm> immediates2; - FillImmediates(immediates2, imm2_min, imm2_max); - - std::vector<Cond>& cond = GetConditions(); - - WarnOnCombinations(cond.size() * immediates1.size() * immediates2.size() * - reg1_registers.size() * reg2_registers.size()); - - std::ostringstream oss; - bool first = true; - for (Cond& c : cond) { - std::string after_cond = fmt; - - size_t cond_index = after_cond.find(COND_TOKEN); - if (cond_index != std::string::npos) { - after_cond.replace(cond_index, ConstexprStrLen(COND_TOKEN), GetConditionString(c)); - } - - for (Imm i : immediates1) { - std::string base = after_cond; - - size_t imm1_index = base.find(IMM1_TOKEN); - if (imm1_index != std::string::npos) { - std::ostringstream sreg; - sreg << i; - std::string imm_string = sreg.str(); - base.replace(imm1_index, ConstexprStrLen(IMM1_TOKEN), imm_string); - } - - for (Imm j : immediates2) { - std::string base2 = base; - - size_t imm2_index = base2.find(IMM2_TOKEN); - if (imm2_index != std::string::npos) { - std::ostringstream sreg; - sreg << j; - std::string imm_string = sreg.str(); - base2.replace(imm2_index, ConstexprStrLen(IMM2_TOKEN), imm_string); - } - - for (auto reg1 : reg1_registers) { - std::string base3 = base2; - - std::string reg1_string = (this->*GetName1)(*reg1); - size_t reg1_index; - while ((reg1_index = base3.find(Base::REG1_TOKEN)) != std::string::npos) { - base3.replace(reg1_index, ConstexprStrLen(Base::REG1_TOKEN), reg1_string); - } - - for (auto reg2 : reg2_registers) { - std::string base4 = base3; - - std::string reg2_string = (this->*GetName2)(*reg2); - size_t reg2_index; - while ((reg2_index = base4.find(Base::REG2_TOKEN)) != std::string::npos) { - base4.replace(reg2_index, ConstexprStrLen(Base::REG2_TOKEN), reg2_string); - } - - if (first) { - first = false; - } else { - oss << "\n"; - } - oss << base4; - - (Base::GetAssembler()->*f)(*reg1, *reg2, i, j, c); - } - } - } - } - } - // Add a newline at the end. - oss << "\n"; - - return oss.str(); - } - - std::string RepeatRRiiC(void (Ass::*f)(Reg, Reg, Imm, Imm, Cond), - std::vector<std::pair<Imm, Imm>>& immediates, - std::string fmt) { - return RepeatTemplatedRRiiC<Reg, Reg>(f, GetRegisters(), GetRegisters(), - &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, - &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, - immediates, fmt); - } - - template <typename Reg1, typename Reg2> - std::string RepeatTemplatedRRiiC(void (Ass::*f)(Reg1, Reg2, Imm, Imm, Cond), - const std::vector<Reg1*> reg1_registers, - const std::vector<Reg2*> reg2_registers, - std::string (AssemblerArmTest::*GetName1)(const Reg1&), - std::string (AssemblerArmTest::*GetName2)(const Reg2&), - std::vector<std::pair<Imm, Imm>>& immediates, - std::string fmt) { - std::vector<Cond>& cond = GetConditions(); - - WarnOnCombinations(cond.size() * immediates.size() * reg1_registers.size() * - reg2_registers.size()); - - std::ostringstream oss; - bool first = true; - for (Cond& c : cond) { - std::string after_cond = fmt; - - size_t cond_index = after_cond.find(COND_TOKEN); - if (cond_index != std::string::npos) { - after_cond.replace(cond_index, ConstexprStrLen(COND_TOKEN), GetConditionString(c)); - } - - for (std::pair<Imm, Imm>& pair : immediates) { - Imm i = pair.first; - Imm j = pair.second; - std::string after_imm1 = after_cond; - - size_t imm1_index = after_imm1.find(IMM1_TOKEN); - if (imm1_index != std::string::npos) { - std::ostringstream sreg; - sreg << i; - std::string imm_string = sreg.str(); - after_imm1.replace(imm1_index, ConstexprStrLen(IMM1_TOKEN), imm_string); - } - - std::string after_imm2 = after_imm1; - - size_t imm2_index = after_imm2.find(IMM2_TOKEN); - if (imm2_index != std::string::npos) { - std::ostringstream sreg; - sreg << j; - std::string imm_string = sreg.str(); - after_imm2.replace(imm2_index, ConstexprStrLen(IMM2_TOKEN), imm_string); - } - - for (auto reg1 : reg1_registers) { - std::string after_reg1 = after_imm2; - - std::string reg1_string = (this->*GetName1)(*reg1); - size_t reg1_index; - while ((reg1_index = after_reg1.find(Base::REG1_TOKEN)) != std::string::npos) { - after_reg1.replace(reg1_index, ConstexprStrLen(Base::REG1_TOKEN), reg1_string); - } - - for (auto reg2 : reg2_registers) { - std::string after_reg2 = after_reg1; - - std::string reg2_string = (this->*GetName2)(*reg2); - size_t reg2_index; - while ((reg2_index = after_reg2.find(Base::REG2_TOKEN)) != std::string::npos) { - after_reg2.replace(reg2_index, ConstexprStrLen(Base::REG2_TOKEN), reg2_string); - } - - if (first) { - first = false; - } else { - oss << "\n"; - } - oss << after_reg2; - - (Base::GetAssembler()->*f)(*reg1, *reg2, i, j, c); - } - } - } - } - // Add a newline at the end. - oss << "\n"; - - return oss.str(); - } - - std::string RepeatRRC(void (Ass::*f)(Reg, Reg, Cond), std::string fmt) { - return RepeatTemplatedRRC(f, GetRegisters(), GetRegisters(), GetConditions(), - &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, - &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, - fmt); - } - - template <typename Reg1, typename Reg2> - std::string RepeatTemplatedRRC(void (Ass::*f)(Reg1, Reg2, Cond), - const std::vector<Reg1*>& reg1_registers, - const std::vector<Reg2*>& reg2_registers, - const std::vector<Cond>& cond, - std::string (AssemblerArmTest::*GetName1)(const Reg1&), - std::string (AssemblerArmTest::*GetName2)(const Reg2&), - std::string fmt) { - WarnOnCombinations(cond.size() * reg1_registers.size() * reg2_registers.size()); - - std::ostringstream oss; - bool first = true; - for (const Cond& c : cond) { - std::string after_cond = fmt; - - size_t cond_index = after_cond.find(COND_TOKEN); - if (cond_index != std::string::npos) { - after_cond.replace(cond_index, ConstexprStrLen(COND_TOKEN), GetConditionString(c)); - } - - for (auto reg1 : reg1_registers) { - std::string after_reg1 = after_cond; - - std::string reg1_string = (this->*GetName1)(*reg1); - size_t reg1_index; - while ((reg1_index = after_reg1.find(Base::REG1_TOKEN)) != std::string::npos) { - after_reg1.replace(reg1_index, ConstexprStrLen(Base::REG1_TOKEN), reg1_string); - } - - for (auto reg2 : reg2_registers) { - std::string after_reg2 = after_reg1; - - std::string reg2_string = (this->*GetName2)(*reg2); - size_t reg2_index; - while ((reg2_index = after_reg2.find(Base::REG2_TOKEN)) != std::string::npos) { - after_reg2.replace(reg2_index, ConstexprStrLen(Base::REG2_TOKEN), reg2_string); - } - - if (first) { - first = false; - } else { - oss << "\n"; - } - oss << after_reg2; - - (Base::GetAssembler()->*f)(*reg1, *reg2, c); - } - } - } - // Add a newline at the end. - oss << "\n"; - - return oss.str(); - } - - std::string RepeatRRRC(void (Ass::*f)(Reg, Reg, Reg, Cond), std::string fmt) { - return RepeatTemplatedRRRC(f, GetRegisters(), GetRegisters(), GetRegisters(), GetConditions(), - &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, - &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, - &AssemblerArmTest::template GetRegName<RegisterView::kUsePrimaryName>, - fmt); - } - - template <typename Reg1, typename Reg2, typename Reg3> - std::string RepeatTemplatedRRRC(void (Ass::*f)(Reg1, Reg2, Reg3, Cond), - const std::vector<Reg1*>& reg1_registers, - const std::vector<Reg2*>& reg2_registers, - const std::vector<Reg3*>& reg3_registers, - const std::vector<Cond>& cond, - std::string (AssemblerArmTest::*GetName1)(const Reg1&), - std::string (AssemblerArmTest::*GetName2)(const Reg2&), - std::string (AssemblerArmTest::*GetName3)(const Reg3&), - std::string fmt) { - WarnOnCombinations(cond.size() * reg1_registers.size() * reg2_registers.size() * - reg3_registers.size()); - - std::ostringstream oss; - bool first = true; - for (const Cond& c : cond) { - std::string after_cond = fmt; - - size_t cond_index = after_cond.find(COND_TOKEN); - if (cond_index != std::string::npos) { - after_cond.replace(cond_index, ConstexprStrLen(COND_TOKEN), GetConditionString(c)); - } - - for (auto reg1 : reg1_registers) { - std::string after_reg1 = after_cond; - - std::string reg1_string = (this->*GetName1)(*reg1); - size_t reg1_index; - while ((reg1_index = after_reg1.find(Base::REG1_TOKEN)) != std::string::npos) { - after_reg1.replace(reg1_index, ConstexprStrLen(Base::REG1_TOKEN), reg1_string); - } - - for (auto reg2 : reg2_registers) { - std::string after_reg2 = after_reg1; - - std::string reg2_string = (this->*GetName2)(*reg2); - size_t reg2_index; - while ((reg2_index = after_reg2.find(Base::REG2_TOKEN)) != std::string::npos) { - after_reg2.replace(reg2_index, ConstexprStrLen(Base::REG2_TOKEN), reg2_string); - } - - for (auto reg3 : reg3_registers) { - std::string after_reg3 = after_reg2; - - std::string reg3_string = (this->*GetName3)(*reg3); - size_t reg3_index; - while ((reg3_index = after_reg3.find(REG3_TOKEN)) != std::string::npos) { - after_reg3.replace(reg3_index, ConstexprStrLen(REG3_TOKEN), reg3_string); - } - - if (first) { - first = false; - } else { - oss << "\n"; - } - oss << after_reg3; - - (Base::GetAssembler()->*f)(*reg1, *reg2, *reg3, c); - } - } - } - } - // Add a newline at the end. - oss << "\n"; - - return oss.str(); - } - - template <typename RegT> - std::string RepeatTemplatedRSC(void (Ass::*f)(RegT, SOp, Cond), - const std::vector<RegT*>& registers, - const std::vector<SOp>& shifts, - const std::vector<Cond>& cond, - std::string (AssemblerArmTest::*GetName)(const RegT&), - std::string fmt) { - WarnOnCombinations(cond.size() * registers.size() * shifts.size()); - - std::ostringstream oss; - bool first = true; - for (const Cond& c : cond) { - std::string after_cond = fmt; - - size_t cond_index = after_cond.find(COND_TOKEN); - if (cond_index != std::string::npos) { - after_cond.replace(cond_index, ConstexprStrLen(COND_TOKEN), GetConditionString(c)); - } - - for (const SOp& shift : shifts) { - std::string after_shift = after_cond; - - std::string shift_string = GetShiftString(shift); - size_t shift_index; - while ((shift_index = after_shift.find(Base::SHIFT_TOKEN)) != std::string::npos) { - after_shift.replace(shift_index, ConstexprStrLen(Base::SHIFT_TOKEN), shift_string); - } - - for (auto reg : registers) { - std::string after_reg = after_shift; - - std::string reg_string = (this->*GetName)(*reg); - size_t reg_index; - while ((reg_index = after_reg.find(Base::REG_TOKEN)) != std::string::npos) { - after_reg.replace(reg_index, ConstexprStrLen(Base::REG_TOKEN), reg_string); - } - - if (first) { - first = false; - } else { - oss << "\n"; - } - oss << after_reg; - - (Base::GetAssembler()->*f)(*reg, shift, c); - } - } - } - // Add a newline at the end. - oss << "\n"; - - return oss.str(); - } - - template <typename Reg1, typename Reg2> - std::string RepeatTemplatedRRSC(void (Ass::*f)(Reg1, Reg2, const SOp&, Cond), - const std::vector<Reg1*>& reg1_registers, - const std::vector<Reg2*>& reg2_registers, - const std::vector<SOp>& shifts, - const std::vector<Cond>& cond, - std::string (AssemblerArmTest::*GetName1)(const Reg1&), - std::string (AssemblerArmTest::*GetName2)(const Reg2&), - std::string fmt) { - WarnOnCombinations(cond.size() * reg1_registers.size() * reg2_registers.size() * shifts.size()); - - std::ostringstream oss; - bool first = true; - for (const Cond& c : cond) { - std::string after_cond = fmt; - - size_t cond_index = after_cond.find(COND_TOKEN); - if (cond_index != std::string::npos) { - after_cond.replace(cond_index, ConstexprStrLen(COND_TOKEN), GetConditionString(c)); - } - - for (const SOp& shift : shifts) { - std::string after_shift = after_cond; - - std::string shift_string = GetShiftString(shift); - size_t shift_index; - while ((shift_index = after_shift.find(SHIFT_TOKEN)) != std::string::npos) { - after_shift.replace(shift_index, ConstexprStrLen(SHIFT_TOKEN), shift_string); - } - - for (auto reg1 : reg1_registers) { - std::string after_reg1 = after_shift; - - std::string reg1_string = (this->*GetName1)(*reg1); - size_t reg1_index; - while ((reg1_index = after_reg1.find(Base::REG1_TOKEN)) != std::string::npos) { - after_reg1.replace(reg1_index, ConstexprStrLen(Base::REG1_TOKEN), reg1_string); - } - - for (auto reg2 : reg2_registers) { - std::string after_reg2 = after_reg1; - - std::string reg2_string = (this->*GetName2)(*reg2); - size_t reg2_index; - while ((reg2_index = after_reg2.find(Base::REG2_TOKEN)) != std::string::npos) { - after_reg2.replace(reg2_index, ConstexprStrLen(Base::REG2_TOKEN), reg2_string); - } - - if (first) { - first = false; - } else { - oss << "\n"; - } - oss << after_reg2; - - (Base::GetAssembler()->*f)(*reg1, *reg2, shift, c); - } - } - } - } - // Add a newline at the end. - oss << "\n"; - - return oss.str(); - } - - protected: - AssemblerArmTest() {} - - virtual std::vector<Cond>& GetConditions() = 0; - virtual std::string GetConditionString(Cond c) = 0; - - virtual std::vector<SetCc>& GetSetCcs() = 0; - virtual std::string GetSetCcString(SetCc s) = 0; - - virtual std::vector<SOp>& GetShiftOperands() = 0; - virtual std::string GetShiftString(SOp sop) = 0; - - virtual Reg GetPCRegister() = 0; - virtual std::vector<Reg*> GetRegistersWithoutPC() { - std::vector<Reg*> without_pc = GetRegisters(); - Reg pc_reg = GetPCRegister(); - - for (auto it = without_pc.begin(); it != without_pc.end(); ++it) { - if (**it == pc_reg) { - without_pc.erase(it); - break; - } - } - - return without_pc; - } - - static constexpr const char* IMM1_TOKEN = "{imm1}"; - static constexpr const char* IMM2_TOKEN = "{imm2}"; - static constexpr const char* REG3_TOKEN = "{reg3}"; - static constexpr const char* REG4_TOKEN = "{reg4}"; - static constexpr const char* COND_TOKEN = "{cond}"; - static constexpr const char* SET_CC_TOKEN = "{s}"; - static constexpr const char* SHIFT_TOKEN = "{shift}"; - - private: - DISALLOW_COPY_AND_ASSIGN(AssemblerArmTest); -}; - -} // namespace art - -#endif // ART_COMPILER_UTILS_ARM_ASSEMBLER_ARM_TEST_H_ diff --git a/compiler/utils/arm/assembler_arm_vixl.cc b/compiler/utils/arm/assembler_arm_vixl.cc index d6b24da407..05250a4157 100644 --- a/compiler/utils/arm/assembler_arm_vixl.cc +++ b/compiler/utils/arm/assembler_arm_vixl.cc @@ -112,12 +112,14 @@ bool ArmVIXLAssembler::ShifterOperandCanAlwaysHold(uint32_t immediate) { return vixl_masm_.IsModifiedImmediate(immediate); } -bool ArmVIXLAssembler::ShifterOperandCanHold(Opcode opcode, uint32_t immediate, SetCc set_cc) { +bool ArmVIXLAssembler::ShifterOperandCanHold(Opcode opcode, + uint32_t immediate, + vixl::aarch32::FlagsUpdate update_flags) { switch (opcode) { case ADD: case SUB: // Less than (or equal to) 12 bits can be done if we don't need to set condition codes. - if (IsUint<12>(immediate) && set_cc != kCcSet) { + if (IsUint<12>(immediate) && update_flags != vixl::aarch32::SetFlags) { return true; } return ShifterOperandCanAlwaysHold(immediate); diff --git a/compiler/utils/arm/assembler_arm_vixl.h b/compiler/utils/arm/assembler_arm_vixl.h index 1377e64073..b0310f2fb6 100644 --- a/compiler/utils/arm/assembler_arm_vixl.h +++ b/compiler/utils/arm/assembler_arm_vixl.h @@ -218,7 +218,9 @@ class ArmVIXLAssembler FINAL : public Assembler { void StoreRegisterList(RegList regs, size_t stack_offset); bool ShifterOperandCanAlwaysHold(uint32_t immediate); - bool ShifterOperandCanHold(Opcode opcode, uint32_t immediate, SetCc set_cc = kCcDontCare); + bool ShifterOperandCanHold(Opcode opcode, + uint32_t immediate, + vixl::aarch32::FlagsUpdate update_flags = vixl::aarch32::DontCare); bool CanSplitLoadStoreOffset(int32_t allowed_offset_bits, int32_t offset, /*out*/ int32_t* add_to_base, diff --git a/compiler/utils/arm/jni_macro_assembler_arm_vixl.cc b/compiler/utils/arm/jni_macro_assembler_arm_vixl.cc index 2b3e979606..065c3de23c 100644 --- a/compiler/utils/arm/jni_macro_assembler_arm_vixl.cc +++ b/compiler/utils/arm/jni_macro_assembler_arm_vixl.cc @@ -492,7 +492,7 @@ void ArmVIXLJNIMacroAssembler::CreateHandleScopeEntry(ManagedRegister mout_reg, temps.Exclude(in_reg.AsVIXLRegister()); ___ Cmp(in_reg.AsVIXLRegister(), 0); - if (asm_.ShifterOperandCanHold(ADD, handle_scope_offset.Int32Value(), kCcDontCare)) { + if (asm_.ShifterOperandCanHold(ADD, handle_scope_offset.Int32Value())) { if (!out_reg.Equals(in_reg)) { ExactAssemblyScope guard(asm_.GetVIXLAssembler(), 3 * vixl32::kMaxInstructionSizeInBytes, @@ -531,7 +531,7 @@ void ArmVIXLJNIMacroAssembler::CreateHandleScopeEntry(FrameOffset out_off, // e.g. scratch = (scratch == 0) ? 0 : (SP+handle_scope_offset) ___ Cmp(scratch.AsVIXLRegister(), 0); - if (asm_.ShifterOperandCanHold(ADD, handle_scope_offset.Int32Value(), kCcDontCare)) { + if (asm_.ShifterOperandCanHold(ADD, handle_scope_offset.Int32Value())) { ExactAssemblyScope guard(asm_.GetVIXLAssembler(), 2 * vixl32::kMaxInstructionSizeInBytes, CodeBufferCheckScope::kMaximumSize); diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc index c91240e19d..f176cc2839 100644 --- a/dex2oat/dex2oat_test.cc +++ b/dex2oat/dex2oat_test.cc @@ -44,6 +44,7 @@ namespace art { static constexpr size_t kMaxMethodIds = 65535; static constexpr bool kDebugArgs = false; +static const char* kDisableCompactDex = "--compact-dex-level=none"; using android::base::StringPrintf; @@ -776,7 +777,7 @@ class Dex2oatLayoutTest : public Dex2oatTest { app_image_file_name, /* use_fd */ true, /* num_profile_classes */ 1, - { input_vdex, output_vdex }); + { input_vdex, output_vdex, kDisableCompactDex }); EXPECT_GT(vdex_file1->GetLength(), 0u); } { @@ -788,7 +789,7 @@ class Dex2oatLayoutTest : public Dex2oatTest { app_image_file_name, /* use_fd */ true, /* num_profile_classes */ 1, - { input_vdex, output_vdex }, + { input_vdex, output_vdex, kDisableCompactDex }, /* expect_success */ true); EXPECT_GT(vdex_file2.GetFile()->GetLength(), 0u); } @@ -876,8 +877,6 @@ TEST_F(Dex2oatLayoutTest, TestLayoutAppImage) { } TEST_F(Dex2oatLayoutTest, TestVdexLayout) { - // Disabled until figure out running compact dex + DexLayout causes quickening errors. - TEST_DISABLED_FOR_COMPACT_DEX(); RunTestVDex(); } @@ -898,7 +897,7 @@ class Dex2oatUnquickenTest : public Dex2oatTest { GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kQuicken, - { input_vdex, output_vdex }, + { input_vdex, output_vdex, kDisableCompactDex }, /* expect_success */ true, /* use_fd */ true); EXPECT_GT(vdex_file1->GetLength(), 0u); @@ -910,7 +909,7 @@ class Dex2oatUnquickenTest : public Dex2oatTest { GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kVerify, - { input_vdex, output_vdex }, + { input_vdex, output_vdex, kDisableCompactDex }, /* expect_success */ true, /* use_fd */ true); } @@ -944,8 +943,8 @@ 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())) { - ASSERT_FALSE(inst->IsQuickened()); + CodeItemInstructionAccessor(*dex_file, class_it.GetMethodCodeItem())) { + ASSERT_FALSE(inst->IsQuickened()) << output_; } } } @@ -956,8 +955,6 @@ class Dex2oatUnquickenTest : public Dex2oatTest { }; TEST_F(Dex2oatUnquickenTest, UnquickenMultiDex) { - // Disabled until figure out running compact dex + DexLayout causes quickening errors. - TEST_DISABLED_FOR_COMPACT_DEX(); RunUnquickenMultiDex(); } 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/dex_writer.cc b/dexlayout/dex_writer.cc index a18a2cfd8a..489a6b15ba 100644 --- a/dexlayout/dex_writer.cc +++ b/dexlayout/dex_writer.cc @@ -774,9 +774,16 @@ uint32_t DexWriter::GenerateAndWriteMapItems(uint32_t offset) { void DexWriter::WriteHeader() { StandardDexFile::Header header; - static constexpr size_t kMagicAndVersionLen = - StandardDexFile::kDexMagicSize + StandardDexFile::kDexVersionLen; - std::copy_n(header_->Magic(), kMagicAndVersionLen, header.magic_); + if (CompactDexFile::IsMagicValid(header_->Magic())) { + StandardDexFile::WriteMagic(header.magic_); + // TODO: Should we write older versions based on the feature flags? + StandardDexFile::WriteCurrentVersion(header.magic_); + } else { + // Standard dex -> standard dex, just reuse the same header. + static constexpr size_t kMagicAndVersionLen = + StandardDexFile::kDexMagicSize + StandardDexFile::kDexVersionLen; + std::copy_n(header_->Magic(), kMagicAndVersionLen, header.magic_); + } header.checksum_ = header_->Checksum(); std::copy_n(header_->Signature(), DexFile::kSha1DigestSize, header.signature_); header.file_size_ = header_->FileSize(); diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc index 47a3e943a5..000d1356b9 100644 --- a/dexlayout/dexlayout.cc +++ b/dexlayout/dexlayout.cc @@ -1912,7 +1912,8 @@ void DexLayout::ProcessDexFile(const char* file_name, if (do_layout) { LayoutOutputFile(dex_file); } - OutputDexFile(dex_file, do_layout); + // If we didn't set the offsets eagerly, we definitely need to compute them here. + OutputDexFile(dex_file, do_layout || !eagerly_assign_offsets); // Clear header before verifying to reduce peak RAM usage. const size_t file_size = header_->FileSize(); 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/openjdkjvmti/Android.bp b/openjdkjvmti/Android.bp index 9ba7068176..0283999d54 100644 --- a/openjdkjvmti/Android.bp +++ b/openjdkjvmti/Android.bp @@ -68,6 +68,7 @@ art_cc_library { shared_libs: [ "libart", "libart-compiler", + "libart-dexlayout", ], } @@ -80,5 +81,6 @@ art_cc_library { shared_libs: [ "libartd", "libartd-compiler", + "libartd-dexlayout", ], } diff --git a/openjdkjvmti/fixed_up_dex_file.cc b/openjdkjvmti/fixed_up_dex_file.cc index ad928d9b37..da7d60ac2f 100644 --- a/openjdkjvmti/fixed_up_dex_file.cc +++ b/openjdkjvmti/fixed_up_dex_file.cc @@ -34,7 +34,9 @@ #include "dex/dex_file_loader.h" // Runtime includes. +#include "dex/compact_dex_level.h" #include "dex_to_dex_decompiler.h" +#include "dexlayout.h" #include "oat_file.h" #include "vdex_file.h" @@ -85,6 +87,33 @@ std::unique_ptr<FixedUpDexFile> FixedUpDexFile::Create(const art::DexFile& origi } DoDexUnquicken(*new_dex_file, original); + + if (original.IsCompactDexFile()) { + // Since we are supposed to return a standard dex, convert back using dexlayout. + art::Options options; + options.output_to_memmap_ = true; + options.compact_dex_level_ = art::CompactDexLevel::kCompactDexLevelNone; + options.update_checksum_ = true; + art::DexLayout dex_layout(options, nullptr, nullptr); + dex_layout.ProcessDexFile(new_dex_file->GetLocation().c_str(), new_dex_file.get(), 0); + std::unique_ptr<art::MemMap> mem_map(dex_layout.GetAndReleaseMemMap()); + + const uint32_t dex_file_size = + reinterpret_cast<const art::DexFile::Header*>(mem_map->Begin())->file_size_; + // Overwrite the dex file stored in data with the new result. + data.clear(); + data.insert(data.end(), mem_map->Begin(), mem_map->Begin() + dex_file_size); + new_dex_file = art::DexFileLoader::Open( + data.data(), + data.size(), + /*location*/"Unquickening_dexfile.dex", + /*location_checksum*/0, + /*oat_dex_file*/nullptr, + /*verify*/false, + /*verify_checksum*/false, + &error); + } + RecomputeDexChecksum(const_cast<art::DexFile*>(new_dex_file.get())); std::unique_ptr<FixedUpDexFile> ret(new FixedUpDexFile(std::move(new_dex_file), std::move(data))); return ret; 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..7265aad1ba 100644 --- a/runtime/dex/dex_file_verifier.cc +++ b/runtime/dex/dex_file_verifier.cc @@ -386,15 +386,14 @@ bool DexFileVerifier::CheckHeader() { return false; } - bool size_matches = false; - if (dex_file_->IsCompactDexFile()) { - size_matches = header_->header_size_ == sizeof(CompactDexFile::Header); - } else { - size_matches = header_->header_size_ == sizeof(StandardDexFile::Header); - } + const uint32_t expected_header_size = dex_file_->IsCompactDexFile() + ? sizeof(CompactDexFile::Header) + : sizeof(StandardDexFile::Header); - if (!size_matches) { - ErrorStringPrintf("Bad header size: %ud", header_->header_size_); + if (header_->header_size_ != expected_header_size) { + ErrorStringPrintf("Bad header size: %ud expected %ud", + header_->header_size_, + expected_header_size); return false; } @@ -580,7 +579,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 +1232,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/623-checker-loop-regressions/expected.txt b/test/623-checker-loop-regressions/expected.txt index b0aad4deb5..805857dc65 100644 --- a/test/623-checker-loop-regressions/expected.txt +++ b/test/623-checker-loop-regressions/expected.txt @@ -1 +1,2 @@ +JNI_OnLoad called passed diff --git a/test/623-checker-loop-regressions/src/Main.java b/test/623-checker-loop-regressions/src/Main.java index 29f3817afb..4e2b241fd7 100644 --- a/test/623-checker-loop-regressions/src/Main.java +++ b/test/623-checker-loop-regressions/src/Main.java @@ -19,6 +19,8 @@ */ public class Main { + private static native void ensureJitCompiled(Class<?> cls, String methodName); + /// CHECK-START: int Main.earlyExitFirst(int) loop_optimization (before) /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none /// CHECK-DAG: Phi loop:<<Loop>> outer_loop:none @@ -583,6 +585,8 @@ public class Main { } public static void main(String[] args) { + System.loadLibrary(args[0]); + expectEquals(10, earlyExitFirst(-1)); for (int i = 0; i <= 10; i++) { expectEquals(i, earlyExitFirst(i)); @@ -746,6 +750,9 @@ public class Main { expectEquals(153, doNotMoveSIMD()); + // This test exposed SIMDization issues on x86 and x86_64 + // so we make sure the test runs with JIT enabled. + ensureJitCompiled(Main.class, "reduction32Values"); { int[] a1 = new int[100]; int[] a2 = new int[100]; 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 || diff --git a/tools/run-jdwp-tests.sh b/tools/run-jdwp-tests.sh index 381c129208..2cf614d795 100755 --- a/tools/run-jdwp-tests.sh +++ b/tools/run-jdwp-tests.sh @@ -26,8 +26,6 @@ if [ -z "$ANDROID_HOST_OUT" ] ; then ANDROID_HOST_OUT=${OUT_DIR-$ANDROID_BUILD_TOP/out}/host/linux-x86 fi -using_jack=$(get_build_var ANDROID_COMPILE_WITH_JACK) - java_lib_location="${ANDROID_HOST_OUT}/../common/obj/JAVA_LIBRARIES" make_target_name="apache-harmony-jdwp-tests-hostdex" @@ -184,7 +182,6 @@ if [[ $has_gdb = "yes" ]]; then fi if [[ $mode == "ri" ]]; then - using_jack="false" if [[ "x$with_jdwp_path" != "x" ]]; then vm_args="${vm_args} --vm-arg -Djpda.settings.debuggeeAgentArgument=-agentpath:${agent_wrapper}" vm_args="${vm_args} --vm-arg -Djpda.settings.debuggeeAgentName=$with_jdwp_path" @@ -225,10 +222,7 @@ function jlib_name { local str="classes" local suffix="jar" if [[ $mode == "ri" ]]; then - suffix="jar" str="javalib" - elif [[ $using_jack == "true" ]]; then - suffix="jack" fi echo "$path/$str.$suffix" } @@ -290,9 +284,7 @@ if [[ $verbose == "yes" ]]; then art_debugee="$art_debugee -verbose:jdwp" fi -if [[ $using_jack == "true" ]]; then - toolchain_args="--toolchain jack --language JN --jack-arg -g" -elif [[ $mode != "ri" ]]; then +if [[ $mode != "ri" ]]; then toolchain_args="--toolchain d8 --language CUR" else toolchain_args="--toolchain javac --language CUR" diff --git a/tools/run-libcore-tests.sh b/tools/run-libcore-tests.sh index 779620fcba..739646a754 100755 --- a/tools/run-libcore-tests.sh +++ b/tools/run-libcore-tests.sh @@ -28,16 +28,10 @@ else JAVA_LIBRARIES=${ANDROID_PRODUCT_OUT}/../../common/obj/JAVA_LIBRARIES fi -using_jack=$(get_build_var ANDROID_COMPILE_WITH_JACK) - function classes_jar_path { local var="$1" local suffix="jar" - if [[ $using_jack == "true" ]]; then - suffix="jack" - fi - echo "${JAVA_LIBRARIES}/${var}_intermediates/classes.${suffix}" } @@ -145,12 +139,8 @@ done # the default timeout. vogar_args="$vogar_args --timeout 480" -# Switch between using jack or javac+desugar+d8 -if [[ $using_jack == "true" ]]; then - vogar_args="$vogar_args --toolchain jack --language JO" -else - vogar_args="$vogar_args --toolchain d8 --language CUR" -fi +# set the toolchain to use. +vogar_args="$vogar_args --toolchain d8 --language CUR" # JIT settings. if $use_jit; then |