diff options
26 files changed, 354 insertions, 51 deletions
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc index 5a95abdb50..da2acd1fd3 100644 --- a/compiler/optimizing/loop_optimization.cc +++ b/compiler/optimizing/loop_optimization.cc @@ -1001,8 +1001,9 @@ void HLoopOptimization::GenerateVecMem(HInstruction* org, vector = new (global_allocator_) HVecStore( global_allocator_, org->InputAt(0), opa, opb, type, vector_length_); } else { + bool is_string_char_at = org->AsArrayGet()->IsStringCharAt(); vector = new (global_allocator_) HVecLoad( - global_allocator_, org->InputAt(0), opa, type, vector_length_); + global_allocator_, org->InputAt(0), opa, type, vector_length_, is_string_char_at); } } else { // Scalar store or load. @@ -1010,7 +1011,9 @@ void HLoopOptimization::GenerateVecMem(HInstruction* org, if (opb != nullptr) { vector = new (global_allocator_) HArraySet(org->InputAt(0), opa, opb, type, kNoDexPc); } else { - vector = new (global_allocator_) HArrayGet(org->InputAt(0), opa, type, kNoDexPc); + bool is_string_char_at = org->AsArrayGet()->IsStringCharAt(); + vector = new (global_allocator_) HArrayGet( + org->InputAt(0), opa, type, kNoDexPc, is_string_char_at); } } vector_map_->Put(org, vector); diff --git a/compiler/optimizing/nodes_vector.h b/compiler/optimizing/nodes_vector.h index fb9dfb7afa..c9d6ff83ad 100644 --- a/compiler/optimizing/nodes_vector.h +++ b/compiler/optimizing/nodes_vector.h @@ -98,7 +98,7 @@ class HVecOperation : public HVariableInputSizeInstruction { DECLARE_ABSTRACT_INSTRUCTION(VecOperation); - private: + protected: // Additional packed bits. static constexpr size_t kFieldType = HInstruction::kNumberOfGenericPackedBits; static constexpr size_t kFieldTypeSize = @@ -107,6 +107,7 @@ class HVecOperation : public HVariableInputSizeInstruction { static_assert(kNumberOfVectorOpPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); using TypeField = BitField<Primitive::Type, kFieldType, kFieldTypeSize>; + private: const size_t vector_length_; DISALLOW_COPY_AND_ASSIGN(HVecOperation); @@ -348,22 +349,25 @@ class HVecHalvingAdd FINAL : public HVecBinaryOperation { bool is_unsigned, bool is_rounded, uint32_t dex_pc = kNoDexPc) - : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc), - is_unsigned_(is_unsigned), - is_rounded_(is_rounded) { + : HVecBinaryOperation(arena, left, right, packed_type, vector_length, dex_pc) { DCHECK(left->IsVecOperation() && right->IsVecOperation()); DCHECK_EQ(left->AsVecOperation()->GetPackedType(), packed_type); DCHECK_EQ(right->AsVecOperation()->GetPackedType(), packed_type); + SetPackedFlag<kFieldHAddIsUnsigned>(is_unsigned); + SetPackedFlag<kFieldHAddIsRounded>(is_rounded); } - bool IsUnsigned() const { return is_unsigned_; } - bool IsRounded() const { return is_rounded_; } + bool IsUnsigned() const { return GetPackedFlag<kFieldHAddIsUnsigned>(); } + bool IsRounded() const { return GetPackedFlag<kFieldHAddIsRounded>(); } DECLARE_INSTRUCTION(VecHalvingAdd); private: - bool is_unsigned_; - bool is_rounded_; + // Additional packed bits. + static constexpr size_t kFieldHAddIsUnsigned = HVecOperation::kNumberOfVectorOpPackedBits; + static constexpr size_t kFieldHAddIsRounded = kFieldHAddIsUnsigned + 1; + static constexpr size_t kNumberOfHAddPackedBits = kFieldHAddIsRounded + 1; + static_assert(kNumberOfHAddPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); DISALLOW_COPY_AND_ASSIGN(HVecHalvingAdd); }; @@ -687,6 +691,7 @@ class HVecLoad FINAL : public HVecMemoryOperation { HInstruction* index, Primitive::Type packed_type, size_t vector_length, + bool is_string_char_at, uint32_t dex_pc = kNoDexPc) : HVecMemoryOperation(arena, packed_type, @@ -696,9 +701,18 @@ class HVecLoad FINAL : public HVecMemoryOperation { dex_pc) { SetRawInputAt(0, base); SetRawInputAt(1, index); + SetPackedFlag<kFieldIsStringCharAt>(is_string_char_at); } DECLARE_INSTRUCTION(VecLoad); + + bool IsStringCharAt() const { return GetPackedFlag<kFieldIsStringCharAt>(); } + private: + // Additional packed bits. + static constexpr size_t kFieldIsStringCharAt = HVecOperation::kNumberOfVectorOpPackedBits; + static constexpr size_t kNumberOfVecLoadPackedBits = kFieldIsStringCharAt + 1; + static_assert(kNumberOfVecLoadPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); + DISALLOW_COPY_AND_ASSIGN(HVecLoad); }; diff --git a/compiler/utils/mips64/assembler_mips64.cc b/compiler/utils/mips64/assembler_mips64.cc index 57223b52a3..f4afb33034 100644 --- a/compiler/utils/mips64/assembler_mips64.cc +++ b/compiler/utils/mips64/assembler_mips64.cc @@ -1356,6 +1356,106 @@ void Mips64Assembler::Mod_uD(VectorRegister wd, VectorRegister ws, VectorRegiste EmitMsa3R(0x7, 0x3, wt, ws, wd, 0x12); } +void Mips64Assembler::Add_aB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x0, 0x0, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Add_aH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x0, 0x1, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Add_aW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x0, 0x2, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Add_aD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x0, 0x3, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Ave_sB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x4, 0x0, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Ave_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x4, 0x1, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Ave_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x4, 0x2, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Ave_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x4, 0x3, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Ave_uB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x5, 0x0, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Ave_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x5, 0x1, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Ave_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x5, 0x2, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Ave_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Aver_sB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x6, 0x0, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Aver_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x6, 0x1, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Aver_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x6, 0x2, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Aver_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x6, 0x3, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Aver_uB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x7, 0x0, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Aver_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x7, 0x1, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Aver_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x7, 0x2, wt, ws, wd, 0x10); +} + +void Mips64Assembler::Aver_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x7, 0x3, wt, ws, wd, 0x10); +} + void Mips64Assembler::FaddW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); EmitMsa3R(0x0, 0x0, wt, ws, wd, 0x1b); diff --git a/compiler/utils/mips64/assembler_mips64.h b/compiler/utils/mips64/assembler_mips64.h index 666c6935a1..6ac336178b 100644 --- a/compiler/utils/mips64/assembler_mips64.h +++ b/compiler/utils/mips64/assembler_mips64.h @@ -682,6 +682,26 @@ class Mips64Assembler FINAL : public Assembler, public JNIMacroAssembler<Pointer void Mod_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt); void Mod_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt); void Mod_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Add_aB(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Add_aH(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Add_aW(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Add_aD(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Ave_sB(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Ave_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Ave_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Ave_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Ave_uB(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Ave_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Ave_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Ave_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Aver_sB(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Aver_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Aver_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Aver_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Aver_uB(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Aver_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Aver_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Aver_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt); void FaddW(VectorRegister wd, VectorRegister ws, VectorRegister wt); void FaddD(VectorRegister wd, VectorRegister ws, VectorRegister wt); diff --git a/compiler/utils/mips64/assembler_mips64_test.cc b/compiler/utils/mips64/assembler_mips64_test.cc index f2e3b1610c..084ce6fa08 100644 --- a/compiler/utils/mips64/assembler_mips64_test.cc +++ b/compiler/utils/mips64/assembler_mips64_test.cc @@ -2668,6 +2668,106 @@ TEST_F(AssemblerMIPS64Test, Mod_uD) { "mod_u.d"); } +TEST_F(AssemblerMIPS64Test, Add_aB) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Add_aB, "add_a.b ${reg1}, ${reg2}, ${reg3}"), + "add_a.b"); +} + +TEST_F(AssemblerMIPS64Test, Add_aH) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Add_aH, "add_a.h ${reg1}, ${reg2}, ${reg3}"), + "add_a.h"); +} + +TEST_F(AssemblerMIPS64Test, Add_aW) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Add_aW, "add_a.w ${reg1}, ${reg2}, ${reg3}"), + "add_a.w"); +} + +TEST_F(AssemblerMIPS64Test, Add_aD) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Add_aD, "add_a.d ${reg1}, ${reg2}, ${reg3}"), + "add_a.d"); +} + +TEST_F(AssemblerMIPS64Test, Ave_sB) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Ave_sB, "ave_s.b ${reg1}, ${reg2}, ${reg3}"), + "ave_s.b"); +} + +TEST_F(AssemblerMIPS64Test, Ave_sH) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Ave_sH, "ave_s.h ${reg1}, ${reg2}, ${reg3}"), + "ave_s.h"); +} + +TEST_F(AssemblerMIPS64Test, Ave_sW) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Ave_sW, "ave_s.w ${reg1}, ${reg2}, ${reg3}"), + "ave_s.w"); +} + +TEST_F(AssemblerMIPS64Test, Ave_sD) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Ave_sD, "ave_s.d ${reg1}, ${reg2}, ${reg3}"), + "ave_s.d"); +} + +TEST_F(AssemblerMIPS64Test, Ave_uB) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Ave_uB, "ave_u.b ${reg1}, ${reg2}, ${reg3}"), + "ave_u.b"); +} + +TEST_F(AssemblerMIPS64Test, Ave_uH) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Ave_uH, "ave_u.h ${reg1}, ${reg2}, ${reg3}"), + "ave_u.h"); +} + +TEST_F(AssemblerMIPS64Test, Ave_uW) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Ave_uW, "ave_u.w ${reg1}, ${reg2}, ${reg3}"), + "ave_u.w"); +} + +TEST_F(AssemblerMIPS64Test, Ave_uD) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Ave_uD, "ave_u.d ${reg1}, ${reg2}, ${reg3}"), + "ave_u.d"); +} + +TEST_F(AssemblerMIPS64Test, Aver_sB) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Aver_sB, "aver_s.b ${reg1}, ${reg2}, ${reg3}"), + "aver_s.b"); +} + +TEST_F(AssemblerMIPS64Test, Aver_sH) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Aver_sH, "aver_s.h ${reg1}, ${reg2}, ${reg3}"), + "aver_s.h"); +} + +TEST_F(AssemblerMIPS64Test, Aver_sW) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Aver_sW, "aver_s.w ${reg1}, ${reg2}, ${reg3}"), + "aver_s.w"); +} + +TEST_F(AssemblerMIPS64Test, Aver_sD) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Aver_sD, "aver_s.d ${reg1}, ${reg2}, ${reg3}"), + "aver_s.d"); +} + +TEST_F(AssemblerMIPS64Test, Aver_uB) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Aver_uB, "aver_u.b ${reg1}, ${reg2}, ${reg3}"), + "aver_u.b"); +} + +TEST_F(AssemblerMIPS64Test, Aver_uH) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Aver_uH, "aver_u.h ${reg1}, ${reg2}, ${reg3}"), + "aver_u.h"); +} + +TEST_F(AssemblerMIPS64Test, Aver_uW) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Aver_uW, "aver_u.w ${reg1}, ${reg2}, ${reg3}"), + "aver_u.w"); +} + +TEST_F(AssemblerMIPS64Test, Aver_uD) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Aver_uD, "aver_u.d ${reg1}, ${reg2}, ${reg3}"), + "aver_u.d"); +} + TEST_F(AssemblerMIPS64Test, FaddW) { DriverStr(RepeatVVV(&mips64::Mips64Assembler::FaddW, "fadd.w ${reg1}, ${reg2}, ${reg3}"), "fadd.w"); diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc index a267766456..d546072f58 100644 --- a/dex2oat/dex2oat_test.cc +++ b/dex2oat/dex2oat_test.cc @@ -884,6 +884,7 @@ class Dex2oatReturnCodeTest : public Dex2oatTest { }; TEST_F(Dex2oatReturnCodeTest, TestCreateRuntime) { + TEST_DISABLED_FOR_MEMORY_TOOL(); // b/19100793 int status = RunTest({ "--boot-image=/this/does/not/exist/yolo.oat" }); EXPECT_EQ(static_cast<int>(dex2oat::ReturnCode::kCreateRuntime), WEXITSTATUS(status)) << output_; } diff --git a/dexlayout/Android.bp b/dexlayout/Android.bp index 4b65c5299a..a2116cdc93 100644 --- a/dexlayout/Android.bp +++ b/dexlayout/Android.bp @@ -49,6 +49,7 @@ art_cc_binary { shared_libs: [ "libart", "libart-dexlayout", + "libbase", ], } diff --git a/dexlayout/dex_ir.cc b/dexlayout/dex_ir.cc index 3f715cf37f..f1c6f67a7c 100644 --- a/dexlayout/dex_ir.cc +++ b/dexlayout/dex_ir.cc @@ -451,8 +451,8 @@ AnnotationItem* Collections::CreateAnnotationItem(const DexFile::AnnotationItem* } uint8_t visibility = annotation->visibility_; const uint8_t* annotation_data = annotation->annotation_; - EncodedValue* encoded_value = - ReadEncodedValue(&annotation_data, DexFile::kDexAnnotationAnnotation, 0); + std::unique_ptr<EncodedValue> encoded_value( + ReadEncodedValue(&annotation_data, DexFile::kDexAnnotationAnnotation, 0)); // TODO: Calculate the size of the annotation. AnnotationItem* annotation_item = new AnnotationItem(visibility, encoded_value->ReleaseEncodedAnnotation()); diff --git a/dexlayout/dexlayout_main.cc b/dexlayout/dexlayout_main.cc index 38faf9688b..3c627ea6f0 100644 --- a/dexlayout/dexlayout_main.cc +++ b/dexlayout/dexlayout_main.cc @@ -170,14 +170,14 @@ int DexlayoutDriver(int argc, char** argv) { } // Open profile file. - ProfileCompilationInfo* profile_info = nullptr; + std::unique_ptr<ProfileCompilationInfo> profile_info; if (options.profile_file_name_) { int profile_fd = open(options.profile_file_name_, O_RDONLY); if (profile_fd < 0) { fprintf(stderr, "Can't open %s\n", options.profile_file_name_); return 1; } - profile_info = new ProfileCompilationInfo(); + profile_info.reset(new ProfileCompilationInfo()); if (!profile_info->Load(profile_fd)) { fprintf(stderr, "Can't read profile info from %s\n", options.profile_file_name_); return 1; @@ -185,13 +185,19 @@ int DexlayoutDriver(int argc, char** argv) { } // Create DexLayout instance. - DexLayout dex_layout(options, profile_info, out_file); + DexLayout dex_layout(options, profile_info.get(), out_file); // Process all files supplied on command line. int result = 0; while (optind < argc) { result |= dex_layout.ProcessFile(argv[optind++]); } // while + + if (options.output_file_name_) { + CHECK(out_file != nullptr && out_file != stdout); + fclose(out_file); + } + return result != 0; } diff --git a/dexoptanalyzer/dexoptanalyzer.cc b/dexoptanalyzer/dexoptanalyzer.cc index 965e4073ea..9a2eb7f8dd 100644 --- a/dexoptanalyzer/dexoptanalyzer.cc +++ b/dexoptanalyzer/dexoptanalyzer.cc @@ -216,6 +216,8 @@ class DexoptAnalyzer FINAL { if (!CreateRuntime()) { return kErrorCannotCreateRuntime; } + std::unique_ptr<Runtime> runtime(Runtime::Current()); + OatFileAssistant oat_file_assistant(dex_file_.c_str(), isa_, /*load_executable*/ false); // Always treat elements of the bootclasspath as up-to-date. // TODO(calin): this check should be in OatFileAssistant. diff --git a/disassembler/disassembler_mips.cc b/disassembler/disassembler_mips.cc index eb57d339af..3c60bf4be5 100644 --- a/disassembler/disassembler_mips.cc +++ b/disassembler/disassembler_mips.cc @@ -433,6 +433,11 @@ static const MipsInstruction gMipsInstructions[] = { { kMsaMask | (0x7 << 23), kMsa | (0x5 << 23) | 0x12, "div_u", "Vkmn" }, { kMsaMask | (0x7 << 23), kMsa | (0x6 << 23) | 0x12, "mod_s", "Vkmn" }, { kMsaMask | (0x7 << 23), kMsa | (0x7 << 23) | 0x12, "mod_u", "Vkmn" }, + { kMsaMask | (0x7 << 23), kMsa | (0x0 << 23) | 0x10, "add_a", "Vkmn" }, + { kMsaMask | (0x7 << 23), kMsa | (0x4 << 23) | 0x10, "ave_s", "Vkmn" }, + { kMsaMask | (0x7 << 23), kMsa | (0x5 << 23) | 0x10, "ave_u", "Vkmn" }, + { kMsaMask | (0x7 << 23), kMsa | (0x6 << 23) | 0x10, "aver_s", "Vkmn" }, + { kMsaMask | (0x7 << 23), kMsa | (0x7 << 23) | 0x10, "aver_u", "Vkmn" }, { kMsaMask | (0xf << 22), kMsa | (0x0 << 22) | 0x1b, "fadd", "Ukmn" }, { kMsaMask | (0xf << 22), kMsa | (0x1 << 22) | 0x1b, "fsub", "Ukmn" }, { kMsaMask | (0xf << 22), kMsa | (0x2 << 22) | 0x1b, "fmul", "Ukmn" }, diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 878d0f2cfe..f07e0f9941 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -125,9 +125,12 @@ class OatSymbolizer FINAL { std::unique_ptr<const InstructionSetFeatures> features = InstructionSetFeatures::FromBitmap( isa, oat_file_->GetOatHeader().GetInstructionSetFeaturesBitmap()); - File* elf_file = OS::CreateEmptyFile(output_name_.c_str()); + std::unique_ptr<File> elf_file(OS::CreateEmptyFile(output_name_.c_str())); + if (elf_file == nullptr) { + return false; + } std::unique_ptr<BufferedOutputStream> output_stream( - MakeUnique<BufferedOutputStream>(MakeUnique<FileOutputStream>(elf_file))); + MakeUnique<BufferedOutputStream>(MakeUnique<FileOutputStream>(elf_file.get()))); builder_.reset(new ElfBuilder<ElfTypes>(isa, features.get(), output_stream.get())); builder_->Start(); @@ -182,7 +185,17 @@ class OatSymbolizer FINAL { builder_->End(); - return builder_->Good(); + bool ret_value = builder_->Good(); + + builder_.reset(); + output_stream.reset(); + + if (elf_file->FlushCloseOrErase() != 0) { + return false; + } + elf_file.reset(); + + return ret_value; } void Walk() { @@ -2842,14 +2855,14 @@ static int DumpOat(Runtime* runtime, const char* oat_filename, OatDumperOptions* static int SymbolizeOat(const char* oat_filename, std::string& output_name, bool no_bits) { std::string error_msg; - OatFile* oat_file = OatFile::Open(oat_filename, - oat_filename, - nullptr, - nullptr, - false, - /*low_4gb*/false, - nullptr, - &error_msg); + std::unique_ptr<OatFile> oat_file(OatFile::Open(oat_filename, + oat_filename, + nullptr, + nullptr, + false, + /*low_4gb*/false, + nullptr, + &error_msg)); if (oat_file == nullptr) { fprintf(stderr, "Failed to open oat file from '%s': %s\n", oat_filename, error_msg.c_str()); return EXIT_FAILURE; @@ -2859,10 +2872,10 @@ static int SymbolizeOat(const char* oat_filename, std::string& output_name, bool // Try to produce an ELF file of the same type. This is finicky, as we have used 32-bit ELF // files for 64-bit code in the past. if (Is64BitInstructionSet(oat_file->GetOatHeader().GetInstructionSet())) { - OatSymbolizer<ElfTypes64> oat_symbolizer(oat_file, output_name, no_bits); + OatSymbolizer<ElfTypes64> oat_symbolizer(oat_file.get(), output_name, no_bits); result = oat_symbolizer.Symbolize(); } else { - OatSymbolizer<ElfTypes32> oat_symbolizer(oat_file, output_name, no_bits); + OatSymbolizer<ElfTypes32> oat_symbolizer(oat_file.get(), output_name, no_bits); result = oat_symbolizer.Symbolize(); } if (!result) { diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc index fbb0978d53..e750ede8fa 100644 --- a/patchoat/patchoat.cc +++ b/patchoat/patchoat.cc @@ -30,6 +30,7 @@ #include "art_field-inl.h" #include "art_method-inl.h" #include "base/dumpable.h" +#include "base/memory_tool.h" #include "base/scoped_flock.h" #include "base/stringpiece.h" #include "base/unix_file/fd_file.h" @@ -142,6 +143,8 @@ bool PatchOat::Patch(const std::string& image_location, LOG(ERROR) << "Unable to initialize runtime"; return false; } + std::unique_ptr<Runtime> runtime(Runtime::Current()); + // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start, // give it away now and then switch to a more manageable ScopedObjectAccess. Thread::Current()->TransitionFromRunnableToSuspended(kNative); @@ -286,6 +289,13 @@ bool PatchOat::Patch(const std::string& image_location, return false; } } + + if (!kIsDebugBuild && !(RUNNING_ON_MEMORY_TOOL && kMemoryToolDetectsLeaks)) { + // We want to just exit on non-debug builds, not bringing the runtime down + // in an orderly fashion. So release the following fields. + runtime.release(); + } + return true; } diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S index 029de4680c..a277edfa29 100644 --- a/runtime/arch/arm/quick_entrypoints_arm.S +++ b/runtime/arch/arm/quick_entrypoints_arm.S @@ -872,7 +872,7 @@ ENTRY art_quick_aput_obj POISON_HEAP_REF r2 str r2, [r3, r1, lsl #2] ldr r3, [r9, #THREAD_CARD_TABLE_OFFSET] - lsr r0, r0, #7 + lsr r0, r0, #CARD_TABLE_CARD_SHIFT strb r3, [r3, r0] blx lr .Ldo_aput_null: @@ -900,7 +900,7 @@ ENTRY art_quick_aput_obj POISON_HEAP_REF r2 str r2, [r3, r1, lsl #2] ldr r3, [r9, #THREAD_CARD_TABLE_OFFSET] - lsr r0, r0, #7 + lsr r0, r0, #CARD_TABLE_CARD_SHIFT strb r3, [r3, r0] blx lr .Lthrow_array_store_exception: diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S index d043962b96..c555126668 100644 --- a/runtime/arch/arm64/quick_entrypoints_arm64.S +++ b/runtime/arch/arm64/quick_entrypoints_arm64.S @@ -1416,7 +1416,7 @@ ENTRY art_quick_aput_obj POISON_HEAP_REF w2 str w2, [x3, x1, lsl #2] // Heap reference = 32b ldr x3, [xSELF, #THREAD_CARD_TABLE_OFFSET] - lsr x0, x0, #7 + lsr x0, x0, #CARD_TABLE_CARD_SHIFT strb w3, [x3, x0] ret .Ldo_aput_null: @@ -1447,7 +1447,7 @@ ENTRY art_quick_aput_obj POISON_HEAP_REF w2 str w2, [x3, x1, lsl #2] // Heap reference = 32b ldr x3, [xSELF, #THREAD_CARD_TABLE_OFFSET] - lsr x0, x0, #7 + lsr x0, x0, #CARD_TABLE_CARD_SHIFT strb w3, [x3, x0] ret .cfi_restore_state // Reset unwind info so following code unwinds. diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S index 722a67908f..61a3a04708 100644 --- a/runtime/arch/mips/quick_entrypoints_mips.S +++ b/runtime/arch/mips/quick_entrypoints_mips.S @@ -1406,7 +1406,7 @@ ENTRY art_quick_aput_obj POISON_HEAP_REF $a2 sw $a2, MIRROR_OBJECT_ARRAY_DATA_OFFSET($t0) lw $t0, THREAD_CARD_TABLE_OFFSET(rSELF) - srl $t1, $a0, 7 + srl $t1, $a0, CARD_TABLE_CARD_SHIFT add $t1, $t1, $t0 sb $t0, ($t1) jalr $zero, $ra diff --git a/runtime/arch/mips64/quick_entrypoints_mips64.S b/runtime/arch/mips64/quick_entrypoints_mips64.S index 9402232996..24caa0e290 100644 --- a/runtime/arch/mips64/quick_entrypoints_mips64.S +++ b/runtime/arch/mips64/quick_entrypoints_mips64.S @@ -1374,7 +1374,7 @@ ENTRY art_quick_aput_obj POISON_HEAP_REF $a2 sw $a2, MIRROR_OBJECT_ARRAY_DATA_OFFSET($t0) ld $t0, THREAD_CARD_TABLE_OFFSET(rSELF) - dsrl $t1, $a0, 7 + dsrl $t1, $a0, CARD_TABLE_CARD_SHIFT daddu $t1, $t1, $t0 sb $t0, ($t1) jalr $zero, $ra diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S index 6c0bcc9d88..3694c3e7a6 100644 --- a/runtime/arch/x86/quick_entrypoints_x86.S +++ b/runtime/arch/x86/quick_entrypoints_x86.S @@ -1526,7 +1526,7 @@ DEFINE_FUNCTION art_quick_aput_obj POISON_HEAP_REF edx movl %edx, MIRROR_OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4) movl %fs:THREAD_CARD_TABLE_OFFSET, %edx - shrl LITERAL(7), %eax + shrl LITERAL(CARD_TABLE_CARD_SHIFT), %eax movb %dl, (%edx, %eax) ret .Ldo_aput_null: @@ -1567,7 +1567,7 @@ DEFINE_FUNCTION art_quick_aput_obj POISON_HEAP_REF edx movl %edx, MIRROR_OBJECT_ARRAY_DATA_OFFSET(%eax, %ecx, 4) // do the aput movl %fs:THREAD_CARD_TABLE_OFFSET, %edx - shrl LITERAL(7), %eax + shrl LITERAL(CARD_TABLE_CARD_SHIFT), %eax movb %dl, (%edx, %eax) ret CFI_ADJUST_CFA_OFFSET(12) // 3 POP after the jz for unwinding. diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S index 8e2acab3eb..ad7c2b3765 100644 --- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S +++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S @@ -1504,8 +1504,8 @@ DEFINE_FUNCTION art_quick_aput_obj movl %edx, MIRROR_OBJECT_ARRAY_DATA_OFFSET(%edi, %esi, 4) // movq %rdx, MIRROR_OBJECT_ARRAY_DATA_OFFSET(%rdi, %rsi, 4) movq %gs:THREAD_CARD_TABLE_OFFSET, %rdx - shrl LITERAL(7), %edi -// shrl LITERAL(7), %rdi + shrl LITERAL(CARD_TABLE_CARD_SHIFT), %edi +// shrl LITERAL(CARD_TABLE_CARD_SHIFT), %rdi movb %dl, (%rdx, %rdi) // Note: this assumes that top 32b of %rdi are zero ret .Ldo_aput_null: @@ -1545,8 +1545,8 @@ DEFINE_FUNCTION art_quick_aput_obj movl %edx, MIRROR_OBJECT_ARRAY_DATA_OFFSET(%edi, %esi, 4) // movq %rdx, MIRROR_OBJECT_ARRAY_DATA_OFFSET(%rdi, %rsi, 4) movq %gs:THREAD_CARD_TABLE_OFFSET, %rdx - shrl LITERAL(7), %edi -// shrl LITERAL(7), %rdi + shrl LITERAL(CARD_TABLE_CARD_SHIFT), %edi +// shrl LITERAL(CARD_TABLE_CARD_SHIFT), %rdi movb %dl, (%rdx, %rdi) // Note: this assumes that top 32b of %rdi are zero // movb %dl, (%rdx, %rdi) ret diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index 7da722160e..bd4f99b7f5 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -3517,7 +3517,13 @@ collector::GcType Heap::WaitForGcToCompleteLocked(GcCause cause, Thread* self) { // is not the heap task daemon thread, it's considered as a // blocking GC (i.e., blocking itself). running_collection_is_blocking_ = true; - VLOG(gc) << "Starting a blocking GC " << cause; + // Don't log fake "GC" types that are only used for debugger or hidden APIs. If we log these, + // it results in log spam. kGcCauseExplicit is already logged in LogGC, so avoid it here too. + if (cause == kGcCauseForAlloc || + cause == kGcCauseForNativeAlloc || + cause == kGcCauseDisableMovingGc) { + VLOG(gc) << "Starting a blocking GC " << cause; + } } return last_gc_type; } diff --git a/runtime/generated/asm_support_gen.h b/runtime/generated/asm_support_gen.h index af57397f96..4af562560c 100644 --- a/runtime/generated/asm_support_gen.h +++ b/runtime/generated/asm_support_gen.h @@ -78,6 +78,8 @@ DEFINE_CHECK_EQ(static_cast<int32_t>(STRING_DEX_CACHE_SIZE_MINUS_ONE), (static_c DEFINE_CHECK_EQ(static_cast<int32_t>(STRING_DEX_CACHE_HASH_BITS), (static_cast<int32_t>(art::LeastSignificantBit(art::mirror::DexCache::kDexCacheStringCacheSize)))) #define STRING_DEX_CACHE_ELEMENT_SIZE 8 DEFINE_CHECK_EQ(static_cast<int32_t>(STRING_DEX_CACHE_ELEMENT_SIZE), (static_cast<int32_t>(sizeof(art::mirror::StringDexCachePair)))) +#define CARD_TABLE_CARD_SHIFT 0x7 +DEFINE_CHECK_EQ(static_cast<size_t>(CARD_TABLE_CARD_SHIFT), (static_cast<size_t>(art::gc::accounting::CardTable::kCardShift))) #define MIN_LARGE_OBJECT_THRESHOLD 0x3000 DEFINE_CHECK_EQ(static_cast<size_t>(MIN_LARGE_OBJECT_THRESHOLD), (static_cast<size_t>(art::gc::Heap::kMinLargeObjectThreshold))) #define LOCK_WORD_STATE_SHIFT 30 diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc index 70be30c22c..96934bc0ca 100644 --- a/runtime/interpreter/unstarted_runtime.cc +++ b/runtime/interpreter/unstarted_runtime.cc @@ -568,7 +568,7 @@ static void GetResourceAsStream(Thread* self, // Copy in content. memcpy(h_array->GetData(), mem_map->Begin(), map_size); // Be proactive releasing memory. - mem_map.release(); + mem_map.reset(); // Create a ByteArrayInputStream. Handle<mirror::Class> h_class(hs.NewHandle( diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar index f725b89eb1..df822e7cf5 100755 --- a/test/etc/run-test-jar +++ b/test/etc/run-test-jar @@ -603,10 +603,10 @@ if [ "$PREBUILD" = "y" ]; then # Use -k 1m to SIGKILL it a minute later if it hasn't ended. dex2oat_cmdline="timeout -k 1m -s SIGRTMIN+2 1m ${dex2oat_cmdline}" fi - if [ "$TEST_VDEX" = "y" ]; then + if [ "$PROFILE" = "y" ] || [ "$RANDOM_PROFILE" = "y" ]; then + vdex_cmdline="${dex2oat_cmdline} ${VDEX_FILTER} --input-vdex=$DEX_LOCATION/oat/$ISA/$TEST_NAME.vdex --output-vdex=$DEX_LOCATION/oat/$ISA/$TEST_NAME.vdex" + elif [ "$TEST_VDEX" = "y" ]; then vdex_cmdline="${dex2oat_cmdline} ${VDEX_FILTER} --input-vdex=$DEX_LOCATION/oat/$ISA/$TEST_NAME.vdex" - elif [ "$PROFILE" = "y" ] || [ "$RANDOM_PROFILE" = "y" ]; then - vdex_cmdline="${dex2oat_cmdline} --input-vdex=$DEX_LOCATION/oat/$ISA/$TEST_NAME.vdex --output-vdex=$DEX_LOCATION/oat/$ISA/$TEST_NAME.vdex" fi fi diff --git a/test/knownfailures.json b/test/knownfailures.json index c7ad5bf9c1..f7fb3573e6 100644 --- a/test/knownfailures.json +++ b/test/knownfailures.json @@ -667,12 +667,6 @@ "bug": "b/37636792" }, { - "tests": "648-many-direct-methods", - "variant": "optimizing", - "description": "Test disabled with AOT because of dex2oatd timeouts.", - "bug": "b/33650497" - }, - { "tests": [ "536-checker-needs-access-check", "537-checker-inline-and-unverified", diff --git a/tools/cpp-define-generator/constant_card_table.def b/tools/cpp-define-generator/constant_card_table.def new file mode 100644 index 0000000000..ae3e8f399f --- /dev/null +++ b/tools/cpp-define-generator/constant_card_table.def @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2017 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. + */ + +// Export heap values. + +#if defined(DEFINE_INCLUDE_DEPENDENCIES) +#include "gc/accounting/card_table.h" +#endif + +// Size of references to the heap on the stack. +DEFINE_EXPR(CARD_TABLE_CARD_SHIFT, size_t, art::gc::accounting::CardTable::kCardShift) + diff --git a/tools/cpp-define-generator/offsets_all.def b/tools/cpp-define-generator/offsets_all.def index 13371a1f71..b8947de2dc 100644 --- a/tools/cpp-define-generator/offsets_all.def +++ b/tools/cpp-define-generator/offsets_all.def @@ -49,6 +49,7 @@ // TODO: MIRROR_STRING offsets (depends on header size) #include "offset_dexcache.def" #include "constant_dexcache.def" +#include "constant_card_table.def" #include "constant_heap.def" #include "constant_lockword.def" #include "constant_globals.def" |