summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/compiler.cc2
-rw-r--r--compiler/debug/elf_debug_info_writer.h4
-rw-r--r--compiler/debug/elf_debug_line_writer.h2
-rw-r--r--compiler/debug/elf_debug_loc_writer.h2
-rw-r--r--compiler/driver/compiler_driver.cc2
-rw-r--r--compiler/driver/dex_compilation_unit.cc3
-rw-r--r--compiler/exception_test.cc2
-rw-r--r--compiler/optimizing/code_generator.cc2
-rw-r--r--compiler/optimizing/code_generator_arm_vixl.cc81
-rw-r--r--compiler/optimizing/code_generator_arm_vixl.h1
-rw-r--r--compiler/optimizing/inliner.cc4
-rw-r--r--compiler/optimizing/optimization.cc2
-rw-r--r--compiler/optimizing/optimizing_compiler.cc4
-rw-r--r--compiler/optimizing/optimizing_unit_test.h2
-rw-r--r--compiler/optimizing/scheduler_arm.cc6
-rw-r--r--compiler/utils/arm/assembler_arm_shared.h7
-rw-r--r--compiler/utils/arm/assembler_arm_test.h555
-rw-r--r--compiler/utils/arm/assembler_arm_vixl.cc6
-rw-r--r--compiler/utils/arm/assembler_arm_vixl.h4
-rw-r--r--compiler/utils/arm/jni_macro_assembler_arm_vixl.cc4
-rw-r--r--dex2oat/dex2oat_test.cc17
-rw-r--r--dex2oat/linker/oat_writer.cc2
-rw-r--r--dexdump/dexdump.cc8
-rw-r--r--dexdump/dexdump_cfg.cc2
-rw-r--r--dexlayout/dex_ir.cc2
-rw-r--r--dexlayout/dex_writer.cc13
-rw-r--r--dexlayout/dexlayout.cc3
-rw-r--r--dexlayout/dexlayout_test.cc2
-rw-r--r--dexlist/dexlist.cc2
-rw-r--r--oatdump/oatdump.cc4
-rw-r--r--openjdkjvmti/Android.bp2
-rw-r--r--openjdkjvmti/fixed_up_dex_file.cc29
-rw-r--r--profman/profman.cc2
-rw-r--r--runtime/dex/code_item_accessors-inl.h10
-rw-r--r--runtime/dex/code_item_accessors-no_art-inl.h49
-rw-r--r--runtime/dex/code_item_accessors.h16
-rw-r--r--runtime/dex/code_item_accessors_test.cc4
-rw-r--r--runtime/dex/compact_dex_file.cc30
-rw-r--r--runtime/dex/dex_file_test.cc2
-rw-r--r--runtime/dex/dex_file_tracking_registrar.cc4
-rw-r--r--runtime/dex/dex_file_verifier.cc19
-rw-r--r--runtime/dex/standard_dex_file.cc33
-rw-r--r--runtime/dex_to_dex_decompiler.cc2
-rw-r--r--runtime/verifier/method_verifier.cc2
-rw-r--r--test/623-checker-loop-regressions/expected.txt1
-rw-r--r--test/623-checker-loop-regressions/src/Main.java7
-rw-r--r--test/983-source-transform-verify/source_transform.cc2
-rwxr-xr-xtools/run-jdwp-tests.sh10
-rwxr-xr-xtools/run-libcore-tests.sh14
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