diff options
160 files changed, 1181 insertions, 701 deletions
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk index d59d8f690c..bd7f900965 100644 --- a/build/Android.gtest.mk +++ b/build/Android.gtest.mk @@ -26,6 +26,8 @@ GTEST_DEX_DIRECTORIES := \ AbstractMethod \ AllFields \ DexToDexDecompiler \ + ErroneousA \ + ErroneousB \ ExceptionHandle \ GetMethodSignature \ ImageLayoutA \ @@ -85,7 +87,7 @@ $(ART_TEST_TARGET_GTEST_VerifierDeps_DEX): $(ART_TEST_GTEST_VerifierDeps_SRC) $( ART_GTEST_dex2oat_environment_tests_DEX_DEPS := Main MainStripped MultiDex MultiDexModifiedSecondary Nested ART_GTEST_atomic_method_ref_map_test_DEX_DEPS := Interfaces -ART_GTEST_class_linker_test_DEX_DEPS := Interfaces MethodTypes MultiDex MyClass Nested Statics StaticsFromCode +ART_GTEST_class_linker_test_DEX_DEPS := ErroneousA ErroneousB Interfaces MethodTypes MultiDex MyClass Nested Statics StaticsFromCode ART_GTEST_class_table_test_DEX_DEPS := XandY ART_GTEST_compiler_driver_test_DEX_DEPS := AbstractMethod StaticLeafMethods ProfileTestMultiDex ART_GTEST_dex_cache_test_DEX_DEPS := Main Packages MethodTypes diff --git a/cmdline/cmdline.h b/cmdline/cmdline.h index 6e042c3c27..f4540ff655 100644 --- a/cmdline/cmdline.h +++ b/cmdline/cmdline.h @@ -24,10 +24,12 @@ #include <iostream> #include <string> -#include "runtime.h" +#include "android-base/stringprintf.h" + +#include "base/logging.h" #include "base/stringpiece.h" #include "noop_compiler_callbacks.h" -#include "base/logging.h" +#include "runtime.h" #if !defined(NDEBUG) #define DBG_LOG LOG(INFO) @@ -197,7 +199,7 @@ struct CmdlineArgs { " Example: --boot-image=/system/framework/boot.art\n" " (specifies /system/framework/<arch>/boot.art as the image file)\n" "\n"; - usage += StringPrintf( // Optional. + usage += android::base::StringPrintf( // Optional. " --instruction-set=(arm|arm64|mips|mips64|x86|x86_64): for locating the image\n" " file based on the image location set.\n" " Example: --instruction-set=x86\n" @@ -264,8 +266,8 @@ struct CmdlineArgs { // Check that the boot image location points to a valid file name. std::string file_name; if (!LocationToFilename(boot_image_location, instruction_set_, &file_name)) { - *error_msg = StringPrintf("No corresponding file for location '%s' exists", - file_name.c_str()); + *error_msg = android::base::StringPrintf("No corresponding file for location '%s' exists", + file_name.c_str()); return false; } diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc index cf69f469a0..d4f6545c59 100644 --- a/compiler/dex/dex_to_dex_compiler.cc +++ b/compiler/dex/dex_to_dex_compiler.cc @@ -16,6 +16,8 @@ #include "dex_to_dex_compiler.h" +#include "android-base/stringprintf.h" + #include "art_field-inl.h" #include "art_method-inl.h" #include "base/logging.h" @@ -32,6 +34,8 @@ namespace art { namespace optimizer { +using android::base::StringPrintf; + // Controls quickening activation. const bool kEnableQuickening = true; // Control check-cast elision. diff --git a/compiler/driver/dex_compilation_unit.cc b/compiler/driver/dex_compilation_unit.cc index 64fd9e7f0f..47b19297e5 100644 --- a/compiler/driver/dex_compilation_unit.cc +++ b/compiler/driver/dex_compilation_unit.cc @@ -16,7 +16,6 @@ #include "dex_compilation_unit.h" -#include "base/stringprintf.h" #include "mirror/dex_cache.h" #include "utils.h" diff --git a/compiler/elf_writer_test.cc b/compiler/elf_writer_test.cc index 6f48779258..9669c4a9d3 100644 --- a/compiler/elf_writer_test.cc +++ b/compiler/elf_writer_test.cc @@ -16,7 +16,6 @@ #include "elf_file.h" -#include "base/stringprintf.h" #include "base/unix_file/fd_file.h" #include "common_compiler_test.h" #include "elf_file.h" diff --git a/compiler/image_test.cc b/compiler/image_test.cc index 9bbe595fa9..1290379569 100644 --- a/compiler/image_test.cc +++ b/compiler/image_test.cc @@ -20,6 +20,8 @@ #include <string> #include <vector> +#include "android-base/stringprintf.h" + #include "base/unix_file/fd_file.h" #include "class_linker-inl.h" #include "common_compiler_test.h" @@ -134,7 +136,8 @@ void CompilationHelper::Compile(CompilerDriver* driver, // Create a generic tmp file, to be the base of the .art and .oat temporary files. ScratchFile location; for (int i = 0; i < static_cast<int>(class_path.size()); ++i) { - std::string cur_location(StringPrintf("%s-%d.art", location.GetFilename().c_str(), i)); + std::string cur_location = + android::base::StringPrintf("%s-%d.art", location.GetFilename().c_str(), i); image_locations.push_back(ScratchFile(cur_location)); } } diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index b22ca470b5..9c38445276 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -1113,11 +1113,15 @@ ObjectArray<Object>* ImageWriter::CreateImageRoots(size_t oat_index) const { } // build an Object[] of the roots needed to restore the runtime + int32_t image_roots_size = ImageHeader::NumberOfImageRoots(compile_app_image_); auto image_roots(hs.NewHandle( - ObjectArray<Object>::Alloc(self, object_array_class.Get(), ImageHeader::kImageRootsMax))); + ObjectArray<Object>::Alloc(self, object_array_class.Get(), image_roots_size))); image_roots->Set<false>(ImageHeader::kDexCaches, dex_caches.Get()); image_roots->Set<false>(ImageHeader::kClassRoots, class_linker->GetClassRoots()); - for (int i = 0; i < ImageHeader::kImageRootsMax; i++) { + // image_roots[ImageHeader::kClassLoader] will be set later for app image. + static_assert(ImageHeader::kClassLoader + 1u == ImageHeader::kImageRootsMax, + "Class loader should be the last image root."); + for (int32_t i = 0; i < ImageHeader::kImageRootsMax - 1; ++i) { CHECK(image_roots->Get(i) != nullptr); } return image_roots.Get(); @@ -1539,6 +1543,12 @@ void ImageWriter::CalculateNewObjectOffsets() { } // Process the work stack in case anything was added by TryAssignBinSlot. ProcessWorkStack(&work_stack); + + // Store the class loader in the class roots. + CHECK_EQ(class_loaders_.size(), 1u); + CHECK_EQ(image_roots.size(), 1u); + CHECK(*class_loaders_.begin() != nullptr); + image_roots[0]->Set<false>(ImageHeader::kClassLoader, *class_loaders_.begin()); } // Verify that all objects have assigned image bin slots. diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc index 9dfb434b10..148ce4f9ee 100644 --- a/compiler/jit/jit_compiler.cc +++ b/compiler/jit/jit_compiler.cc @@ -16,6 +16,8 @@ #include "jit_compiler.h" +#include "android-base/stringprintf.h" + #include "arch/instruction_set.h" #include "arch/instruction_set_features.h" #include "art_method-inl.h" @@ -81,7 +83,7 @@ NO_RETURN static void Usage(const char* fmt, ...) { va_list ap; va_start(ap, fmt); std::string error; - StringAppendV(&error, fmt, ap); + android::base::StringAppendV(&error, fmt, ap); LOG(FATAL) << error; va_end(ap); exit(EXIT_FAILURE); diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc index 0a778b0954..edc93ab0c4 100644 --- a/compiler/oat_test.cc +++ b/compiler/oat_test.cc @@ -14,6 +14,8 @@ * limitations under the License. */ +#include "android-base/stringprintf.h" + #include "arch/instruction_set_features.h" #include "art_method-inl.h" #include "base/enums.h" @@ -48,7 +50,7 @@ NO_RETURN static void Usage(const char* fmt, ...) { va_list ap; va_start(ap, fmt); std::string error; - StringAppendV(&error, fmt, ap); + android::base::StringAppendV(&error, fmt, ap); LOG(FATAL) << error; va_end(ap); UNREACHABLE(); diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 55f3c3ceef..1c5aec01c6 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -46,8 +46,10 @@ using helpers::InputOperandAt; using helpers::InputRegister; using helpers::InputRegisterAt; using helpers::InputSRegisterAt; +using helpers::InputVRegister; using helpers::InputVRegisterAt; using helpers::Int32ConstantFrom; +using helpers::Int64ConstantFrom; using helpers::LocationFrom; using helpers::LowRegisterFrom; using helpers::LowSRegisterFrom; @@ -56,6 +58,7 @@ using helpers::OutputSRegister; using helpers::OutputVRegister; using helpers::RegisterFrom; using helpers::SRegisterFrom; +using helpers::Uint64ConstantFrom; using vixl::ExactAssemblyScope; using vixl::CodeBufferCheckScope; @@ -1378,7 +1381,7 @@ void CodeGeneratorARMVIXL::GenerateFrameEntry() { if (!skip_overflow_check) { UseScratchRegisterScope temps(GetVIXLAssembler()); vixl32::Register temp = temps.Acquire(); - __ Sub(temp, sp, static_cast<int32_t>(GetStackOverflowReservedBytes(kArm))); + __ Sub(temp, sp, Operand::From(GetStackOverflowReservedBytes(kArm))); // The load must immediately precede RecordPcInfo. ExactAssemblyScope aas(GetVIXLAssembler(), vixl32::kMaxInstructionSizeInBytes, @@ -1795,7 +1798,7 @@ void InstructionCodeGeneratorARMVIXL::GenerateLongComparesAndJumps(HCondition* c break; } if (right.IsConstant()) { - int64_t value = right.GetConstant()->AsLongConstant()->GetValue(); + int64_t value = Int64ConstantFrom(right); int32_t val_low = Low32Bits(value); int32_t val_high = High32Bits(value); @@ -1880,7 +1883,7 @@ void InstructionCodeGeneratorARMVIXL::GenerateTestAndBranch(HInstruction* instru __ B(true_target); } } else { - DCHECK(cond->AsIntConstant()->IsFalse()) << cond->AsIntConstant()->GetValue(); + DCHECK(cond->AsIntConstant()->IsFalse()) << Int32ConstantFrom(cond); if (false_target != nullptr) { __ B(false_target); } @@ -2482,9 +2485,7 @@ void InstructionCodeGeneratorARMVIXL::VisitNeg(HNeg* neg) { case Primitive::kPrimFloat: case Primitive::kPrimDouble: - // TODO(VIXL): Consider introducing an InputVRegister() - // helper function (equivalent to InputRegister()). - __ Vneg(OutputVRegister(neg), InputVRegisterAt(neg, 0)); + __ Vneg(OutputVRegister(neg), InputVRegister(neg)); break; default: @@ -2774,8 +2775,8 @@ void InstructionCodeGeneratorARMVIXL::VisitTypeConversion(HTypeConversion* conve } else { DCHECK(in.IsConstant()); DCHECK(in.GetConstant()->IsLongConstant()); - int64_t value = in.GetConstant()->AsLongConstant()->GetValue(); - __ Mov(OutputRegister(conversion), static_cast<int32_t>(value)); + int32_t value = Int32ConstantFrom(in); + __ Mov(OutputRegister(conversion), value); } break; @@ -3114,8 +3115,8 @@ void InstructionCodeGeneratorARMVIXL::VisitMul(HMul* mul) { // Extra checks to protect caused by the existence of R1_R2. // The algorithm is wrong if out.hi is either in1.lo or in2.lo: // (e.g. in1=r0_r1, in2=r2_r3 and out=r1_r2); - DCHECK_NE(out_hi.GetCode(), in1_lo.GetCode()); - DCHECK_NE(out_hi.GetCode(), in2_lo.GetCode()); + DCHECK(!out_hi.Is(in1_lo)); + DCHECK(!out_hi.Is(in2_lo)); // input: in1 - 64 bits, in2 - 64 bits // output: out @@ -3155,7 +3156,7 @@ void InstructionCodeGeneratorARMVIXL::DivRemOneOrMinusOne(HBinaryOperation* inst vixl32::Register out = OutputRegister(instruction); vixl32::Register dividend = InputRegisterAt(instruction, 0); - int32_t imm = second.GetConstant()->AsIntConstant()->GetValue(); + int32_t imm = Int32ConstantFrom(second); DCHECK(imm == 1 || imm == -1); if (instruction->IsRem()) { @@ -3180,7 +3181,7 @@ void InstructionCodeGeneratorARMVIXL::DivRemByPowerOfTwo(HBinaryOperation* instr vixl32::Register out = OutputRegister(instruction); vixl32::Register dividend = InputRegisterAt(instruction, 0); vixl32::Register temp = RegisterFrom(locations->GetTemp(0)); - int32_t imm = second.GetConstant()->AsIntConstant()->GetValue(); + int32_t imm = Int32ConstantFrom(second); uint32_t abs_imm = static_cast<uint32_t>(AbsOrMin(imm)); int ctz_imm = CTZ(abs_imm); @@ -3253,7 +3254,7 @@ void InstructionCodeGeneratorARMVIXL::GenerateDivRemConstantIntegral( Location second = instruction->GetLocations()->InAt(1); DCHECK(second.IsConstant()); - int32_t imm = second.GetConstant()->AsIntConstant()->GetValue(); + int32_t imm = Int32ConstantFrom(second); if (imm == 0) { // Do not generate anything. DivZeroCheck would prevent any code to be executed. } else if (imm == 1 || imm == -1) { @@ -3287,7 +3288,7 @@ void LocationsBuilderARMVIXL::VisitDiv(HDiv* div) { locations->SetInAt(0, Location::RequiresRegister()); locations->SetInAt(1, Location::ConstantLocation(div->InputAt(1)->AsConstant())); locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); - int32_t value = div->InputAt(1)->AsIntConstant()->GetValue(); + int32_t value = Int32ConstantFrom(div->InputAt(1)); if (value == 1 || value == 0 || value == -1) { // No temp register required. } else { @@ -3400,7 +3401,7 @@ void LocationsBuilderARMVIXL::VisitRem(HRem* rem) { locations->SetInAt(0, Location::RequiresRegister()); locations->SetInAt(1, Location::ConstantLocation(rem->InputAt(1)->AsConstant())); locations->SetOut(Location::RequiresRegister(), Location::kNoOutputOverlap); - int32_t value = rem->InputAt(1)->AsIntConstant()->GetValue(); + int32_t value = Int32ConstantFrom(rem->InputAt(1)); if (value == 1 || value == 0 || value == -1) { // No temp register required. } else { @@ -3535,7 +3536,7 @@ void InstructionCodeGeneratorARMVIXL::VisitDivZeroCheck(HDivZeroCheck* instructi __ CompareAndBranchIfZero(InputRegisterAt(instruction, 0), slow_path->GetEntryLabel()); } else { DCHECK(value.IsConstant()) << value; - if (value.GetConstant()->AsIntConstant()->GetValue() == 0) { + if (Int32ConstantFrom(value) == 0) { __ B(slow_path->GetEntryLabel()); } } @@ -3549,7 +3550,7 @@ void InstructionCodeGeneratorARMVIXL::VisitDivZeroCheck(HDivZeroCheck* instructi __ B(eq, slow_path->GetEntryLabel()); } else { DCHECK(value.IsConstant()) << value; - if (value.GetConstant()->AsLongConstant()->GetValue() == 0) { + if (Int64ConstantFrom(value) == 0) { __ B(slow_path->GetEntryLabel()); } } @@ -3759,7 +3760,7 @@ void InstructionCodeGeneratorARMVIXL::HandleShift(HBinaryOperation* op) { __ Lsr(out_reg, first_reg, out_reg); } } else { - int32_t cst = second.GetConstant()->AsIntConstant()->GetValue(); + int32_t cst = Int32ConstantFrom(second); uint32_t shift_value = cst & kMaxIntShiftDistance; if (shift_value == 0) { // ARM does not support shifting with 0 immediate. __ Mov(out_reg, first_reg); @@ -3844,7 +3845,7 @@ void InstructionCodeGeneratorARMVIXL::HandleShift(HBinaryOperation* op) { // Register allocator doesn't create partial overlap. DCHECK(!o_l.Is(high)); DCHECK(!o_h.Is(low)); - int32_t cst = second.GetConstant()->AsIntConstant()->GetValue(); + int32_t cst = Int32ConstantFrom(second); uint32_t shift_value = cst & kMaxLongShiftDistance; if (shift_value > 32) { if (op->IsShl()) { @@ -4911,7 +4912,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArrayGet(HArrayGet* instruction) { codegen_->MaybeRecordImplicitNullCheck(instruction); } if (index.IsConstant()) { - int32_t const_index = index.GetConstant()->AsIntConstant()->GetValue(); + int32_t const_index = Int32ConstantFrom(index); if (maybe_compressed_char_at) { vixl32::Label uncompressed_load, done; __ Lsrs(length, length, 1u); // LSRS has a 16-bit encoding, TST (immediate) does not. @@ -4945,7 +4946,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArrayGet(HArrayGet* instruction) { // `TryExtractArrayAccessAddress()`. if (kIsDebugBuild) { HIntermediateAddress* tmp = array_instr->AsIntermediateAddress(); - DCHECK_EQ(tmp->GetOffset()->AsIntConstant()->GetValueAsUint64(), data_offset); + DCHECK_EQ(Uint64ConstantFrom(tmp->GetOffset()), data_offset); } temp = obj; } else { @@ -4990,7 +4991,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArrayGet(HArrayGet* instruction) { vixl32::Register out = OutputRegister(instruction); if (index.IsConstant()) { size_t offset = - (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset; + (Int32ConstantFrom(index) << TIMES_4) + data_offset; GetAssembler()->LoadFromOffset(kLoadWord, out, obj, offset); // TODO(VIXL): Here and for other calls to `MaybeRecordImplicitNullCheck` in this method, // we should use a scope and the assembler to emit the load instruction to guarantee that @@ -5012,7 +5013,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArrayGet(HArrayGet* instruction) { // `TryExtractArrayAccessAddress()`. if (kIsDebugBuild) { HIntermediateAddress* tmp = array_instr->AsIntermediateAddress(); - DCHECK_EQ(tmp->GetOffset()->AsIntConstant()->GetValueAsUint64(), data_offset); + DCHECK_EQ(Uint64ConstantFrom(tmp->GetOffset()), data_offset); } temp = obj; } else { @@ -5037,7 +5038,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArrayGet(HArrayGet* instruction) { case Primitive::kPrimLong: { if (index.IsConstant()) { size_t offset = - (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset; + (Int32ConstantFrom(index) << TIMES_8) + data_offset; GetAssembler()->LoadFromOffset(kLoadWordPair, LowRegisterFrom(out_loc), obj, offset); } else { UseScratchRegisterScope temps(GetVIXLAssembler()); @@ -5051,7 +5052,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArrayGet(HArrayGet* instruction) { case Primitive::kPrimFloat: { vixl32::SRegister out = SRegisterFrom(out_loc); if (index.IsConstant()) { - size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset; + size_t offset = (Int32ConstantFrom(index) << TIMES_4) + data_offset; GetAssembler()->LoadSFromOffset(out, obj, offset); } else { UseScratchRegisterScope temps(GetVIXLAssembler()); @@ -5064,7 +5065,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArrayGet(HArrayGet* instruction) { case Primitive::kPrimDouble: { if (index.IsConstant()) { - size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset; + size_t offset = (Int32ConstantFrom(index) << TIMES_8) + data_offset; GetAssembler()->LoadDFromOffset(DRegisterFrom(out_loc), obj, offset); } else { UseScratchRegisterScope temps(GetVIXLAssembler()); @@ -5138,7 +5139,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArraySet(HArraySet* instruction) { case Primitive::kPrimChar: case Primitive::kPrimInt: { if (index.IsConstant()) { - int32_t const_index = index.GetConstant()->AsIntConstant()->GetValue(); + int32_t const_index = Int32ConstantFrom(index); uint32_t full_offset = data_offset + (const_index << Primitive::ComponentSizeShift(value_type)); StoreOperandType store_type = GetStoreOperandType(value_type); @@ -5153,7 +5154,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArraySet(HArraySet* instruction) { // `TryExtractArrayAccessAddress()`. if (kIsDebugBuild) { HIntermediateAddress* tmp = array_instr->AsIntermediateAddress(); - DCHECK(tmp->GetOffset()->AsIntConstant()->GetValueAsUint64() == data_offset); + DCHECK_EQ(Uint64ConstantFrom(tmp->GetOffset()), data_offset); } temp = array; } else { @@ -5174,7 +5175,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArraySet(HArraySet* instruction) { // Just setting null. if (index.IsConstant()) { size_t offset = - (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset; + (Int32ConstantFrom(index) << TIMES_4) + data_offset; GetAssembler()->StoreToOffset(kStoreWord, value, array, offset); } else { DCHECK(index.IsRegister()) << index; @@ -5210,7 +5211,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArraySet(HArraySet* instruction) { __ CompareAndBranchIfNonZero(value, &non_zero); if (index.IsConstant()) { size_t offset = - (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset; + (Int32ConstantFrom(index) << TIMES_4) + data_offset; GetAssembler()->StoreToOffset(kStoreWord, value, array, offset); } else { DCHECK(index.IsRegister()) << index; @@ -5284,7 +5285,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArraySet(HArraySet* instruction) { if (index.IsConstant()) { size_t offset = - (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset; + (Int32ConstantFrom(index) << TIMES_4) + data_offset; GetAssembler()->StoreToOffset(kStoreWord, source, array, offset); } else { DCHECK(index.IsRegister()) << index; @@ -5321,7 +5322,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArraySet(HArraySet* instruction) { Location value = locations->InAt(2); if (index.IsConstant()) { size_t offset = - (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset; + (Int32ConstantFrom(index) << TIMES_8) + data_offset; GetAssembler()->StoreToOffset(kStoreWordPair, LowRegisterFrom(value), array, offset); } else { UseScratchRegisterScope temps(GetVIXLAssembler()); @@ -5336,7 +5337,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArraySet(HArraySet* instruction) { Location value = locations->InAt(2); DCHECK(value.IsFpuRegister()); if (index.IsConstant()) { - size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_4) + data_offset; + size_t offset = (Int32ConstantFrom(index) << TIMES_4) + data_offset; GetAssembler()->StoreSToOffset(SRegisterFrom(value), array, offset); } else { UseScratchRegisterScope temps(GetVIXLAssembler()); @@ -5351,7 +5352,7 @@ void InstructionCodeGeneratorARMVIXL::VisitArraySet(HArraySet* instruction) { Location value = locations->InAt(2); DCHECK(value.IsFpuRegisterPair()); if (index.IsConstant()) { - size_t offset = (index.GetConstant()->AsIntConstant()->GetValue() << TIMES_8) + data_offset; + size_t offset = (Int32ConstantFrom(index) << TIMES_8) + data_offset; GetAssembler()->StoreDToOffset(DRegisterFrom(value), array, offset); } else { UseScratchRegisterScope temps(GetVIXLAssembler()); @@ -5416,7 +5417,7 @@ void InstructionCodeGeneratorARMVIXL::VisitIntermediateAddress(HIntermediateAddr if (second.IsRegister()) { __ Add(out, first, RegisterFrom(second)); } else { - __ Add(out, first, second.GetConstant()->AsIntConstant()->GetValue()); + __ Add(out, first, Int32ConstantFrom(second)); } } @@ -5612,7 +5613,7 @@ void ParallelMoveResolverARMVIXL::EmitMove(size_t index) { GetAssembler()->StoreToOffset(kStoreWord, temp, sp, destination.GetStackIndex()); } } else if (constant->IsLongConstant()) { - int64_t value = constant->AsLongConstant()->GetValue(); + int64_t value = Int64ConstantFrom(source); if (destination.IsRegisterPair()) { __ Mov(LowRegisterFrom(destination), Low32Bits(value)); __ Mov(HighRegisterFrom(destination), High32Bits(value)); diff --git a/compiler/optimizing/common_arm.h b/compiler/optimizing/common_arm.h index eabdbad13c..21c3ae628a 100644 --- a/compiler/optimizing/common_arm.h +++ b/compiler/optimizing/common_arm.h @@ -122,10 +122,16 @@ inline vixl::aarch32::VRegister InputVRegisterAt(HInstruction* instr, int input_ if (type == Primitive::kPrimFloat) { return InputSRegisterAt(instr, input_index); } else { + DCHECK_EQ(type, Primitive::kPrimDouble); return InputDRegisterAt(instr, input_index); } } +inline vixl::aarch32::VRegister InputVRegister(HInstruction* instr) { + DCHECK_EQ(instr->InputCount(), 1u); + return InputVRegisterAt(instr, 0); +} + inline vixl::aarch32::Register OutputRegister(HInstruction* instr) { return RegisterFrom(instr->GetLocations()->Out(), instr->GetType()); } @@ -140,8 +146,7 @@ inline vixl::aarch32::Register InputRegister(HInstruction* instr) { return InputRegisterAt(instr, 0); } -inline int32_t Int32ConstantFrom(Location location) { - HConstant* instr = location.GetConstant(); +inline int32_t Int32ConstantFrom(HInstruction* instr) { if (instr->IsIntConstant()) { return instr->AsIntConstant()->GetValue(); } else if (instr->IsNullConstant()) { @@ -155,6 +160,10 @@ inline int32_t Int32ConstantFrom(Location location) { } } +inline int32_t Int32ConstantFrom(Location location) { + return Int32ConstantFrom(location.GetConstant()); +} + inline int64_t Int64ConstantFrom(Location location) { HConstant* instr = location.GetConstant(); if (instr->IsIntConstant()) { @@ -167,6 +176,11 @@ inline int64_t Int64ConstantFrom(Location location) { } } +inline uint64_t Uint64ConstantFrom(HInstruction* instr) { + DCHECK(instr->IsConstant()) << instr->DebugName(); + return instr->AsConstant()->GetValueAsUint64(); +} + inline vixl::aarch32::Operand OperandFrom(Location location, Primitive::Type type) { if (location.IsRegister()) { return vixl::aarch32::Operand(RegisterFrom(location, type)); diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc index 188ee3a8d1..34b52a87b5 100644 --- a/compiler/optimizing/graph_checker.cc +++ b/compiler/optimizing/graph_checker.cc @@ -20,12 +20,15 @@ #include <string> #include <sstream> +#include "android-base/stringprintf.h" + #include "base/arena_containers.h" #include "base/bit_vector-inl.h" -#include "base/stringprintf.h" namespace art { +using android::base::StringPrintf; + static bool IsAllowedToJumpToExitBlock(HInstruction* instruction) { return instruction->IsThrow() || instruction->IsReturn() || instruction->IsReturnVoid(); } diff --git a/compiler/optimizing/graph_test.cc b/compiler/optimizing/graph_test.cc index d5305646a8..28ee3a5e8b 100644 --- a/compiler/optimizing/graph_test.cc +++ b/compiler/optimizing/graph_test.cc @@ -15,7 +15,6 @@ */ #include "base/arena_allocator.h" -#include "base/stringprintf.h" #include "builder.h" #include "nodes.h" #include "optimizing_unit_test.h" diff --git a/compiler/optimizing/induction_var_analysis.cc b/compiler/optimizing/induction_var_analysis.cc index c240c67e79..b21bc09cbd 100644 --- a/compiler/optimizing/induction_var_analysis.cc +++ b/compiler/optimizing/induction_var_analysis.cc @@ -211,7 +211,7 @@ uint32_t HInductionVarAnalysis::VisitDescendant(HLoopInformation* loop, HInstruc void HInductionVarAnalysis::ClassifyTrivial(HLoopInformation* loop, HInstruction* instruction) { InductionInfo* info = nullptr; if (instruction->IsPhi()) { - info = TransferPhi(loop, instruction, /* input_index */ 0); + info = TransferPhi(loop, instruction, /*input_index*/ 0, /*adjust_input_size*/ 0); } else if (instruction->IsAdd()) { info = TransferAddSub(LookupInfo(loop, instruction->InputAt(0)), LookupInfo(loop, instruction->InputAt(1)), kAdd); @@ -224,11 +224,13 @@ void HInductionVarAnalysis::ClassifyTrivial(HLoopInformation* loop, HInstruction info = TransferMul(LookupInfo(loop, instruction->InputAt(0)), LookupInfo(loop, instruction->InputAt(1))); } else if (instruction->IsShl()) { - HInstruction* mulc = GetMultConstantForShift(loop, instruction); + HInstruction* mulc = GetShiftConstant(loop, instruction, /*initial*/ nullptr); if (mulc != nullptr) { info = TransferMul(LookupInfo(loop, instruction->InputAt(0)), LookupInfo(loop, mulc)); } + } else if (instruction->IsSelect()) { + info = TransferPhi(loop, instruction, /*input_index*/ 0, /*adjust_input_size*/ 1); } else if (instruction->IsTypeConversion()) { info = TransferCnv(LookupInfo(loop, instruction->InputAt(0)), instruction->AsTypeConversion()->GetInputType(), @@ -270,7 +272,7 @@ void HInductionVarAnalysis::ClassifyNonTrivial(HLoopInformation* loop) { // Singleton is wrap-around induction if all internal links have the same meaning. if (size == 1) { - InductionInfo* update = TransferPhi(loop, phi, /* input_index */ 1); + InductionInfo* update = TransferPhi(loop, phi, /*input_index*/ 1, /*adjust_input_size*/ 0); if (update != nullptr) { AssignInfo(loop, phi, CreateInduction(kWrapAround, kNop, @@ -305,10 +307,15 @@ void HInductionVarAnalysis::ClassifyNonTrivial(HLoopInformation* loop) { update = SolveOp( loop, phi, instruction, instruction->InputAt(0), instruction->InputAt(1), kRem); } else if (instruction->IsShl()) { - HInstruction* mulc = GetMultConstantForShift(loop, instruction); + HInstruction* mulc = GetShiftConstant(loop, instruction, /*initial*/ nullptr); if (mulc != nullptr) { update = SolveOp(loop, phi, instruction, instruction->InputAt(0), mulc, kMul); } + } else if (instruction->IsShr() || instruction->IsUShr()) { + HInstruction* divc = GetShiftConstant(loop, instruction, initial); + if (divc != nullptr) { + update = SolveOp(loop, phi, instruction, instruction->InputAt(0), divc, kDiv); + } } else if (instruction->IsXor()) { update = SolveOp( loop, phi, instruction, instruction->InputAt(0), instruction->InputAt(1), kXor); @@ -316,6 +323,8 @@ void HInductionVarAnalysis::ClassifyNonTrivial(HLoopInformation* loop) { update = SolveTest(loop, phi, instruction, 0); } else if (instruction->IsNotEqual()) { update = SolveTest(loop, phi, instruction, 1); + } else if (instruction->IsSelect()) { + update = SolvePhi(instruction, /*input_index*/ 0, /*adjust_input_size*/ 1); // acts like Phi } else if (instruction->IsTypeConversion()) { update = SolveCnv(instruction->AsTypeConversion()); } @@ -326,7 +335,7 @@ void HInductionVarAnalysis::ClassifyNonTrivial(HLoopInformation* loop) { } // Success if all internal links received the same temporary meaning. - InductionInfo* induction = SolvePhi(phi, /* input_index */ 1); + InductionInfo* induction = SolvePhi(phi, /*input_index*/ 1, /*adjust_input_size*/ 0); if (induction != nullptr) { switch (induction->induction_class) { case kInvariant: @@ -385,12 +394,13 @@ HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::RotatePeriodicInduc HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::TransferPhi(HLoopInformation* loop, HInstruction* phi, - size_t input_index) { + size_t input_index, + size_t adjust_input_size) { // Match all phi inputs from input_index onwards exactly. HInputsRef inputs = phi->GetInputs(); DCHECK_LT(input_index, inputs.size()); InductionInfo* a = LookupInfo(loop, inputs[input_index]); - for (size_t i = input_index + 1; i < inputs.size(); i++) { + for (size_t i = input_index + 1, n = inputs.size() - adjust_input_size; i < n; i++) { InductionInfo* b = LookupInfo(loop, inputs[i]); if (!InductionEqual(a, b)) { return nullptr; @@ -504,13 +514,14 @@ HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::TransferCnv(Inducti } HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::SolvePhi(HInstruction* phi, - size_t input_index) { + size_t input_index, + size_t adjust_input_size) { // Match all phi inputs from input_index onwards exactly. HInputsRef inputs = phi->GetInputs(); DCHECK_LT(input_index, inputs.size()); auto ita = cycle_.find(inputs[input_index]); if (ita != cycle_.end()) { - for (size_t i = input_index + 1; i < inputs.size(); i++) { + for (size_t i = input_index + 1, n = inputs.size() - adjust_input_size; i < n; i++) { auto itb = cycle_.find(inputs[i]); if (itb == cycle_.end() || !HInductionVarAnalysis::InductionEqual(ita->second, itb->second)) { @@ -527,7 +538,7 @@ HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::SolvePhiAllInputs( HInstruction* entry_phi, HInstruction* phi) { // Match all phi inputs. - InductionInfo* match = SolvePhi(phi, /* input_index */ 0); + InductionInfo* match = SolvePhi(phi, /*input_index*/ 0, /*adjust_input_size*/ 0); if (match != nullptr) { return match; } @@ -542,7 +553,7 @@ HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::SolvePhiAllInputs( InductionInfo* initial = LookupInfo(loop, entry_phi->InputAt(0)); return CreateInduction(kPeriodic, kNop, a, initial, /*fetch*/ nullptr, type_); } - InductionInfo* b = SolvePhi(phi, /* input_index */ 1); + InductionInfo* b = SolvePhi(phi, /*input_index*/ 1, /*adjust_input_size*/ 0); if (b != nullptr && b->induction_class == kPeriodic) { return CreateInduction(kPeriodic, kNop, a, b, /*fetch*/ nullptr, type_); } @@ -574,14 +585,14 @@ HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::SolveAddSub(HLoopIn return CreateInvariantOp(op, a, b); } } - } else if (op == kAdd && b->induction_class == kLinear) { + } else if (b->induction_class == kLinear) { // Solve within a tight cycle that adds a term that is already classified as a linear // induction for a polynomial induction k = k + i (represented as sum over linear terms). if (x == entry_phi && entry_phi->InputCount() == 2 && instruction == entry_phi->InputAt(1)) { InductionInfo* initial = LookupInfo(loop, entry_phi->InputAt(0)); return CreateInduction(kPolynomial, kNop, - b, + op == kAdd ? b : TransferNeg(b), initial, /*fetch*/ nullptr, type_); @@ -1038,13 +1049,23 @@ HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::CreateSimplifiedInv return new (graph_->GetArena()) InductionInfo(kInvariant, op, a, b, nullptr, b->type); } -HInstruction* HInductionVarAnalysis::GetMultConstantForShift(HLoopInformation* loop, - HInstruction* instruction) { - // Obtain the constant needed to treat shift as equivalent multiplication. This yields an - // existing instruction if the constant is already there. Otherwise, this has a side effect - // on the HIR. The restriction on the shift factor avoids generating a negative constant - // (viz. 1 << 31 and 1L << 63 set the sign bit). The code assumes that generalization for - // shift factors outside [0,32) and [0,64) ranges is done by earlier simplification. +HInstruction* HInductionVarAnalysis::GetShiftConstant(HLoopInformation* loop, + HInstruction* instruction, + InductionInfo* initial) { + DCHECK(instruction->IsShl() || instruction->IsShr() || instruction->IsUShr()); + // Shift-rights are only the same as division for non-negative initial inputs. + // Otherwise we would round incorrectly. + if (initial != nullptr) { + int64_t value = -1; + if (!IsAtLeast(initial, &value) || value < 0) { + return nullptr; + } + } + // Obtain the constant needed to treat shift as equivalent multiplication or division. + // This yields an existing instruction if the constant is already there. Otherwise, this + // has a side effect on the HIR. The restriction on the shift factor avoids generating a + // negative constant (viz. 1 << 31 and 1L << 63 set the sign bit). The code assumes that + // generalization for shift factors outside [0,32) and [0,64) ranges is done earlier. InductionInfo* b = LookupInfo(loop, instruction->InputAt(1)); int64_t value = -1; if (IsExact(b, &value)) { diff --git a/compiler/optimizing/induction_var_analysis.h b/compiler/optimizing/induction_var_analysis.h index 4720f2d61c..293aa70525 100644 --- a/compiler/optimizing/induction_var_analysis.h +++ b/compiler/optimizing/induction_var_analysis.h @@ -115,7 +115,7 @@ class HInductionVarAnalysis : public HOptimization { InductionInfo* op_a; InductionInfo* op_b; HInstruction* fetch; - Primitive::Type type; // precision of induction + Primitive::Type type; // precision of operation }; bool IsVisitedNode(HInstruction* instruction) const { @@ -160,14 +160,17 @@ class HInductionVarAnalysis : public HOptimization { InductionInfo* RotatePeriodicInduction(InductionInfo* induction, InductionInfo* last); // Transfer operations. - InductionInfo* TransferPhi(HLoopInformation* loop, HInstruction* phi, size_t input_index); + InductionInfo* TransferPhi(HLoopInformation* loop, + HInstruction* phi, + size_t input_index, + size_t adjust_input_size); InductionInfo* TransferAddSub(InductionInfo* a, InductionInfo* b, InductionOp op); InductionInfo* TransferNeg(InductionInfo* a); InductionInfo* TransferMul(InductionInfo* a, InductionInfo* b); InductionInfo* TransferCnv(InductionInfo* a, Primitive::Type from, Primitive::Type to); // Solvers. - InductionInfo* SolvePhi(HInstruction* phi, size_t input_index); + InductionInfo* SolvePhi(HInstruction* phi, size_t input_index, size_t adjust_input_size); InductionInfo* SolvePhiAllInputs(HLoopInformation* loop, HInstruction* entry_phi, HInstruction* phi); @@ -220,7 +223,9 @@ class HInductionVarAnalysis : public HOptimization { InductionInfo* LookupInfo(HLoopInformation* loop, HInstruction* instruction); InductionInfo* CreateConstant(int64_t value, Primitive::Type type); InductionInfo* CreateSimplifiedInvariant(InductionOp op, InductionInfo* a, InductionInfo* b); - HInstruction* GetMultConstantForShift(HLoopInformation* loop, HInstruction* instruction); + HInstruction* GetShiftConstant(HLoopInformation* loop, + HInstruction* instruction, + InductionInfo* initial); void AssignCycle(HPhi* phi); ArenaSet<HInstruction*>* LookupCycle(HPhi* phi); diff --git a/compiler/optimizing/induction_var_analysis_test.cc b/compiler/optimizing/induction_var_analysis_test.cc index 2d182f6483..f52a1aad5a 100644 --- a/compiler/optimizing/induction_var_analysis_test.cc +++ b/compiler/optimizing/induction_var_analysis_test.cc @@ -87,6 +87,7 @@ class InductionVarAnalysisTest : public CommonCompilerTest { constant2_ = graph_->GetIntConstant(2); constant7_ = graph_->GetIntConstant(7); constant100_ = graph_->GetIntConstant(100); + constantm1_ = graph_->GetIntConstant(-1); float_constant0_ = graph_->GetFloatConstant(0.0f); return_->AddInstruction(new (&allocator_) HReturnVoid()); exit_->AddInstruction(new (&allocator_) HExit()); @@ -196,6 +197,7 @@ class InductionVarAnalysisTest : public CommonCompilerTest { HInstruction* constant2_; HInstruction* constant7_; HInstruction* constant100_; + HInstruction* constantm1_; HInstruction* float_constant0_; // Loop specifics. @@ -612,6 +614,45 @@ TEST_F(InductionVarAnalysisTest, FindGeometricDivInductionAndDerived) { EXPECT_STREQ("", GetInductionInfo(div, 0).c_str()); } +TEST_F(InductionVarAnalysisTest, FindGeometricShrInduction) { + // Setup: + // k = 100; + // for (int i = 0; i < 100; i++) { + // k = k >> 1; // geometric (/ 2) + // } + BuildLoopNest(1); + HPhi* k_header = InsertLoopPhi(0, 0); + k_header->AddInput(constant100_); + + HInstruction* shr = InsertInstruction( + new (&allocator_) HShr(Primitive::kPrimInt, k_header, constant1_), 0); + k_header->AddInput(shr); + PerformInductionVarAnalysis(); + + // Note, only the phi in the cycle is classified. + EXPECT_STREQ("geo((100) * 2 ^ -i + (0)):PrimInt", GetInductionInfo(k_header, 0).c_str()); + EXPECT_STREQ("", GetInductionInfo(shr, 0).c_str()); +} + +TEST_F(InductionVarAnalysisTest, FindNotGeometricShrInduction) { + // Setup: + // k = -1; + // for (int i = 0; i < 100; i++) { + // k = k >> 1; // initial value is negative + // } + BuildLoopNest(1); + HPhi* k_header = InsertLoopPhi(0, 0); + k_header->AddInput(constantm1_); + + HInstruction* shr = InsertInstruction( + new (&allocator_) HShr(Primitive::kPrimInt, k_header, constant1_), 0); + k_header->AddInput(shr); + PerformInductionVarAnalysis(); + + EXPECT_STREQ("", GetInductionInfo(k_header, 0).c_str()); + EXPECT_STREQ("", GetInductionInfo(shr, 0).c_str()); +} + TEST_F(InductionVarAnalysisTest, FindRemWrapAroundInductionAndDerived) { // Setup: // k = 100; diff --git a/compiler/optimizing/induction_var_range.cc b/compiler/optimizing/induction_var_range.cc index e665551012..7bcc3845e7 100644 --- a/compiler/optimizing/induction_var_range.cc +++ b/compiler/optimizing/induction_var_range.cc @@ -983,10 +983,10 @@ bool InductionVarRange::GenerateLastValuePolynomial(HInductionVarAnalysis::Induc int64_t a = 0; int64_t b = 0; int64_t m = 0; - if (IsConstant(info->op_a->op_a, kExact, &a) && a >= 0 && - IsConstant(info->op_a->op_b, kExact, &b) && b >= 0 && + if (IsConstant(info->op_a->op_a, kExact, &a) && + IsConstant(info->op_a->op_b, kExact, &b) && IsConstant(trip->op_a, kExact, &m) && m >= 1) { - // Evaluate bounds on sum_i=0^m-1(a * i + b) + c with a,b >= 0 for known + // Evaluate bounds on sum_i=0^m-1(a * i + b) + c for known // maximum index value m as a * (m * (m-1)) / 2 + b * m + c. // TODO: generalize HInstruction* c_instr = nullptr; diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index c615df1f1d..439e3b66db 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -1897,7 +1897,8 @@ void InstructionSimplifierVisitor::SimplifyReturnThis(HInvoke* invoke) { static bool NoEscapeForStringBufferReference(HInstruction* reference, HInstruction* user) { if (user->IsInvokeStaticOrDirect()) { // Any constructor on StringBuffer is okay. - return user->AsInvokeStaticOrDirect()->GetResolvedMethod()->IsConstructor() && + return user->AsInvokeStaticOrDirect()->GetResolvedMethod() != nullptr && + user->AsInvokeStaticOrDirect()->GetResolvedMethod()->IsConstructor() && user->InputAt(0) == reference; } else if (user->IsInvokeVirtual()) { switch (user->AsInvokeVirtual()->GetIntrinsic()) { diff --git a/compiler/optimizing/intrinsics_arm_vixl.cc b/compiler/optimizing/intrinsics_arm_vixl.cc index 95551c8fd9..641a5c92ea 100644 --- a/compiler/optimizing/intrinsics_arm_vixl.cc +++ b/compiler/optimizing/intrinsics_arm_vixl.cc @@ -1509,7 +1509,7 @@ static void GenerateVisitStringIndexOf(HInvoke* invoke, SlowPathCodeARMVIXL* slow_path = nullptr; HInstruction* code_point = invoke->InputAt(1); if (code_point->IsIntConstant()) { - if (static_cast<uint32_t>(code_point->AsIntConstant()->GetValue()) > + if (static_cast<uint32_t>(Int32ConstantFrom(code_point)) > std::numeric_limits<uint16_t>::max()) { // Always needs the slow-path. We could directly dispatch to it, but this case should be // rare, so for simplicity just put the full slow-path down and branch unconditionally. diff --git a/compiler/optimizing/linearize_test.cc b/compiler/optimizing/linearize_test.cc index 13e14c53b5..3831aa6c91 100644 --- a/compiler/optimizing/linearize_test.cc +++ b/compiler/optimizing/linearize_test.cc @@ -18,7 +18,6 @@ #include "arch/x86/instruction_set_features_x86.h" #include "base/arena_allocator.h" -#include "base/stringprintf.h" #include "builder.h" #include "code_generator.h" #include "code_generator_x86.h" diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index ba7012ab1a..0d0f62a55c 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -1193,7 +1193,7 @@ bool OptimizingCompiler::JitCompile(Thread* self, } uint8_t* stack_map_data = nullptr; uint8_t* roots_data = nullptr; - code_cache->ReserveData( + uint32_t data_size = code_cache->ReserveData( self, stack_map_size, number_of_roots, method, &stack_map_data, &roots_data); if (stack_map_data == nullptr || roots_data == nullptr) { return false; @@ -1212,6 +1212,7 @@ bool OptimizingCompiler::JitCompile(Thread* self, codegen->GetFpuSpillMask(), code_allocator.GetMemory().data(), code_allocator.GetSize(), + data_size, osr, roots, codegen->GetGraph()->HasShouldDeoptimizeFlag(), diff --git a/compiler/optimizing/pretty_printer.h b/compiler/optimizing/pretty_printer.h index 5891350894..c6579dc5e0 100644 --- a/compiler/optimizing/pretty_printer.h +++ b/compiler/optimizing/pretty_printer.h @@ -17,7 +17,8 @@ #ifndef ART_COMPILER_OPTIMIZING_PRETTY_PRINTER_H_ #define ART_COMPILER_OPTIMIZING_PRETTY_PRINTER_H_ -#include "base/stringprintf.h" +#include "android-base/stringprintf.h" + #include "nodes.h" namespace art { @@ -108,7 +109,7 @@ class StringPrettyPrinter : public HPrettyPrinter { : HPrettyPrinter(graph), str_(""), current_block_(nullptr) { } void PrintInt(int value) OVERRIDE { - str_ += StringPrintf("%d", value); + str_ += android::base::StringPrintf("%d", value); } void PrintString(const char* value) OVERRIDE { diff --git a/compiler/optimizing/pretty_printer_test.cc b/compiler/optimizing/pretty_printer_test.cc index 951cdfbd8b..1af94f3445 100644 --- a/compiler/optimizing/pretty_printer_test.cc +++ b/compiler/optimizing/pretty_printer_test.cc @@ -15,7 +15,6 @@ */ #include "base/arena_allocator.h" -#include "base/stringprintf.h" #include "builder.h" #include "dex_file.h" #include "dex_instruction.h" diff --git a/compiler/optimizing/ssa_test.cc b/compiler/optimizing/ssa_test.cc index 429763423c..f69f417efc 100644 --- a/compiler/optimizing/ssa_test.cc +++ b/compiler/optimizing/ssa_test.cc @@ -14,8 +14,9 @@ * limitations under the License. */ +#include "android-base/stringprintf.h" + #include "base/arena_allocator.h" -#include "base/stringprintf.h" #include "builder.h" #include "dex_file.h" #include "dex_instruction.h" @@ -35,7 +36,7 @@ class SsaPrettyPrinter : public HPrettyPrinter { explicit SsaPrettyPrinter(HGraph* graph) : HPrettyPrinter(graph), str_("") {} void PrintInt(int value) OVERRIDE { - str_ += StringPrintf("%d", value); + str_ += android::base::StringPrintf("%d", value); } void PrintString(const char* value) OVERRIDE { diff --git a/compiler/utils/arm/assembler_thumb2_test.cc b/compiler/utils/arm/assembler_thumb2_test.cc index 30e8f4e604..0147a76744 100644 --- a/compiler/utils/arm/assembler_thumb2_test.cc +++ b/compiler/utils/arm/assembler_thumb2_test.cc @@ -16,12 +16,15 @@ #include "assembler_thumb2.h" +#include "android-base/stringprintf.h" + #include "base/stl_util.h" -#include "base/stringprintf.h" #include "utils/assembler_test.h" namespace art { +using android::base::StringPrintf; + class AssemblerThumb2Test : public AssemblerTest<arm::Thumb2Assembler, arm::Register, arm::SRegister, uint32_t> { diff --git a/compiler/utils/dedupe_set-inl.h b/compiler/utils/dedupe_set-inl.h index ac5481336b..c06e9cadcc 100644 --- a/compiler/utils/dedupe_set-inl.h +++ b/compiler/utils/dedupe_set-inl.h @@ -23,10 +23,11 @@ #include <inttypes.h> #include <unordered_map> +#include "android-base/stringprintf.h" + #include "base/mutex.h" #include "base/hash_set.h" #include "base/stl_util.h" -#include "base/stringprintf.h" #include "base/time_utils.h" namespace art { @@ -238,13 +239,13 @@ std::string DedupeSet<InKey, StoreKey, Alloc, HashType, HashFunc, kShard>::DumpS for (HashType shard = 0; shard < kShard; ++shard) { shards_[shard]->UpdateStats(self, &stats); } - return StringPrintf("%zu collisions, %zu max hash collisions, " - "%zu/%zu probe distance, %" PRIu64 " ns hash time", - stats.collision_sum, - stats.collision_max, - stats.total_probe_distance, - stats.total_size, - hash_time_); + return android::base::StringPrintf("%zu collisions, %zu max hash collisions, " + "%zu/%zu probe distance, %" PRIu64 " ns hash time", + stats.collision_sum, + stats.collision_max, + stats.total_probe_distance, + stats.total_size, + hash_time_); } diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 5a0f0c6e50..2346635198 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -33,6 +33,7 @@ #include <sys/utsname.h> #endif +#include "android-base/stringprintf.h" #include "android-base/strings.h" #include "arch/instruction_set_features.h" @@ -87,6 +88,9 @@ namespace art { +using android::base::StringAppendV; +using android::base::StringPrintf; + static constexpr size_t kDefaultMinDexFilesForSwap = 2; static constexpr size_t kDefaultMinDexFileCumulativeSizeForSwap = 20 * MB; diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc index b6b62a80dc..cdb3b9fe2a 100644 --- a/dex2oat/dex2oat_test.cc +++ b/dex2oat/dex2oat_test.cc @@ -19,11 +19,15 @@ #include <string> #include <vector> +#include <sys/wait.h> +#include <unistd.h> + +#include "android-base/stringprintf.h" + #include "common_runtime_test.h" #include "base/logging.h" #include "base/macros.h" -#include "base/stringprintf.h" #include "dex_file-inl.h" #include "dex2oat_environment_test.h" #include "jit/offline_profiling_info.h" @@ -31,9 +35,6 @@ #include "oat_file.h" #include "utils.h" -#include <sys/wait.h> -#include <unistd.h> - namespace art { class Dex2oatTest : public Dex2oatEnvironmentTest { @@ -217,7 +218,7 @@ class Dex2oatSwapTest : public Dex2oatTest { std::unique_ptr<ScratchFile> sf; if (use_fd) { sf.reset(new ScratchFile()); - copy.push_back(StringPrintf("--swap-fd=%d", sf->GetFd())); + copy.push_back(android::base::StringPrintf("--swap-fd=%d", sf->GetFd())); } else { std::string swap_location = GetOdexDir() + "/Dex2OatSwapTest.odex.swap"; copy.push_back("--swap-file=" + swap_location); diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc index 916984c261..d5776fa61e 100644 --- a/dexdump/dexdump.cc +++ b/dexdump/dexdump.cc @@ -42,7 +42,8 @@ #include <sstream> #include <vector> -#include "base/stringprintf.h" +#include "android-base/stringprintf.h" + #include "dexdump_cfg.h" #include "dex_file-inl.h" #include "dex_file_types.h" @@ -887,8 +888,10 @@ static std::unique_ptr<char[]> indexString(const DexFile* pDexFile, const char* name = pDexFile->StringDataByIdx(pMethodId.name_idx_); const Signature signature = pDexFile->GetMethodSignature(pMethodId); const char* backDescriptor = pDexFile->StringByTypeIdx(pMethodId.class_idx_); - method = StringPrintf("%s.%s:%s", - backDescriptor, name, signature.ToString().c_str()); + method = android::base::StringPrintf("%s.%s:%s", + backDescriptor, + name, + signature.ToString().c_str()); } if (secondary_index < pDexFile->GetHeader().proto_ids_size_) { const DexFile::ProtoId& protoId = pDexFile->GetProtoId(secondary_index); diff --git a/dexdump/dexdump_test.cc b/dexdump/dexdump_test.cc index d28ca2834e..53dda6a995 100644 --- a/dexdump/dexdump_test.cc +++ b/dexdump/dexdump_test.cc @@ -21,7 +21,6 @@ #include <sys/types.h> #include <unistd.h> -#include "base/stringprintf.h" #include "common_runtime_test.h" #include "runtime/arch/instruction_set.h" #include "runtime/os.h" diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc index cfe48378ae..cac60900bc 100644 --- a/dexlayout/dexlayout.cc +++ b/dexlayout/dexlayout.cc @@ -30,7 +30,8 @@ #include <sstream> #include <vector> -#include "base/stringprintf.h" +#include "android-base/stringprintf.h" + #include "dex_ir_builder.h" #include "dex_file-inl.h" #include "dex_instruction-inl.h" @@ -43,6 +44,8 @@ namespace art { +using android::base::StringPrintf; + /* * Flags for use with createAccessFlagStr(). */ diff --git a/dexlayout/dexlayout_test.cc b/dexlayout/dexlayout_test.cc index 665baa6c73..46a1c43548 100644 --- a/dexlayout/dexlayout_test.cc +++ b/dexlayout/dexlayout_test.cc @@ -21,7 +21,6 @@ #include <sys/types.h> #include <unistd.h> -#include "base/stringprintf.h" #include "base/unix_file/fd_file.h" #include "common_runtime_test.h" #include "utils.h" diff --git a/dexlist/dexlist_test.cc b/dexlist/dexlist_test.cc index da1dd7fd89..13209427c9 100644 --- a/dexlist/dexlist_test.cc +++ b/dexlist/dexlist_test.cc @@ -21,7 +21,6 @@ #include <sys/types.h> #include <unistd.h> -#include "base/stringprintf.h" #include "common_runtime_test.h" #include "runtime/arch/instruction_set.h" #include "runtime/gc/heap.h" diff --git a/imgdiag/imgdiag.cc b/imgdiag/imgdiag.cc index a374686dc5..f307cbc4f5 100644 --- a/imgdiag/imgdiag.cc +++ b/imgdiag/imgdiag.cc @@ -26,9 +26,10 @@ #include <map> #include <unordered_set> +#include "android-base/stringprintf.h" + #include "art_method-inl.h" #include "base/unix_file/fd_file.h" -#include "base/stringprintf.h" #include "gc/space/image_space.h" #include "gc/heap.h" #include "mirror/class-inl.h" @@ -46,6 +47,8 @@ namespace art { +using android::base::StringPrintf; + class ImgDiagDumper { public: explicit ImgDiagDumper(std::ostream* os, diff --git a/imgdiag/imgdiag_test.cc b/imgdiag/imgdiag_test.cc index 9f771ba8a3..3f2afc0696 100644 --- a/imgdiag/imgdiag_test.cc +++ b/imgdiag/imgdiag_test.cc @@ -20,12 +20,13 @@ #include "common_runtime_test.h" +#include "android-base/stringprintf.h" + #include "runtime/os.h" #include "runtime/arch/instruction_set.h" #include "runtime/utils.h" #include "runtime/gc/space/image_space.h" #include "runtime/gc/heap.h" -#include "base/stringprintf.h" #include <sys/types.h> #include <unistd.h> @@ -57,7 +58,7 @@ class ImgDiagTest : public CommonRuntimeTest { virtual void SetUpRuntimeOptions(RuntimeOptions* options) OVERRIDE { // Needs to live until CommonRuntimeTest::SetUp finishes, since we pass it a cstring. - runtime_args_image_ = StringPrintf("-Ximage:%s", GetCoreArtLocation().c_str()); + runtime_args_image_ = android::base::StringPrintf("-Ximage:%s", GetCoreArtLocation().c_str()); options->push_back(std::make_pair(runtime_args_image_, nullptr)); } diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index e4462d8305..148ee88669 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -26,6 +26,7 @@ #include <unordered_set> #include <vector> +#include "android-base/stringprintf.h" #include "android-base/strings.h" #include "arch/instruction_set_features.h" @@ -76,6 +77,8 @@ namespace art { +using android::base::StringPrintf; + const char* image_methods_descriptions_[] = { "kResolutionMethod", "kImtConflictMethod", @@ -89,6 +92,7 @@ const char* image_methods_descriptions_[] = { const char* image_roots_descriptions_[] = { "kDexCaches", "kClassRoots", + "kClassLoader", }; // Map is so that we don't allocate multiple dex files for the same OatDexFile. @@ -1506,12 +1510,13 @@ class ImageDumper { os << "ROOTS: " << reinterpret_cast<void*>(image_header_.GetImageRoots()) << "\n"; static_assert(arraysize(image_roots_descriptions_) == static_cast<size_t>(ImageHeader::kImageRootsMax), "sizes must match"); - for (int i = 0; i < ImageHeader::kImageRootsMax; i++) { + DCHECK_LE(image_header_.GetImageRoots()->GetLength(), ImageHeader::kImageRootsMax); + for (int32_t i = 0, size = image_header_.GetImageRoots()->GetLength(); i != size; ++i) { ImageHeader::ImageRoot image_root = static_cast<ImageHeader::ImageRoot>(i); const char* image_root_description = image_roots_descriptions_[i]; mirror::Object* image_root_object = image_header_.GetImageRoot(image_root); indent_os << StringPrintf("%s: %p\n", image_root_description, image_root_object); - if (image_root_object->IsObjectArray()) { + if (image_root_object != nullptr && image_root_object->IsObjectArray()) { mirror::ObjectArray<mirror::Object>* image_root_object_array = image_root_object->AsObjectArray<mirror::Object>(); ScopedIndentation indent2(&vios_); diff --git a/oatdump/oatdump_test.cc b/oatdump/oatdump_test.cc index a2eba4514b..e77d03bae7 100644 --- a/oatdump/oatdump_test.cc +++ b/oatdump/oatdump_test.cc @@ -22,7 +22,6 @@ #include "common_runtime_test.h" -#include "base/stringprintf.h" #include "base/unix_file/fd_file.h" #include "runtime/arch/instruction_set.h" #include "runtime/gc/heap.h" diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc index 62d1ddff75..7ae13a574b 100644 --- a/patchoat/patchoat.cc +++ b/patchoat/patchoat.cc @@ -24,6 +24,7 @@ #include <string> #include <vector> +#include "android-base/stringprintf.h" #include "android-base/strings.h" #include "art_field-inl.h" @@ -31,7 +32,6 @@ #include "base/dumpable.h" #include "base/scoped_flock.h" #include "base/stringpiece.h" -#include "base/stringprintf.h" #include "base/unix_file/fd_file.h" #include "base/unix_file/random_access_file_utils.h" #include "elf_utils.h" @@ -939,7 +939,7 @@ static std::string CommandLine() { static void UsageErrorV(const char* fmt, va_list ap) { std::string error; - StringAppendV(&error, fmt, ap); + android::base::StringAppendV(&error, fmt, ap); LOG(ERROR) << error; } diff --git a/profman/profman.cc b/profman/profman.cc index 0b2d172726..e5384078f1 100644 --- a/profman/profman.cc +++ b/profman/profman.cc @@ -25,12 +25,12 @@ #include <string> #include <vector> +#include "android-base/stringprintf.h" #include "android-base/strings.h" #include "base/dumpable.h" #include "base/scoped_flock.h" #include "base/stringpiece.h" -#include "base/stringprintf.h" #include "base/time_utils.h" #include "base/unix_file/fd_file.h" #include "dex_file.h" @@ -61,7 +61,7 @@ static bool FdIsValid(int fd) { static void UsageErrorV(const char* fmt, va_list ap) { std::string error; - StringAppendV(&error, fmt, ap); + android::base::StringAppendV(&error, fmt, ap); LOG(ERROR) << error; } diff --git a/runtime/Android.bp b/runtime/Android.bp index 32ebee24c8..86019bf71c 100644 --- a/runtime/Android.bp +++ b/runtime/Android.bp @@ -40,7 +40,6 @@ cc_defaults { "base/scoped_arena_allocator.cc", "base/scoped_flock.cc", "base/stringpiece.cc", - "base/stringprintf.cc", "base/time_utils.cc", "base/timing_logger.cc", "base/unix_file/fd_file.cc", @@ -508,7 +507,6 @@ art_cc_test { "base/histogram_test.cc", "base/mutex_test.cc", "base/scoped_flock_test.cc", - "base/stringprintf_test.cc", "base/time_utils_test.cc", "base/timing_logger_test.cc", "base/transform_array_ref_test.cc", diff --git a/runtime/arch/arm/instruction_set_features_arm.cc b/runtime/arch/arm/instruction_set_features_arm.cc index f264b82448..181b2ed723 100644 --- a/runtime/arch/arm/instruction_set_features_arm.cc +++ b/runtime/arch/arm/instruction_set_features_arm.cc @@ -24,10 +24,10 @@ #include "signal.h" #include <fstream> +#include "android-base/stringprintf.h" #include "android-base/strings.h" -#include "base/stringprintf.h" -#include "utils.h" // For Trim. +#include "base/logging.h" #if defined(__arm__) extern "C" bool artCheckForArmSdivInstruction(); @@ -35,6 +35,8 @@ extern "C" bool artCheckForArmSdivInstruction(); namespace art { +using android::base::StringPrintf; + ArmFeaturesUniquePtr ArmInstructionSetFeatures::FromVariant( const std::string& variant, std::string* error_msg) { // Assume all ARM processors are SMP. diff --git a/runtime/arch/arm64/instruction_set_features_arm64.cc b/runtime/arch/arm64/instruction_set_features_arm64.cc index f7b5a7649a..52d8b3e367 100644 --- a/runtime/arch/arm64/instruction_set_features_arm64.cc +++ b/runtime/arch/arm64/instruction_set_features_arm64.cc @@ -19,14 +19,16 @@ #include <fstream> #include <sstream> +#include "android-base/stringprintf.h" #include "android-base/strings.h" +#include "base/logging.h" #include "base/stl_util.h" -#include "base/stringprintf.h" -#include "utils.h" // For Trim. namespace art { +using android::base::StringPrintf; + Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromVariant( const std::string& variant, std::string* error_msg) { const bool smp = true; // Conservative default. diff --git a/runtime/arch/instruction_set_features_test.cc b/runtime/arch/instruction_set_features_test.cc index 0b8e531896..d4893923d6 100644 --- a/runtime/arch/instruction_set_features_test.cc +++ b/runtime/arch/instruction_set_features_test.cc @@ -22,11 +22,14 @@ #include "android-base/properties.h" #endif +#include "android-base/stringprintf.h" + #include "base/logging.h" -#include "base/stringprintf.h" namespace art { +using android::base::StringPrintf; + #ifdef ART_TARGET_ANDROID #if defined(__aarch64__) TEST(InstructionSetFeaturesTest, DISABLED_FeaturesFromSystemPropertyVariant) { diff --git a/runtime/arch/instruction_set_test.cc b/runtime/arch/instruction_set_test.cc index 5dfc4b4c48..5aae93acc5 100644 --- a/runtime/arch/instruction_set_test.cc +++ b/runtime/arch/instruction_set_test.cc @@ -19,7 +19,6 @@ #include <gtest/gtest.h> #include "base/enums.h" -#include "base/stringprintf.h" namespace art { diff --git a/runtime/arch/mips/instruction_set_features_mips.cc b/runtime/arch/mips/instruction_set_features_mips.cc index a65c967efd..5b50573695 100644 --- a/runtime/arch/mips/instruction_set_features_mips.cc +++ b/runtime/arch/mips/instruction_set_features_mips.cc @@ -19,14 +19,16 @@ #include <fstream> #include <sstream> +#include "android-base/stringprintf.h" #include "android-base/strings.h" +#include "base/logging.h" #include "base/stl_util.h" -#include "base/stringprintf.h" -#include "utils.h" // For Trim. namespace art { +using android::base::StringPrintf; + // An enum for the Mips revision. enum class MipsLevel { kBase, diff --git a/runtime/arch/mips64/instruction_set_features_mips64.cc b/runtime/arch/mips64/instruction_set_features_mips64.cc index e564d1eab5..92c44e85de 100644 --- a/runtime/arch/mips64/instruction_set_features_mips64.cc +++ b/runtime/arch/mips64/instruction_set_features_mips64.cc @@ -19,13 +19,15 @@ #include <fstream> #include <sstream> +#include "android-base/stringprintf.h" #include "android-base/strings.h" -#include "base/stringprintf.h" -#include "utils.h" // For Trim. +#include "base/logging.h" namespace art { +using android::base::StringPrintf; + Mips64FeaturesUniquePtr Mips64InstructionSetFeatures::FromVariant( const std::string& variant, std::string* error_msg ATTRIBUTE_UNUSED) { if (variant != "default" && variant != "mips64r6") { diff --git a/runtime/arch/x86/instruction_set_features_x86.cc b/runtime/arch/x86/instruction_set_features_x86.cc index cc102ecedd..c520d63cf3 100644 --- a/runtime/arch/x86/instruction_set_features_x86.cc +++ b/runtime/arch/x86/instruction_set_features_x86.cc @@ -19,14 +19,16 @@ #include <fstream> #include <sstream> +#include "android-base/stringprintf.h" #include "android-base/strings.h" #include "arch/x86_64/instruction_set_features_x86_64.h" -#include "base/stringprintf.h" -#include "utils.h" // For Trim. +#include "base/logging.h" namespace art { +using android::base::StringPrintf; + // Feature-support arrays. static constexpr const char* x86_known_variants[] = { diff --git a/runtime/art_method.cc b/runtime/art_method.cc index 96b6f18403..dfc7837aea 100644 --- a/runtime/art_method.cc +++ b/runtime/art_method.cc @@ -18,6 +18,8 @@ #include <cstddef> +#include "android-base/stringprintf.h" + #include "arch/context.h" #include "art_field-inl.h" #include "art_method-inl.h" @@ -46,6 +48,8 @@ namespace art { +using android::base::StringPrintf; + extern "C" void art_quick_invoke_stub(ArtMethod*, uint32_t*, uint32_t, Thread*, JValue*, const char*); extern "C" void art_quick_invoke_static_stub(ArtMethod*, uint32_t*, uint32_t, Thread*, JValue*, diff --git a/runtime/asm_support.h b/runtime/asm_support.h index 5ef1f06e77..e4972da13d 100644 --- a/runtime/asm_support.h +++ b/runtime/asm_support.h @@ -175,19 +175,19 @@ ADD_TEST_EQ(MIRROR_CLASS_COMPONENT_TYPE_OFFSET, #define MIRROR_CLASS_IF_TABLE_OFFSET (16 + MIRROR_OBJECT_HEADER_SIZE) ADD_TEST_EQ(MIRROR_CLASS_IF_TABLE_OFFSET, art::mirror::Class::IfTableOffset().Int32Value()) -#define MIRROR_CLASS_ACCESS_FLAGS_OFFSET (64 + MIRROR_OBJECT_HEADER_SIZE) +#define MIRROR_CLASS_ACCESS_FLAGS_OFFSET (56 + MIRROR_OBJECT_HEADER_SIZE) ADD_TEST_EQ(MIRROR_CLASS_ACCESS_FLAGS_OFFSET, art::mirror::Class::AccessFlagsOffset().Int32Value()) -#define MIRROR_CLASS_OBJECT_SIZE_OFFSET (96 + MIRROR_OBJECT_HEADER_SIZE) +#define MIRROR_CLASS_OBJECT_SIZE_OFFSET (88 + MIRROR_OBJECT_HEADER_SIZE) ADD_TEST_EQ(MIRROR_CLASS_OBJECT_SIZE_OFFSET, art::mirror::Class::ObjectSizeOffset().Int32Value()) -#define MIRROR_CLASS_OBJECT_SIZE_ALLOC_FAST_PATH_OFFSET (100 + MIRROR_OBJECT_HEADER_SIZE) +#define MIRROR_CLASS_OBJECT_SIZE_ALLOC_FAST_PATH_OFFSET (92 + MIRROR_OBJECT_HEADER_SIZE) ADD_TEST_EQ(MIRROR_CLASS_OBJECT_SIZE_ALLOC_FAST_PATH_OFFSET, art::mirror::Class::ObjectSizeAllocFastPathOffset().Int32Value()) -#define MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET (104 + MIRROR_OBJECT_HEADER_SIZE) +#define MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET (96 + MIRROR_OBJECT_HEADER_SIZE) ADD_TEST_EQ(MIRROR_CLASS_OBJECT_PRIMITIVE_TYPE_OFFSET, art::mirror::Class::PrimitiveTypeOffset().Int32Value()) -#define MIRROR_CLASS_STATUS_OFFSET (112 + MIRROR_OBJECT_HEADER_SIZE) +#define MIRROR_CLASS_STATUS_OFFSET (104 + MIRROR_OBJECT_HEADER_SIZE) ADD_TEST_EQ(MIRROR_CLASS_STATUS_OFFSET, art::mirror::Class::StatusOffset().Int32Value()) diff --git a/runtime/base/file_magic.cc b/runtime/base/file_magic.cc index de6f4237ff..568a7ae5d6 100644 --- a/runtime/base/file_magic.cc +++ b/runtime/base/file_magic.cc @@ -20,13 +20,16 @@ #include <sys/stat.h> #include <sys/types.h> +#include "android-base/stringprintf.h" + #include "base/logging.h" #include "base/unix_file/fd_file.h" #include "dex_file.h" -#include "stringprintf.h" namespace art { +using android::base::StringPrintf; + File OpenAndReadMagic(const char* filename, uint32_t* magic, std::string* error_msg) { CHECK(magic != nullptr); File fd(filename, O_RDONLY, /* check_usage */ false); diff --git a/runtime/base/mutex-inl.h b/runtime/base/mutex-inl.h index 92b7c6537c..44a84c834f 100644 --- a/runtime/base/mutex-inl.h +++ b/runtime/base/mutex-inl.h @@ -21,7 +21,6 @@ #include "mutex.h" -#include "base/stringprintf.h" #include "base/value_object.h" #include "thread.h" #include "utils.h" diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc index ce452cbcf6..9116097604 100644 --- a/runtime/base/mutex.cc +++ b/runtime/base/mutex.cc @@ -19,6 +19,8 @@ #include <errno.h> #include <sys/time.h> +#include "android-base/stringprintf.h" + #include "atomic.h" #include "base/logging.h" #include "base/time_utils.h" @@ -30,6 +32,8 @@ namespace art { +using android::base::StringPrintf; + static Atomic<Locks::ClientCallback*> safe_to_call_abort_callback(nullptr); Mutex* Locks::abort_lock_ = nullptr; diff --git a/runtime/base/scoped_flock.cc b/runtime/base/scoped_flock.cc index 0e8031f4f2..d4bb56b62a 100644 --- a/runtime/base/scoped_flock.cc +++ b/runtime/base/scoped_flock.cc @@ -19,12 +19,15 @@ #include <sys/file.h> #include <sys/stat.h> +#include "android-base/stringprintf.h" + #include "base/logging.h" -#include "base/stringprintf.h" #include "base/unix_file/fd_file.h" namespace art { +using android::base::StringPrintf; + bool ScopedFlock::Init(const char* filename, std::string* error_msg) { return Init(filename, O_CREAT | O_RDWR, true, error_msg); } diff --git a/runtime/base/stringprintf.cc b/runtime/base/stringprintf.cc deleted file mode 100644 index 8fd9257048..0000000000 --- a/runtime/base/stringprintf.cc +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -#include "stringprintf.h" - -#include <stdio.h> - -namespace art { - -void StringAppendV(std::string* dst, const char* format, va_list ap) { - // First try with a small fixed size buffer - char space[1024]; - - // It's possible for methods that use a va_list to invalidate - // the data in it upon use. The fix is to make a copy - // of the structure before using it and use that copy instead. - va_list backup_ap; - va_copy(backup_ap, ap); - int result = vsnprintf(space, sizeof(space), format, backup_ap); - va_end(backup_ap); - - if (result < static_cast<int>(sizeof(space))) { - if (result >= 0) { - // Normal case -- everything fit. - dst->append(space, result); - return; - } - - if (result < 0) { - // Just an error. - return; - } - } - - // Increase the buffer size to the size requested by vsnprintf, - // plus one for the closing \0. - int length = result+1; - char* buf = new char[length]; - - // Restore the va_list before we use it again - va_copy(backup_ap, ap); - result = vsnprintf(buf, length, format, backup_ap); - va_end(backup_ap); - - if (result >= 0 && result < length) { - // It fit - dst->append(buf, result); - } - delete[] buf; -} - -std::string StringPrintf(const char* fmt, ...) { - va_list ap; - va_start(ap, fmt); - std::string result; - StringAppendV(&result, fmt, ap); - va_end(ap); - return result; -} - -void StringAppendF(std::string* dst, const char* format, ...) { - va_list ap; - va_start(ap, format); - StringAppendV(dst, format, ap); - va_end(ap); -} - -} // namespace art diff --git a/runtime/base/stringprintf.h b/runtime/base/stringprintf.h deleted file mode 100644 index 4767a750c3..0000000000 --- a/runtime/base/stringprintf.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2011 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_RUNTIME_BASE_STRINGPRINTF_H_ -#define ART_RUNTIME_BASE_STRINGPRINTF_H_ - -#include <stdarg.h> -#include <string> - -namespace art { - -// Returns a string corresponding to printf-like formatting of the arguments. -std::string StringPrintf(const char* fmt, ...) - __attribute__((__format__(__printf__, 1, 2))); - -// Appends a printf-like formatting of the arguments to 'dst'. -void StringAppendF(std::string* dst, const char* fmt, ...) - __attribute__((__format__(__printf__, 2, 3))); - -// Appends a printf-like formatting of the arguments to 'dst'. -void StringAppendV(std::string* dst, const char* format, va_list ap); - -} // namespace art - -#endif // ART_RUNTIME_BASE_STRINGPRINTF_H_ diff --git a/runtime/base/time_utils.cc b/runtime/base/time_utils.cc index 57f198d7e5..3c09d5a36f 100644 --- a/runtime/base/time_utils.cc +++ b/runtime/base/time_utils.cc @@ -20,8 +20,9 @@ #include "time_utils.h" +#include "android-base/stringprintf.h" + #include "base/logging.h" -#include "base/stringprintf.h" #if defined(__APPLE__) #include <sys/time.h> @@ -29,6 +30,8 @@ namespace art { +using android::base::StringPrintf; + std::string PrettyDuration(uint64_t nano_duration, size_t max_fraction_digits) { if (nano_duration == 0) { return "0"; diff --git a/runtime/check_jni.cc b/runtime/check_jni.cc index 6c27bc61e4..1c3328e484 100644 --- a/runtime/check_jni.cc +++ b/runtime/check_jni.cc @@ -20,6 +20,8 @@ #include <sys/mman.h> #include <zlib.h> +#include "android-base/stringprintf.h" + #include "art_field-inl.h" #include "art_method-inl.h" #include "base/logging.h" @@ -42,6 +44,9 @@ namespace art { +using android::base::StringAppendF; +using android::base::StringPrintf; + /* * =========================================================================== * JNI function helpers diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h index 213986ae45..a11257f21b 100644 --- a/runtime/class_linker-inl.h +++ b/runtime/class_linker-inl.h @@ -73,7 +73,7 @@ inline mirror::String* ClassLinker::ResolveString(dex::StringIndex string_idx, // MethodVerifier refuses methods with string_idx out of bounds. DCHECK_LT(string_idx.index_, declaring_class->GetDexFile().NumStringIds()); ObjPtr<mirror::String> string = - mirror::StringDexCachePair::Lookup(declaring_class->GetDexCacheStrings(), + mirror::StringDexCachePair::Lookup(declaring_class->GetDexCache()->GetStrings(), string_idx.index_, mirror::DexCache::kDexCacheStringCacheSize).Read(); if (UNLIKELY(string == nullptr)) { diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index f3a5be2172..20aaa429f7 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -28,6 +28,8 @@ #include <utility> #include <vector> +#include "android-base/stringprintf.h" + #include "art_field-inl.h" #include "art_method-inl.h" #include "base/arena_allocator.h" @@ -106,6 +108,8 @@ namespace art { +using android::base::StringPrintf; + static constexpr bool kSanityCheckObjects = kIsDebugBuild; static constexpr bool kVerifyArtMethodDeclaringClasses = kIsDebugBuild; @@ -1401,39 +1405,20 @@ bool ClassLinker::UpdateAppImageClassLoadersAndDexCaches( return true; } -// Update the class loader and resolved string dex cache array of classes. Should only be used on -// classes in the image space. -class UpdateClassLoaderAndResolvedStringsVisitor { +// Update the class loader. Should only be used on classes in the image space. +class UpdateClassLoaderVisitor { public: - UpdateClassLoaderAndResolvedStringsVisitor(gc::space::ImageSpace* space, - ObjPtr<mirror::ClassLoader> class_loader, - bool forward_strings) + UpdateClassLoaderVisitor(gc::space::ImageSpace* space, ObjPtr<mirror::ClassLoader> class_loader) : space_(space), - class_loader_(class_loader), - forward_strings_(forward_strings) {} + class_loader_(class_loader) {} bool operator()(ObjPtr<mirror::Class> klass) const REQUIRES_SHARED(Locks::mutator_lock_) { - if (forward_strings_) { - mirror::StringDexCacheType* strings = klass->GetDexCacheStrings(); - if (strings != nullptr) { - DCHECK( - space_->GetImageHeader().GetImageSection(ImageHeader::kSectionDexCacheArrays).Contains( - reinterpret_cast<uint8_t*>(strings) - space_->Begin())) - << "String dex cache array for " << klass->PrettyClass() << " is not in app image"; - // Dex caches have already been updated, so take the strings pointer from there. - mirror::StringDexCacheType* new_strings = klass->GetDexCache()->GetStrings(); - DCHECK_NE(strings, new_strings); - klass->SetDexCacheStrings(new_strings); - } - } - // Finally, update class loader. klass->SetClassLoader(class_loader_); return true; } gc::space::ImageSpace* const space_; ObjPtr<mirror::ClassLoader> const class_loader_; - const bool forward_strings_; }; static std::unique_ptr<const DexFile> OpenOatDexFile(const OatFile* oat_file, @@ -1655,13 +1640,6 @@ bool ClassLinker::AddImageSpace( Runtime* const runtime = Runtime::Current(); gc::Heap* const heap = runtime->GetHeap(); Thread* const self = Thread::Current(); - StackHandleScope<2> hs(self); - Handle<mirror::ObjectArray<mirror::DexCache>> dex_caches( - hs.NewHandle(dex_caches_object->AsObjectArray<mirror::DexCache>())); - Handle<mirror::ObjectArray<mirror::Class>> class_roots(hs.NewHandle( - header.GetImageRoot(ImageHeader::kClassRoots)->AsObjectArray<mirror::Class>())); - const OatFile* oat_file = space->GetOatFile(); - std::unordered_set<mirror::ClassLoader*> image_class_loaders; // Check that the image is what we are expecting. if (image_pointer_size_ != space->GetImageHeader().GetPointerSize()) { *error_msg = StringPrintf("Application image pointer size does not match runtime: %zu vs %zu", @@ -1669,6 +1647,22 @@ bool ClassLinker::AddImageSpace( image_pointer_size_); return false; } + size_t expected_image_roots = ImageHeader::NumberOfImageRoots(app_image); + if (static_cast<size_t>(header.GetImageRoots()->GetLength()) != expected_image_roots) { + *error_msg = StringPrintf("Expected %zu image roots but got %d", + expected_image_roots, + header.GetImageRoots()->GetLength()); + return false; + } + StackHandleScope<3> hs(self); + Handle<mirror::ObjectArray<mirror::DexCache>> dex_caches( + hs.NewHandle(dex_caches_object->AsObjectArray<mirror::DexCache>())); + Handle<mirror::ObjectArray<mirror::Class>> class_roots(hs.NewHandle( + header.GetImageRoot(ImageHeader::kClassRoots)->AsObjectArray<mirror::Class>())); + static_assert(ImageHeader::kClassLoader + 1u == ImageHeader::kImageRootsMax, + "Class loader should be the last image root."); + MutableHandle<mirror::ClassLoader> image_class_loader(hs.NewHandle( + app_image ? header.GetImageRoot(ImageHeader::kClassLoader)->AsClassLoader() : nullptr)); DCHECK(class_roots.Get() != nullptr); if (class_roots->GetLength() != static_cast<int32_t>(kClassRootsMax)) { *error_msg = StringPrintf("Expected %d class roots but got %d", @@ -1683,6 +1677,7 @@ bool ClassLinker::AddImageSpace( return false; } } + const OatFile* oat_file = space->GetOatFile(); if (oat_file->GetOatHeader().GetDexFileCount() != static_cast<uint32_t>(dex_caches->GetLength())) { *error_msg = "Dex cache count and dex file count mismatch while trying to initialize from " @@ -1715,15 +1710,11 @@ bool ClassLinker::AddImageSpace( // The current dex file field is bogus, overwrite it so that we can get the dex file in the // loop below. h_dex_cache->SetDexFile(dex_file.get()); - // Check that each class loader resolved the same way. - // TODO: Store image class loaders as image roots. GcRoot<mirror::Class>* const types = h_dex_cache->GetResolvedTypes(); for (int32_t j = 0, num_types = h_dex_cache->NumResolvedTypes(); j < num_types; j++) { ObjPtr<mirror::Class> klass = types[j].Read(); if (klass != nullptr) { DCHECK_NE(klass->GetStatus(), mirror::Class::kStatusError); - ObjPtr<mirror::ClassLoader> image_class_loader = klass->GetClassLoader(); - image_class_loaders.insert(image_class_loader.Ptr()); } } } else { @@ -1749,59 +1740,57 @@ bool ClassLinker::AddImageSpace( // for PathClassLoader does this by looping through the array of dex files. To ensure they // resolve the same way, simply flatten the hierarchy in the way the resolution order would be, // and check that the dex file names are the same. - for (ObjPtr<mirror::ClassLoader> image_class_loader : image_class_loaders) { - if (IsBootClassLoader(soa, image_class_loader)) { - // The dex cache can reference types from the boot class loader. - continue; - } - std::list<mirror::String*> image_dex_file_names; - std::string temp_error_msg; - if (!FlattenPathClassLoader(image_class_loader, &image_dex_file_names, &temp_error_msg)) { - *error_msg = StringPrintf("Failed to flatten image class loader hierarchy '%s'", - temp_error_msg.c_str()); - return false; - } - std::list<mirror::String*> loader_dex_file_names; - if (!FlattenPathClassLoader(class_loader.Get(), &loader_dex_file_names, &temp_error_msg)) { - *error_msg = StringPrintf("Failed to flatten class loader hierarchy '%s'", - temp_error_msg.c_str()); - return false; + if (IsBootClassLoader(soa, image_class_loader.Get())) { + *error_msg = "Unexpected BootClassLoader in app image"; + return false; + } + std::list<mirror::String*> image_dex_file_names; + std::string temp_error_msg; + if (!FlattenPathClassLoader(image_class_loader.Get(), &image_dex_file_names, &temp_error_msg)) { + *error_msg = StringPrintf("Failed to flatten image class loader hierarchy '%s'", + temp_error_msg.c_str()); + return false; + } + std::list<mirror::String*> loader_dex_file_names; + if (!FlattenPathClassLoader(class_loader.Get(), &loader_dex_file_names, &temp_error_msg)) { + *error_msg = StringPrintf("Failed to flatten class loader hierarchy '%s'", + temp_error_msg.c_str()); + return false; + } + // Add the temporary dex path list elements at the end. + auto elements = soa.Decode<mirror::ObjectArray<mirror::Object>>(dex_elements); + for (size_t i = 0, num_elems = elements->GetLength(); i < num_elems; ++i) { + ObjPtr<mirror::Object> element = elements->GetWithoutChecks(i); + if (element != nullptr) { + // If we are somewhere in the middle of the array, there may be nulls at the end. + loader_dex_file_names.push_back(GetDexPathListElementName(element)); } - // Add the temporary dex path list elements at the end. - auto elements = soa.Decode<mirror::ObjectArray<mirror::Object>>(dex_elements); - for (size_t i = 0, num_elems = elements->GetLength(); i < num_elems; ++i) { - ObjPtr<mirror::Object> element = elements->GetWithoutChecks(i); - if (element != nullptr) { - // If we are somewhere in the middle of the array, there may be nulls at the end. - loader_dex_file_names.push_back(GetDexPathListElementName(element)); - } + } + // Ignore the number of image dex files since we are adding those to the class loader anyways. + CHECK_GE(static_cast<size_t>(image_dex_file_names.size()), + static_cast<size_t>(dex_caches->GetLength())); + size_t image_count = image_dex_file_names.size() - dex_caches->GetLength(); + // Check that the dex file names match. + bool equal = image_count == loader_dex_file_names.size(); + if (equal) { + auto it1 = image_dex_file_names.begin(); + auto it2 = loader_dex_file_names.begin(); + for (size_t i = 0; equal && i < image_count; ++i, ++it1, ++it2) { + equal = equal && (*it1)->Equals(*it2); } - // Ignore the number of image dex files since we are adding those to the class loader anyways. - CHECK_GE(static_cast<size_t>(image_dex_file_names.size()), - static_cast<size_t>(dex_caches->GetLength())); - size_t image_count = image_dex_file_names.size() - dex_caches->GetLength(); - // Check that the dex file names match. - bool equal = image_count == loader_dex_file_names.size(); - if (equal) { - auto it1 = image_dex_file_names.begin(); - auto it2 = loader_dex_file_names.begin(); - for (size_t i = 0; equal && i < image_count; ++i, ++it1, ++it2) { - equal = equal && (*it1)->Equals(*it2); - } + } + if (!equal) { + VLOG(image) << "Image dex files " << image_dex_file_names.size(); + for (ObjPtr<mirror::String> name : image_dex_file_names) { + VLOG(image) << name->ToModifiedUtf8(); } - if (!equal) { - VLOG(image) << "Image dex files " << image_dex_file_names.size(); - for (ObjPtr<mirror::String> name : image_dex_file_names) { - VLOG(image) << name->ToModifiedUtf8(); - } - VLOG(image) << "Loader dex files " << loader_dex_file_names.size(); - for (ObjPtr<mirror::String> name : loader_dex_file_names) { - VLOG(image) << name->ToModifiedUtf8(); - } - *error_msg = "Rejecting application image due to class loader mismatch"; - // Ignore class loader mismatch for now since these would just use possibly incorrect - // oat code anyways. The structural class check should be done in the parent. + VLOG(image) << "Loader dex files " << loader_dex_file_names.size(); + for (ObjPtr<mirror::String> name : loader_dex_file_names) { + VLOG(image) << name->ToModifiedUtf8(); } + *error_msg = "Rejecting application image due to class loader mismatch"; + // Ignore class loader mismatch for now since these would just use possibly incorrect + // oat code anyways. The structural class check should be done in the parent. } } @@ -1856,10 +1845,8 @@ bool ClassLinker::AddImageSpace( } // Update class loader and resolved strings. If added_class_table is false, the resolved // strings were forwarded UpdateAppImageClassLoadersAndDexCaches. - UpdateClassLoaderAndResolvedStringsVisitor visitor(space, - class_loader.Get(), - forward_dex_cache_arrays); - for (ClassTable::TableSlot& root : temp_set) { + UpdateClassLoaderVisitor visitor(space, class_loader.Get()); + for (const ClassTable::TableSlot& root : temp_set) { visitor(root.Read()); } // forward_dex_cache_arrays is true iff we copied all of the dex cache arrays into the .bss. @@ -2659,6 +2646,8 @@ mirror::Class* ClassLinker::DefineClass(Thread* self, ObjectLock<mirror::Class> lock(self, klass); klass->SetClinitThreadId(self->GetTid()); + // Make sure we have a valid empty iftable even if there are errors. + klass->SetIfTable(GetClassRoot(kJavaLangObject)->GetIfTable()); // Add the newly loaded class to the loaded classes table. ObjPtr<mirror::Class> existing = InsertClass(descriptor, klass.Get(), hash); @@ -3010,7 +2999,6 @@ void ClassLinker::SetupClass(const DexFile& dex_file, klass->SetDexClassDefIndex(dex_file.GetIndexForClassDef(dex_class_def)); klass->SetDexTypeIndex(dex_class_def.class_idx_); - CHECK(klass->GetDexCacheStrings() != nullptr); } void ClassLinker::LoadClass(Thread* self, diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index 685677bd80..42108d8621 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -278,8 +278,6 @@ class ClassLinkerTest : public CommonRuntimeTest { EXPECT_FALSE(klass->IsArrayClass()); EXPECT_TRUE(klass->GetComponentType() == nullptr); EXPECT_TRUE(klass->IsInSamePackage(klass.Get())); - EXPECT_TRUE(klass->GetDexCacheStrings() != nullptr); - EXPECT_EQ(klass->GetDexCacheStrings(), klass->GetDexCache()->GetStrings()); std::string temp2; EXPECT_TRUE(mirror::Class::IsInSamePackage(klass->GetDescriptor(&temp), klass->GetDescriptor(&temp2))); @@ -590,7 +588,6 @@ struct ClassOffsets : public CheckOffsets<mirror::Class> { addOffset(OFFSETOF_MEMBER(mirror::Class, component_type_), "componentType"); addOffset(OFFSETOF_MEMBER(mirror::Class, copied_methods_offset_), "copiedMethodsOffset"); addOffset(OFFSETOF_MEMBER(mirror::Class, dex_cache_), "dexCache"); - addOffset(OFFSETOF_MEMBER(mirror::Class, dex_cache_strings_), "dexCacheStrings"); addOffset(OFFSETOF_MEMBER(mirror::Class, dex_class_def_idx_), "dexClassDefIndex"); addOffset(OFFSETOF_MEMBER(mirror::Class, dex_type_idx_), "dexTypeIndex"); addOffset(OFFSETOF_MEMBER(mirror::Class, ext_data_), "extData"); @@ -1175,6 +1172,24 @@ TEST_F(ClassLinkerTest, ResolveVerifyAndClinit) { EXPECT_TRUE(init->IsInitialized()); } +TEST_F(ClassLinkerTest, ErroneousClass) { + ScopedObjectAccess soa(Thread::Current()); + jobject jclass_loader = LoadMultiDex("ErroneousA", "ErroneousB"); + StackHandleScope<1> hs(soa.Self()); + Handle<mirror::ClassLoader> class_loader( + hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader))); + hs.Self()->AssertNoPendingException(); + const char* descriptor = "LErroneous;"; + ObjPtr<mirror::Class> klass = class_linker_->FindClass(soa.Self(), descriptor, class_loader); + // Erronenous since we are extending final class. + hs.Self()->AssertPendingException(); + EXPECT_TRUE(klass == nullptr); + klass = class_linker_->LookupClass(soa.Self(), descriptor, class_loader.Get()); + EXPECT_FALSE(klass == nullptr); + EXPECT_TRUE(klass->IsErroneous()); + EXPECT_TRUE(klass->GetIfTable() != nullptr); +} + TEST_F(ClassLinkerTest, FinalizableBit) { ScopedObjectAccess soa(Thread::Current()); mirror::Class* c; diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc index 8226e6049e..743fcc87eb 100644 --- a/runtime/common_runtime_test.cc +++ b/runtime/common_runtime_test.cc @@ -24,11 +24,12 @@ #include <stdlib.h> #include "../../external/icu/icu4c/source/common/unicode/uvernum.h" +#include "android-base/stringprintf.h" + #include "art_field-inl.h" #include "base/macros.h" #include "base/logging.h" #include "base/stl_util.h" -#include "base/stringprintf.h" #include "base/unix_file/fd_file.h" #include "class_linker.h" #include "compiler_callbacks.h" @@ -65,6 +66,8 @@ int main(int argc, char **argv) { namespace art { +using android::base::StringPrintf; + ScratchFile::ScratchFile() { // ANDROID_DATA needs to be set CHECK_NE(static_cast<char*>(nullptr), getenv("ANDROID_DATA")) << diff --git a/runtime/common_throws.cc b/runtime/common_throws.cc index 9f0dbbbdd0..c30272e114 100644 --- a/runtime/common_throws.cc +++ b/runtime/common_throws.cc @@ -18,6 +18,7 @@ #include <sstream> +#include "android-base/stringprintf.h" #include "ScopedLocalRef.h" #include "art_field-inl.h" @@ -37,6 +38,9 @@ namespace art { +using android::base::StringAppendV; +using android::base::StringPrintf; + static void AddReferrerLocation(std::ostream& os, ObjPtr<mirror::Class> referrer) REQUIRES_SHARED(Locks::mutator_lock_) { if (referrer != nullptr) { diff --git a/runtime/debugger.cc b/runtime/debugger.cc index e33966617f..df4413d52c 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -20,6 +20,8 @@ #include <set> +#include "android-base/stringprintf.h" + #include "arch/context.h" #include "art_field-inl.h" #include "art_method-inl.h" @@ -61,6 +63,8 @@ namespace art { +using android::base::StringPrintf; + // The key identifying the debugger to update instrumentation. static constexpr const char* kDbgInstrumentationKey = "Debugger"; diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc index aa8fb38fca..7d704ad0cc 100644 --- a/runtime/dex_file.cc +++ b/runtime/dex_file.cc @@ -28,10 +28,11 @@ #include <sstream> #include <type_traits> +#include "android-base/stringprintf.h" + #include "base/enums.h" #include "base/file_magic.h" #include "base/logging.h" -#include "base/stringprintf.h" #include "base/systrace.h" #include "base/unix_file/fd_file.h" #include "dex_file-inl.h" @@ -45,6 +46,8 @@ namespace art { +using android::base::StringPrintf; + static_assert(sizeof(dex::StringIndex) == sizeof(uint32_t), "StringIndex size is wrong"); static_assert(std::is_trivially_copyable<dex::StringIndex>::value, "StringIndex not trivial"); static_assert(sizeof(dex::TypeIndex) == sizeof(uint16_t), "TypeIndex size is wrong"); diff --git a/runtime/dex_file_annotations.cc b/runtime/dex_file_annotations.cc index 52b9f114d2..9504e8bd29 100644 --- a/runtime/dex_file_annotations.cc +++ b/runtime/dex_file_annotations.cc @@ -18,6 +18,8 @@ #include <stdlib.h> +#include "android-base/stringprintf.h" + #include "art_field-inl.h" #include "art_method-inl.h" #include "class_linker-inl.h" @@ -31,6 +33,8 @@ namespace art { +using android::base::StringPrintf; + struct DexFile::AnnotationValue { JValue value_; uint8_t type_; diff --git a/runtime/dex_file_verifier.cc b/runtime/dex_file_verifier.cc index 07f0fcae56..a3ab9fa5bd 100644 --- a/runtime/dex_file_verifier.cc +++ b/runtime/dex_file_verifier.cc @@ -22,7 +22,8 @@ #include <limits> #include <memory> -#include "base/stringprintf.h" +#include "android-base/stringprintf.h" + #include "dex_file-inl.h" #include "experimental_flags.h" #include "leb128.h" @@ -32,6 +33,9 @@ namespace art { +using android::base::StringAppendV; +using android::base::StringPrintf; + static constexpr uint32_t kTypeIdLimit = std::numeric_limits<uint16_t>::max(); static bool IsValidOrNoTypeId(uint16_t low, uint16_t high) { diff --git a/runtime/dex_instruction.cc b/runtime/dex_instruction.cc index 99023893ba..7b8974fa5a 100644 --- a/runtime/dex_instruction.cc +++ b/runtime/dex_instruction.cc @@ -21,12 +21,15 @@ #include <iomanip> #include <sstream> -#include "base/stringprintf.h" +#include "android-base/stringprintf.h" + #include "dex_file-inl.h" #include "utils.h" namespace art { +using android::base::StringPrintf; + const char* const Instruction::kInstructionNames[] = { #define INSTRUCTION_NAME(o, c, pname, f, i, a, v) pname, #include "dex_instruction_list.h" diff --git a/runtime/elf_file.cc b/runtime/elf_file.cc index ee0f34002b..59b734f169 100644 --- a/runtime/elf_file.cc +++ b/runtime/elf_file.cc @@ -20,11 +20,11 @@ #include <sys/types.h> #include <unistd.h> +#include "android-base/stringprintf.h" #include "android-base/strings.h" #include "arch/instruction_set.h" #include "base/logging.h" -#include "base/stringprintf.h" #include "base/stl_util.h" #include "base/unix_file/fd_file.h" #include "elf_file_impl.h" @@ -34,6 +34,8 @@ namespace art { +using android::base::StringPrintf; + template <typename ElfTypes> ElfFileImpl<ElfTypes>::ElfFileImpl(File* file, bool writable, bool program_header_only, diff --git a/runtime/gc/accounting/space_bitmap.cc b/runtime/gc/accounting/space_bitmap.cc index f4d0bc7dbf..eb9f0395ac 100644 --- a/runtime/gc/accounting/space_bitmap.cc +++ b/runtime/gc/accounting/space_bitmap.cc @@ -16,8 +16,9 @@ #include "space_bitmap-inl.h" +#include "android-base/stringprintf.h" + #include "art_field-inl.h" -#include "base/stringprintf.h" #include "dex_file-inl.h" #include "mem_map.h" #include "mirror/object-inl.h" @@ -28,6 +29,8 @@ namespace art { namespace gc { namespace accounting { +using android::base::StringPrintf; + template<size_t kAlignment> size_t SpaceBitmap<kAlignment>::ComputeBitmapSize(uint64_t capacity) { const uint64_t kBytesCoveredPerWord = kAlignment * kBitsPerIntPtrT; diff --git a/runtime/gc/allocator/rosalloc.cc b/runtime/gc/allocator/rosalloc.cc index 2e4475f225..35a251fda8 100644 --- a/runtime/gc/allocator/rosalloc.cc +++ b/runtime/gc/allocator/rosalloc.cc @@ -16,6 +16,13 @@ #include "rosalloc.h" +#include <map> +#include <list> +#include <sstream> +#include <vector> + +#include "android-base/stringprintf.h" + #include "base/memory_tool.h" #include "base/mutex-inl.h" #include "gc/space/memory_tool_settings.h" @@ -26,15 +33,12 @@ #include "thread-inl.h" #include "thread_list.h" -#include <map> -#include <list> -#include <sstream> -#include <vector> - namespace art { namespace gc { namespace allocator { +using android::base::StringPrintf; + static constexpr bool kUsePrefetchDuringAllocRun = false; static constexpr bool kPrefetchNewRunDataByZeroing = false; static constexpr size_t kPrefetchStride = 64; diff --git a/runtime/gc/collector/garbage_collector.cc b/runtime/gc/collector/garbage_collector.cc index ed16854d66..01bcb7df19 100644 --- a/runtime/gc/collector/garbage_collector.cc +++ b/runtime/gc/collector/garbage_collector.cc @@ -18,6 +18,8 @@ #include "garbage_collector.h" +#include "android-base/stringprintf.h" + #include "base/dumpable.h" #include "base/histogram-inl.h" #include "base/logging.h" @@ -81,7 +83,7 @@ void GarbageCollector::ResetCumulativeStatistics() { } void GarbageCollector::Run(GcCause gc_cause, bool clear_soft_references) { - ScopedTrace trace(StringPrintf("%s %s GC", PrettyCause(gc_cause), GetName())); + ScopedTrace trace(android::base::StringPrintf("%s %s GC", PrettyCause(gc_cause), GetName())); Thread* self = Thread::Current(); uint64_t start_time = NanoTime(); Iteration* current_iteration = GetCurrentIteration(); diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index 3ed138c00e..34d82845dc 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -21,6 +21,8 @@ #include <unwind.h> // For GC verification. #include <vector> +#include "android-base/stringprintf.h" + #include "allocation_listener.h" #include "art_field-inl.h" #include "base/allocator.h" @@ -82,6 +84,8 @@ namespace art { namespace gc { +using android::base::StringPrintf; + static constexpr size_t kCollectorTransitionStressIterations = 0; static constexpr size_t kCollectorTransitionStressWait = 10 * 1000; // Microseconds // Minimum amount of remaining bytes before a concurrent GC is triggered. @@ -3919,7 +3923,7 @@ void Heap::RegisterNativeFree(JNIEnv* env, size_t bytes) { ScopedObjectAccess soa(env); env->ThrowNew(WellKnownClasses::java_lang_RuntimeException, StringPrintf("Attempted to free %zd native bytes with only %zd native bytes " - "registered as allocated", bytes, expected_size).c_str()); + "registered as allocated", bytes, expected_size).c_str()); break; } } while (!native_bytes_allocated_.CompareExchangeWeakRelaxed(expected_size, diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index 76f3692f41..e03958d717 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -22,6 +22,7 @@ #include <sys/types.h> #include <unistd.h> +#include "android-base/stringprintf.h" #include "android-base/strings.h" #include "art_method.h" @@ -45,6 +46,9 @@ namespace art { namespace gc { namespace space { +using android::base::StringAppendF; +using android::base::StringPrintf; + Atomic<uint32_t> ImageSpace::bitmap_index_(0); ImageSpace::ImageSpace(const std::string& image_filename, diff --git a/runtime/gc/space/image_space_fs.h b/runtime/gc/space/image_space_fs.h index fa941c0376..5999548d2b 100644 --- a/runtime/gc/space/image_space_fs.h +++ b/runtime/gc/space/image_space_fs.h @@ -20,9 +20,10 @@ #include <dirent.h> #include <dlfcn.h> +#include "android-base/stringprintf.h" + #include "base/logging.h" #include "base/macros.h" -#include "base/stringprintf.h" #include "base/unix_file/fd_file.h" #include "globals.h" #include "os.h" @@ -56,7 +57,7 @@ static void DeleteDirectoryContents(const std::string& dir, bool recurse) { continue; } // We only want to delete regular files and symbolic links. - std::string file = StringPrintf("%s/%s", dir.c_str(), name); + std::string file = android::base::StringPrintf("%s/%s", dir.c_str(), name); if (de->d_type != DT_REG && de->d_type != DT_LNK) { if (de->d_type == DT_DIR) { if (recurse) { diff --git a/runtime/gc/space/malloc_space.cc b/runtime/gc/space/malloc_space.cc index b1572cc7ea..a186f4c922 100644 --- a/runtime/gc/space/malloc_space.cc +++ b/runtime/gc/space/malloc_space.cc @@ -16,6 +16,8 @@ #include "malloc_space.h" +#include "android-base/stringprintf.h" + #include "gc/accounting/card_table-inl.h" #include "gc/accounting/space_bitmap-inl.h" #include "gc/heap.h" @@ -33,6 +35,8 @@ namespace art { namespace gc { namespace space { +using android::base::StringPrintf; + size_t MallocSpace::bitmap_index_ = 0; MallocSpace::MallocSpace(const std::string& name, MemMap* mem_map, diff --git a/runtime/generated/asm_support_gen.h b/runtime/generated/asm_support_gen.h index f13ff8c9bc..bebcd71951 100644 --- a/runtime/generated/asm_support_gen.h +++ b/runtime/generated/asm_support_gen.h @@ -74,8 +74,6 @@ DEFINE_CHECK_EQ(static_cast<int32_t>(ART_METHOD_QUICK_CODE_OFFSET_32), (static_c DEFINE_CHECK_EQ(static_cast<int32_t>(ART_METHOD_QUICK_CODE_OFFSET_64), (static_cast<int32_t>(art::ArtMethod:: EntryPointFromQuickCompiledCodeOffset(art::PointerSize::k64).Int32Value()))) #define ART_METHOD_DECLARING_CLASS_OFFSET 0 DEFINE_CHECK_EQ(static_cast<int32_t>(ART_METHOD_DECLARING_CLASS_OFFSET), (static_cast<int32_t>(art::ArtMethod:: DeclaringClassOffset().Int32Value()))) -#define DECLARING_CLASS_DEX_CACHE_STRINGS_OFFSET 40 -DEFINE_CHECK_EQ(static_cast<int32_t>(DECLARING_CLASS_DEX_CACHE_STRINGS_OFFSET), (static_cast<int32_t>(art::mirror::Class:: DexCacheStringsOffset().Int32Value()))) #define STRING_DEX_CACHE_ELEMENT_SIZE_SHIFT 3 DEFINE_CHECK_EQ(static_cast<int32_t>(STRING_DEX_CACHE_ELEMENT_SIZE_SHIFT), (static_cast<int32_t>(art::WhichPowerOf2(sizeof(art::mirror::StringDexCachePair))))) #define STRING_DEX_CACHE_SIZE_MINUS_ONE 1023 diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc index 8cbe49166a..fe6a6e9140 100644 --- a/runtime/hprof/hprof.cc +++ b/runtime/hprof/hprof.cc @@ -37,9 +37,10 @@ #include <set> +#include "android-base/stringprintf.h" + #include "art_field-inl.h" #include "base/logging.h" -#include "base/stringprintf.h" #include "base/time_utils.h" #include "base/unix_file/fd_file.h" #include "class_linker.h" @@ -797,8 +798,9 @@ class Hprof : public SingleRootVisitor { file->Erase(); } if (!okay) { - std::string msg(StringPrintf("Couldn't dump heap; writing \"%s\" failed: %s", - filename_.c_str(), strerror(errno))); + std::string msg(android::base::StringPrintf("Couldn't dump heap; writing \"%s\" failed: %s", + filename_.c_str(), + strerror(errno))); ThrowRuntimeException("%s", msg.c_str()); LOG(ERROR) << msg; } diff --git a/runtime/image.cc b/runtime/image.cc index 52c9f4edf0..2ef60c3e07 100644 --- a/runtime/image.cc +++ b/runtime/image.cc @@ -25,7 +25,7 @@ namespace art { const uint8_t ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' }; -const uint8_t ImageHeader::kImageVersion[] = { '0', '3', '3', '\0' }; +const uint8_t ImageHeader::kImageVersion[] = { '0', '3', '4', '\0' }; // mirror::Class update ImageHeader::ImageHeader(uint32_t image_begin, uint32_t image_size, diff --git a/runtime/image.h b/runtime/image.h index da9976a901..6c76f4915e 100644 --- a/runtime/image.h +++ b/runtime/image.h @@ -189,6 +189,7 @@ class PACKED(4) ImageHeader { enum ImageRoot { kDexCaches, kClassRoots, + kClassLoader, // App image only. kImageRootsMax, }; @@ -206,6 +207,10 @@ class PACKED(4) ImageHeader { kSectionCount, // Number of elements in enum. }; + static size_t NumberOfImageRoots(bool app_image) { + return app_image ? kImageRootsMax : kImageRootsMax - 1u; + } + ArtMethod* GetImageMethod(ImageMethod index) const; void SetImageMethod(ImageMethod index, ArtMethod* method); diff --git a/runtime/indirect_reference_table-inl.h b/runtime/indirect_reference_table-inl.h index 9c634fa861..0e66ae96b5 100644 --- a/runtime/indirect_reference_table-inl.h +++ b/runtime/indirect_reference_table-inl.h @@ -19,6 +19,8 @@ #include "indirect_reference_table.h" +#include "android-base/stringprintf.h" + #include "base/dumpable.h" #include "gc_root-inl.h" #include "obj_ptr-inl.h" @@ -38,15 +40,15 @@ inline bool IndirectReferenceTable::GetChecked(IndirectRef iref) const { return false; } if (UNLIKELY(GetIndirectRefKind(iref) == kHandleScopeOrInvalid)) { - AbortIfNoCheckJNI(StringPrintf("JNI ERROR (app bug): invalid %s %p", - GetIndirectRefKindString(kind_), - iref)); + AbortIfNoCheckJNI(android::base::StringPrintf("JNI ERROR (app bug): invalid %s %p", + GetIndirectRefKindString(kind_), + iref)); return false; } const uint32_t top_index = segment_state_.top_index; uint32_t idx = ExtractIndex(iref); if (UNLIKELY(idx >= top_index)) { - std::string msg = StringPrintf( + std::string msg = android::base::StringPrintf( "JNI ERROR (app bug): accessed stale %s %p (index %d in a table of size %d)", GetIndirectRefKindString(kind_), iref, @@ -56,9 +58,9 @@ inline bool IndirectReferenceTable::GetChecked(IndirectRef iref) const { return false; } if (UNLIKELY(table_[idx].GetReference()->IsNull())) { - AbortIfNoCheckJNI(StringPrintf("JNI ERROR (app bug): accessed deleted %s %p", - GetIndirectRefKindString(kind_), - iref)); + AbortIfNoCheckJNI(android::base::StringPrintf("JNI ERROR (app bug): accessed deleted %s %p", + GetIndirectRefKindString(kind_), + iref)); return false; } if (UNLIKELY(!CheckEntry("use", iref, idx))) { @@ -73,7 +75,7 @@ inline bool IndirectReferenceTable::CheckEntry(const char* what, uint32_t idx) const { IndirectRef checkRef = ToIndirectRef(idx); if (UNLIKELY(checkRef != iref)) { - std::string msg = StringPrintf( + std::string msg = android::base::StringPrintf( "JNI ERROR (app bug): attempt to %s stale %s %p (should be %p)", what, GetIndirectRefKindString(kind_), diff --git a/runtime/indirect_reference_table_test.cc b/runtime/indirect_reference_table_test.cc index 722b411f97..bf4cab24cc 100644 --- a/runtime/indirect_reference_table_test.cc +++ b/runtime/indirect_reference_table_test.cc @@ -16,6 +16,8 @@ #include "indirect_reference_table-inl.h" +#include "android-base/stringprintf.h" + #include "class_linker-inl.h" #include "common_runtime_test.h" #include "mirror/object-inl.h" @@ -23,6 +25,8 @@ namespace art { +using android::base::StringPrintf; + class IndirectReferenceTableTest : public CommonRuntimeTest {}; static void CheckDump(IndirectReferenceTable* irt, size_t num_objects, size_t num_unique) diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc index 870d1ae9b5..03ef962f05 100644 --- a/runtime/instrumentation.cc +++ b/runtime/instrumentation.cc @@ -1098,10 +1098,14 @@ TwoWordReturn Instrumentation::PopInstrumentationStackFrame(Thread* self, uintpt Dbg::IsForcedInterpreterNeededForUpcall(self, visitor.caller)); if (deoptimize && Runtime::Current()->IsDeoptimizeable(*return_pc)) { if (kVerboseInstrumentation) { - LOG(INFO) << StringPrintf("Deoptimizing %s by returning from %s with result %#" PRIx64 " in ", - visitor.caller->PrettyMethod().c_str(), - method->PrettyMethod().c_str(), - return_value.GetJ()) << *self; + LOG(INFO) << "Deoptimizing " + << visitor.caller->PrettyMethod() + << " by returning from " + << method->PrettyMethod() + << " with result " + << std::hex << return_value.GetJ() << std::dec + << " in " + << *self; } self->PushDeoptimizationContext(return_value, return_shorty == 'L', diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index 22da07dd24..a09e71b6c0 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -676,7 +676,7 @@ void AbortTransactionV(Thread* self, const char* fmt, va_list args) { CHECK(Runtime::Current()->IsActiveTransaction()); // Constructs abort message. std::string abort_msg; - StringAppendV(&abort_msg, fmt, args); + android::base::StringAppendV(&abort_msg, fmt, args); // Throws an exception so we can abort the transaction and rollback every change. Runtime::Current()->AbortTransactionAndThrowAbortError(self, abort_msg); } diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h index c9a5b44c54..423f0543d5 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -25,6 +25,8 @@ #include <sstream> #include <atomic> +#include "android-base/stringprintf.h" + #include "art_field-inl.h" #include "art_method-inl.h" #include "base/enums.h" @@ -254,7 +256,7 @@ static inline ObjPtr<mirror::String> ResolveString(Thread* self, DCHECK_LT(string_idx.index_ % mirror::DexCache::kDexCacheStringCacheSize, declaring_class->GetDexFile().NumStringIds()); ObjPtr<mirror::String> string_ptr = - mirror::StringDexCachePair::Lookup(declaring_class->GetDexCacheStrings(), + mirror::StringDexCachePair::Lookup(declaring_class->GetDexCache()->GetStrings(), string_idx.index_, mirror::DexCache::kDexCacheStringCacheSize).Read(); if (UNLIKELY(string_ptr == nullptr)) { @@ -430,12 +432,12 @@ static inline void TraceExecution(const ShadowFrame& shadow_frame, const Instruc #define TRACE_LOG std::cerr std::ostringstream oss; oss << shadow_frame.GetMethod()->PrettyMethod() - << StringPrintf("\n0x%x: ", dex_pc) + << android::base::StringPrintf("\n0x%x: ", dex_pc) << inst->DumpString(shadow_frame.GetMethod()->GetDexFile()) << "\n"; for (uint32_t i = 0; i < shadow_frame.NumberOfVRegs(); ++i) { uint32_t raw_value = shadow_frame.GetVReg(i); ObjPtr<mirror::Object> ref_value = shadow_frame.GetVRegReference(i); - oss << StringPrintf(" vreg%u=0x%08X", i, raw_value); + oss << android::base::StringPrintf(" vreg%u=0x%08X", i, raw_value); if (ref_value != nullptr) { if (ref_value->GetClass()->IsStringClass() && !ref_value->AsString()->IsValueNull()) { diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc index a5b1038d5a..7dd3d3db4d 100644 --- a/runtime/interpreter/unstarted_runtime.cc +++ b/runtime/interpreter/unstarted_runtime.cc @@ -25,6 +25,7 @@ #include <locale> #include <unordered_map> +#include "android-base/stringprintf.h" #include "ScopedLocalRef.h" #include "art_method-inl.h" @@ -56,6 +57,9 @@ namespace art { namespace interpreter { +using android::base::StringAppendV; +using android::base::StringPrintf; + static void AbortTransactionOrFail(Thread* self, const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) REQUIRES_SHARED(Locks::mutator_lock_); diff --git a/runtime/java_vm_ext.cc b/runtime/java_vm_ext.cc index caf705a9cb..f80c43d80c 100644 --- a/runtime/java_vm_ext.cc +++ b/runtime/java_vm_ext.cc @@ -18,6 +18,8 @@ #include <dlfcn.h> +#include "android-base/stringprintf.h" + #include "art_method.h" #include "base/dumpable.h" #include "base/mutex.h" @@ -42,6 +44,9 @@ namespace art { +using android::base::StringAppendF; +using android::base::StringAppendV; + static constexpr size_t kGlobalsMax = 51200; // Arbitrary sanity check. (Must fit in 16 bits.) static constexpr size_t kWeakGlobalsMax = 51200; // Arbitrary sanity check. (Must fit in 16 bits.) diff --git a/runtime/jdwp/jdwp_adb.cc b/runtime/jdwp/jdwp_adb.cc index e9d6d079c1..0eff2ab47b 100644 --- a/runtime/jdwp/jdwp_adb.cc +++ b/runtime/jdwp/jdwp_adb.cc @@ -20,8 +20,9 @@ #include <sys/un.h> #include <unistd.h> +#include "android-base/stringprintf.h" + #include "base/logging.h" -#include "base/stringprintf.h" #include "jdwp/jdwp_priv.h" #ifdef ART_TARGET_ANDROID @@ -52,6 +53,8 @@ namespace art { namespace JDWP { +using android::base::StringPrintf; + struct JdwpAdbState : public JdwpNetStateBase { public: explicit JdwpAdbState(JdwpState* state) : JdwpNetStateBase(state) { diff --git a/runtime/jdwp/jdwp_event.cc b/runtime/jdwp/jdwp_event.cc index 5574a117a7..172f52a974 100644 --- a/runtime/jdwp/jdwp_event.cc +++ b/runtime/jdwp/jdwp_event.cc @@ -21,10 +21,11 @@ #include <string.h> #include <unistd.h> +#include "android-base/stringprintf.h" + #include "art_field-inl.h" #include "art_method-inl.h" #include "base/logging.h" -#include "base/stringprintf.h" #include "debugger.h" #include "jdwp/jdwp_constants.h" #include "jdwp/jdwp_expand_buf.h" @@ -103,6 +104,8 @@ namespace art { namespace JDWP { +using android::base::StringPrintf; + /* * Stuff to compare against when deciding if a mod matches. Only the * values for mods valid for the event being evaluated will be filled in. diff --git a/runtime/jdwp/jdwp_handler.cc b/runtime/jdwp/jdwp_handler.cc index 0f2d188bca..964c5679d7 100644 --- a/runtime/jdwp/jdwp_handler.cc +++ b/runtime/jdwp/jdwp_handler.cc @@ -20,11 +20,12 @@ #include <memory> #include <string> +#include "android-base/stringprintf.h" + #include "atomic.h" #include "base/hex_dump.h" #include "base/logging.h" #include "base/macros.h" -#include "base/stringprintf.h" #include "debugger.h" #include "jdwp/jdwp_constants.h" #include "jdwp/jdwp_event.h" @@ -39,6 +40,8 @@ namespace art { namespace JDWP { +using android::base::StringPrintf; + std::string DescribeField(const FieldId& field_id) { return StringPrintf("%#" PRIx64 " (%s)", field_id, Dbg::GetFieldName(field_id).c_str()); } diff --git a/runtime/jdwp/jdwp_main.cc b/runtime/jdwp/jdwp_main.cc index e3bf3e5a9d..7707ba4932 100644 --- a/runtime/jdwp/jdwp_main.cc +++ b/runtime/jdwp/jdwp_main.cc @@ -20,6 +20,8 @@ #include <time.h> #include <unistd.h> +#include "android-base/stringprintf.h" + #include "atomic.h" #include "base/logging.h" #include "base/time_utils.h" @@ -31,6 +33,8 @@ namespace art { namespace JDWP { +using android::base::StringPrintf; + static void* StartJdwpThread(void* arg); /* diff --git a/runtime/jdwp/jdwp_request.cc b/runtime/jdwp/jdwp_request.cc index 18f40a143c..6af267e674 100644 --- a/runtime/jdwp/jdwp_request.cc +++ b/runtime/jdwp/jdwp_request.cc @@ -18,7 +18,8 @@ #include <inttypes.h> -#include "base/stringprintf.h" +#include "android-base/stringprintf.h" + #include "jdwp/jdwp_priv.h" namespace art { @@ -100,7 +101,7 @@ MethodId Request::ReadMethodId() { ObjectId Request::ReadObjectId(const char* specific_kind) { ObjectId id = Read8BE(); - VLOG(jdwp) << StringPrintf(" %s id %#" PRIx64, specific_kind, id); + VLOG(jdwp) << android::base::StringPrintf(" %s id %#" PRIx64, specific_kind, id); return id; } diff --git a/runtime/jdwp/jdwp_socket.cc b/runtime/jdwp/jdwp_socket.cc index 3be7fd6428..97662f0727 100644 --- a/runtime/jdwp/jdwp_socket.cc +++ b/runtime/jdwp/jdwp_socket.cc @@ -26,8 +26,9 @@ #include <sys/types.h> #include <unistd.h> +#include "android-base/stringprintf.h" + #include "base/logging.h" -#include "base/stringprintf.h" #include "jdwp/jdwp_priv.h" namespace art { @@ -500,7 +501,7 @@ bool JdwpSocketState::ProcessIncoming() { */ if (IsAwaitingHandshake()) { if (memcmp(input_buffer_, kMagicHandshake, kMagicHandshakeLen) != 0) { - LOG(ERROR) << StringPrintf("ERROR: bad handshake '%.14s'", input_buffer_); + LOG(ERROR) << android::base::StringPrintf("ERROR: bad handshake '%.14s'", input_buffer_); goto fail; } diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc index 1b0ad8341b..f43e30dd6f 100644 --- a/runtime/jit/jit_code_cache.cc +++ b/runtime/jit/jit_code_cache.cc @@ -217,6 +217,7 @@ uint8_t* JitCodeCache::CommitCode(Thread* self, size_t fp_spill_mask, const uint8_t* code, size_t code_size, + size_t data_size, bool osr, Handle<mirror::ObjectArray<mirror::Object>> roots, bool has_should_deoptimize_flag, @@ -230,6 +231,7 @@ uint8_t* JitCodeCache::CommitCode(Thread* self, fp_spill_mask, code, code_size, + data_size, osr, roots, has_should_deoptimize_flag, @@ -246,6 +248,7 @@ uint8_t* JitCodeCache::CommitCode(Thread* self, fp_spill_mask, code, code_size, + data_size, osr, roots, has_should_deoptimize_flag, @@ -513,6 +516,7 @@ uint8_t* JitCodeCache::CommitCodeInternal(Thread* self, size_t fp_spill_mask, const uint8_t* code, size_t code_size, + size_t data_size, bool osr, Handle<mirror::ObjectArray<mirror::Object>> roots, bool has_should_deoptimize_flag, @@ -547,6 +551,11 @@ uint8_t* JitCodeCache::CommitCodeInternal(Thread* self, core_spill_mask, fp_spill_mask, code_size); + DCHECK_EQ(FromStackMapToRoots(stack_map), roots_data); + DCHECK_LE(roots_data, stack_map); + // Flush data cache, as compiled code references literals in it. + FlushDataCache(reinterpret_cast<char*>(roots_data), + reinterpret_cast<char*>(roots_data + data_size)); // Flush caches before we remove write permission because on some ARMv8 hardware, // flushing caches require write permissions. // @@ -657,12 +666,12 @@ void JitCodeCache::ClearData(Thread* self, FreeData(reinterpret_cast<uint8_t*>(roots_data)); } -void JitCodeCache::ReserveData(Thread* self, - size_t stack_map_size, - size_t number_of_roots, - ArtMethod* method, - uint8_t** stack_map_data, - uint8_t** roots_data) { +size_t JitCodeCache::ReserveData(Thread* self, + size_t stack_map_size, + size_t number_of_roots, + ArtMethod* method, + uint8_t** stack_map_data, + uint8_t** roots_data) { size_t table_size = ComputeRootTableSize(number_of_roots); size_t size = RoundUp(stack_map_size + table_size, sizeof(void*)); uint8_t* result = nullptr; @@ -695,9 +704,11 @@ void JitCodeCache::ReserveData(Thread* self, *roots_data = result; *stack_map_data = result + table_size; FillRootTableLength(*roots_data, number_of_roots); + return size; } else { *roots_data = nullptr; *stack_map_data = nullptr; + return 0; } } diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h index 30e2efbac5..d97742d00b 100644 --- a/runtime/jit/jit_code_cache.h +++ b/runtime/jit/jit_code_cache.h @@ -106,6 +106,7 @@ class JitCodeCache { size_t fp_spill_mask, const uint8_t* code, size_t code_size, + size_t data_size, bool osr, Handle<mirror::ObjectArray<mirror::Object>> roots, bool has_should_deoptimize_flag, @@ -121,12 +122,13 @@ class JitCodeCache { // Allocate a region of data that contain `size` bytes, and potentially space // for storing `number_of_roots` roots. Returns null if there is no more room. - void ReserveData(Thread* self, - size_t size, - size_t number_of_roots, - ArtMethod* method, - uint8_t** stack_map_data, - uint8_t** roots_data) + // Return the number of bytes allocated. + size_t ReserveData(Thread* self, + size_t size, + size_t number_of_roots, + ArtMethod* method, + uint8_t** stack_map_data, + uint8_t** roots_data) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!lock_); @@ -237,6 +239,7 @@ class JitCodeCache { size_t fp_spill_mask, const uint8_t* code, size_t code_size, + size_t data_size, bool osr, Handle<mirror::ObjectArray<mirror::Object>> roots, bool has_should_deoptimize_flag, diff --git a/runtime/jni_env_ext.cc b/runtime/jni_env_ext.cc index 342e0d2a53..5a3fafa726 100644 --- a/runtime/jni_env_ext.cc +++ b/runtime/jni_env_ext.cc @@ -19,6 +19,8 @@ #include <algorithm> #include <vector> +#include "android-base/stringprintf.h" + #include "check_jni.h" #include "indirect_reference_table.h" #include "java_vm_ext.h" @@ -30,6 +32,8 @@ namespace art { +using android::base::StringPrintf; + static constexpr size_t kMonitorsInitial = 32; // Arbitrary. static constexpr size_t kMonitorsMax = 4096; // Arbitrary sanity check. diff --git a/runtime/jni_internal_test.cc b/runtime/jni_internal_test.cc index a421c340ae..4da5e23502 100644 --- a/runtime/jni_internal_test.cc +++ b/runtime/jni_internal_test.cc @@ -16,6 +16,8 @@ #include "jni_internal.h" +#include "android-base/stringprintf.h" + #include "art_method-inl.h" #include "common_compiler_test.h" #include "indirect_reference_table.h" @@ -27,6 +29,8 @@ namespace art { +using android::base::StringPrintf; + // TODO: Convert to CommonRuntimeTest. Currently MakeExecutable is used. class JniInternalTest : public CommonCompilerTest { protected: diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc index 6da72e4625..19a65bb27e 100644 --- a/runtime/mem_map.cc +++ b/runtime/mem_map.cc @@ -24,7 +24,8 @@ #include <memory> #include <sstream> -#include "base/stringprintf.h" +#include "android-base/stringprintf.h" + #include "base/unix_file/fd_file.h" #include "os.h" #include "thread-inl.h" @@ -42,6 +43,8 @@ namespace art { +using android::base::StringPrintf; + static std::ostream& operator<<( std::ostream& os, std::pair<BacktraceMap::const_iterator, BacktraceMap::const_iterator> iters) { diff --git a/runtime/method_handles.cc b/runtime/method_handles.cc index 3c22d7f656..da510ceb5c 100644 --- a/runtime/method_handles.cc +++ b/runtime/method_handles.cc @@ -14,9 +14,10 @@ * limitations under the License. */ -#include "method_handles.h" - #include "method_handles-inl.h" + +#include "android-base/stringprintf.h" + #include "jvalue.h" #include "jvalue-inl.h" #include "reflection.h" @@ -25,6 +26,8 @@ namespace art { +using android::base::StringPrintf; + namespace { #define PRIMITIVES_LIST(V) \ diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h index 7d7c1d7cfd..a5db0c0a8a 100644 --- a/runtime/mirror/array-inl.h +++ b/runtime/mirror/array-inl.h @@ -19,10 +19,11 @@ #include "array.h" +#include "android-base/stringprintf.h" + #include "base/bit_utils.h" #include "base/casts.h" #include "base/logging.h" -#include "base/stringprintf.h" #include "class-inl.h" #include "gc/heap-inl.h" #include "obj_ptr-inl.h" @@ -167,9 +168,9 @@ inline Array* Array::Alloc(Thread* self, #else // 32-bit. if (UNLIKELY(size == 0)) { - self->ThrowOutOfMemoryError(StringPrintf("%s of length %d would overflow", - array_class->PrettyDescriptor().c_str(), - component_count).c_str()); + self->ThrowOutOfMemoryError(android::base::StringPrintf("%s of length %d would overflow", + array_class->PrettyDescriptor().c_str(), + component_count).c_str()); return nullptr; } #endif diff --git a/runtime/mirror/array.cc b/runtime/mirror/array.cc index 8afa4aa744..cc548b9cc8 100644 --- a/runtime/mirror/array.cc +++ b/runtime/mirror/array.cc @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "array.h" +#include "array-inl.h" #include "class.h" #include "class-inl.h" @@ -23,7 +23,6 @@ #include "dex_file-inl.h" #include "gc/accounting/card_table-inl.h" #include "object-inl.h" -#include "object_array.h" #include "object_array-inl.h" #include "handle_scope-inl.h" #include "thread.h" @@ -32,6 +31,8 @@ namespace art { namespace mirror { +using android::base::StringPrintf; + // Create a multi-dimensional array of Objects or primitive types. // // We have to generate the names for X[], X[][], X[][][], and so on. The diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h index 5fdf8f3c3a..2fb8d28de9 100644 --- a/runtime/mirror/class-inl.h +++ b/runtime/mirror/class-inl.h @@ -937,14 +937,6 @@ inline uint32_t Class::NumDirectInterfaces() { } } -inline void Class::SetDexCacheStrings(StringDexCacheType* new_dex_cache_strings) { - SetFieldPtr<false>(DexCacheStringsOffset(), new_dex_cache_strings); -} - -inline StringDexCacheType* Class::GetDexCacheStrings() { - return GetFieldPtr64<StringDexCacheType*>(DexCacheStringsOffset()); -} - template<ReadBarrierOption kReadBarrierOption, class Visitor> void Class::VisitNativeRoots(Visitor& visitor, PointerSize pointer_size) { for (ArtField& field : GetSFieldsUnchecked()) { @@ -1095,12 +1087,6 @@ inline void Class::FixupNativePointers(Class* dest, if (methods != new_methods) { dest->SetMethodsPtrInternal(new_methods); } - // Update dex cache strings. - StringDexCacheType* strings = GetDexCacheStrings(); - StringDexCacheType* new_strings = visitor(strings); - if (strings != new_strings) { - dest->SetDexCacheStrings(new_strings); - } // Fix up embedded tables. if (!IsTemp() && ShouldHaveEmbeddedVTable<kVerifyNone, kReadBarrierOption>()) { for (int32_t i = 0, count = GetEmbeddedVTableLength(); i < count; ++i) { diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc index a862c9798a..9964b73c98 100644 --- a/runtime/mirror/class.cc +++ b/runtime/mirror/class.cc @@ -16,6 +16,8 @@ #include "class.h" +#include "android-base/stringprintf.h" + #include "art_field-inl.h" #include "art_method-inl.h" #include "class_ext.h" @@ -40,6 +42,8 @@ namespace art { namespace mirror { +using android::base::StringPrintf; + GcRoot<Class> Class::java_lang_Class_; void Class::SetClassClass(ObjPtr<Class> java_lang_Class) { @@ -187,7 +191,6 @@ void Class::SetStatus(Handle<Class> h_this, Status new_status, Thread* self) { void Class::SetDexCache(ObjPtr<DexCache> new_dex_cache) { SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), new_dex_cache); - SetDexCacheStrings(new_dex_cache != nullptr ? new_dex_cache->GetStrings() : nullptr); } void Class::SetClassSize(uint32_t new_class_size) { diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h index d7449c8008..fb2792a316 100644 --- a/runtime/mirror/class.h +++ b/runtime/mirror/class.h @@ -1247,13 +1247,6 @@ class MANAGED Class FINAL : public Object { bool GetSlowPathEnabled() REQUIRES_SHARED(Locks::mutator_lock_); void SetSlowPath(bool enabled) REQUIRES_SHARED(Locks::mutator_lock_); - StringDexCacheType* GetDexCacheStrings() REQUIRES_SHARED(Locks::mutator_lock_); - void SetDexCacheStrings(StringDexCacheType* new_dex_cache_strings) - REQUIRES_SHARED(Locks::mutator_lock_); - static MemberOffset DexCacheStringsOffset() { - return OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_strings_); - } - // May cause thread suspension due to EqualParameters. ArtMethod* GetDeclaredConstructor(Thread* self, Handle<ObjectArray<Class>> args, @@ -1438,9 +1431,6 @@ class MANAGED Class FINAL : public Object { // virtual_ methods_ for miranda methods. HeapReference<PointerArray> vtable_; - // Short cuts to dex_cache_ member for fast compiled code access. - uint64_t dex_cache_strings_; - // instance fields // // These describe the layout of the contents of an Object. diff --git a/runtime/mirror/object_array-inl.h b/runtime/mirror/object_array-inl.h index 0fdf1323eb..3e04bf6474 100644 --- a/runtime/mirror/object_array-inl.h +++ b/runtime/mirror/object_array-inl.h @@ -17,12 +17,13 @@ #ifndef ART_RUNTIME_MIRROR_OBJECT_ARRAY_INL_H_ #define ART_RUNTIME_MIRROR_OBJECT_ARRAY_INL_H_ +#include "object_array.h" + #include <string> -#include "object_array.h" +#include "android-base/stringprintf.h" #include "array-inl.h" -#include "base/stringprintf.h" #include "gc/heap.h" #include "mirror/class.h" #include "obj_ptr-inl.h" @@ -330,13 +331,15 @@ inline void ObjectArray<T>::AssignableCheckingMemcpy(int32_t dst_pos, std::string actualSrcType(mirror::Object::PrettyTypeOf(o)); std::string dstType(PrettyTypeOf()); Thread* self = Thread::Current(); + std::string msg = android::base::StringPrintf( + "source[%d] of type %s cannot be stored in destination array of type %s", + src_pos + i, + actualSrcType.c_str(), + dstType.c_str()); if (throw_exception) { - self->ThrowNewExceptionF("Ljava/lang/ArrayStoreException;", - "source[%d] of type %s cannot be stored in destination array of type %s", - src_pos + i, actualSrcType.c_str(), dstType.c_str()); + self->ThrowNewException("Ljava/lang/ArrayStoreException;", msg.c_str()); } else { - LOG(FATAL) << StringPrintf("source[%d] of type %s cannot be stored in destination array of type %s", - src_pos + i, actualSrcType.c_str(), dstType.c_str()); + LOG(FATAL) << msg; } } } diff --git a/runtime/mirror/string-inl.h b/runtime/mirror/string-inl.h index 95516ace9f..9b8445dc9e 100644 --- a/runtime/mirror/string-inl.h +++ b/runtime/mirror/string-inl.h @@ -16,6 +16,10 @@ #ifndef ART_RUNTIME_MIRROR_STRING_INL_H_ #define ART_RUNTIME_MIRROR_STRING_INL_H_ +#include "string.h" + +#include "android-base/stringprintf.h" + #include "array.h" #include "base/bit_utils.h" #include "class.h" @@ -24,7 +28,6 @@ #include "globals.h" #include "intern_table.h" #include "runtime.h" -#include "string.h" #include "thread.h" #include "utf.h" #include "utils.h" @@ -228,9 +231,10 @@ inline String* String::Alloc(Thread* self, int32_t utf16_length_with_flag, "kObjectAlignment must be at least as big as Java char alignment"); const size_t max_length = RoundDown(max_alloc_length, kObjectAlignment / block_size); if (UNLIKELY(length > max_length)) { - self->ThrowOutOfMemoryError(StringPrintf("%s of length %d would overflow", - Class::PrettyDescriptor(string_class).c_str(), - static_cast<int>(length)).c_str()); + self->ThrowOutOfMemoryError( + android::base::StringPrintf("%s of length %d would overflow", + Class::PrettyDescriptor(string_class).c_str(), + static_cast<int>(length)).c_str()); return nullptr; } diff --git a/runtime/mirror/throwable.cc b/runtime/mirror/throwable.cc index ade4e87afd..e50409f2c5 100644 --- a/runtime/mirror/throwable.cc +++ b/runtime/mirror/throwable.cc @@ -16,6 +16,8 @@ #include "throwable.h" +#include "android-base/stringprintf.h" + #include "art_method-inl.h" #include "base/enums.h" #include "class-inl.h" @@ -31,6 +33,8 @@ namespace art { namespace mirror { +using android::base::StringPrintf; + GcRoot<Class> Throwable::java_lang_Throwable_; void Throwable::SetDetailMessage(ObjPtr<String> new_detail_message) { diff --git a/runtime/monitor.cc b/runtime/monitor.cc index e7de7e64c6..222eb5c556 100644 --- a/runtime/monitor.cc +++ b/runtime/monitor.cc @@ -18,6 +18,8 @@ #include <vector> +#include "android-base/stringprintf.h" + #include "art_method-inl.h" #include "base/mutex.h" #include "base/stl_util.h" @@ -38,6 +40,8 @@ namespace art { +using android::base::StringPrintf; + static constexpr uint64_t kLongWaitMs = 100; /* diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc index 1a77072921..cd0e55f261 100644 --- a/runtime/native/dalvik_system_DexFile.cc +++ b/runtime/native/dalvik_system_DexFile.cc @@ -18,9 +18,10 @@ #include <sstream> +#include "android-base/stringprintf.h" + #include "base/logging.h" #include "base/stl_util.h" -#include "base/stringprintf.h" #include "class_linker.h" #include "common_throws.h" #include "compiler_filter.h" @@ -43,6 +44,8 @@ namespace art { +using android::base::StringPrintf; + static bool ConvertJavaArrayToDexFiles( JNIEnv* env, jobject arrayObject, diff --git a/runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc b/runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc index db245aa0d8..981be68199 100644 --- a/runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc +++ b/runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc @@ -16,6 +16,8 @@ #include "dalvik_system_InMemoryDexClassLoader_DexData.h" +#include "android-base/stringprintf.h" + #include "class_linker.h" #include "common_throws.h" #include "dex_file.h" @@ -29,6 +31,8 @@ namespace art { +using android::base::StringPrintf; + static std::unique_ptr<MemMap> AllocateDexMemoryMap(JNIEnv* env, jint start, jint end) { if (end <= start) { ScopedObjectAccess soa(env); diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc index 3058df442c..1af861929e 100644 --- a/runtime/native/dalvik_system_VMRuntime.cc +++ b/runtime/native/dalvik_system_VMRuntime.cc @@ -27,6 +27,8 @@ extern "C" void android_set_application_target_sdk_version(uint32_t version); #include "toStringArray.h" #pragma GCC diagnostic pop +#include "android-base/stringprintf.h" + #include "art_method-inl.h" #include "arch/instruction_set.h" #include "base/enums.h" @@ -54,6 +56,8 @@ extern "C" void android_set_application_target_sdk_version(uint32_t version); namespace art { +using android::base::StringPrintf; + static jfloat VMRuntime_getTargetHeapUtilization(JNIEnv*, jobject) { return Runtime::Current()->GetHeap()->GetTargetHeapUtilization(); } diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc index a78909b879..10fc90bc27 100644 --- a/runtime/native/dalvik_system_ZygoteHooks.cc +++ b/runtime/native/dalvik_system_ZygoteHooks.cc @@ -18,6 +18,8 @@ #include <stdlib.h> +#include "android-base/stringprintf.h" + #include "arch/instruction_set.h" #include "debugger.h" #include "java_vm_ext.h" @@ -37,6 +39,8 @@ namespace art { +using android::base::StringPrintf; + static void EnableDebugger() { #if defined(__linux__) // To let a non-privileged gdbserver attach to this diff --git a/runtime/native/java_lang_ref_Reference.cc b/runtime/native/java_lang_ref_Reference.cc index 3f4573d55b..c778068bc4 100644 --- a/runtime/native/java_lang_ref_Reference.cc +++ b/runtime/native/java_lang_ref_Reference.cc @@ -33,7 +33,7 @@ static jobject Reference_getReferent(JNIEnv* env, jobject javaThis) { return soa.AddLocalReference<jobject>(referent); } -static void Reference_clear(JNIEnv* env, jobject javaThis) { +static void Reference_clearReferent(JNIEnv* env, jobject javaThis) { ScopedFastNativeObjectAccess soa(env); ObjPtr<mirror::Reference> ref = soa.Decode<mirror::Reference>(javaThis); Runtime::Current()->GetHeap()->GetReferenceProcessor()->ClearReferent(ref); @@ -41,7 +41,7 @@ static void Reference_clear(JNIEnv* env, jobject javaThis) { static JNINativeMethod gMethods[] = { NATIVE_METHOD(Reference, getReferent, "!()Ljava/lang/Object;"), - NATIVE_METHOD(Reference, clear, "!()V"), + NATIVE_METHOD(Reference, clearReferent, "!()V"), }; void register_java_lang_ref_Reference(JNIEnv* env) { diff --git a/runtime/native/java_lang_reflect_Executable.cc b/runtime/native/java_lang_reflect_Executable.cc index 73b81a71f8..ee59c4a9e2 100644 --- a/runtime/native/java_lang_reflect_Executable.cc +++ b/runtime/native/java_lang_reflect_Executable.cc @@ -16,6 +16,8 @@ #include "java_lang_reflect_Executable.h" +#include "android-base/stringprintf.h" + #include "art_method-inl.h" #include "dex_file_annotations.h" #include "handle.h" @@ -30,6 +32,8 @@ namespace art { +using android::base::StringPrintf; + static jobjectArray Executable_getDeclaredAnnotationsNative(JNIEnv* env, jobject javaMethod) { ScopedFastNativeObjectAccess soa(env); ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); diff --git a/runtime/native/java_lang_reflect_Field.cc b/runtime/native/java_lang_reflect_Field.cc index 6206948225..374eeb5806 100644 --- a/runtime/native/java_lang_reflect_Field.cc +++ b/runtime/native/java_lang_reflect_Field.cc @@ -16,6 +16,8 @@ #include "java_lang_reflect_Field.h" +#include "android-base/stringprintf.h" + #include "class_linker.h" #include "class_linker-inl.h" #include "common_throws.h" @@ -30,6 +32,8 @@ namespace art { +using android::base::StringPrintf; + template<bool kIsSet> ALWAYS_INLINE inline static bool VerifyFieldAccess(Thread* self, ObjPtr<mirror::Field> field, diff --git a/runtime/native/java_lang_reflect_Parameter.cc b/runtime/native/java_lang_reflect_Parameter.cc index 16164d2f9b..0bb9e382d3 100644 --- a/runtime/native/java_lang_reflect_Parameter.cc +++ b/runtime/native/java_lang_reflect_Parameter.cc @@ -16,6 +16,8 @@ #include "java_lang_reflect_Parameter.h" +#include "android-base/stringprintf.h" + #include "art_method-inl.h" #include "common_throws.h" #include "dex_file-inl.h" @@ -26,6 +28,8 @@ namespace art { +using android::base::StringPrintf; + static jobject Parameter_getAnnotationNative(JNIEnv* env, jclass, jobject javaMethod, diff --git a/runtime/native_stack_dump.cc b/runtime/native_stack_dump.cc index 5565565c7b..7460d622b5 100644 --- a/runtime/native_stack_dump.cc +++ b/runtime/native_stack_dump.cc @@ -37,10 +37,11 @@ #include <sys/time.h> #include <sys/types.h> +#include "android-base/stringprintf.h" + #include "arch/instruction_set.h" #include "base/memory_tool.h" #include "base/mutex.h" -#include "base/stringprintf.h" #include "base/unix_file/fd_file.h" #include "oat_quick_method_header.h" #include "os.h" @@ -53,6 +54,8 @@ namespace art { #if defined(__linux__) +using android::base::StringPrintf; + static constexpr bool kUseAddr2line = !kIsTargetBuild; ALWAYS_INLINE diff --git a/runtime/oat.cc b/runtime/oat.cc index aab0e81047..cebe765369 100644 --- a/runtime/oat.cc +++ b/runtime/oat.cc @@ -19,12 +19,15 @@ #include <string.h> #include <zlib.h> +#include "android-base/stringprintf.h" + #include "arch/instruction_set_features.h" #include "base/bit_utils.h" -#include "base/stringprintf.h" namespace art { +using android::base::StringPrintf; + constexpr uint8_t OatHeader::kOatMagic[4]; constexpr uint8_t OatHeader::kOatVersion[4]; constexpr const char OatHeader::kTrueValue[]; diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc index bdf8b0e65d..0bf713679b 100644 --- a/runtime/oat_file.cc +++ b/runtime/oat_file.cc @@ -32,6 +32,8 @@ #include "android/dlext.h" #endif +#include "android-base/stringprintf.h" + #include "art_method-inl.h" #include "base/bit_vector.h" #include "base/enums.h" @@ -58,6 +60,8 @@ namespace art { +using android::base::StringPrintf; + // Whether OatFile::Open will try dlopen. Fallback is our own ELF loader. static constexpr bool kUseDlopen = true; diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc index 7f7b1b5b06..ee7cf9deef 100644 --- a/runtime/oat_file_assistant.cc +++ b/runtime/oat_file_assistant.cc @@ -23,7 +23,6 @@ #include "android-base/strings.h" #include "base/logging.h" -#include "base/stringprintf.h" #include "compiler_filter.h" #include "class_linker.h" #include "gc/heap.h" diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc index 5641459f41..33bd0f311d 100644 --- a/runtime/oat_file_manager.cc +++ b/runtime/oat_file_manager.cc @@ -20,6 +20,8 @@ #include <queue> #include <vector> +#include "android-base/stringprintf.h" + #include "base/logging.h" #include "base/stl_util.h" #include "base/systrace.h" @@ -38,6 +40,8 @@ namespace art { +using android::base::StringPrintf; + // If true, then we attempt to load the application image if it exists. static constexpr bool kEnableAppImage = true; diff --git a/runtime/openjdkjvmti/OpenjdkJvmTi.cc b/runtime/openjdkjvmti/OpenjdkJvmTi.cc index 1ad3f0814f..5f97b60079 100644 --- a/runtime/openjdkjvmti/OpenjdkJvmTi.cc +++ b/runtime/openjdkjvmti/OpenjdkJvmTi.cc @@ -700,7 +700,7 @@ class JvmtiFunctions { jmethodID method, jint* entry_count_ptr, jvmtiLineNumberEntry** table_ptr) { - return ERR(NOT_IMPLEMENTED); + return MethodUtil::GetLineNumberTable(env, method, entry_count_ptr, table_ptr); } static jvmtiError GetMethodLocation(jvmtiEnv* env, diff --git a/runtime/openjdkjvmti/ti_method.cc b/runtime/openjdkjvmti/ti_method.cc index ffa5ac7e32..a0a09239fa 100644 --- a/runtime/openjdkjvmti/ti_method.cc +++ b/runtime/openjdkjvmti/ti_method.cc @@ -130,4 +130,63 @@ jvmtiError MethodUtil::GetMethodModifiers(jvmtiEnv* env ATTRIBUTE_UNUSED, return ERR(NONE); } +using LineNumberContext = std::vector<jvmtiLineNumberEntry>; + +static bool CollectLineNumbers(void* void_context, const art::DexFile::PositionInfo& entry) { + LineNumberContext* context = reinterpret_cast<LineNumberContext*>(void_context); + jvmtiLineNumberEntry jvmti_entry = { static_cast<jlocation>(entry.address_), + static_cast<jint>(entry.line_) }; + context->push_back(jvmti_entry); + return false; // Collect all, no early exit. +} + +jvmtiError MethodUtil::GetLineNumberTable(jvmtiEnv* env, + jmethodID method, + jint* entry_count_ptr, + jvmtiLineNumberEntry** table_ptr) { + if (method == nullptr) { + return ERR(NULL_POINTER); + } + art::ArtMethod* art_method = art::jni::DecodeArtMethod(method); + DCHECK(!art_method->IsRuntimeMethod()); + + const art::DexFile::CodeItem* code_item; + const art::DexFile* dex_file; + { + art::ScopedObjectAccess soa(art::Thread::Current()); + + if (art_method->IsProxyMethod()) { + return ERR(ABSENT_INFORMATION); + } + if (art_method->IsNative()) { + return ERR(NATIVE_METHOD); + } + if (entry_count_ptr == nullptr || table_ptr == nullptr) { + return ERR(NULL_POINTER); + } + + code_item = art_method->GetCodeItem(); + dex_file = art_method->GetDexFile(); + DCHECK(code_item != nullptr) << art_method->PrettyMethod() << " " << dex_file->GetLocation(); + } + + LineNumberContext context; + bool success = dex_file->DecodeDebugPositionInfo(code_item, CollectLineNumbers, &context); + if (!success) { + return ERR(ABSENT_INFORMATION); + } + + unsigned char* data; + jlong mem_size = context.size() * sizeof(jvmtiLineNumberEntry); + jvmtiError alloc_error = env->Allocate(mem_size, &data); + if (alloc_error != ERR(NONE)) { + return alloc_error; + } + *table_ptr = reinterpret_cast<jvmtiLineNumberEntry*>(data); + memcpy(*table_ptr, context.data(), mem_size); + *entry_count_ptr = static_cast<jint>(context.size()); + + return ERR(NONE); +} + } // namespace openjdkjvmti diff --git a/runtime/openjdkjvmti/ti_method.h b/runtime/openjdkjvmti/ti_method.h index 43f11f97ec..fb2fbb2b27 100644 --- a/runtime/openjdkjvmti/ti_method.h +++ b/runtime/openjdkjvmti/ti_method.h @@ -52,6 +52,11 @@ class MethodUtil { static jvmtiError GetMethodModifiers(jvmtiEnv* env, jmethodID method, jint* modifiers_ptr); + + static jvmtiError GetLineNumberTable(jvmtiEnv* env, + jmethodID method, + jint* entry_count_ptr, + jvmtiLineNumberEntry** table_ptr); }; } // namespace openjdkjvmti diff --git a/runtime/openjdkjvmti/ti_redefine.cc b/runtime/openjdkjvmti/ti_redefine.cc index d0349b987f..e70547dc6a 100644 --- a/runtime/openjdkjvmti/ti_redefine.cc +++ b/runtime/openjdkjvmti/ti_redefine.cc @@ -33,6 +33,8 @@ #include <limits> +#include "android-base/stringprintf.h" + #include "art_jvmti.h" #include "base/logging.h" #include "events-inl.h" @@ -49,13 +51,15 @@ namespace openjdkjvmti { +using android::base::StringPrintf; + // Moves dex data to an anonymous, read-only mmap'd region. std::unique_ptr<art::MemMap> Redefiner::MoveDataToMemMap(const std::string& original_location, jint data_len, unsigned char* dex_data, std::string* error_msg) { std::unique_ptr<art::MemMap> map(art::MemMap::MapAnonymous( - art::StringPrintf("%s-transformed", original_location.c_str()).c_str(), + StringPrintf("%s-transformed", original_location.c_str()).c_str(), nullptr, data_len, PROT_READ|PROT_WRITE, @@ -246,9 +250,9 @@ art::mirror::LongArray* Redefiner::AllocateDexFileCookie( } void Redefiner::RecordFailure(jvmtiError result, const std::string& error_msg) { - *error_msg_ = art::StringPrintf("Unable to perform redefinition of '%s': %s", - class_sig_, - error_msg.c_str()); + *error_msg_ = StringPrintf("Unable to perform redefinition of '%s': %s", + class_sig_, + error_msg.c_str()); result_ = result; } @@ -439,7 +443,6 @@ bool Redefiner::UpdateClass(art::ObjPtr<art::mirror::Class> mclass, // Need to update class last since the ArtMethod gets its DexFile from the class (which is needed // to call GetReturnTypeDescriptor and GetParameterTypeList above). mclass->SetDexCache(new_dex_cache.Ptr()); - mclass->SetDexCacheStrings(new_dex_cache->GetStrings()); mclass->SetDexClassDefIndex(dex_file_->GetIndexForClassDef(*class_def)); mclass->SetDexTypeIndex(dex_file_->GetIndexForTypeId(*dex_file_->FindTypeId(class_sig_))); return true; diff --git a/runtime/parsed_options_test.cc b/runtime/parsed_options_test.cc index 5b90c6adad..8948c710db 100644 --- a/runtime/parsed_options_test.cc +++ b/runtime/parsed_options_test.cc @@ -19,7 +19,6 @@ #include <memory> #include "arch/instruction_set.h" -#include "base/stringprintf.h" #include "common_runtime_test.h" namespace art { diff --git a/runtime/plugin.cc b/runtime/plugin.cc index 481b1caa15..731967c738 100644 --- a/runtime/plugin.cc +++ b/runtime/plugin.cc @@ -17,11 +17,15 @@ #include "plugin.h" #include <dlfcn.h> -#include "base/stringprintf.h" + +#include "android-base/stringprintf.h" + #include "base/logging.h" namespace art { +using android::base::StringPrintf; + const char* PLUGIN_INITIALIZATION_FUNCTION_NAME = "ArtPlugin_Initialize"; const char* PLUGIN_DEINITIALIZATION_FUNCTION_NAME = "ArtPlugin_Deinitialize"; diff --git a/runtime/reference_table.cc b/runtime/reference_table.cc index 1c975a453a..d8b9dcc016 100644 --- a/runtime/reference_table.cc +++ b/runtime/reference_table.cc @@ -16,6 +16,8 @@ #include "reference_table.h" +#include "android-base/stringprintf.h" + #include "base/mutex.h" #include "indirect_reference_table.h" #include "mirror/array.h" @@ -30,6 +32,9 @@ namespace art { +using android::base::StringAppendF; +using android::base::StringPrintf; + ReferenceTable::ReferenceTable(const char* name, size_t initial_size, size_t max_size) : name_(name), max_size_(max_size) { CHECK_LE(initial_size, max_size); diff --git a/runtime/reference_table_test.cc b/runtime/reference_table_test.cc index d80a9b3dd1..9523e92d7c 100644 --- a/runtime/reference_table_test.cc +++ b/runtime/reference_table_test.cc @@ -16,6 +16,8 @@ #include "reference_table.h" +#include "android-base/stringprintf.h" + #include "class_linker.h" #include "common_runtime_test.h" #include "handle_scope-inl.h" @@ -30,6 +32,8 @@ namespace art { +using android::base::StringPrintf; + class ReferenceTableTest : public CommonRuntimeTest {}; static mirror::Object* CreateWeakReference(mirror::Object* referent) diff --git a/runtime/reflection-inl.h b/runtime/reflection-inl.h index 68e7a10e01..62ce9e9509 100644 --- a/runtime/reflection-inl.h +++ b/runtime/reflection-inl.h @@ -19,7 +19,8 @@ #include "reflection.h" -#include "base/stringprintf.h" +#include "android-base/stringprintf.h" + #include "common_throws.h" #include "jvalue-inl.h" #include "mirror/object-inl.h" @@ -103,13 +104,14 @@ inline bool ConvertPrimitiveValue(bool unbox_for_result, } if (!unbox_for_result) { - ThrowIllegalArgumentException(StringPrintf("Invalid primitive conversion from %s to %s", - PrettyDescriptor(srcType).c_str(), - PrettyDescriptor(dstType).c_str()).c_str()); + ThrowIllegalArgumentException( + android::base::StringPrintf("Invalid primitive conversion from %s to %s", + PrettyDescriptor(srcType).c_str(), + PrettyDescriptor(dstType).c_str()).c_str()); } else { - ThrowClassCastException(StringPrintf("Couldn't convert result of type %s to %s", - PrettyDescriptor(srcType).c_str(), - PrettyDescriptor(dstType).c_str()).c_str()); + ThrowClassCastException(android::base::StringPrintf("Couldn't convert result of type %s to %s", + PrettyDescriptor(srcType).c_str(), + PrettyDescriptor(dstType).c_str()).c_str()); } return false; } diff --git a/runtime/reflection.cc b/runtime/reflection.cc index 8446b525ad..4d2450135e 100644 --- a/runtime/reflection.cc +++ b/runtime/reflection.cc @@ -34,6 +34,8 @@ namespace art { +using android::base::StringPrintf; + class ArgArray { public: ArgArray(const char* shorty, uint32_t shorty_len) diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 59c596170d..0977093ed6 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -1721,7 +1721,7 @@ void Runtime::VisitImageRoots(RootVisitor* visitor) { if (space->IsImageSpace()) { auto* image_space = space->AsImageSpace(); const auto& image_header = image_space->GetImageHeader(); - for (size_t i = 0; i < ImageHeader::kImageRootsMax; ++i) { + for (int32_t i = 0, size = image_header.GetImageRoots()->GetLength(); i != size; ++i) { auto* obj = image_header.GetImageRoot(static_cast<ImageHeader::ImageRoot>(i)); if (obj != nullptr) { auto* after_obj = obj; diff --git a/runtime/runtime_android.cc b/runtime/runtime_android.cc index be9786024a..0a996a9e55 100644 --- a/runtime/runtime_android.cc +++ b/runtime/runtime_android.cc @@ -21,7 +21,6 @@ #include "base/logging.h" #include "base/mutex.h" -#include "base/stringprintf.h" #include "thread-inl.h" #include "utils.h" diff --git a/runtime/runtime_linux.cc b/runtime/runtime_linux.cc index 93704a971c..b8894d2569 100644 --- a/runtime/runtime_linux.cc +++ b/runtime/runtime_linux.cc @@ -24,11 +24,12 @@ #include <iostream> #include <sstream> +#include "android-base/stringprintf.h" + #include "base/dumpable.h" #include "base/logging.h" #include "base/macros.h" #include "base/mutex.h" -#include "base/stringprintf.h" #include "native_stack_dump.h" #include "thread-inl.h" #include "thread_list.h" @@ -36,6 +37,8 @@ namespace art { +using android::base::StringPrintf; + static constexpr bool kUseSigRTTimeout = true; static constexpr bool kDumpNativeStackOnTimeout = true; diff --git a/runtime/stack.cc b/runtime/stack.cc index 792da88a63..3fed7c9458 100644 --- a/runtime/stack.cc +++ b/runtime/stack.cc @@ -16,6 +16,8 @@ #include "stack.h" +#include "android-base/stringprintf.h" + #include "arch/context.h" #include "art_method-inl.h" #include "base/enums.h" @@ -39,6 +41,8 @@ namespace art { +using android::base::StringPrintf; + static constexpr bool kDebugStackWalk = false; mirror::Object* ShadowFrame::GetThisObject() const { diff --git a/runtime/thread.cc b/runtime/thread.cc index d79bf36380..9c93a5f962 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -28,6 +28,8 @@ #include <list> #include <sstream> +#include "android-base/stringprintf.h" + #include "arch/context.h" #include "art_field-inl.h" #include "art_method-inl.h" @@ -88,6 +90,9 @@ namespace art { +using android::base::StringAppendV; +using android::base::StringPrintf; + extern "C" NO_RETURN void artDeoptimize(Thread* self); bool Thread::is_started_ = false; diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc index 664eeb4b94..bf9eef8370 100644 --- a/runtime/thread_list.cc +++ b/runtime/thread_list.cc @@ -25,6 +25,8 @@ #include <sstream> +#include "android-base/stringprintf.h" + #include "base/histogram-inl.h" #include "base/mutex-inl.h" #include "base/systrace.h" @@ -52,6 +54,8 @@ namespace art { +using android::base::StringPrintf; + static constexpr uint64_t kLongThreadSuspendThreshold = MsToNs(5); static constexpr uint64_t kThreadSuspendTimeoutMs = 30 * 1000; // 30s. // Use 0 since we want to yield to prevent blocking for an unpredictable amount of time. diff --git a/runtime/thread_pool.cc b/runtime/thread_pool.cc index d9d2ea31a2..6abdca176d 100644 --- a/runtime/thread_pool.cc +++ b/runtime/thread_pool.cc @@ -21,6 +21,8 @@ #include <sys/time.h> #include <sys/resource.h> +#include "android-base/stringprintf.h" + #include "base/bit_utils.h" #include "base/casts.h" #include "base/logging.h" @@ -31,6 +33,8 @@ namespace art { +using android::base::StringPrintf; + static constexpr bool kMeasureWaitTime = false; ThreadPoolWorker::ThreadPoolWorker(ThreadPool* thread_pool, const std::string& name, diff --git a/runtime/ti/agent.cc b/runtime/ti/agent.cc index d21ff77849..0bba44c988 100644 --- a/runtime/ti/agent.cc +++ b/runtime/ti/agent.cc @@ -15,12 +15,17 @@ */ #include "agent.h" + +#include "android-base/stringprintf.h" + #include "java_vm_ext.h" #include "runtime.h" namespace art { namespace ti { +using android::base::StringPrintf; + const char* AGENT_ON_LOAD_FUNCTION_NAME = "Agent_OnLoad"; const char* AGENT_ON_ATTACH_FUNCTION_NAME = "Agent_OnAttach"; const char* AGENT_ON_UNLOAD_FUNCTION_NAME = "Agent_OnUnload"; diff --git a/runtime/ti/agent.h b/runtime/ti/agent.h index 6561756edd..7408aeec35 100644 --- a/runtime/ti/agent.h +++ b/runtime/ti/agent.h @@ -20,7 +20,6 @@ #include <dlfcn.h> #include <jni.h> // for jint, JavaVM* etc declarations -#include "base/stringprintf.h" #include "runtime.h" #include "utils.h" diff --git a/runtime/trace.cc b/runtime/trace.cc index f564de4952..9d9360e9cb 100644 --- a/runtime/trace.cc +++ b/runtime/trace.cc @@ -19,6 +19,8 @@ #include <sys/uio.h> #include <unistd.h> +#include "android-base/stringprintf.h" + #include "art_method-inl.h" #include "base/casts.h" #include "base/enums.h" @@ -46,6 +48,8 @@ namespace art { +using android::base::StringPrintf; + static constexpr size_t TraceActionBits = MinimumBitsToStore( static_cast<size_t>(kTraceMethodActionMask)); static constexpr uint8_t kOpNewMethod = 1U; diff --git a/runtime/utils.cc b/runtime/utils.cc index 4732f59ae1..8867743ec1 100644 --- a/runtime/utils.cc +++ b/runtime/utils.cc @@ -25,6 +25,7 @@ #include <unistd.h> #include <memory> +#include "android-base/stringprintf.h" #include "android-base/strings.h" #include "base/stl_util.h" @@ -48,6 +49,9 @@ namespace art { +using android::base::StringAppendF; +using android::base::StringPrintf; + static const uint8_t kBase64Map[256] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, diff --git a/runtime/utils.h b/runtime/utils.h index 04e0dded27..16ef706159 100644 --- a/runtime/utils.h +++ b/runtime/utils.h @@ -284,6 +284,12 @@ inline void FlushInstructionCache(char* begin, char* end) { __builtin___clear_cache(begin, end); } +inline void FlushDataCache(char* begin, char* end) { + // Same as FlushInstructionCache for lack of other builtin. __builtin___clear_cache + // flushes both caches. + __builtin___clear_cache(begin, end); +} + template <typename T> constexpr PointerSize ConvertToPointerSize(T any) { if (any == 4 || any == 8) { diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index ebecc85a3c..7e23c8b4bc 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -18,6 +18,8 @@ #include <iostream> +#include "android-base/stringprintf.h" + #include "art_field-inl.h" #include "art_method-inl.h" #include "base/enums.h" @@ -55,6 +57,8 @@ namespace art { namespace verifier { +using android::base::StringPrintf; + static constexpr bool kTimeVerifyMethod = !kIsDebugBuild; static constexpr bool kDebugVerify = false; // TODO: Add a constant to method_verifier to turn on verbose logging? diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc index ab23773bc4..52f7e348ce 100644 --- a/runtime/verifier/reg_type.cc +++ b/runtime/verifier/reg_type.cc @@ -16,6 +16,8 @@ #include "reg_type-inl.h" +#include "android-base/stringprintf.h" + #include "base/arena_bit_vector.h" #include "base/bit_vector-inl.h" #include "base/casts.h" @@ -35,6 +37,8 @@ namespace art { namespace verifier { +using android::base::StringPrintf; + const UndefinedType* UndefinedType::instance_ = nullptr; const ConflictType* ConflictType::instance_ = nullptr; const BooleanType* BooleanType::instance_ = nullptr; diff --git a/runtime/verifier/register_line.cc b/runtime/verifier/register_line.cc index a6088aa036..383d890702 100644 --- a/runtime/verifier/register_line.cc +++ b/runtime/verifier/register_line.cc @@ -16,7 +16,8 @@ #include "register_line.h" -#include "base/stringprintf.h" +#include "android-base/stringprintf.h" + #include "dex_instruction-inl.h" #include "method_verifier-inl.h" #include "register_line-inl.h" @@ -25,6 +26,8 @@ namespace art { namespace verifier { +using android::base::StringPrintf; + bool RegisterLine::CheckConstructorReturn(MethodVerifier* verifier) const { if (kIsDebugBuild && this_initialized_) { // Ensure that there is no UninitializedThisReference type anymore if this_initialized_ is true. diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc index 35495867c7..009170cb1c 100644 --- a/runtime/well_known_classes.cc +++ b/runtime/well_known_classes.cc @@ -20,6 +20,8 @@ #include <sstream> +#include "android-base/stringprintf.h" + #include "base/logging.h" #include "entrypoints/quick/quick_entrypoints_enum.h" #include "jni_internal.h" @@ -189,7 +191,7 @@ jmethodID CacheMethod(JNIEnv* env, jclass c, bool is_static, static jmethodID CachePrimitiveBoxingMethod(JNIEnv* env, char prim_name, const char* boxed_name) { ScopedLocalRef<jclass> boxed_class(env, env->FindClass(boxed_name)); return CacheMethod(env, boxed_class.get(), true, "valueOf", - StringPrintf("(%c)L%s;", prim_name, boxed_name).c_str()); + android::base::StringPrintf("(%c)L%s;", prim_name, boxed_name).c_str()); } #define STRING_INIT_LIST(V) \ diff --git a/runtime/zip_archive.cc b/runtime/zip_archive.cc index d96fb429e5..cd79bb61f3 100644 --- a/runtime/zip_archive.cc +++ b/runtime/zip_archive.cc @@ -23,7 +23,6 @@ #include <unistd.h> #include <vector> -#include "base/stringprintf.h" #include "base/unix_file/fd_file.h" namespace art { diff --git a/test/137-cfi/cfi.cc b/test/137-cfi/cfi.cc index 113b35f98d..3b237f40ff 100644 --- a/test/137-cfi/cfi.cc +++ b/test/137-cfi/cfi.cc @@ -25,11 +25,11 @@ #include "jni.h" +#include "android-base/stringprintf.h" #include <backtrace/Backtrace.h> #include "base/logging.h" #include "base/macros.h" -#include "base/stringprintf.h" #include "gc/heap.h" #include "gc/space/image_space.h" #include "oat_file.h" @@ -91,7 +91,7 @@ static bool CheckStack(Backtrace* bt, const std::vector<std::string>& seq) { static void MoreErrorInfo(pid_t pid, bool sig_quit_on_fail) { printf("Secondary pid is %d\n", pid); - PrintFileToLog(StringPrintf("/proc/%d/maps", pid), ::android::base::ERROR); + PrintFileToLog(android::base::StringPrintf("/proc/%d/maps", pid), ::android::base::ERROR); if (sig_quit_on_fail) { int res = kill(pid, SIGQUIT); diff --git a/test/530-checker-loops4/src/Main.java b/test/530-checker-loops4/src/Main.java index 7d3d7d9bfe..91af1f4ee9 100644 --- a/test/530-checker-loops4/src/Main.java +++ b/test/530-checker-loops4/src/Main.java @@ -96,7 +96,29 @@ public class Main { /// CHECK-NOT: Phi public static int geo4(int a) { for (int i = 0; i < 10; i++) { - a %= 7; + a %= 7; // a wrap-around induction + } + return a; + } + + /// CHECK-START: int Main.geo5() loop_optimization (before) + /// CHECK-DAG: Phi loop:<<Loop:B\d+>> + /// CHECK-DAG: Shr loop:<<Loop>> + // + /// CHECK-START: int Main.geo5() loop_optimization (after) + /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 loop:none + /// CHECK-DAG: <<Int1:i\d+>> IntConstant 2147483647 loop:none + /// CHECK-DAG: <<Int2:i\d+>> IntConstant 1024 loop:none + /// CHECK-DAG: <<Div:i\d+>> Div [<<Int1>>,<<Int2>>] loop:none + /// CHECK-DAG: <<Add:i\d+>> Add [<<Div>>,<<Zero>>] loop:none + /// CHECK-DAG: Return [<<Add>>] loop:none + // + /// CHECK-START: int Main.geo5() loop_optimization (after) + /// CHECK-NOT: Phi + public static int geo5() { + int a = 0x7fffffff; + for (int i = 0; i < 10; i++) { + a >>= 1; } return a; } @@ -186,7 +208,7 @@ public class Main { int r = 0; for (int i = 0; i < 100; i++) { // a converges to 0 r += x[a]; - a %= 5; + a %= 5; // a wrap-around induction } return r; } @@ -305,6 +327,8 @@ public class Main { expectEquals(i % 7, geo4(i)); } + expectEquals(0x1fffff, geo5()); + expectEquals(34, geo1BCE()); expectEquals(36, geo2BCE()); expectEquals(131, geo3BCE()); diff --git a/test/618-checker-induction/src/Main.java b/test/618-checker-induction/src/Main.java index 87a69b25c4..ecc129a374 100644 --- a/test/618-checker-induction/src/Main.java +++ b/test/618-checker-induction/src/Main.java @@ -248,6 +248,33 @@ public class Main { return closed; // only needs last value } + /// CHECK-START: int Main.closedFormInductionTrivialIf() loop_optimization (before) + /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none + /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop>> outer_loop:none + /// CHECK-DAG: Select loop:<<Loop>> outer_loop:none + /// CHECK-DAG: Return [<<Phi1>>] loop:none + // + /// CHECK-START: int Main.closedFormInductionTrivialIf() loop_optimization (after) + /// CHECK-NOT: Phi + /// CHECK-NOT: Select + // + /// CHECK-START: int Main.closedFormInductionTrivialIf() instruction_simplifier$after_bce (after) + /// CHECK-DAG: <<Int:i\d+>> IntConstant 81 loop:none + /// CHECK-DAG: Return [<<Int>>] loop:none + static int closedFormInductionTrivialIf() { + int closed = 11; + for (int i = 0; i < 10; i++) { + // Trivial if becomes trivial select at HIR level. + // Make sure this is still recognized as induction. + if (i < 5) { + closed += 7; + } else { + closed += 7; + } + } + return closed; // only needs last value + } + /// CHECK-START: int Main.closedFormNested() loop_optimization (before) /// CHECK-DAG: <<Phi1:i\d+>> Phi loop:<<Loop1:B\d+>> outer_loop:none /// CHECK-DAG: <<Phi2:i\d+>> Phi loop:<<Loop1>> outer_loop:none @@ -732,6 +759,7 @@ public class Main { expectEquals(12395, closedFormInductionUp()); expectEquals(12295, closedFormInductionInAndDown(12345)); + expectEquals(81, closedFormInductionTrivialIf()); expectEquals(10 * 10, closedFormNested()); expectEquals(12345 + 17 * 23 * 7, closedFormNestedAlt()); for (int n = -4; n < 10; n++) { diff --git a/test/624-checker-stringops/src/Main.java b/test/624-checker-stringops/src/Main.java index d965e3ffce..75b782e8c0 100644 --- a/test/624-checker-stringops/src/Main.java +++ b/test/624-checker-stringops/src/Main.java @@ -258,6 +258,20 @@ public class Main { return b.length(); } + // Regression b/33656359: StringBuffer x is passed to constructor of String + // (this caused old code to crash due to missing nullptr check). + // + /// CHECK-START: void Main.doesNothing() instruction_simplifier (before) + /// CHECK-DAG: InvokeVirtual intrinsic:StringBufferToString + // + /// CHECK-START: void Main.doesNothing() instruction_simplifier (after) + /// CHECK-DAG: InvokeVirtual intrinsic:StringBufferToString + static void doesNothing() { + StringBuffer x = new StringBuffer(); + String y = new String(x); + x.toString(); + } + public static void main(String[] args) { expectEquals(1865, liveIndexOf()); expectEquals(29, deadIndexOf()); @@ -281,6 +295,8 @@ public class Main { expectEquals(0, bufferDeadLoop()); expectEquals(0, builderDeadLoop()); + doesNothing(); + System.out.println("passed"); } diff --git a/test/911-get-stack-trace/expected.txt b/test/911-get-stack-trace/expected.txt index 77c77ca21e..f8c97ce475 100644 --- a/test/911-get-stack-trace/expected.txt +++ b/test/911-get-stack-trace/expected.txt @@ -3,206 +3,206 @@ ################### From top --------- - getStackTrace (Ljava/lang/Thread;II)[[Ljava/lang/String; -1 - print (Ljava/lang/Thread;II)V 0 - printOrWait (IILMain$ControlData;)V 6 - baz (IIILMain$ControlData;)Ljava/lang/Object; 2 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - doTest ()V 38 - main ([Ljava/lang/String;)V 6 ---------- - print (Ljava/lang/Thread;II)V 0 - printOrWait (IILMain$ControlData;)V 6 - baz (IIILMain$ControlData;)Ljava/lang/Object; 2 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - doTest ()V 42 - main ([Ljava/lang/String;)V 6 ---------- - getStackTrace (Ljava/lang/Thread;II)[[Ljava/lang/String; -1 - print (Ljava/lang/Thread;II)V 0 - printOrWait (IILMain$ControlData;)V 6 - baz (IIILMain$ControlData;)Ljava/lang/Object; 2 - bar (IIILMain$ControlData;)J 0 ---------- - printOrWait (IILMain$ControlData;)V 6 - baz (IIILMain$ControlData;)Ljava/lang/Object; 2 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 + getStackTrace (Ljava/lang/Thread;II)[[Ljava/lang/String; -1 -2 + print (Ljava/lang/Thread;II)V 0 124 + printOrWait (IILMain$ControlData;)V 6 151 + baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + doTest ()V 38 34 + main ([Ljava/lang/String;)V 6 24 +--------- + print (Ljava/lang/Thread;II)V 0 124 + printOrWait (IILMain$ControlData;)V 6 151 + baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + doTest ()V 42 35 + main ([Ljava/lang/String;)V 6 24 +--------- + getStackTrace (Ljava/lang/Thread;II)[[Ljava/lang/String; -1 -2 + print (Ljava/lang/Thread;II)V 0 124 + printOrWait (IILMain$ControlData;)V 6 151 + baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142 + bar (IIILMain$ControlData;)J 0 136 +--------- + printOrWait (IILMain$ControlData;)V 6 151 + baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 From bottom --------- - main ([Ljava/lang/String;)V 6 + main ([Ljava/lang/String;)V 6 24 --------- - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - doTest ()V 65 - main ([Ljava/lang/String;)V 6 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + doTest ()V 65 41 + main ([Ljava/lang/String;)V 6 24 --------- - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 ################################ ### Other thread (suspended) ### ################################ From top --------- - wait ()V -1 - printOrWait (IILMain$ControlData;)V 24 - baz (IIILMain$ControlData;)Ljava/lang/Object; 2 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - run ()V 4 ---------- - printOrWait (IILMain$ControlData;)V 24 - baz (IIILMain$ControlData;)Ljava/lang/Object; 2 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - run ()V 4 ---------- - wait ()V -1 - printOrWait (IILMain$ControlData;)V 24 - baz (IIILMain$ControlData;)Ljava/lang/Object; 2 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 ---------- - baz (IIILMain$ControlData;)Ljava/lang/Object; 2 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 + wait ()V -1 -2 + printOrWait (IILMain$ControlData;)V 24 157 + baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + run ()V 4 54 +--------- + printOrWait (IILMain$ControlData;)V 24 157 + baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + run ()V 4 54 +--------- + wait ()V -1 -2 + printOrWait (IILMain$ControlData;)V 24 157 + baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 +--------- + baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 From bottom --------- - run ()V 4 + run ()V 4 54 --------- - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - run ()V 4 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + run ()V 4 54 --------- - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 ########################### ### Other thread (live) ### ########################### From top --------- - printOrWait (IILMain$ControlData;)V 44 - baz (IIILMain$ControlData;)Ljava/lang/Object; 2 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - run ()V 4 ---------- - baz (IIILMain$ControlData;)Ljava/lang/Object; 2 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - run ()V 4 ---------- - printOrWait (IILMain$ControlData;)V 44 - baz (IIILMain$ControlData;)Ljava/lang/Object; 2 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 ---------- - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 + printOrWait (IILMain$ControlData;)V 44 164 + baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + run ()V 4 88 +--------- + baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + run ()V 4 88 +--------- + printOrWait (IILMain$ControlData;)V 44 164 + baz (IIILMain$ControlData;)Ljava/lang/Object; 2 142 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 +--------- + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 From bottom --------- - run ()V 4 + run ()V 4 88 --------- - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - run ()V 4 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + run ()V 4 88 --------- - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 - foo (IIILMain$ControlData;)I 0 - baz (IIILMain$ControlData;)Ljava/lang/Object; 9 - bar (IIILMain$ControlData;)J 0 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 + foo (IIILMain$ControlData;)I 0 131 + baz (IIILMain$ControlData;)Ljava/lang/Object; 9 144 + bar (IIILMain$ControlData;)J 0 136 diff --git a/test/911-get-stack-trace/stack_trace.cc b/test/911-get-stack-trace/stack_trace.cc index b5b5678f54..57f6a927ea 100644 --- a/test/911-get-stack-trace/stack_trace.cc +++ b/test/911-get-stack-trace/stack_trace.cc @@ -20,9 +20,10 @@ #include <memory> #include <stdio.h> +#include "android-base/stringprintf.h" + #include "base/logging.h" #include "base/macros.h" -#include "base/stringprintf.h" #include "jni.h" #include "openjdkjvmti/jvmti.h" #include "ScopedLocalRef.h" @@ -32,6 +33,25 @@ namespace art { namespace Test911GetStackTrace { +using android::base::StringPrintf; + +static jint FindLineNumber(jint line_number_count, + jvmtiLineNumberEntry* line_number_table, + jlocation location) { + if (line_number_table == nullptr) { + return -2; + } + + jint line_number = -1; + for (jint i = 0; i != line_number_count; ++i) { + if (line_number_table[i].start_location > location) { + return line_number; + } + line_number = line_number_table[i].line_number; + } + return line_number; +} + extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getStackTrace( JNIEnv* env, jclass klass ATTRIBUTE_UNUSED, jthread thread, jint start, jint max) { std::unique_ptr<jvmtiFrameInfo[]> frames(new jvmtiFrameInfo[max]); @@ -61,6 +81,26 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getStackTrace( } } + jint line_number_count; + jvmtiLineNumberEntry* line_number_table; + { + jvmtiError line_result = jvmti_env->GetLineNumberTable(frames[method_index].method, + &line_number_count, + &line_number_table); + if (line_result != JVMTI_ERROR_NONE) { + // Accept absent info and native method errors. + if (line_result != JVMTI_ERROR_ABSENT_INFORMATION && + line_result != JVMTI_ERROR_NATIVE_METHOD) { + char* err; + jvmti_env->GetErrorName(line_result, &err); + printf("Failure running GetLineNumberTable: %s\n", err); + return nullptr; + } + line_number_table = nullptr; + line_number_count = 0; + } + } + auto inner_callback = [&](jint component_index) -> jstring { switch (component_index) { case 0: @@ -69,11 +109,17 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getStackTrace( return (sig == nullptr) ? nullptr : env->NewStringUTF(sig); case 2: return env->NewStringUTF(StringPrintf("%" PRId64, frames[method_index].location).c_str()); + case 3: { + jint line_number = FindLineNumber(line_number_count, + line_number_table, + frames[method_index].location); + return env->NewStringUTF(StringPrintf("%d", line_number).c_str()); + } } LOG(FATAL) << "Unreachable"; UNREACHABLE(); }; - jobjectArray inner_array = CreateObjectArray(env, 3, "java/lang/String", inner_callback); + jobjectArray inner_array = CreateObjectArray(env, 4, "java/lang/String", inner_callback); if (name != nullptr) { jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(name)); @@ -84,6 +130,9 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_getStackTrace( if (gen != nullptr) { jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(gen)); } + if (line_number_table != nullptr) { + jvmti_env->Deallocate(reinterpret_cast<unsigned char*>(line_number_table)); + } return inner_array; }; diff --git a/test/913-heaps/expected.txt b/test/913-heaps/expected.txt index e5fa53f207..7522a659f2 100644 --- a/test/913-heaps/expected.txt +++ b/test/913-heaps/expected.txt @@ -5,12 +5,12 @@ root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vre root@root --(thread)--> 3000@0 [size=132, length=-1] 0@0 --(array-element@0)--> 1@1000 [size=16, length=-1] 1001@0 --(superclass)--> 1000@0 [size=123, length=-1] -1002@0 --(interface)--> 2001@0 [size=132, length=-1] +1002@0 --(interface)--> 2001@0 [size=124, length=-1] 1002@0 --(superclass)--> 1001@0 [size=123, length=-1] 1@1000 --(class)--> 1000@0 [size=123, length=-1] 1@1000 --(field@12)--> 3@1001 [size=24, length=-1] 1@1000 --(field@8)--> 2@1000 [size=16, length=-1] -2001@0 --(interface)--> 2000@0 [size=132, length=-1] +2001@0 --(interface)--> 2000@0 [size=124, length=-1] 2@1000 --(class)--> 1000@0 [size=123, length=-1] 3@1001 --(class)--> 1001@0 [size=123, length=-1] 3@1001 --(field@16)--> 4@1000 [size=16, length=-1] @@ -22,12 +22,12 @@ root@root --(thread)--> 3000@0 [size=132, length=-1] 6@1000 --(class)--> 1000@0 [size=123, length=-1] --- 1001@0 --(superclass)--> 1000@0 [size=123, length=-1] -1002@0 --(interface)--> 2001@0 [size=132, length=-1] +1002@0 --(interface)--> 2001@0 [size=124, length=-1] 1002@0 --(superclass)--> 1001@0 [size=123, length=-1] 1@1000 --(class)--> 1000@0 [size=123, length=-1] 1@1000 --(field@12)--> 3@1001 [size=24, length=-1] 1@1000 --(field@8)--> 2@1000 [size=16, length=-1] -2001@0 --(interface)--> 2000@0 [size=132, length=-1] +2001@0 --(interface)--> 2000@0 [size=124, length=-1] 2@1000 --(class)--> 1000@0 [size=123, length=-1] 3@1001 --(class)--> 1001@0 [size=123, length=-1] 3@1001 --(field@16)--> 4@1000 [size=16, length=-1] @@ -46,12 +46,12 @@ root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestRoot root@root --(thread)--> 1@1000 [size=16, length=-1] root@root --(thread)--> 3000@0 [size=132, length=-1] 1001@0 --(superclass)--> 1000@0 [size=123, length=-1] -1002@0 --(interface)--> 2001@0 [size=132, length=-1] +1002@0 --(interface)--> 2001@0 [size=124, length=-1] 1002@0 --(superclass)--> 1001@0 [size=123, length=-1] 1@1000 --(class)--> 1000@0 [size=123, length=-1] 1@1000 --(field@12)--> 3@1001 [size=24, length=-1] 1@1000 --(field@8)--> 2@1000 [size=16, length=-1] -2001@0 --(interface)--> 2000@0 [size=132, length=-1] +2001@0 --(interface)--> 2000@0 [size=124, length=-1] 2@1000 --(class)--> 1000@0 [size=123, length=-1] 3@1001 --(class)--> 1001@0 [size=123, length=-1] 3@1001 --(field@16)--> 4@1000 [size=16, length=-1] @@ -63,12 +63,12 @@ root@root --(thread)--> 3000@0 [size=132, length=-1] 6@1000 --(class)--> 1000@0 [size=123, length=-1] --- 1001@0 --(superclass)--> 1000@0 [size=123, length=-1] -1002@0 --(interface)--> 2001@0 [size=132, length=-1] +1002@0 --(interface)--> 2001@0 [size=124, length=-1] 1002@0 --(superclass)--> 1001@0 [size=123, length=-1] 1@1000 --(class)--> 1000@0 [size=123, length=-1] 1@1000 --(field@12)--> 3@1001 [size=24, length=-1] 1@1000 --(field@8)--> 2@1000 [size=16, length=-1] -2001@0 --(interface)--> 2000@0 [size=132, length=-1] +2001@0 --(interface)--> 2000@0 [size=124, length=-1] 2@1000 --(class)--> 1000@0 [size=123, length=-1] 3@1001 --(class)--> 1001@0 [size=123, length=-1] 3@1001 --(field@16)--> 4@1000 [size=16, length=-1] diff --git a/test/913-heaps/heaps.cc b/test/913-heaps/heaps.cc index 7b00fcdcc1..49ab7dd83e 100644 --- a/test/913-heaps/heaps.cc +++ b/test/913-heaps/heaps.cc @@ -22,9 +22,10 @@ #include <vector> +#include "android-base/stringprintf.h" + #include "base/logging.h" #include "base/macros.h" -#include "base/stringprintf.h" #include "jit/jit.h" #include "jni.h" #include "native_stack_dump.h" @@ -39,6 +40,8 @@ namespace art { namespace Test913Heaps { +using android::base::StringPrintf; + extern "C" JNIEXPORT void JNICALL Java_Main_forceGarbageCollection(JNIEnv* env ATTRIBUTE_UNUSED, jclass klass ATTRIBUTE_UNUSED) { jvmtiError ret = jvmti_env->ForceGarbageCollection(); @@ -180,7 +183,7 @@ extern "C" JNIEXPORT jobjectArray JNICALL Java_Main_followReferences(JNIEnv* env if (*tag_ptr >= 1000) { // This is a class or interface, the size of which will be dependent on the architecture. // Do not print the size, but detect known values and "normalize" for the golden file. - if ((sizeof(void*) == 4 && size == 180) || (sizeof(void*) == 8 && size == 232)) { + if ((sizeof(void*) == 4 && size == 172) || (sizeof(void*) == 8 && size == 224)) { adapted_size = 123; } } diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk index b515130a49..c02999bb07 100644 --- a/test/Android.run-test.mk +++ b/test/Android.run-test.mk @@ -492,6 +492,24 @@ ifneq (,$(filter trace stream,$(TRACE_TYPES))) $(PICTEST_TYPES),$(DEBUGGABLE_TYPES), $(TEST_ART_BROKEN_TRACING_RUN_TESTS),$(ALL_ADDRESS_SIZES)) endif +TEST_ART_BROKEN_TRACING_RUN_TESTS := + +# These tests expect JIT compilation, which is suppressed when tracing. +TEST_ART_BROKEN_JIT_TRACING_RUN_TESTS := \ + 604-hot-static-interface \ + 612-jit-dex-cache \ + 613-inlining-dex-cache \ + 616-cha \ + 626-set-resolved-string \ + +ifneq (,$(filter trace stream,$(TRACE_TYPES))) + ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \ + jit,$(RELOCATE_TYPES),trace stream,$(GC_TYPES),$(JNI_TYPES),$(IMAGE_TYPES), \ + $(PICTEST_TYPES),$(DEBUGGABLE_TYPES), $(TEST_ART_BROKEN_JIT_TRACING_RUN_TESTS),$(ALL_ADDRESS_SIZES)) +endif + +TEST_ART_BROKEN_JIT_TRACING_RUN_TESTS := + # Known broken tests for the interpreter. # CFI unwinding expects managed frames. # 629 requires compilation. diff --git a/test/ErroneousA/ErroneousA.java b/test/ErroneousA/ErroneousA.java new file mode 100644 index 0000000000..49da54452a --- /dev/null +++ b/test/ErroneousA/ErroneousA.java @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2016 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. + */ + +final class FinalSuper {} diff --git a/runtime/base/stringprintf_test.cc b/test/ErroneousB/ErroneousB.java index 0bfde33a3f..6c2902ab7d 100644 --- a/runtime/base/stringprintf_test.cc +++ b/test/ErroneousB/ErroneousB.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2016 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. @@ -14,16 +14,7 @@ * limitations under the License. */ -#include "stringprintf.h" +// Only final in first dex. +class FinalSuper {} -#include "gtest/gtest.h" - -namespace art { - -TEST(StringPrintfTest, HexSizeT) { - size_t size = 0x00107e59; - EXPECT_STREQ("00107e59", StringPrintf("%08zx", size).c_str()); - EXPECT_STREQ("0x00107e59", StringPrintf("0x%08zx", size).c_str()); -} - -} // namespace art +class Erroneous extends FinalSuper {} diff --git a/tools/cpp-define-generator/offset_dexcache.def b/tools/cpp-define-generator/offset_dexcache.def index 4b9d481eb1..abb5e1ecac 100644 --- a/tools/cpp-define-generator/offset_dexcache.def +++ b/tools/cpp-define-generator/offset_dexcache.def @@ -38,7 +38,6 @@ DEFINE_ART_METHOD_OFFSET_SIZED(DEX_CACHE_TYPES, DexCacheResolvedTypes) DEFINE_ART_METHOD_OFFSET_SIZED(JNI, EntryPointFromJni) DEFINE_ART_METHOD_OFFSET_SIZED(QUICK_CODE, EntryPointFromQuickCompiledCode) DEFINE_ART_METHOD_OFFSET(DECLARING_CLASS, DeclaringClass) -DEFINE_DECLARING_CLASS_OFFSET(DEX_CACHE_STRINGS, DexCacheStrings) #undef DEFINE_ART_METHOD_OFFSET #undef DEFINE_ART_METHOD_OFFSET_32 diff --git a/tools/jfuzz/run_jfuzz_test.py b/tools/jfuzz/run_jfuzz_test.py index fd8415d3a9..42745d247a 100755 --- a/tools/jfuzz/run_jfuzz_test.py +++ b/tools/jfuzz/run_jfuzz_test.py @@ -414,14 +414,16 @@ class JFuzzTester(object): retc2: int, normalized return code of second runner """ if retc1 == retc2: - # Non-divergent in return code. + # No divergence in return code. if retc1 == RetCode.SUCCESS: # Both compilations and runs were successful, inspect generated output. runner1_out = self._runner1.output_file runner2_out = self._runner2.output_file if not filecmp.cmp(runner1_out, runner2_out, shallow=False): + # Divergence in output. self.ReportDivergence(retc1, retc2, is_output_divergence=True) else: + # No divergence in output. self._num_success += 1 elif retc1 == RetCode.TIMEOUT: self._num_timed_out += 1 @@ -429,8 +431,12 @@ class JFuzzTester(object): self._num_not_compiled += 1 else: self._num_not_run += 1 + elif self._true_divergence_only and RetCode.TIMEOUT in (retc1, retc2): + # When only true divergences are requested, any divergence in return + # code where one is a time out is treated as a regular time out. + self._num_timed_out += 1 else: - # Divergent in return code. + # Divergence in return code. self.ReportDivergence(retc1, retc2, is_output_divergence=False) def GetCurrentDivergenceDir(self): @@ -450,13 +456,12 @@ class JFuzzTester(object): os.mkdir(ddir) for f in glob('*.txt') + ['Test.java']: shutil.copy(f, ddir) - if not (self._true_divergence_only and RetCode.TIMEOUT in (retc1, retc2)): - # Maybe run bisection bug search. - if retc1 in BISECTABLE_RET_CODES and retc2 in BISECTABLE_RET_CODES: - self.MaybeBisectDivergence(retc1, retc2, is_output_divergence) - # Call reporting script. - if self._report_script: - self.RunReportScript(retc1, retc2, is_output_divergence) + # Maybe run bisection bug search. + if retc1 in BISECTABLE_RET_CODES and retc2 in BISECTABLE_RET_CODES: + self.MaybeBisectDivergence(retc1, retc2, is_output_divergence) + # Call reporting script. + if self._report_script: + self.RunReportScript(retc1, retc2, is_output_divergence) def RunReportScript(self, retc1, retc2, is_output_divergence): """Runs report script.""" |