diff options
132 files changed, 1584 insertions, 1230 deletions
diff --git a/adbconnection/adbconnection.cc b/adbconnection/adbconnection.cc index c716d92a9d..205013335b 100644 --- a/adbconnection/adbconnection.cc +++ b/adbconnection/adbconnection.cc @@ -251,6 +251,8 @@ void AdbConnectionState::StartDebuggerThreads() { runtime->StartThreadBirth(); } ScopedLocalRef<jobject> thr(soa.Env(), CreateAdbConnectionThread(soa.Self())); + // Note: Using pthreads instead of std::thread to not abort when the thread cannot be + // created (exception support required). pthread_t pthread; std::unique_ptr<CallbackData> data(new CallbackData { this, soa.Env()->NewGlobalRef(thr.get()) }); started_debugger_threads_ = true; @@ -268,7 +270,7 @@ void AdbConnectionState::StartDebuggerThreads() { runtime->EndThreadBirth(); return; } - data.release(); + data.release(); // NOLINT pthreads API. } static bool FlagsSet(int16_t data, int16_t flags) { diff --git a/build/Android.bp b/build/Android.bp index 9797268680..47a540d521 100644 --- a/build/Android.bp +++ b/build/Android.bp @@ -21,6 +21,7 @@ art_clang_tidy_errors = [ "bugprone-argument-comment", "bugprone-lambda-function-name", "bugprone-unused-raii", // Protect scoped things like MutexLock. + "bugprone-unused-return-value", "bugprone-virtual-near-miss", "modernize-use-bool-literals", "modernize-use-nullptr", @@ -37,6 +38,7 @@ art_clang_tidy_errors = [ art_clang_tidy_errors_str = "bugprone-argument-comment" + ",bugprone-lambda-function-name" + ",bugprone-unused-raii" + + ",bugprone-unused-return-value" + ",bugprone-virtual-near-miss" + ",modernize-redundant-void-arg" + ",modernize-use-bool-literals" diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk index 4badc5a907..e2a0a391ab 100644 --- a/build/Android.gtest.mk +++ b/build/Android.gtest.mk @@ -61,6 +61,7 @@ GTEST_DEX_DIRECTORIES := \ StaticLeafMethods \ Statics \ StaticsFromCode \ + StringLiterals \ Transaction \ XandY @@ -174,7 +175,7 @@ ART_GTEST_compiler_driver_test_DEX_DEPS := AbstractMethod StaticLeafMethods Prof ART_GTEST_dex_cache_test_DEX_DEPS := Main Packages MethodTypes ART_GTEST_dexanalyze_test_DEX_DEPS := MultiDex ART_GTEST_dexlayout_test_DEX_DEPS := ManyMethods -ART_GTEST_dex2oat_test_DEX_DEPS := $(ART_GTEST_dex2oat_environment_tests_DEX_DEPS) ManyMethods Statics VerifierDeps MainUncompressed EmptyUncompressed +ART_GTEST_dex2oat_test_DEX_DEPS := $(ART_GTEST_dex2oat_environment_tests_DEX_DEPS) ManyMethods Statics VerifierDeps MainUncompressed EmptyUncompressed StringLiterals ART_GTEST_dex2oat_image_test_DEX_DEPS := $(ART_GTEST_dex2oat_environment_tests_DEX_DEPS) Statics VerifierDeps ART_GTEST_exception_test_DEX_DEPS := ExceptionHandle ART_GTEST_hiddenapi_test_DEX_DEPS := HiddenApi diff --git a/compiler/dex/verification_results.cc b/compiler/dex/verification_results.cc index 1e0b94de81..dd947d90b7 100644 --- a/compiler/dex/verification_results.cc +++ b/compiler/dex/verification_results.cc @@ -79,7 +79,7 @@ void VerificationResults::ProcessVerifiedMethod(verifier::MethodVerifier* method if (inserted) { // Successfully added, release the unique_ptr since we no longer have ownership. DCHECK_EQ(GetVerifiedMethod(ref), verified_method.get()); - verified_method.release(); + verified_method.release(); // NOLINT b/117926937 } else { // TODO: Investigate why are we doing the work again for this method and try to avoid it. LOG(WARNING) << "Method processed more than once: " << ref.PrettyMethod(); @@ -117,7 +117,7 @@ void VerificationResults::CreateVerifiedMethodFor(MethodReference ref) { /*expected*/ nullptr, verified_method.get()) == AtomicMap::InsertResult::kInsertResultSuccess) { - verified_method.release(); + verified_method.release(); // NOLINT b/117926937 } } diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index a32de2923e..864b215a90 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -708,25 +708,42 @@ void CompilerDriver::Resolve(jobject class_loader, } } -static void ResolveConstStrings(CompilerDriver* driver, - const std::vector<const DexFile*>& dex_files, - TimingLogger* timings) { +void CompilerDriver::ResolveConstStrings(const std::vector<const DexFile*>& dex_files, + bool only_startup_strings, + TimingLogger* timings) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<1> hs(soa.Self()); ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); MutableHandle<mirror::DexCache> dex_cache(hs.NewHandle<mirror::DexCache>(nullptr)); + size_t num_instructions = 0u; for (const DexFile* dex_file : dex_files) { dex_cache.Assign(class_linker->FindDexCache(soa.Self(), *dex_file)); TimingLogger::ScopedTiming t("Resolve const-string Strings", timings); for (ClassAccessor accessor : dex_file->GetClasses()) { - if (!driver->IsClassToCompile(accessor.GetDescriptor())) { + if (!IsClassToCompile(accessor.GetDescriptor())) { // Compilation is skipped, do not resolve const-string in code of this class. // FIXME: Make sure that inlining honors this. b/26687569 continue; } + + const bool is_startup_class = + profile_compilation_info_ != nullptr && + profile_compilation_info_->ContainsClass(*dex_file, accessor.GetClassIdx()); + for (const ClassAccessor::Method& method : accessor.GetMethods()) { + const bool is_clinit = (method.GetAccessFlags() & kAccConstructor) != 0 && + (method.GetAccessFlags() & kAccStatic) != 0; + const bool is_startup_clinit = is_startup_class && is_clinit; + + if (only_startup_strings && + profile_compilation_info_ != nullptr && + (!profile_compilation_info_->GetMethodHotness(method.GetReference()).IsStartup() && + !is_startup_clinit)) { + continue; + } + // Resolve const-strings in the code. Done to have deterministic allocation behavior. Right // now this is single-threaded for simplicity. // TODO: Collect the relevant string indices in parallel, then allocate them sequentially @@ -740,6 +757,7 @@ static void ResolveConstStrings(CompilerDriver* driver, : inst->VRegB_31c()); ObjPtr<mirror::String> string = class_linker->ResolveString(string_index, dex_cache); CHECK(string != nullptr) << "Could not allocate a string when forcing determinism"; + ++num_instructions; break; } @@ -750,6 +768,7 @@ static void ResolveConstStrings(CompilerDriver* driver, } } } + VLOG(compiler) << "Resolved " << num_instructions << " const string instructions"; } // Initialize type check bit strings for check-cast and instance-of in the code. Done to have @@ -897,8 +916,10 @@ void CompilerDriver::PreCompile(jobject class_loader, if (GetCompilerOptions().IsForceDeterminism() && GetCompilerOptions().IsBootImage()) { // Resolve strings from const-string. Do this now to have a deterministic image. - ResolveConstStrings(this, dex_files, timings); + ResolveConstStrings(dex_files, /*only_startup_strings=*/ false, timings); VLOG(compiler) << "Resolve const-strings: " << GetMemoryUsageString(false); + } else if (GetCompilerOptions().ResolveStartupConstStrings()) { + ResolveConstStrings(dex_files, /*only_startup_strings=*/ true, timings); } Verify(class_loader, dex_files, timings); diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index 343f67c6d5..9a83e55c96 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -430,6 +430,12 @@ class CompilerDriver { typedef AtomicDexRefMap<MethodReference, CompiledMethod*> MethodTable; private: + // Resolve const string literals that are loaded from dex code. If only_startup_strings is + // specified, only methods that are marked startup in the profile are resolved. + void ResolveConstStrings(const std::vector<const DexFile*>& dex_files, + bool only_startup_strings, + /*inout*/ TimingLogger* timings); + // All method references that this compiler has compiled. MethodTable compiled_methods_; diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc index 3ab9afc5d6..6b0e45629b 100644 --- a/compiler/driver/compiler_options.cc +++ b/compiler/driver/compiler_options.cc @@ -69,6 +69,7 @@ CompilerOptions::CompilerOptions() force_determinism_(false), deduplicate_code_(true), count_hotness_in_compiled_code_(false), + resolve_startup_const_strings_(false), register_allocation_strategy_(RegisterAllocator::kRegisterAllocatorDefault), passes_to_run_(nullptr) { } diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h index e9cbf74428..4a6bbfaae6 100644 --- a/compiler/driver/compiler_options.h +++ b/compiler/driver/compiler_options.h @@ -313,6 +313,10 @@ class CompilerOptions final { return count_hotness_in_compiled_code_; } + bool ResolveStartupConstStrings() const { + return resolve_startup_const_strings_; + } + private: bool ParseDumpInitFailures(const std::string& option, std::string* error_msg); void ParseDumpCfgPasses(const StringPiece& option, UsageFn Usage); @@ -392,6 +396,10 @@ class CompilerOptions final { // won't be atomic for performance reasons, so we accept races, just like in interpreter. bool count_hotness_in_compiled_code_; + // Whether we eagerly resolve all of the const strings that are loaded from startup methods in the + // profile. + bool resolve_startup_const_strings_; + RegisterAllocator::Strategy register_allocation_strategy_; // If not null, specifies optimization passes which will be run instead of defaults. diff --git a/compiler/driver/compiler_options_map-inl.h b/compiler/driver/compiler_options_map-inl.h index d4a582fb35..5a844959c4 100644 --- a/compiler/driver/compiler_options_map-inl.h +++ b/compiler/driver/compiler_options_map-inl.h @@ -80,6 +80,7 @@ inline bool ReadCompilerOptions(Base& map, CompilerOptions* options, std::string if (map.Exists(Base::CountHotnessInCompiledCode)) { options->count_hotness_in_compiled_code_ = true; } + map.AssignIfExists(Base::ResolveStartupConstStrings, &options->resolve_startup_const_strings_); if (map.Exists(Base::DumpTimings)) { options->dump_timings_ = true; @@ -184,6 +185,11 @@ inline void AddCompilerOptionsArgumentParserOptions(Builder& b) { .template WithType<std::string>() .IntoKey(Map::RegisterAllocationStrategy) + .Define("--resolve-startup-const-strings=_") + .template WithType<bool>() + .WithValueMap({{"false", false}, {"true", true}}) + .IntoKey(Map::ResolveStartupConstStrings) + .Define("--verbose-methods=_") .template WithType<ParseStringList<','>>() .IntoKey(Map::VerboseMethods); diff --git a/compiler/driver/compiler_options_map.def b/compiler/driver/compiler_options_map.def index 238cd465df..a593240365 100644 --- a/compiler/driver/compiler_options_map.def +++ b/compiler/driver/compiler_options_map.def @@ -52,13 +52,14 @@ COMPILER_OPTIONS_KEY (Unit, Baseline) COMPILER_OPTIONS_KEY (double, TopKProfileThreshold) COMPILER_OPTIONS_KEY (bool, AbortOnHardVerifierFailure) COMPILER_OPTIONS_KEY (bool, AbortOnSoftVerifierFailure) +COMPILER_OPTIONS_KEY (bool, ResolveStartupConstStrings, false) COMPILER_OPTIONS_KEY (std::string, DumpInitFailures) COMPILER_OPTIONS_KEY (std::string, DumpCFG) COMPILER_OPTIONS_KEY (Unit, DumpCFGAppend) // TODO: Add type parser. COMPILER_OPTIONS_KEY (std::string, RegisterAllocationStrategy) COMPILER_OPTIONS_KEY (ParseStringList<','>, VerboseMethods) -COMPILER_OPTIONS_KEY (bool, DeduplicateCode, true) +COMPILER_OPTIONS_KEY (bool, DeduplicateCode, true) COMPILER_OPTIONS_KEY (Unit, CountHotnessInCompiledCode) COMPILER_OPTIONS_KEY (Unit, DumpTimings) COMPILER_OPTIONS_KEY (Unit, DumpPassTimings) diff --git a/compiler/optimizing/bounds_check_elimination_test.cc b/compiler/optimizing/bounds_check_elimination_test.cc index 7c29df877a..e15161e093 100644 --- a/compiler/optimizing/bounds_check_elimination_test.cc +++ b/compiler/optimizing/bounds_check_elimination_test.cc @@ -598,9 +598,10 @@ static HInstruction* BuildSSAGraph3(HGraph* graph, entry->AddSuccessor(block); // We pass a bogus constant for the class to avoid mocking one. HInstruction* new_array = new (allocator) HNewArray( - constant_10, - constant_10, - 0); + /* cls= */ constant_10, + /* length= */ constant_10, + /* dex_pc= */ 0, + /* component_size_shift= */ 0); block->AddInstruction(new_array); block->AddInstruction(new (allocator) HGoto()); @@ -977,7 +978,11 @@ TEST_F(BoundsCheckEliminationTest, ModArrayBoundsElimination) { graph_->AddBlock(block); entry->AddSuccessor(block); // We pass a bogus constant for the class to avoid mocking one. - HInstruction* new_array = new (GetAllocator()) HNewArray(constant_10, constant_10, 0); + HInstruction* new_array = new (GetAllocator()) HNewArray( + /* cls= */ constant_10, + /* length= */ constant_10, + /* dex_pc= */ 0, + /* component_size_shift= */ 0); block->AddInstruction(new_array); block->AddInstruction(new (GetAllocator()) HGoto()); diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index d440cf3e4c..d8e442c642 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -1653,19 +1653,12 @@ void CodeGenerator::EmitJitRoots(uint8_t* code, EmitJitRootPatches(code, roots_data); } -QuickEntrypointEnum CodeGenerator::GetArrayAllocationEntrypoint(Handle<mirror::Class> array_klass) { - ScopedObjectAccess soa(Thread::Current()); - if (array_klass == nullptr) { - // This can only happen for non-primitive arrays, as primitive arrays can always - // be resolved. - return kQuickAllocArrayResolved32; - } - - switch (array_klass->GetComponentSize()) { - case 1: return kQuickAllocArrayResolved8; - case 2: return kQuickAllocArrayResolved16; - case 4: return kQuickAllocArrayResolved32; - case 8: return kQuickAllocArrayResolved64; +QuickEntrypointEnum CodeGenerator::GetArrayAllocationEntrypoint(HNewArray* new_array) { + switch (new_array->GetComponentSizeShift()) { + case 0: return kQuickAllocArrayResolved8; + case 1: return kQuickAllocArrayResolved16; + case 2: return kQuickAllocArrayResolved32; + case 3: return kQuickAllocArrayResolved64; } LOG(FATAL) << "Unreachable"; return kQuickAllocArrayResolved; diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h index 4e73e0bdcb..3f560780ce 100644 --- a/compiler/optimizing/code_generator.h +++ b/compiler/optimizing/code_generator.h @@ -636,7 +636,7 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> { virtual void GenerateNop() = 0; - static QuickEntrypointEnum GetArrayAllocationEntrypoint(Handle<mirror::Class> array_klass); + static QuickEntrypointEnum GetArrayAllocationEntrypoint(HNewArray* new_array); protected: // Patch info used for recording locations of required linker patches and their targets, diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index 0a28f6557a..3f4fb156b4 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -5004,10 +5004,8 @@ void LocationsBuilderARM64::VisitNewArray(HNewArray* instruction) { } void InstructionCodeGeneratorARM64::VisitNewArray(HNewArray* instruction) { - // Note: if heap poisoning is enabled, the entry point takes cares - // of poisoning the reference. - QuickEntrypointEnum entrypoint = - CodeGenerator::GetArrayAllocationEntrypoint(instruction->GetLoadClass()->GetClass()); + // Note: if heap poisoning is enabled, the entry point takes care of poisoning the reference. + QuickEntrypointEnum entrypoint = CodeGenerator::GetArrayAllocationEntrypoint(instruction); codegen_->InvokeRuntime(entrypoint, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>(); codegen_->MaybeGenerateMarkingRegisterCheck(/* code */ __LINE__); diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 8bd4af50f3..d5b734d55a 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -5043,10 +5043,8 @@ void LocationsBuilderARMVIXL::VisitNewArray(HNewArray* instruction) { } void InstructionCodeGeneratorARMVIXL::VisitNewArray(HNewArray* instruction) { - // Note: if heap poisoning is enabled, the entry point takes cares - // of poisoning the reference. - QuickEntrypointEnum entrypoint = - CodeGenerator::GetArrayAllocationEntrypoint(instruction->GetLoadClass()->GetClass()); + // Note: if heap poisoning is enabled, the entry point takes care of poisoning the reference. + QuickEntrypointEnum entrypoint = CodeGenerator::GetArrayAllocationEntrypoint(instruction); codegen_->InvokeRuntime(entrypoint, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>(); DCHECK(!codegen_->IsLeafMethod()); diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index 1f0e200cb7..c6d0f3f618 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -8702,10 +8702,8 @@ void LocationsBuilderMIPS::VisitNewArray(HNewArray* instruction) { } void InstructionCodeGeneratorMIPS::VisitNewArray(HNewArray* instruction) { - // Note: if heap poisoning is enabled, the entry point takes care - // of poisoning the reference. - QuickEntrypointEnum entrypoint = - CodeGenerator::GetArrayAllocationEntrypoint(instruction->GetLoadClass()->GetClass()); + // Note: if heap poisoning is enabled, the entry point takes care of poisoning the reference. + QuickEntrypointEnum entrypoint = CodeGenerator::GetArrayAllocationEntrypoint(instruction); codegen_->InvokeRuntime(entrypoint, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>(); DCHECK(!codegen_->IsLeafMethod()); diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index 0005d8f6b6..039b3ca3ff 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -6633,10 +6633,8 @@ void LocationsBuilderMIPS64::VisitNewArray(HNewArray* instruction) { } void InstructionCodeGeneratorMIPS64::VisitNewArray(HNewArray* instruction) { - // Note: if heap poisoning is enabled, the entry point takes care - // of poisoning the reference. - QuickEntrypointEnum entrypoint = - CodeGenerator::GetArrayAllocationEntrypoint(instruction->GetLoadClass()->GetClass()); + // Note: if heap poisoning is enabled, the entry point takes care of poisoning the reference. + QuickEntrypointEnum entrypoint = CodeGenerator::GetArrayAllocationEntrypoint(instruction); codegen_->InvokeRuntime(entrypoint, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>(); DCHECK(!codegen_->IsLeafMethod()); diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index ca1e93b75e..9f34a51d84 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -4525,10 +4525,8 @@ void LocationsBuilderX86::VisitNewArray(HNewArray* instruction) { } void InstructionCodeGeneratorX86::VisitNewArray(HNewArray* instruction) { - // Note: if heap poisoning is enabled, the entry point takes cares - // of poisoning the reference. - QuickEntrypointEnum entrypoint = - CodeGenerator::GetArrayAllocationEntrypoint(instruction->GetLoadClass()->GetClass()); + // Note: if heap poisoning is enabled, the entry point takes care of poisoning the reference. + QuickEntrypointEnum entrypoint = CodeGenerator::GetArrayAllocationEntrypoint(instruction); codegen_->InvokeRuntime(entrypoint, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>(); DCHECK(!codegen_->IsLeafMethod()); diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index e6643fb08c..dac2dba605 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -4371,10 +4371,8 @@ void LocationsBuilderX86_64::VisitNewArray(HNewArray* instruction) { } void InstructionCodeGeneratorX86_64::VisitNewArray(HNewArray* instruction) { - // Note: if heap poisoning is enabled, the entry point takes cares - // of poisoning the reference. - QuickEntrypointEnum entrypoint = - CodeGenerator::GetArrayAllocationEntrypoint(instruction->GetLoadClass()->GetClass()); + // Note: if heap poisoning is enabled, the entry point takes care of poisoning the reference. + QuickEntrypointEnum entrypoint = CodeGenerator::GetArrayAllocationEntrypoint(instruction); codegen_->InvokeRuntime(entrypoint, instruction, instruction->GetDexPc()); CheckEntrypointTypes<kQuickAllocArrayResolved, void*, mirror::Class*, int32_t>(); DCHECK(!codegen_->IsLeafMethod()); diff --git a/compiler/optimizing/induction_var_range_test.cc b/compiler/optimizing/induction_var_range_test.cc index e5bc6ef22c..223e08e1b4 100644 --- a/compiler/optimizing/induction_var_range_test.cc +++ b/compiler/optimizing/induction_var_range_test.cc @@ -701,7 +701,11 @@ TEST_F(InductionVarRangeTest, MaxValue) { TEST_F(InductionVarRangeTest, ArrayLengthAndHints) { // We pass a bogus constant for the class to avoid mocking one. - HInstruction* new_array = new (GetAllocator()) HNewArray(x_, x_, 0); + HInstruction* new_array = new (GetAllocator()) HNewArray( + /* cls= */ x_, + /* length= */ x_, + /* dex_pc= */ 0, + /* component_size_shift= */ 0); entry_block_->AddInstruction(new_array); HInstruction* array_length = new (GetAllocator()) HArrayLength(new_array, 0); entry_block_->AddInstruction(array_length); diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index b576f8399d..bd94789144 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -1842,15 +1842,27 @@ void HInstructionBuilder::BuildArrayAccess(const Instruction& instruction, graph_->SetHasBoundsChecks(true); } +HNewArray* HInstructionBuilder::BuildNewArray(uint32_t dex_pc, + dex::TypeIndex type_index, + HInstruction* length) { + HLoadClass* cls = BuildLoadClass(type_index, dex_pc); + + const char* descriptor = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(type_index)); + DCHECK_EQ(descriptor[0], '['); + size_t component_type_shift = Primitive::ComponentSizeShift(Primitive::GetType(descriptor[1])); + + HNewArray* new_array = new (allocator_) HNewArray(cls, length, dex_pc, component_type_shift); + AppendInstruction(new_array); + return new_array; +} + HNewArray* HInstructionBuilder::BuildFilledNewArray(uint32_t dex_pc, dex::TypeIndex type_index, const InstructionOperands& operands) { const size_t number_of_operands = operands.GetNumberOfOperands(); HInstruction* length = graph_->GetIntConstant(number_of_operands, dex_pc); - HLoadClass* cls = BuildLoadClass(type_index, dex_pc); - HNewArray* const object = new (allocator_) HNewArray(cls, length, dex_pc); - AppendInstruction(object); + HNewArray* new_array = BuildNewArray(dex_pc, type_index, length); const char* descriptor = dex_file_->StringByTypeIdx(type_index); DCHECK_EQ(descriptor[0], '[') << descriptor; char primitive = descriptor[1]; @@ -1863,13 +1875,13 @@ HNewArray* HInstructionBuilder::BuildFilledNewArray(uint32_t dex_pc, for (size_t i = 0; i < number_of_operands; ++i) { HInstruction* value = LoadLocal(operands.GetOperand(i), type); HInstruction* index = graph_->GetIntConstant(i, dex_pc); - HArraySet* aset = new (allocator_) HArraySet(object, index, value, type, dex_pc); + HArraySet* aset = new (allocator_) HArraySet(new_array, index, value, type, dex_pc); ssa_builder_->MaybeAddAmbiguousArraySet(aset); AppendInstruction(aset); } - latest_result_ = object; + latest_result_ = new_array; - return object; + return new_array; } template <typename T> @@ -2892,10 +2904,8 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, case Instruction::NEW_ARRAY: { dex::TypeIndex type_index(instruction.VRegC_22c()); HInstruction* length = LoadLocal(instruction.VRegB_22c(), DataType::Type::kInt32); - HLoadClass* cls = BuildLoadClass(type_index, dex_pc); + HNewArray* new_array = BuildNewArray(dex_pc, type_index, length); - HNewArray* new_array = new (allocator_) HNewArray(cls, length, dex_pc); - AppendInstruction(new_array); UpdateLocal(instruction.VRegA_22c(), current_block_->GetLastInstruction()); BuildConstructorFenceForAllocation(new_array); break; diff --git a/compiler/optimizing/instruction_builder.h b/compiler/optimizing/instruction_builder.h index af1b86ca6f..2ab2139216 100644 --- a/compiler/optimizing/instruction_builder.h +++ b/compiler/optimizing/instruction_builder.h @@ -179,6 +179,9 @@ class HInstructionBuilder : public ValueObject { uint32_t call_site_idx, const InstructionOperands& operands); + // Builds a new array node. + HNewArray* BuildNewArray(uint32_t dex_pc, dex::TypeIndex type_index, HInstruction* length); + // Builds a new array node and the instructions that fill it. HNewArray* BuildFilledNewArray(uint32_t dex_pc, dex::TypeIndex type_index, diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 97b50d36da..6ebe89eae1 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -4849,10 +4849,11 @@ class HNeg final : public HUnaryOperation { class HNewArray final : public HExpression<2> { public: - HNewArray(HInstruction* cls, HInstruction* length, uint32_t dex_pc) + HNewArray(HInstruction* cls, HInstruction* length, uint32_t dex_pc, size_t component_size_shift) : HExpression(kNewArray, DataType::Type::kReference, SideEffects::CanTriggerGC(), dex_pc) { SetRawInputAt(0, cls); SetRawInputAt(1, length); + SetPackedField<ComponentSizeShiftField>(component_size_shift); } bool IsClonable() const override { return true; } @@ -4874,10 +4875,23 @@ class HNewArray final : public HExpression<2> { return InputAt(1); } + size_t GetComponentSizeShift() { + return GetPackedField<ComponentSizeShiftField>(); + } + DECLARE_INSTRUCTION(NewArray); protected: DEFAULT_COPY_CONSTRUCTOR(NewArray); + + private: + static constexpr size_t kFieldComponentSizeShift = kNumberOfGenericPackedBits; + static constexpr size_t kFieldComponentSizeShiftSize = MinimumBitsToStore(3u); + static constexpr size_t kNumberOfNewArrayPackedBits = + kFieldComponentSizeShift + kFieldComponentSizeShiftSize; + static_assert(kNumberOfNewArrayPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); + using ComponentSizeShiftField = + BitField<size_t, kFieldComponentSizeShift, kFieldComponentSizeShift>; }; class HAdd final : public HBinaryOperation { diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 71cdfd2c08..f0f2b3e397 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -477,6 +477,9 @@ NO_RETURN static void Usage(const char* fmt, ...) { UsageError(" compiling the apk. If specified, the string will be embedded verbatim in"); UsageError(" the key value store of the oat file."); UsageError(""); + UsageError(" --resolve-startup-const-strings=true|false: If true, the compiler eagerly"); + UsageError(" resolves strings referenced from const-string of startup methods."); + UsageError(""); UsageError(" Example: --compilation-reason=install"); UsageError(""); std::cerr << "See log for usage error information\n"; @@ -586,8 +589,10 @@ class WatchDog { const char* reason = "dex2oat watch dog thread waiting"; CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason); while (!shutting_down_) { - int rc = TEMP_FAILURE_RETRY(pthread_cond_timedwait(&cond_, &mutex_, &timeout_ts)); - if (rc == ETIMEDOUT) { + int rc = pthread_cond_timedwait(&cond_, &mutex_, &timeout_ts); + if (rc == EINTR) { + continue; + } else if (rc == ETIMEDOUT) { Fatal(StringPrintf("dex2oat did not finish after %" PRId64 " seconds", timeout_in_milliseconds_/1000)); } else if (rc != 0) { @@ -657,21 +662,21 @@ class Dex2Oat final { if (!kIsDebugBuild && !(kRunningOnMemoryTool && kMemoryToolDetectsLeaks)) { // We want to just exit on non-debug builds, not bringing the runtime down // in an orderly fashion. So release the following fields. - driver_.release(); - image_writer_.release(); + driver_.release(); // NOLINT + image_writer_.release(); // NOLINT for (std::unique_ptr<const DexFile>& dex_file : opened_dex_files_) { - dex_file.release(); + dex_file.release(); // NOLINT } new std::vector<MemMap>(std::move(opened_dex_files_maps_)); // Leak MemMaps. for (std::unique_ptr<File>& vdex_file : vdex_files_) { - vdex_file.release(); + vdex_file.release(); // NOLINT } for (std::unique_ptr<File>& oat_file : oat_files_) { - oat_file.release(); + oat_file.release(); // NOLINT } - runtime_.release(); - verification_results_.release(); - key_value_store_.release(); + runtime_.release(); // NOLINT + verification_results_.release(); // NOLINT + key_value_store_.release(); // NOLINT } } diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc index a1fed5f6d9..6f53861a3d 100644 --- a/dex2oat/dex2oat_test.cc +++ b/dex2oat/dex2oat_test.cc @@ -39,6 +39,7 @@ #include "dex/dex_file_loader.h" #include "dex2oat_environment_test.h" #include "dex2oat_return_codes.h" +#include "intern_table-inl.h" #include "oat.h" #include "oat_file.h" #include "profile/profile_compilation_info.h" @@ -136,14 +137,13 @@ class Dex2oatTest : public Dex2oatEnvironmentTest { ASSERT_TRUE(success) << error_msg << std::endl << output_; // Verify the odex file was generated as expected. - std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1, odex_location.c_str(), odex_location.c_str(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, + /*executable=*/ false, + /*low_4gb=*/ false, dex_location.c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(odex_file.get() != nullptr) << error_msg; @@ -156,14 +156,13 @@ class Dex2oatTest : public Dex2oatEnvironmentTest { if (!test_accepts_odex_file_on_failure) { // Verify there's no loadable odex file. - std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1, odex_location.c_str(), odex_location.c_str(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, + /*executable=*/ false, + /*low_4gb=*/ false, dex_location.c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(odex_file.get() == nullptr); } @@ -324,26 +323,26 @@ class Dex2oatSwapTest : public Dex2oatTest { }; TEST_F(Dex2oatSwapTest, DoNotUseSwapDefaultSingleSmall) { - RunTest(false /* use_fd */, false /* expect_use */); - RunTest(true /* use_fd */, false /* expect_use */); + RunTest(/*use_fd=*/ false, /*expect_use=*/ false); + RunTest(/*use_fd=*/ true, /*expect_use=*/ false); } TEST_F(Dex2oatSwapTest, DoNotUseSwapSingle) { - RunTest(false /* use_fd */, false /* expect_use */, { "--swap-dex-size-threshold=0" }); - RunTest(true /* use_fd */, false /* expect_use */, { "--swap-dex-size-threshold=0" }); + RunTest(/*use_fd=*/ false, /*expect_use=*/ false, { "--swap-dex-size-threshold=0" }); + RunTest(/*use_fd=*/ true, /*expect_use=*/ false, { "--swap-dex-size-threshold=0" }); } TEST_F(Dex2oatSwapTest, DoNotUseSwapSmall) { - RunTest(false /* use_fd */, false /* expect_use */, { "--swap-dex-count-threshold=0" }); - RunTest(true /* use_fd */, false /* expect_use */, { "--swap-dex-count-threshold=0" }); + RunTest(/*use_fd=*/ false, /*expect_use=*/ false, { "--swap-dex-count-threshold=0" }); + RunTest(/*use_fd=*/ true, /*expect_use=*/ false, { "--swap-dex-count-threshold=0" }); } TEST_F(Dex2oatSwapTest, DoUseSwapSingleSmall) { - RunTest(false /* use_fd */, - true /* expect_use */, + RunTest(/*use_fd=*/ false, + /*expect_use=*/ true, { "--swap-dex-size-threshold=0", "--swap-dex-count-threshold=0" }); - RunTest(true /* use_fd */, - true /* expect_use */, + RunTest(/*use_fd=*/ true, + /*expect_use=*/ true, { "--swap-dex-size-threshold=0", "--swap-dex-count-threshold=0" }); } @@ -369,7 +368,7 @@ class Dex2oatSwapUseTest : public Dex2oatSwapTest { void GrabResult1() { if (!kIsTargetBuild) { native_alloc_1_ = ParseNativeAlloc(); - swap_1_ = ParseSwap(false /* expected */); + swap_1_ = ParseSwap(/*expected=*/ false); } else { native_alloc_1_ = std::numeric_limits<size_t>::max(); swap_1_ = 0; @@ -379,7 +378,7 @@ class Dex2oatSwapUseTest : public Dex2oatSwapTest { void GrabResult2() { if (!kIsTargetBuild) { native_alloc_2_ = ParseNativeAlloc(); - swap_2_ = ParseSwap(true /* expected */); + swap_2_ = ParseSwap(/*expected=*/ true); } else { native_alloc_2_ = 0; swap_2_ = std::numeric_limits<size_t>::max(); @@ -449,15 +448,15 @@ TEST_F(Dex2oatSwapUseTest, CheckSwapUsage) { // investigate (b/29259363). TEST_DISABLED_FOR_X86(); - RunTest(false /* use_fd */, - false /* expect_use */); + RunTest(/*use_fd=*/ false, + /*expect_use=*/ false); GrabResult1(); std::string output_1 = output_; output_ = ""; - RunTest(false /* use_fd */, - true /* expect_use */, + RunTest(/*use_fd=*/ false, + /*expect_use=*/ true, { "--swap-dex-size-threshold=0", "--swap-dex-count-threshold=0" }); GrabResult2(); std::string output_2 = output_; @@ -513,14 +512,13 @@ class Dex2oatVeryLargeTest : public Dex2oatTest { } // Host/target independent checks. std::string error_msg; - std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1, odex_location.c_str(), odex_location.c_str(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, + /*executable=*/ false, + /*low_4gb=*/ false, dex_location.c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(odex_file.get() != nullptr) << error_msg; EXPECT_GT(app_image_file.length(), 0u); @@ -662,7 +660,7 @@ class Dex2oatLayoutTest : public Dex2oatTest { std::vector<std::unique_ptr<const DexFile>> dex_files; const ArtDexFileLoader dex_file_loader; ASSERT_TRUE(dex_file_loader.Open( - location, location, /* verify */ true, /* verify_checksum */ true, &error_msg, &dex_files)); + location, location, /*verify=*/ true, /*verify_checksum=*/ true, &error_msg, &dex_files)); EXPECT_EQ(dex_files.size(), 1U); std::unique_ptr<const DexFile>& dex_file = dex_files[0]; GenerateProfile(profile_location, @@ -714,8 +712,8 @@ class Dex2oatLayoutTest : public Dex2oatTest { CompileProfileOdex(dex_location, odex_location, app_image_file, - /* use_fd */ false, - /* num_profile_classes */ 0); + /*use_fd=*/ false, + /*num_profile_classes=*/ 0); CheckValidity(); ASSERT_TRUE(success_); // Don't check the result since CheckResult relies on the class being in the profile. @@ -727,8 +725,8 @@ class Dex2oatLayoutTest : public Dex2oatTest { CompileProfileOdex(dex_location, odex_location, app_image_file, - /* use_fd */ false, - /* num_profile_classes */ 1); + /*use_fd=*/ false, + /*num_profile_classes=*/ 1); CheckValidity(); ASSERT_TRUE(success_); CheckResult(dex_location, odex_location, app_image_file); @@ -756,8 +754,8 @@ class Dex2oatLayoutTest : public Dex2oatTest { CompileProfileOdex(dex_location, odex_location, app_image_file_name, - /* use_fd */ true, - /* num_profile_classes */ 1, + /*use_fd=*/ true, + /*num_profile_classes=*/ 1, { input_vdex, output_vdex }); EXPECT_GT(vdex_file1->GetLength(), 0u); } @@ -768,10 +766,10 @@ class Dex2oatLayoutTest : public Dex2oatTest { CompileProfileOdex(dex_location, odex_location, app_image_file_name, - /* use_fd */ true, - /* num_profile_classes */ 1, + /*use_fd=*/ true, + /*num_profile_classes=*/ 1, { input_vdex, output_vdex }, - /* expect_success */ true); + /*expect_success=*/ true); EXPECT_GT(vdex_file2.GetFile()->GetLength(), 0u); } ASSERT_EQ(vdex_file1->FlushCloseOrErase(), 0) << "Could not flush and close vdex file"; @@ -784,14 +782,13 @@ class Dex2oatLayoutTest : public Dex2oatTest { const std::string& app_image_file_name) { // Host/target independent checks. std::string error_msg; - std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1, odex_location.c_str(), odex_location.c_str(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, + /*executable=*/ false, + /*low_4gb=*/ false, dex_location.c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(odex_file.get() != nullptr) << error_msg; @@ -799,7 +796,7 @@ class Dex2oatLayoutTest : public Dex2oatTest { std::vector<std::unique_ptr<const DexFile>> dex_files; const ArtDexFileLoader dex_file_loader; ASSERT_TRUE(dex_file_loader.Open( - location, location, /* verify */ true, /* verify_checksum */ true, &error_msg, &dex_files)); + location, location, /*verify=*/ true, /*verify_checksum=*/ true, &error_msg, &dex_files)); EXPECT_EQ(dex_files.size(), 1U); std::unique_ptr<const DexFile>& old_dex_file = dex_files[0]; @@ -852,11 +849,11 @@ class Dex2oatLayoutTest : public Dex2oatTest { }; TEST_F(Dex2oatLayoutTest, TestLayout) { - RunTest(/* app-image */ false); + RunTest(/*app_image=*/ false); } TEST_F(Dex2oatLayoutTest, TestLayoutAppImage) { - RunTest(/* app-image */ true); + RunTest(/*app_image=*/ true); } TEST_F(Dex2oatLayoutTest, TestVdexLayout) { @@ -881,8 +878,8 @@ class Dex2oatUnquickenTest : public Dex2oatTest { odex_location, CompilerFilter::kQuicken, { input_vdex, output_vdex }, - /* expect_success */ true, - /* use_fd */ true); + /*expect_success=*/ true, + /*use_fd=*/ true); EXPECT_GT(vdex_file1->GetLength(), 0u); } // Unquicken by running the verify compiler filter on the vdex file. @@ -893,8 +890,8 @@ class Dex2oatUnquickenTest : public Dex2oatTest { odex_location, CompilerFilter::kVerify, { input_vdex, output_vdex, kDisableCompactDex }, - /* expect_success */ true, - /* use_fd */ true); + /*expect_success=*/ true, + /*use_fd=*/ true); } ASSERT_EQ(vdex_file1->FlushCloseOrErase(), 0) << "Could not flush and close vdex file"; CheckResult(dex_location, odex_location); @@ -922,8 +919,8 @@ class Dex2oatUnquickenTest : public Dex2oatTest { odex_location, CompilerFilter::kQuicken, { input_vdex, output_vdex, "--compact-dex-level=fast"}, - /* expect_success */ true, - /* use_fd */ true); + /*expect_success=*/ true, + /*use_fd=*/ true); EXPECT_GT(vdex_file1->GetLength(), 0u); } @@ -935,8 +932,8 @@ class Dex2oatUnquickenTest : public Dex2oatTest { odex_location2, CompilerFilter::kVerify, { input_vdex, output_vdex, "--compact-dex-level=none"}, - /* expect_success */ true, - /* use_fd */ true); + /*expect_success=*/ true, + /*use_fd=*/ true); } ASSERT_EQ(vdex_file1->FlushCloseOrErase(), 0) << "Could not flush and close vdex file"; ASSERT_EQ(vdex_file2->FlushCloseOrErase(), 0) << "Could not flush and close vdex file"; @@ -946,14 +943,13 @@ class Dex2oatUnquickenTest : public Dex2oatTest { void CheckResult(const std::string& dex_location, const std::string& odex_location) { std::string error_msg; - std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1, odex_location.c_str(), odex_location.c_str(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, + /*executable=*/ false, + /*low_4gb=*/ false, dex_location.c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(odex_file.get() != nullptr) << error_msg; ASSERT_GE(odex_file->GetOatDexFiles().size(), 1u); @@ -1326,14 +1322,13 @@ TEST_F(Dex2oatTest, LayoutSections) { EXPECT_EQ(res, 0); // Open our generated oat file. - std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1, oat_filename.c_str(), oat_filename.c_str(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, + /*executable=*/ false, + /*low_4gb=*/ false, dex->GetLocation().c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(odex_file != nullptr); std::vector<const OatDexFile*> oat_dex_files = odex_file->GetOatDexFiles(); @@ -1436,14 +1431,13 @@ TEST_F(Dex2oatTest, GenerateCompactDex) { {"--compact-dex-level=fast"}); EXPECT_EQ(res, 0); // Open our generated oat file. - std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1, oat_filename.c_str(), oat_filename.c_str(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, + /*executable=*/ false, + /*low_4gb=*/ false, dex_location.c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(odex_file != nullptr); std::vector<const OatDexFile*> oat_dex_files = odex_file->GetOatDexFiles(); @@ -1681,14 +1675,13 @@ TEST_F(Dex2oatTest, CompactDexGenerationFailure) { }); // Open our generated oat file. std::string error_msg; - std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1, oat_filename.c_str(), oat_filename.c_str(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, + /*executable=*/ false, + /*low_4gb=*/ false, temp_dex.GetFilename().c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(odex_file != nullptr); std::vector<const OatDexFile*> oat_dex_files = odex_file->GetOatDexFiles(); @@ -1759,14 +1752,13 @@ TEST_F(Dex2oatTest, VerifyCompilationReason) { { "--compilation-reason=install" }, true); std::string error_msg; - std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1, odex_location.c_str(), odex_location.c_str(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, + /*executable=*/ false, + /*low_4gb=*/ false, dex_location.c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(odex_file != nullptr); ASSERT_STREQ("install", odex_file->GetCompilationReason()); @@ -1785,14 +1777,13 @@ TEST_F(Dex2oatTest, VerifyNoCompilationReason) { {}, true); std::string error_msg; - std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1, odex_location.c_str(), odex_location.c_str(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, + /*executable=*/ false, + /*low_4gb=*/ false, dex_location.c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(odex_file != nullptr); ASSERT_EQ(nullptr, odex_file->GetCompilationReason()); @@ -1816,21 +1807,20 @@ TEST_F(Dex2oatTest, DontExtract) { { // Check the vdex doesn't have dex. std::unique_ptr<VdexFile> vdex(VdexFile::Open(vdex_location.c_str(), - /*writable*/ false, - /*low_4gb*/ false, - /*unquicken*/ false, + /*writable=*/ false, + /*low_4gb=*/ false, + /*unquicken=*/ false, &error_msg)); ASSERT_TRUE(vdex != nullptr); EXPECT_FALSE(vdex->HasDexSection()) << output_; } - std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1, odex_location.c_str(), odex_location.c_str(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, + /*executable=*/ false, + /*low_4gb=*/ false, dex_location.c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(odex_file != nullptr) << dex_location; std::vector<const OatDexFile*> oat_dex_files = odex_file->GetOatDexFiles(); @@ -1929,8 +1919,8 @@ TEST_F(Dex2oatTest, QuickenedInput) { // Disable cdex since we want to compare against the original dex file // after unquickening. { input_vdex, output_vdex, kDisableCompactDex }, - /* expect_success */ true, - /* use_fd */ true); + /*expect_success=*/ true, + /*use_fd=*/ true); } // Unquicken by running the verify compiler filter on the vdex file and verify it matches. std::string odex_location2 = GetOdexDir() + "/unquickened.odex"; @@ -1944,8 +1934,8 @@ TEST_F(Dex2oatTest, QuickenedInput) { CompilerFilter::kVerify, // Disable cdex to avoid needing to write out the shared section. { input_vdex, output_vdex, kDisableCompactDex }, - /* expect_success */ true, - /* use_fd */ true); + /*expect_success=*/ true, + /*use_fd=*/ true); } ASSERT_EQ(vdex_unquickened->Flush(), 0) << "Could not flush and close vdex file"; ASSERT_TRUE(success_); @@ -2062,14 +2052,13 @@ TEST_F(Dex2oatTest, AppImageNoProfile) { [](const OatFile&) {}); // Open our generated oat file. std::string error_msg; - std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1, odex_location.c_str(), odex_location.c_str(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, + /*executable=*/ false, + /*low_4gb=*/ false, odex_location.c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(odex_file != nullptr); ImageHeader header = {}; @@ -2082,6 +2071,89 @@ TEST_F(Dex2oatTest, AppImageNoProfile) { EXPECT_EQ(header.GetImageSection(ImageHeader::kSectionArtFields).Size(), 0u); } +TEST_F(Dex2oatTest, AppImageResolveStrings) { + if (!ClassLinker::kAppImageMayContainStrings) { + TEST_DISABLED(); + } + using Hotness = ProfileCompilationInfo::MethodHotness; + // Create a profile with the startup method marked. + ScratchFile profile_file; + std::vector<uint16_t> methods; + std::vector<dex::TypeIndex> classes; + { + std::unique_ptr<const DexFile> dex(OpenTestDexFile("StringLiterals")); + for (ClassAccessor accessor : dex->GetClasses()) { + if (accessor.GetDescriptor() == std::string("LStringLiterals$StartupClass;")) { + classes.push_back(accessor.GetClassIdx()); + } + for (const ClassAccessor::Method& method : accessor.GetMethods()) { + std::string method_name(dex->GetMethodName(dex->GetMethodId(method.GetIndex()))); + if (method_name == "startUpMethod") { + methods.push_back(method.GetIndex()); + } + } + } + ASSERT_GT(classes.size(), 0u); + ASSERT_GT(methods.size(), 0u); + // Here, we build the profile from the method lists. + ProfileCompilationInfo info; + info.AddClassesForDex(dex.get(), classes.begin(), classes.end()); + info.AddMethodsForDex(Hotness::kFlagStartup, dex.get(), methods.begin(), methods.end()); + // Save the profile since we want to use it with dex2oat to produce an oat file. + ASSERT_TRUE(info.Save(profile_file.GetFd())); + } + const std::string out_dir = GetScratchDir(); + const std::string odex_location = out_dir + "/base.odex"; + const std::string app_image_location = out_dir + "/base.art"; + GenerateOdexForTest(GetTestDexFileName("StringLiterals"), + odex_location, + CompilerFilter::Filter::kSpeedProfile, + { "--app-image-file=" + app_image_location, + "--resolve-startup-const-strings=true", + "--profile-file=" + profile_file.GetFilename()}, + /*expect_success=*/ true, + /*use_fd=*/ false, + [](const OatFile&) {}); + // Open our generated oat file. + std::string error_msg; + std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1, + odex_location.c_str(), + odex_location.c_str(), + /*executable=*/ false, + /*low_4gb=*/ false, + odex_location.c_str(), + /*reservation=*/ nullptr, + &error_msg)); + ASSERT_TRUE(odex_file != nullptr); + // Check the strings in the app image intern table only contain the "startup" strigs. + { + ScopedObjectAccess soa(Thread::Current()); + std::unique_ptr<gc::space::ImageSpace> space = + gc::space::ImageSpace::CreateFromAppImage(app_image_location.c_str(), + odex_file.get(), + &error_msg); + ASSERT_TRUE(space != nullptr) << error_msg; + std::set<std::string> seen; + InternTable intern_table; + intern_table.AddImageStringsToTable(space.get(), [&](InternTable::UnorderedSet& interns) + REQUIRES_SHARED(Locks::mutator_lock_) { + for (const GcRoot<mirror::String>& str : interns) { + seen.insert(str.Read()->ToModifiedUtf8()); + } + }); + // Normal methods + EXPECT_TRUE(seen.find("Loading ") != seen.end()); + EXPECT_TRUE(seen.find("Starting up") != seen.end()); + EXPECT_TRUE(seen.find("abcd.apk") != seen.end()); + EXPECT_TRUE(seen.find("Unexpected error") == seen.end()); + EXPECT_TRUE(seen.find("Shutting down!") == seen.end()); + // Classes initializers + EXPECT_TRUE(seen.find("Startup init") != seen.end()); + EXPECT_TRUE(seen.find("Other class init") == seen.end()); + } +} + + TEST_F(Dex2oatClassLoaderContextTest, StoredClassLoaderContext) { std::vector<std::unique_ptr<const DexFile>> dex_files = OpenTestDexFiles("MultiDex"); const std::string out_dir = GetScratchDir(); diff --git a/dex2oat/linker/oat_writer_test.cc b/dex2oat/linker/oat_writer_test.cc index f764b42bc8..7382208d51 100644 --- a/dex2oat/linker/oat_writer_test.cc +++ b/dex2oat/linker/oat_writer_test.cc @@ -87,7 +87,7 @@ class OatTest : public CommonCompilerTest { void SetupCompiler(const std::vector<std::string>& compiler_options) { std::string error_msg; if (!compiler_options_->ParseCompilerOptions(compiler_options, - false /* ignore_unrecognized */, + /*ignore_unrecognized=*/ false, &error_msg)) { LOG(FATAL) << error_msg; UNREACHABLE(); @@ -176,7 +176,7 @@ class OatTest : public CommonCompilerTest { oat_rodata, &key_value_store, verify, - /* update_input_vdex */ false, + /*update_input_vdex=*/ false, CopyOption::kOnlyIfCompressed, &opened_dex_files_maps, &opened_dex_files)) { @@ -236,7 +236,7 @@ class OatTest : public CommonCompilerTest { } if (!oat_writer.WriteHeader(elf_writer->GetStream(), - /* image_file_location_oat_checksum */ 42U)) { + /*image_file_location_oat_checksum=*/ 42U)) { return false; } @@ -404,14 +404,13 @@ TEST_F(OatTest, WriteRead) { if (kCompile) { // OatWriter strips the code, regenerate to compare compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath(), &timings); } - std::unique_ptr<OatFile> oat_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> oat_file(OatFile::Open(/*zip_fd=*/ -1, tmp_oat.GetFilename(), tmp_oat.GetFilename(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ true, - /* abs_dex_location */ nullptr, - /* reservation */ nullptr, + /*executable=*/ false, + /*low_4gb=*/ true, + /*abs_dex_location=*/ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(oat_file.get() != nullptr) << error_msg; const OatHeader& oat_header = oat_file->GetOatHeader(); @@ -522,18 +521,17 @@ TEST_F(OatTest, EmptyTextSection) { tmp_oat.GetFile(), dex_files, key_value_store, - /* verify */ false); + /*verify=*/ false); ASSERT_TRUE(success); std::string error_msg; - std::unique_ptr<OatFile> oat_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> oat_file(OatFile::Open(/*zip_fd=*/ -1, tmp_oat.GetFilename(), tmp_oat.GetFilename(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, - /* abs_dex_location */ nullptr, - /* reservation */ nullptr, + /*executable=*/ false, + /*low_4gb=*/ false, + /*abs_dex_location=*/ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(oat_file != nullptr); EXPECT_LT(static_cast<size_t>(oat_file->Size()), @@ -604,14 +602,13 @@ void OatTest::TestDexFileInput(bool verify, bool low_4gb, bool use_profile) { ASSERT_TRUE(success); std::string error_msg; - std::unique_ptr<OatFile> opened_oat_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> opened_oat_file(OatFile::Open(/*zip_fd=*/ -1, tmp_oat.GetFilename(), tmp_oat.GetFilename(), - /* requested_base */ nullptr, - /* executable */ false, + /*executable=*/ false, low_4gb, - /* abs_dex_location */ nullptr, - /* reservation */ nullptr, + /*abs_dex_location=*/ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(opened_oat_file != nullptr) << error_msg; if (low_4gb) { @@ -727,7 +724,7 @@ void OatTest::TestZipFileInput(bool verify) { input_filenames, key_value_store, verify, - /* profile_compilation_info */ nullptr); + /*profile_compilation_info=*/ nullptr); if (verify) { ASSERT_FALSE(success); @@ -735,14 +732,13 @@ void OatTest::TestZipFileInput(bool verify) { ASSERT_TRUE(success); std::string error_msg; - std::unique_ptr<OatFile> opened_oat_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> opened_oat_file(OatFile::Open(/*zip_fd=*/ -1, tmp_oat.GetFilename(), tmp_oat.GetFilename(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, - /* abs_dex_location */ nullptr, - /* reservation */ nullptr, + /*executable=*/ false, + /*low_4gb=*/ false, + /*abs_dex_location=*/ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(opened_oat_file != nullptr) << error_msg; ASSERT_EQ(2u, opened_oat_file->GetOatDexFiles().size()); @@ -769,7 +765,7 @@ void OatTest::TestZipFileInput(bool verify) { { // Test using the AddZipDexFileSource() interface with the zip file handle. - File zip_fd(dup(zip_file.GetFd()), /* check_usage */ false); + File zip_fd(dup(zip_file.GetFd()), /*check_usage=*/ false); ASSERT_NE(-1, zip_fd.Fd()); ScratchFile tmp_base, tmp_oat(tmp_base, ".oat"), tmp_vdex(tmp_base, ".vdex"); @@ -785,14 +781,13 @@ void OatTest::TestZipFileInput(bool verify) { ASSERT_TRUE(success); std::string error_msg; - std::unique_ptr<OatFile> opened_oat_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> opened_oat_file(OatFile::Open(/*zip_fd=*/ -1, tmp_oat.GetFilename(), tmp_oat.GetFilename(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, - /* abs_dex_location */ nullptr, - /* reservation */ nullptr, + /*executable=*/ false, + /*low_4gb=*/ false, + /*abs_dex_location=*/ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(opened_oat_file != nullptr) << error_msg; ASSERT_EQ(2u, opened_oat_file->GetOatDexFiles().size()); @@ -843,7 +838,7 @@ void OatTest::TestZipFileInputWithEmptyDex() { oat_file.GetFile(), input_filenames, key_value_store, - /* verify */ false, + /*verify=*/ false, profile_compilation_info.get()); ASSERT_FALSE(success); } diff --git a/dexlayout/dexdiag_test.cc b/dexlayout/dexdiag_test.cc index d3bfd144c3..47ef0a5cf3 100644 --- a/dexlayout/dexdiag_test.cc +++ b/dexlayout/dexdiag_test.cc @@ -68,14 +68,13 @@ class DexDiagTest : public CommonRuntimeTest { EXPECT_TRUE(!oat_location.empty()); std::cout << "==" << oat_location << std::endl; std::string error_msg; - std::unique_ptr<OatFile> oat(OatFile::Open(/* zip_fd= */ -1, + std::unique_ptr<OatFile> oat(OatFile::Open(/*zip_fd=*/ -1, oat_location.c_str(), oat_location.c_str(), - /* requested_base= */ nullptr, - /* executable= */ false, - /* low_4gb= */ false, - /* abs_dex_location= */ nullptr, - /* reservation= */ nullptr, + /*executable=*/ false, + /*low_4gb=*/ false, + /*abs_dex_location=*/ nullptr, + /*reservation=*/ nullptr, &error_msg)); EXPECT_TRUE(oat != nullptr) << error_msg; return oat; diff --git a/dexlayout/dexlayout.cc b/dexlayout/dexlayout.cc index db6945fbaa..8905aa31c4 100644 --- a/dexlayout/dexlayout.cc +++ b/dexlayout/dexlayout.cc @@ -1554,7 +1554,7 @@ void DexLayout::LayoutClassDefsAndClassData(const DexFile* dex_file) { // Overwrite the existing vector with the new ordering, note that the sets of objects are // equivalent, but the order changes. This is why this is not a memory leak. // TODO: Consider cleaning this up with a shared_ptr. - class_datas[class_data_index].release(); + class_datas[class_data_index].release(); // NOLINT b/117926937 class_datas[class_data_index].reset(class_data); ++class_data_index; } @@ -1570,7 +1570,7 @@ void DexLayout::LayoutClassDefsAndClassData(const DexFile* dex_file) { // Overwrite the existing vector with the new ordering, note that the sets of objects are // equivalent, but the order changes. This is why this is not a memory leak. // TODO: Consider cleaning this up with a shared_ptr. - class_defs[i].release(); + class_defs[i].release(); // NOLINT b/117926937 class_defs[i].reset(new_class_def_order[i]); } } @@ -1671,7 +1671,7 @@ void DexLayout::LayoutStringData(const DexFile* dex_file) { // Now we know what order we want the string data, reorder them. size_t data_index = 0; for (dex_ir::StringId* string_id : string_ids) { - string_datas[data_index].release(); + string_datas[data_index].release(); // NOLINT b/117926937 string_datas[data_index].reset(string_id->DataItem()); ++data_index; } diff --git a/libartbase/base/bit_string_test.cc b/libartbase/base/bit_string_test.cc index 89a71a1894..45f4d4ec0d 100644 --- a/libartbase/base/bit_string_test.cc +++ b/libartbase/base/bit_string_test.cc @@ -110,17 +110,17 @@ TEST(InstanceOfBitString, ReadWrite) { ASSERT_EQ(BitString::kCapacity, 3u); EXPECT_BITSTRING_STR("BitString[]", bs); - bs = SetBitStringCharAt(bs, /*i*/0, /*val*/1u); + bs = SetBitStringCharAt(bs, /*i=*/0, /*val=*/1u); EXPECT_BITSTRING_STR("BitString[1]", bs); - bs = SetBitStringCharAt(bs, /*i*/1, /*val*/2u); + bs = SetBitStringCharAt(bs, /*i=*/1, /*val=*/2u); EXPECT_BITSTRING_STR("BitString[1,2]", bs); - bs = SetBitStringCharAt(bs, /*i*/2, /*val*/3u); + bs = SetBitStringCharAt(bs, /*i=*/2, /*val=*/3u); EXPECT_BITSTRING_STR("BitString[1,2,3]", bs); // There should be at least "kCapacity" # of checks here, 1 for each unique position. - EXPECT_EQ(MakeBitStringChar(/*idx*/0, /*val*/1u), bs[0]); - EXPECT_EQ(MakeBitStringChar(/*idx*/1, /*val*/2u), bs[1]); - EXPECT_EQ(MakeBitStringChar(/*idx*/2, /*val*/3u), bs[2]); + EXPECT_EQ(MakeBitStringChar(/*idx=*/0, /*val=*/1u), bs[0]); + EXPECT_EQ(MakeBitStringChar(/*idx=*/1, /*val=*/2u), bs[1]); + EXPECT_EQ(MakeBitStringChar(/*idx=*/2, /*val=*/3u), bs[2]); // Each maximal value should be tested here for each position. uint32_t max_bitstring_ints[] = { diff --git a/libartbase/base/bit_struct_test.cc b/libartbase/base/bit_struct_test.cc index 577682ccce..a2389ebfc7 100644 --- a/libartbase/base/bit_struct_test.cc +++ b/libartbase/base/bit_struct_test.cc @@ -73,7 +73,7 @@ struct CustomBitStruct { TEST(BitStructs, Custom) { CustomBitStruct expected(0b1111); - BitStructField<CustomBitStruct, /*lsb*/4, /*width*/4> f{}; + BitStructField<CustomBitStruct, /*lsb=*/4, /*width=*/4> f{}; EXPECT_EQ(1u, sizeof(f)); @@ -85,9 +85,9 @@ TEST(BitStructs, Custom) { EXPECT_EQ(AsUint(f), 0b11110000u); } -BITSTRUCT_DEFINE_START(TestTwoCustom, /* size */ 8) - BitStructField<CustomBitStruct, /*lsb*/0, /*width*/4> f4_a; - BitStructField<CustomBitStruct, /*lsb*/4, /*width*/4> f4_b; +BITSTRUCT_DEFINE_START(TestTwoCustom, /* size= */ 8) + BitStructField<CustomBitStruct, /*lsb=*/0, /*width=*/4> f4_a; + BitStructField<CustomBitStruct, /*lsb=*/4, /*width=*/4> f4_b; BITSTRUCT_DEFINE_END(TestTwoCustom); TEST(BitStructs, TwoCustom) { @@ -122,7 +122,7 @@ TEST(BitStructs, TwoCustom) { } TEST(BitStructs, Number) { - BitStructNumber<uint16_t, /*lsb*/4, /*width*/4> bsn{}; + BitStructNumber<uint16_t, /*lsb=*/4, /*width=*/4> bsn{}; EXPECT_EQ(2u, sizeof(bsn)); bsn = 0b1111; @@ -135,20 +135,20 @@ TEST(BitStructs, Number) { EXPECT_EQ(AsUint(bsn), 0b11110000u); } -BITSTRUCT_DEFINE_START(TestBitStruct, /* size */ 8) - BitStructInt</*lsb*/0, /*width*/3> i3; - BitStructUint</*lsb*/3, /*width*/4> u4; +BITSTRUCT_DEFINE_START(TestBitStruct, /* size= */ 8) + BitStructInt</*lsb=*/0, /*width=*/3> i3; + BitStructUint</*lsb=*/3, /*width=*/4> u4; - BitStructUint</*lsb*/0, /*width*/7> alias_all; + BitStructUint</*lsb=*/0, /*width=*/7> alias_all; BITSTRUCT_DEFINE_END(TestBitStruct); TEST(BitStructs, Test1) { { // Check minimal size selection is correct. - BitStructInt</*lsb*/0, /*width*/3> i3; - BitStructUint</*lsb*/3, /*width*/4> u4; + BitStructInt</*lsb=*/0, /*width=*/3> i3; + BitStructUint</*lsb=*/3, /*width=*/4> u4; - BitStructUint</*lsb*/0, /*width*/7> alias_all; + BitStructUint</*lsb=*/0, /*width=*/7> alias_all; EXPECT_EQ(1u, sizeof(i3)); EXPECT_EQ(1u, sizeof(u4)); @@ -216,12 +216,12 @@ TEST(BitStructs, Test1) { } } -BITSTRUCT_DEFINE_START(MixedSizeBitStruct, /* size */ 32) - BitStructUint</*lsb*/0, /*width*/3> u3; - BitStructUint</*lsb*/3, /*width*/10> u10; - BitStructUint</*lsb*/13, /*width*/19> u19; +BITSTRUCT_DEFINE_START(MixedSizeBitStruct, /* size= */ 32) + BitStructUint</*lsb=*/0, /*width=*/3> u3; + BitStructUint</*lsb=*/3, /*width=*/10> u10; + BitStructUint</*lsb=*/13, /*width=*/19> u19; - BitStructUint</*lsb*/0, /*width*/32> alias_all; + BitStructUint</*lsb=*/0, /*width=*/32> alias_all; BITSTRUCT_DEFINE_END(MixedSizeBitStruct); // static_assert(sizeof(MixedSizeBitStruct) == sizeof(uint32_t), "TestBitStructs#MixedSize"); @@ -255,11 +255,11 @@ TEST(BitStructs, Mixed) { EXPECT_EQ(0b10101010101010101011111010100111u, AsUint(tst)); } -BITSTRUCT_DEFINE_START(TestBitStruct_u8, /* size */ 8) - BitStructInt</*lsb*/0, /*width*/3> i3; - BitStructUint</*lsb*/3, /*width*/4> u4; +BITSTRUCT_DEFINE_START(TestBitStruct_u8, /* size= */ 8) + BitStructInt</*lsb=*/0, /*width=*/3> i3; + BitStructUint</*lsb=*/3, /*width=*/4> u4; - BitStructUint</*lsb*/0, /*width*/8> alias_all; + BitStructUint</*lsb=*/0, /*width=*/8> alias_all; BITSTRUCT_DEFINE_END(TestBitStruct_u8); TEST(BitStructs, FieldAssignment) { @@ -283,11 +283,11 @@ TEST(BitStructs, FieldAssignment) { } } -BITSTRUCT_DEFINE_START(NestedStruct, /* size */ 64) - BitStructField<MixedSizeBitStruct, /*lsb*/0> mixed_lower; - BitStructField<MixedSizeBitStruct, /*lsb*/32> mixed_upper; +BITSTRUCT_DEFINE_START(NestedStruct, /* size= */ 64) + BitStructField<MixedSizeBitStruct, /*lsb=*/0> mixed_lower; + BitStructField<MixedSizeBitStruct, /*lsb=*/32> mixed_upper; - BitStructUint</*lsb*/0, /*width*/64> alias_all; + BitStructUint</*lsb=*/0, /*width=*/64> alias_all; BITSTRUCT_DEFINE_END(NestedStruct); TEST(BitStructs, NestedFieldAssignment) { diff --git a/libartbase/base/bit_utils_test.cc b/libartbase/base/bit_utils_test.cc index 3a80600b57..91fc3b0bb9 100644 --- a/libartbase/base/bit_utils_test.cc +++ b/libartbase/base/bit_utils_test.cc @@ -353,89 +353,92 @@ static_assert(MaskLeastSignificant<int8_t>(8) == 0xFF, "TestMaskLeastSignificant static_assert(MaskLeastSignificant<uint64_t>(63) == (std::numeric_limits<uint64_t>::max() >> 1u), "TestMaskLeastSignificant#6"); -static_assert(BitFieldClear(0xFF, /*lsb*/0, /*width*/0) == 0xFF, "TestBitFieldClear#1"); -static_assert(BitFieldClear(std::numeric_limits<uint32_t>::max(), /*lsb*/0, /*width*/32) == 0x0, +static_assert(BitFieldClear(0xFF, /*lsb=*/0, /*width=*/0) == 0xFF, "TestBitFieldClear#1"); +static_assert(BitFieldClear(std::numeric_limits<uint32_t>::max(), /*lsb=*/0, /*width=*/32) == 0x0, "TestBitFieldClear#2"); -static_assert(BitFieldClear(std::numeric_limits<int32_t>::max(), /*lsb*/0, /*width*/32) == 0x0, +static_assert(BitFieldClear(std::numeric_limits<int32_t>::max(), /*lsb=*/0, /*width=*/32) == 0x0, "TestBitFieldClear#3"); -static_assert(BitFieldClear(0xFF, /*lsb*/0, /*width*/2) == 0b11111100, "TestBitFieldClear#4"); -static_assert(BitFieldClear(0xFF, /*lsb*/0, /*width*/3) == 0b11111000, "TestBitFieldClear#5"); -static_assert(BitFieldClear(0xFF, /*lsb*/1, /*width*/3) == 0b11110001, "TestBitFieldClear#6"); -static_assert(BitFieldClear(0xFF, /*lsb*/2, /*width*/3) == 0b11100011, "TestBitFieldClear#7"); +static_assert(BitFieldClear(0xFF, /*lsb=*/0, /*width=*/2) == 0b11111100, "TestBitFieldClear#4"); +static_assert(BitFieldClear(0xFF, /*lsb=*/0, /*width=*/3) == 0b11111000, "TestBitFieldClear#5"); +static_assert(BitFieldClear(0xFF, /*lsb=*/1, /*width=*/3) == 0b11110001, "TestBitFieldClear#6"); +static_assert(BitFieldClear(0xFF, /*lsb=*/2, /*width=*/3) == 0b11100011, "TestBitFieldClear#7"); -static_assert(BitFieldExtract(0xFF, /*lsb*/0, /*width*/0) == 0x0, "TestBitFieldExtract#1"); -static_assert(BitFieldExtract(std::numeric_limits<uint32_t>::max(), /*lsb*/0, /*width*/32) +static_assert(BitFieldExtract(0xFF, /*lsb=*/0, /*width=*/0) == 0x0, "TestBitFieldExtract#1"); +static_assert(BitFieldExtract(std::numeric_limits<uint32_t>::max(), /*lsb=*/0, /*width=*/32) == std::numeric_limits<uint32_t>::max(), "TestBitFieldExtract#2"); -static_assert(BitFieldExtract(std::numeric_limits<int32_t>::max(), /*lsb*/0, /*width*/32) +static_assert(BitFieldExtract(std::numeric_limits<int32_t>::max(), /*lsb=*/0, /*width=*/32) == std::numeric_limits<int32_t>::max(), "TestBitFieldExtract#3"); -static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/0, /*width*/2) == 0b00000011, +static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb=*/0, /*width=*/2) == 0b00000011, "TestBitFieldExtract#4"); -static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/0, /*width*/3) == 0b00000111, +static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb=*/0, /*width=*/3) == 0b00000111, "TestBitFieldExtract#5"); -static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/1, /*width*/3) == 0b00000111, +static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb=*/1, /*width=*/3) == 0b00000111, "TestBitFieldExtract#6"); -static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/2, /*width*/3) == 0b00000111, +static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb=*/2, /*width=*/3) == 0b00000111, "TestBitFieldExtract#7"); -static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/3, /*width*/3) == 0b00000111, +static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb=*/3, /*width=*/3) == 0b00000111, "TestBitFieldExtract#8"); -static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/8, /*width*/3) == 0b00000000, +static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb=*/8, /*width=*/3) == 0b00000000, "TestBitFieldExtract#9"); -static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/7, /*width*/3) == 0b00000001, +static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb=*/7, /*width=*/3) == 0b00000001, "TestBitFieldExtract#10"); -static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/6, /*width*/3) == 0b00000011, +static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb=*/6, /*width=*/3) == 0b00000011, "TestBitFieldExtract#11"); -static_assert(BitFieldExtract(0xFF, /*lsb*/0, /*width*/2) == -1, "TestBitFieldExtract#12"); -static_assert(BitFieldExtract(0xFF, /*lsb*/0, /*width*/3) == -1, "TestBitFieldExtract#13"); -static_assert(BitFieldExtract(0xFF, /*lsb*/1, /*width*/3) == -1, "TestBitFieldExtract#14"); -static_assert(BitFieldExtract(0xFF, /*lsb*/2, /*width*/3) == -1, "TestBitFieldExtract#15"); -static_assert(BitFieldExtract(0xFF, /*lsb*/3, /*width*/3) == -1, "TestBitFieldExtract#16"); -static_assert(BitFieldExtract(0xFF, /*lsb*/8, /*width*/3) == 0b00000000, "TestBitFieldExtract#17"); -static_assert(BitFieldExtract(0xFF, /*lsb*/7, /*width*/3) == 0b00000001, "TestBitFieldExtract#18"); -static_assert(BitFieldExtract(0xFF, /*lsb*/6, /*width*/3) == 0b00000011, "TestBitFieldExtract#19"); -static_assert(BitFieldExtract(static_cast<uint8_t>(0b01101010), /*lsb*/2, /*width*/4) +static_assert(BitFieldExtract(0xFF, /*lsb=*/0, /*width=*/2) == -1, "TestBitFieldExtract#12"); +static_assert(BitFieldExtract(0xFF, /*lsb=*/0, /*width=*/3) == -1, "TestBitFieldExtract#13"); +static_assert(BitFieldExtract(0xFF, /*lsb=*/1, /*width=*/3) == -1, "TestBitFieldExtract#14"); +static_assert(BitFieldExtract(0xFF, /*lsb=*/2, /*width=*/3) == -1, "TestBitFieldExtract#15"); +static_assert(BitFieldExtract(0xFF, /*lsb=*/3, /*width=*/3) == -1, "TestBitFieldExtract#16"); +static_assert(BitFieldExtract(0xFF, /*lsb=*/8, /*width=*/3) == 0b00000000, + "TestBitFieldExtract#17"); +static_assert(BitFieldExtract(0xFF, /*lsb=*/7, /*width=*/3) == 0b00000001, + "TestBitFieldExtract#18"); +static_assert(BitFieldExtract(0xFF, /*lsb=*/6, /*width=*/3) == 0b00000011, + "TestBitFieldExtract#19"); +static_assert(BitFieldExtract(static_cast<uint8_t>(0b01101010), /*lsb=*/2, /*width=*/4) == 0b00001010, "TestBitFieldExtract#20"); -static_assert(BitFieldExtract(static_cast<int8_t>(0b01101010), /*lsb*/2, /*width*/4) +static_assert(BitFieldExtract(static_cast<int8_t>(0b01101010), /*lsb=*/2, /*width=*/4) == static_cast<int8_t>(0b11111010), "TestBitFieldExtract#21"); -static_assert(BitFieldInsert(0xFF, /*data*/0x0, /*lsb*/0, /*width*/0) == 0xFF, +static_assert(BitFieldInsert(0xFF, /*data=*/0x0, /*lsb=*/0, /*width=*/0) == 0xFF, "TestBitFieldInsert#1"); static_assert(BitFieldInsert(std::numeric_limits<uint32_t>::max(), - /*data*/std::numeric_limits<uint32_t>::max(), - /*lsb*/0, - /*width*/32) + /*data=*/std::numeric_limits<uint32_t>::max(), + /*lsb=*/0, + /*width=*/32) == std::numeric_limits<uint32_t>::max(), "TestBitFieldInsert#2"); static_assert(BitFieldInsert(std::numeric_limits<int32_t>::max(), - /*data*/std::numeric_limits<uint32_t>::max(), - /*lsb*/0, - /*width*/32) + /*data=*/std::numeric_limits<uint32_t>::max(), + /*lsb=*/0, + /*width=*/32) == std::numeric_limits<uint32_t>::max(), "TestBitFieldInsert#3"); static_assert(BitFieldInsert(0u, - /*data*/std::numeric_limits<uint32_t>::max(), - /*lsb*/0, - /*width*/32) + /*data=*/std::numeric_limits<uint32_t>::max(), + /*lsb=*/0, + /*width=*/32) == std::numeric_limits<uint32_t>::max(), "TestBitFieldInsert#4"); static_assert(BitFieldInsert(-(-0), - /*data*/std::numeric_limits<uint32_t>::max(), - /*lsb*/0, - /*width*/32) + /*data=*/std::numeric_limits<uint32_t>::max(), + /*lsb=*/0, + /*width=*/32) == std::numeric_limits<uint32_t>::max(), "TestBitFieldInsert#5"); -static_assert(BitFieldInsert(0x00, /*data*/0b11u, /*lsb*/0, /*width*/2) == 0b00000011, +static_assert(BitFieldInsert(0x00, /*data=*/0b11u, /*lsb=*/0, /*width=*/2) == 0b00000011, "TestBitFieldInsert#6"); -static_assert(BitFieldInsert(0x00, /*data*/0b111u, /*lsb*/0, /*width*/3) == 0b00000111, +static_assert(BitFieldInsert(0x00, /*data=*/0b111u, /*lsb=*/0, /*width=*/3) == 0b00000111, "TestBitFieldInsert#7"); -static_assert(BitFieldInsert(0x00, /*data*/0b111u, /*lsb*/1, /*width*/3) == 0b00001110, +static_assert(BitFieldInsert(0x00, /*data=*/0b111u, /*lsb=*/1, /*width=*/3) == 0b00001110, "TestBitFieldInsert#8"); -static_assert(BitFieldInsert(0x00, /*data*/0b111u, /*lsb*/2, /*width*/3) == 0b00011100, +static_assert(BitFieldInsert(0x00, /*data=*/0b111u, /*lsb=*/2, /*width=*/3) == 0b00011100, "TestBitFieldInsert#9"); -static_assert(BitFieldInsert(0b01011100, /*data*/0b1101u, /*lsb*/4, /*width*/4) == 0b11011100, +static_assert(BitFieldInsert(0b01011100, /*data=*/0b1101u, /*lsb=*/4, /*width=*/4) == 0b11011100, "TestBitFieldInsert#10"); template <typename Container> diff --git a/libartbase/base/common_art_test.cc b/libartbase/base/common_art_test.cc index b65710bc00..9485fcaa0c 100644 --- a/libartbase/base/common_art_test.cc +++ b/libartbase/base/common_art_test.cc @@ -251,7 +251,7 @@ std::unique_ptr<const DexFile> CommonArtTestImpl::LoadExpectSingleDexFile(const static constexpr bool kVerifyChecksum = true; const ArtDexFileLoader dex_file_loader; if (!dex_file_loader.Open( - location, location, /* verify */ true, kVerifyChecksum, &error_msg, &dex_files)) { + location, location, /* verify= */ true, kVerifyChecksum, &error_msg, &dex_files)) { LOG(FATAL) << "Could not open .dex file '" << location << "': " << error_msg << "\n"; UNREACHABLE(); } else { diff --git a/libartbase/base/file_magic.cc b/libartbase/base/file_magic.cc index d8d843beeb..1471c59b73 100644 --- a/libartbase/base/file_magic.cc +++ b/libartbase/base/file_magic.cc @@ -31,7 +31,7 @@ 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); + File fd(filename, O_RDONLY, /* check_usage= */ false); if (fd.Fd() == -1) { *error_msg = StringPrintf("Unable to open '%s' : %s", filename, strerror(errno)); return File(); diff --git a/libartbase/base/file_utils_test.cc b/libartbase/base/file_utils_test.cc index 2a7273b85e..f7c9c5e264 100644 --- a/libartbase/base/file_utils_test.cc +++ b/libartbase/base/file_utils_test.cc @@ -71,12 +71,12 @@ TEST_F(FileUtilsTest, GetAndroidRootSafe) { // Set ANDROID_ROOT to something else (but the directory must exist). So use dirname. UniqueCPtr<char> root_dup(strdup(android_root_env.c_str())); char* dir = dirname(root_dup.get()); - ASSERT_EQ(0, setenv("ANDROID_ROOT", dir, 1 /* overwrite */)); + ASSERT_EQ(0, setenv("ANDROID_ROOT", dir, /* overwrite */ 1)); std::string android_root2 = GetAndroidRootSafe(&error_msg); EXPECT_STREQ(dir, android_root2.c_str()); // Set a bogus value for ANDROID_ROOT. This should be an error. - ASSERT_EQ(0, setenv("ANDROID_ROOT", "/this/is/obviously/bogus", 1 /* overwrite */)); + ASSERT_EQ(0, setenv("ANDROID_ROOT", "/this/is/obviously/bogus", /* overwrite */ 1)); EXPECT_EQ(GetAndroidRootSafe(&error_msg), ""); // Unset ANDROID_ROOT and see that it still returns something (as libart code is running). @@ -90,7 +90,7 @@ TEST_F(FileUtilsTest, GetAndroidRootSafe) { // Reset ANDROID_ROOT, as other things may depend on it. - ASSERT_EQ(0, setenv("ANDROID_ROOT", android_root_env.c_str(), 1 /* overwrite */)); + ASSERT_EQ(0, setenv("ANDROID_ROOT", android_root_env.c_str(), /* overwrite */ 1)); } TEST_F(FileUtilsTest, ReplaceFileExtension) { diff --git a/libartbase/base/mem_map.cc b/libartbase/base/mem_map.cc index 06a168d761..532ca28b50 100644 --- a/libartbase/base/mem_map.cc +++ b/libartbase/base/mem_map.cc @@ -394,7 +394,7 @@ MemMap MemMap::MapDummy(const char* name, uint8_t* addr, size_t byte_count) { return Invalid(); } const size_t page_aligned_byte_count = RoundUp(byte_count, kPageSize); - return MemMap(name, addr, byte_count, addr, page_aligned_byte_count, 0, true /* reuse */); + return MemMap(name, addr, byte_count, addr, page_aligned_byte_count, 0, /* reuse= */ true); } template<typename A, typename B> @@ -696,8 +696,8 @@ MemMap MemMap::RemapAtEnd(uint8_t* new_end, tail_name, tail_prot, MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, - /* fd */ -1, - /* offset */ 0, + /* fd= */ -1, + /* offset= */ 0, error_msg, use_debug_name); } @@ -771,7 +771,7 @@ MemMap MemMap::TakeReservedMemory(size_t byte_count) { uint8_t* begin = Begin(); ReleaseReservedMemory(byte_count); // Performs necessary DCHECK()s on this reservation. size_t base_size = RoundUp(byte_count, kPageSize); - return MemMap(name_, begin, byte_count, begin, base_size, prot_, /* reuse */ false); + return MemMap(name_, begin, byte_count, begin, base_size, prot_, /* reuse= */ false); } void MemMap::ReleaseReservedMemory(size_t byte_count) { diff --git a/libartbase/base/mem_map_test.cc b/libartbase/base/mem_map_test.cc index bf143d472d..5815cf99e7 100644 --- a/libartbase/base/mem_map_test.cc +++ b/libartbase/base/mem_map_test.cc @@ -53,7 +53,7 @@ class MemMapTest : public CommonArtTest { // Find a valid map address and unmap it before returning. std::string error_msg; MemMap map = MemMap::MapAnonymous("temp", - /* addr */ nullptr, + /* addr= */ nullptr, size, PROT_READ, low_4gb, @@ -68,7 +68,7 @@ class MemMapTest : public CommonArtTest { const size_t page_size = static_cast<size_t>(kPageSize); // Map a two-page memory region. MemMap m0 = MemMap::MapAnonymous("MemMapTest_RemapAtEndTest_map0", - /* addr */ nullptr, + /* addr= */ nullptr, 2 * page_size, PROT_READ | PROT_WRITE, low_4gb, @@ -165,17 +165,17 @@ TEST_F(MemMapTest, Start) { TEST_F(MemMapTest, ReplaceMapping_SameSize) { std::string error_msg; MemMap dest = MemMap::MapAnonymous("MapAnonymousEmpty-atomic-replace-dest", - /* addr */ nullptr, + /* addr= */ nullptr, kPageSize, PROT_READ, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_TRUE(dest.IsValid()); MemMap source = MemMap::MapAnonymous("MapAnonymous-atomic-replace-source", - /* addr */ nullptr, + /* addr= */ nullptr, kPageSize, PROT_WRITE | PROT_READ, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_TRUE(source.IsValid()); void* source_addr = source.Begin(); @@ -200,21 +200,21 @@ TEST_F(MemMapTest, ReplaceMapping_SameSize) { TEST_F(MemMapTest, ReplaceMapping_MakeLarger) { std::string error_msg; MemMap dest = MemMap::MapAnonymous("MapAnonymousEmpty-atomic-replace-dest", - /* addr */ nullptr, + /* addr= */ nullptr, 5 * kPageSize, // Need to make it larger // initially so we know // there won't be mappings // in the way we we move // source. PROT_READ, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_TRUE(dest.IsValid()); MemMap source = MemMap::MapAnonymous("MapAnonymous-atomic-replace-source", - /* addr */ nullptr, + /* addr= */ nullptr, 3 * kPageSize, PROT_WRITE | PROT_READ, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_TRUE(source.IsValid()); uint8_t* source_addr = source.Begin(); @@ -246,17 +246,17 @@ TEST_F(MemMapTest, ReplaceMapping_MakeLarger) { TEST_F(MemMapTest, ReplaceMapping_MakeSmaller) { std::string error_msg; MemMap dest = MemMap::MapAnonymous("MapAnonymousEmpty-atomic-replace-dest", - /* addr */ nullptr, + /* addr= */ nullptr, 3 * kPageSize, PROT_READ, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_TRUE(dest.IsValid()); MemMap source = MemMap::MapAnonymous("MapAnonymous-atomic-replace-source", - /* addr */ nullptr, + /* addr= */ nullptr, kPageSize, PROT_WRITE | PROT_READ, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_TRUE(source.IsValid()); uint8_t* source_addr = source.Begin(); @@ -285,11 +285,11 @@ TEST_F(MemMapTest, ReplaceMapping_FailureOverlap) { MemMap dest = MemMap::MapAnonymous( "MapAnonymousEmpty-atomic-replace-dest", - /* addr */ nullptr, + /* addr= */ nullptr, 3 * kPageSize, // Need to make it larger initially so we know there won't be mappings in // the way we we move source. PROT_READ | PROT_WRITE, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_TRUE(dest.IsValid()); // Resize down to 1 page so we can remap the rest. @@ -299,7 +299,7 @@ TEST_F(MemMapTest, ReplaceMapping_FailureOverlap) { dest.Begin() + kPageSize, 2 * kPageSize, PROT_WRITE | PROT_READ, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_TRUE(source.IsValid()); ASSERT_EQ(dest.Begin() + kPageSize, source.Begin()); @@ -332,20 +332,20 @@ TEST_F(MemMapTest, MapAnonymousEmpty) { CommonInit(); std::string error_msg; MemMap map = MemMap::MapAnonymous("MapAnonymousEmpty", - /* addr */ nullptr, + /* addr= */ nullptr, 0, PROT_READ, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_FALSE(map.IsValid()) << error_msg; ASSERT_FALSE(error_msg.empty()); error_msg.clear(); map = MemMap::MapAnonymous("MapAnonymousNonEmpty", - /* addr */ nullptr, + /* addr= */ nullptr, kPageSize, PROT_READ | PROT_WRITE, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_TRUE(map.IsValid()) << error_msg; ASSERT_TRUE(error_msg.empty()); @@ -358,7 +358,7 @@ TEST_F(MemMapTest, MapAnonymousFailNullError) { reinterpret_cast<uint8_t*>(kPageSize), 0x20000, PROT_READ | PROT_WRITE, - /* low_4gb */ false, + /* low_4gb= */ false, nullptr); ASSERT_FALSE(map.IsValid()); } @@ -368,20 +368,20 @@ TEST_F(MemMapTest, MapAnonymousEmpty32bit) { CommonInit(); std::string error_msg; MemMap map = MemMap::MapAnonymous("MapAnonymousEmpty", - /* addr */ nullptr, + /* addr= */ nullptr, 0, PROT_READ, - /* low_4gb */ true, + /* low_4gb= */ true, &error_msg); ASSERT_FALSE(map.IsValid()) << error_msg; ASSERT_FALSE(error_msg.empty()); error_msg.clear(); map = MemMap::MapAnonymous("MapAnonymousNonEmpty", - /* addr */ nullptr, + /* addr= */ nullptr, kPageSize, PROT_READ | PROT_WRITE, - /* low_4gb */ true, + /* low_4gb= */ true, &error_msg); ASSERT_TRUE(map.IsValid()) << error_msg; ASSERT_TRUE(error_msg.empty()); @@ -394,12 +394,12 @@ TEST_F(MemMapTest, MapFile32Bit) { constexpr size_t kMapSize = kPageSize; std::unique_ptr<uint8_t[]> data(new uint8_t[kMapSize]()); ASSERT_TRUE(scratch_file.GetFile()->WriteFully(&data[0], kMapSize)); - MemMap map = MemMap::MapFile(/*byte_count*/kMapSize, + MemMap map = MemMap::MapFile(/*byte_count=*/kMapSize, PROT_READ, MAP_PRIVATE, scratch_file.GetFd(), - /*start*/0, - /*low_4gb*/true, + /*start=*/0, + /*low_4gb=*/true, scratch_file.GetFilename().c_str(), &error_msg); ASSERT_TRUE(map.IsValid()) << error_msg; @@ -413,23 +413,23 @@ TEST_F(MemMapTest, MapAnonymousExactAddr) { CommonInit(); std::string error_msg; // Find a valid address. - uint8_t* valid_address = GetValidMapAddress(kPageSize, /*low_4gb*/false); + uint8_t* valid_address = GetValidMapAddress(kPageSize, /*low_4gb=*/false); // Map at an address that should work, which should succeed. MemMap map0 = MemMap::MapAnonymous("MapAnonymous0", valid_address, kPageSize, PROT_READ | PROT_WRITE, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_TRUE(map0.IsValid()) << error_msg; ASSERT_TRUE(error_msg.empty()); ASSERT_TRUE(map0.BaseBegin() == valid_address); // Map at an unspecified address, which should succeed. MemMap map1 = MemMap::MapAnonymous("MapAnonymous1", - /* addr */ nullptr, + /* addr= */ nullptr, kPageSize, PROT_READ | PROT_WRITE, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_TRUE(map1.IsValid()) << error_msg; ASSERT_TRUE(error_msg.empty()); @@ -439,7 +439,7 @@ TEST_F(MemMapTest, MapAnonymousExactAddr) { reinterpret_cast<uint8_t*>(map1.BaseBegin()), kPageSize, PROT_READ | PROT_WRITE, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_FALSE(map2.IsValid()) << error_msg; ASSERT_TRUE(!error_msg.empty()); @@ -469,12 +469,12 @@ TEST_F(MemMapTest, RemapFileViewAtEnd) { memset(&data[2 * kPageSize], 0xaa, kPageSize); ASSERT_TRUE(scratch_file.GetFile()->WriteFully(&data[0], kMapSize)); - MemMap map = MemMap::MapFile(/*byte_count*/kMapSize, + MemMap map = MemMap::MapFile(/*byte_count=*/kMapSize, PROT_READ, MAP_PRIVATE, scratch_file.GetFd(), - /*start*/0, - /*low_4gb*/true, + /*start=*/0, + /*low_4gb=*/true, scratch_file.GetFilename().c_str(), &error_msg); ASSERT_TRUE(map.IsValid()) << error_msg; @@ -522,7 +522,7 @@ TEST_F(MemMapTest, MapAnonymousExactAddr32bitHighAddr) { reinterpret_cast<uint8_t*>(start_addr), size, PROT_READ | PROT_WRITE, - /*low_4gb*/ true, + /*low_4gb=*/ true, &error_msg); if (map.IsValid()) { break; @@ -543,7 +543,7 @@ TEST_F(MemMapTest, MapAnonymousOverflow) { reinterpret_cast<uint8_t*>(ptr), 2 * kPageSize, // brings it over the top. PROT_READ | PROT_WRITE, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_FALSE(map.IsValid()); ASSERT_FALSE(error_msg.empty()); @@ -558,7 +558,7 @@ TEST_F(MemMapTest, MapAnonymousLow4GBExpectedTooHigh) { reinterpret_cast<uint8_t*>(UINT64_C(0x100000000)), kPageSize, PROT_READ | PROT_WRITE, - /* low_4gb */ true, + /* low_4gb= */ true, &error_msg); ASSERT_FALSE(map.IsValid()); ASSERT_FALSE(error_msg.empty()); @@ -571,7 +571,7 @@ TEST_F(MemMapTest, MapAnonymousLow4GBRangeTooHigh) { reinterpret_cast<uint8_t*>(0xF0000000), 0x20000000, PROT_READ | PROT_WRITE, - /* low_4gb */ true, + /* low_4gb= */ true, &error_msg); ASSERT_FALSE(map.IsValid()); ASSERT_FALSE(error_msg.empty()); @@ -585,9 +585,9 @@ TEST_F(MemMapTest, MapAnonymousReuse) { nullptr, 0x20000, PROT_READ | PROT_WRITE, - /* low_4gb */ false, - /* reuse */ false, - /* reservation */ nullptr, + /* low_4gb= */ false, + /* reuse= */ false, + /* reservation= */ nullptr, &error_msg); ASSERT_TRUE(map.IsValid()); ASSERT_TRUE(error_msg.empty()); @@ -595,9 +595,9 @@ TEST_F(MemMapTest, MapAnonymousReuse) { reinterpret_cast<uint8_t*>(map.BaseBegin()), 0x10000, PROT_READ | PROT_WRITE, - /* low_4gb */ false, - /* reuse */ true, - /* reservation */ nullptr, + /* low_4gb= */ false, + /* reuse= */ true, + /* reservation= */ nullptr, &error_msg); ASSERT_TRUE(map2.IsValid()); ASSERT_TRUE(error_msg.empty()); @@ -609,10 +609,10 @@ TEST_F(MemMapTest, CheckNoGaps) { constexpr size_t kNumPages = 3; // Map a 3-page mem map. MemMap map = MemMap::MapAnonymous("MapAnonymous0", - /* addr */ nullptr, + /* addr= */ nullptr, kPageSize * kNumPages, PROT_READ | PROT_WRITE, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_TRUE(map.IsValid()) << error_msg; ASSERT_TRUE(error_msg.empty()); @@ -627,7 +627,7 @@ TEST_F(MemMapTest, CheckNoGaps) { map_base, kPageSize, PROT_READ | PROT_WRITE, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_TRUE(map0.IsValid()) << error_msg; ASSERT_TRUE(error_msg.empty()); @@ -635,7 +635,7 @@ TEST_F(MemMapTest, CheckNoGaps) { map_base + kPageSize, kPageSize, PROT_READ | PROT_WRITE, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_TRUE(map1.IsValid()) << error_msg; ASSERT_TRUE(error_msg.empty()); @@ -643,7 +643,7 @@ TEST_F(MemMapTest, CheckNoGaps) { map_base + kPageSize * 2, kPageSize, PROT_READ | PROT_WRITE, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_TRUE(map2.IsValid()) << error_msg; ASSERT_TRUE(error_msg.empty()); @@ -672,10 +672,10 @@ TEST_F(MemMapTest, AlignBy) { const size_t page_size = static_cast<size_t>(kPageSize); // Map a region. MemMap m0 = MemMap::MapAnonymous("MemMapTest_AlignByTest_map0", - /* addr */ nullptr, + /* addr= */ nullptr, 14 * page_size, PROT_READ | PROT_WRITE, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_TRUE(m0.IsValid()); uint8_t* base0 = m0.Begin(); @@ -778,10 +778,10 @@ TEST_F(MemMapTest, Reservation) { ASSERT_TRUE(scratch_file.GetFile()->WriteFully(&data[0], kMapSize)); MemMap reservation = MemMap::MapAnonymous("Test reservation", - /* addr */ nullptr, + /* addr= */ nullptr, kMapSize, PROT_NONE, - /* low_4gb */ false, + /* low_4gb= */ false, &error_msg); ASSERT_TRUE(reservation.IsValid()); ASSERT_TRUE(error_msg.empty()); @@ -791,14 +791,14 @@ TEST_F(MemMapTest, Reservation) { static_assert(kChunk1Size < kMapSize, "We want to split the reservation."); uint8_t* addr1 = reservation.Begin(); MemMap map1 = MemMap::MapFileAtAddress(addr1, - /* byte_count */ kChunk1Size, + /* byte_count= */ kChunk1Size, PROT_READ, MAP_PRIVATE, scratch_file.GetFd(), - /* start */ 0, - /* low_4gb */ false, + /* start= */ 0, + /* low_4gb= */ false, scratch_file.GetFilename().c_str(), - /* reuse */ false, + /* reuse= */ false, &reservation, &error_msg); ASSERT_TRUE(map1.IsValid()) << error_msg; @@ -816,10 +816,10 @@ TEST_F(MemMapTest, Reservation) { uint8_t* addr2 = reservation.Begin(); MemMap map2 = MemMap::MapAnonymous("MiddleReservation", addr2, - /* byte_count */ kChunk2Size, + /* byte_count= */ kChunk2Size, PROT_READ, - /* low_4gb */ false, - /* reuse */ false, + /* low_4gb= */ false, + /* reuse= */ false, &reservation, &error_msg); ASSERT_TRUE(map2.IsValid()) << error_msg; @@ -833,14 +833,14 @@ TEST_F(MemMapTest, Reservation) { const size_t kChunk3Size = reservation.Size() - 1u; uint8_t* addr3 = reservation.Begin(); MemMap map3 = MemMap::MapFileAtAddress(addr3, - /* byte_count */ kChunk3Size, + /* byte_count= */ kChunk3Size, PROT_READ, MAP_PRIVATE, scratch_file.GetFd(), - /* start */ dchecked_integral_cast<size_t>(addr3 - addr1), - /* low_4gb */ false, + /* start= */ dchecked_integral_cast<size_t>(addr3 - addr1), + /* low_4gb= */ false, scratch_file.GetFilename().c_str(), - /* reuse */ false, + /* reuse= */ false, &reservation, &error_msg); ASSERT_TRUE(map3.IsValid()) << error_msg; diff --git a/libartbase/base/scoped_flock.cc b/libartbase/base/scoped_flock.cc index d679328cef..beee501986 100644 --- a/libartbase/base/scoped_flock.cc +++ b/libartbase/base/scoped_flock.cc @@ -40,7 +40,7 @@ using android::base::StringPrintf; // to acquire a lock, and the unlock / close in the corresponding // destructor. Callers should explicitly flush files they're writing to if // that is the desired behaviour. - std::unique_ptr<File> file(OS::OpenFileWithFlags(filename, flags, false /* check_usage */)); + std::unique_ptr<File> file(OS::OpenFileWithFlags(filename, flags, /* auto_flush= */ false)); if (file.get() == nullptr) { *error_msg = StringPrintf("Failed to open file '%s': %s", filename, strerror(errno)); return nullptr; @@ -98,7 +98,7 @@ ScopedFlock LockedFile::DupOf(const int fd, const std::string& path, // destructor. Callers should explicitly flush files they're writing to if // that is the desired behaviour. ScopedFlock locked_file( - new LockedFile(dup(fd), path, false /* check_usage */, read_only_mode)); + new LockedFile(dup(fd), path, /* check_usage= */ false, read_only_mode)); if (locked_file->Fd() == -1) { *error_msg = StringPrintf("Failed to duplicate open file '%s': %s", locked_file->GetPath().c_str(), strerror(errno)); diff --git a/libartbase/base/scoped_flock_test.cc b/libartbase/base/scoped_flock_test.cc index f9ac1e0230..22356cd096 100644 --- a/libartbase/base/scoped_flock_test.cc +++ b/libartbase/base/scoped_flock_test.cc @@ -38,7 +38,7 @@ TEST_F(ScopedFlockTest, TestLocking) { // Attempt to acquire a second lock on the same file. This must fail. ScopedFlock second_lock = LockedFile::Open(scratch_file.GetFilename().c_str(), O_RDONLY, - /* block */ false, + /* block= */ false, &error_msg); ASSERT_TRUE(second_lock.get() == nullptr); ASSERT_TRUE(!error_msg.empty()); diff --git a/libartbase/base/zip_archive.cc b/libartbase/base/zip_archive.cc index 174d22792a..f5761cfbec 100644 --- a/libartbase/base/zip_archive.cc +++ b/libartbase/base/zip_archive.cc @@ -75,10 +75,10 @@ MemMap ZipEntry::ExtractToMemMap(const char* zip_filename, name += " extracted in memory from "; name += zip_filename; MemMap map = MemMap::MapAnonymous(name.c_str(), - /* addr */ nullptr, + /* addr= */ nullptr, GetUncompressedLength(), PROT_READ | PROT_WRITE, - /* low_4gb */ false, + /* low_4gb= */ false, error_msg); if (!map.IsValid()) { DCHECK(!error_msg->empty()); @@ -138,7 +138,7 @@ MemMap ZipEntry::MapDirectlyFromFile(const char* zip_filename, std::string* erro MAP_PRIVATE, zip_fd, offset, - /* low_4gb */ false, + /* low_4gb= */ false, name.c_str(), error_msg); diff --git a/libdexfile/dex/art_dex_file_loader.cc b/libdexfile/dex/art_dex_file_loader.cc index 4f73967353..20a519bf99 100644 --- a/libdexfile/dex/art_dex_file_loader.cc +++ b/libdexfile/dex/art_dex_file_loader.cc @@ -95,7 +95,7 @@ bool ArtDexFileLoader::GetMultiDexChecksums(const char* filename, File fd; if (zip_fd != -1) { if (ReadMagicAndReset(zip_fd, &magic, error_msg)) { - fd = File(DupCloexec(zip_fd), false /* check_usage */); + fd = File(DupCloexec(zip_fd), /* check_usage= */ false); } } else { fd = OpenAndReadMagic(filename, &magic, error_msg); @@ -142,9 +142,9 @@ bool ArtDexFileLoader::GetMultiDexChecksums(const char* filename, if (IsMagicValid(magic)) { std::unique_ptr<const DexFile> dex_file(OpenFile(fd.Release(), filename, - /* verify */ false, - /* verify_checksum */ false, - /* mmap_shared */ false, + /* verify= */ false, + /* verify_checksum= */ false, + /* mmap_shared= */ false, error_msg)); if (dex_file == nullptr) { return false; @@ -167,16 +167,16 @@ std::unique_ptr<const DexFile> ArtDexFileLoader::Open(const uint8_t* base, ScopedTrace trace(std::string("Open dex file from RAM ") + location); return OpenCommon(base, size, - /*data_base*/ nullptr, - /*data_size*/ 0u, + /*data_base=*/ nullptr, + /*data_size=*/ 0u, location, location_checksum, oat_dex_file, verify, verify_checksum, error_msg, - /*container*/ nullptr, - /*verify_result*/ nullptr); + /*container=*/ nullptr, + /*verify_result=*/ nullptr); } std::unique_ptr<const DexFile> ArtDexFileLoader::Open(const std::string& location, @@ -199,8 +199,8 @@ std::unique_ptr<const DexFile> ArtDexFileLoader::Open(const std::string& locatio uint8_t* begin = map.Begin(); std::unique_ptr<DexFile> dex_file = OpenCommon(begin, size, - /*data_base*/ nullptr, - /*data_size*/ 0u, + /*data_base=*/ nullptr, + /*data_size=*/ 0u, location, location_checksum, kNoOatDexFile, @@ -208,7 +208,7 @@ std::unique_ptr<const DexFile> ArtDexFileLoader::Open(const std::string& locatio verify_checksum, error_msg, std::make_unique<MemMapContainer>(std::move(map)), - /*verify_result*/ nullptr); + /*verify_result=*/ nullptr); // Opening CompactDex is only supported from vdex files. if (dex_file != nullptr && dex_file->IsCompactDexFile()) { *error_msg = StringPrintf("Opening CompactDex file '%s' is only supported from vdex files", @@ -240,7 +240,7 @@ bool ArtDexFileLoader::Open(const char* filename, location, verify, verify_checksum, - /* mmap_shared */ false, + /* mmap_shared= */ false, error_msg)); if (dex_file.get() != nullptr) { dex_files->push_back(std::move(dex_file)); @@ -290,7 +290,7 @@ std::unique_ptr<const DexFile> ArtDexFileLoader::OpenFile(int fd, CHECK(!location.empty()); MemMap map; { - File delayed_close(fd, /* check_usage */ false); + File delayed_close(fd, /* check_usage= */ false); struct stat sbuf; memset(&sbuf, 0, sizeof(sbuf)); if (fstat(fd, &sbuf) == -1) { @@ -308,7 +308,7 @@ std::unique_ptr<const DexFile> ArtDexFileLoader::OpenFile(int fd, mmap_shared ? MAP_SHARED : MAP_PRIVATE, fd, 0, - /*low_4gb*/false, + /*low_4gb=*/false, location.c_str(), error_msg); if (!map.IsValid()) { @@ -330,8 +330,8 @@ std::unique_ptr<const DexFile> ArtDexFileLoader::OpenFile(int fd, std::unique_ptr<DexFile> dex_file = OpenCommon(begin, size, - /*data_base*/ nullptr, - /*data_size*/ 0u, + /*data_base=*/ nullptr, + /*data_size=*/ 0u, location, dex_header->checksum_, kNoOatDexFile, @@ -339,7 +339,7 @@ std::unique_ptr<const DexFile> ArtDexFileLoader::OpenFile(int fd, verify_checksum, error_msg, std::make_unique<MemMapContainer>(std::move(map)), - /*verify_result*/ nullptr); + /*verify_result=*/ nullptr); // Opening CompactDex is only supported from vdex files. if (dex_file != nullptr && dex_file->IsCompactDexFile()) { @@ -407,8 +407,8 @@ std::unique_ptr<const DexFile> ArtDexFileLoader::OpenOneDexFileFromZip( size_t size = map.Size(); std::unique_ptr<DexFile> dex_file = OpenCommon(begin, size, - /*data_base*/ nullptr, - /*data_size*/ 0u, + /*data_base=*/ nullptr, + /*data_size=*/ 0u, location, zip_entry->GetCrc32(), kNoOatDexFile, diff --git a/libdexfile/dex/art_dex_file_loader_test.cc b/libdexfile/dex/art_dex_file_loader_test.cc index a7d03637b1..f7a20629f5 100644 --- a/libdexfile/dex/art_dex_file_loader_test.cc +++ b/libdexfile/dex/art_dex_file_loader_test.cc @@ -217,9 +217,9 @@ TEST_F(ArtDexFileLoaderTest, GetMethodSignature) { std::string plain_method = std::string("GetMethodSignature.") + r.name; ASSERT_EQ(plain_method, - raw->PrettyMethod(cur_method->GetIndex(), /* with_signature */ false)); + raw->PrettyMethod(cur_method->GetIndex(), /* with_signature= */ false)); ASSERT_EQ(r.pretty_method, - raw->PrettyMethod(cur_method->GetIndex(), /* with_signature */ true)); + raw->PrettyMethod(cur_method->GetIndex(), /* with_signature= */ true)); } } @@ -332,8 +332,8 @@ TEST_F(ArtDexFileLoaderTest, IsPlatformDexFile_DataDir) { std::string error_msg; bool success = loader.Open(data_location_path.c_str(), data_location_path, - /* verify */ false, - /* verify_checksum */ false, + /* verify= */ false, + /* verify_checksum= */ false, &error_msg, &dex_files); ASSERT_TRUE(success) << error_msg; @@ -360,8 +360,8 @@ TEST_F(ArtDexFileLoaderTest, IsPlatformDexFile_SystemDir) { std::string error_msg; bool success = loader.Open(system_location_path.c_str(), system_location_path, - /* verify */ false, - /* verify_checksum */ false, + /* verify= */ false, + /* verify_checksum= */ false, &error_msg, &dex_files); ASSERT_TRUE(success) << error_msg; @@ -388,8 +388,8 @@ TEST_F(ArtDexFileLoaderTest, IsPlatformDexFile_SystemFrameworkDir) { std::string error_msg; bool success = loader.Open(system_framework_location_path.c_str(), system_framework_location_path, - /* verify */ false, - /* verify_checksum */ false, + /* verify= */ false, + /* verify_checksum= */ false, &error_msg, &dex_files); ASSERT_TRUE(success) << error_msg; @@ -416,8 +416,8 @@ TEST_F(ArtDexFileLoaderTest, IsPlatformDexFile_DataDir_MultiDex) { std::string error_msg; bool success = loader.Open(data_multi_location_path.c_str(), data_multi_location_path, - /* verify */ false, - /* verify_checksum */ false, + /* verify= */ false, + /* verify_checksum= */ false, &error_msg, &dex_files); ASSERT_TRUE(success) << error_msg; @@ -445,8 +445,8 @@ TEST_F(ArtDexFileLoaderTest, IsPlatformDexFile_SystemDir_MultiDex) { std::string error_msg; bool success = loader.Open(system_multi_location_path.c_str(), system_multi_location_path, - /* verify */ false, - /* verify_checksum */ false, + /* verify= */ false, + /* verify_checksum= */ false, &error_msg, &dex_files); ASSERT_TRUE(success) << error_msg; @@ -474,8 +474,8 @@ TEST_F(ArtDexFileLoaderTest, IsPlatformDexFile_SystemFrameworkDir_MultiDex) { std::string error_msg; bool success = loader.Open(system_framework_multi_location_path.c_str(), system_framework_multi_location_path, - /* verify */ false, - /* verify_checksum */ false, + /* verify= */ false, + /* verify_checksum= */ false, &error_msg, &dex_files); ASSERT_TRUE(success) << error_msg; diff --git a/libdexfile/dex/code_item_accessors_test.cc b/libdexfile/dex/code_item_accessors_test.cc index 2bb4dde649..87f4bab672 100644 --- a/libdexfile/dex/code_item_accessors_test.cc +++ b/libdexfile/dex/code_item_accessors_test.cc @@ -45,10 +45,10 @@ std::unique_ptr<const DexFile> CreateFakeDex(bool compact_dex, std::vector<uint8 std::unique_ptr<const DexFile> dex(dex_file_loader.Open(data->data(), data->size(), "location", - /*location_checksum*/ 123, - /*oat_dex_file*/nullptr, - /*verify*/false, - /*verify_checksum*/false, + /*location_checksum=*/ 123, + /*oat_dex_file=*/nullptr, + /*verify=*/false, + /*verify_checksum=*/false, &error_msg)); CHECK(dex != nullptr) << error_msg; return dex; @@ -56,11 +56,11 @@ std::unique_ptr<const DexFile> CreateFakeDex(bool compact_dex, std::vector<uint8 TEST(CodeItemAccessorsTest, TestDexInstructionsAccessor) { std::vector<uint8_t> standard_dex_data; - std::unique_ptr<const DexFile> standard_dex(CreateFakeDex(/*compact_dex*/false, + std::unique_ptr<const DexFile> standard_dex(CreateFakeDex(/*compact_dex=*/false, &standard_dex_data)); ASSERT_TRUE(standard_dex != nullptr); std::vector<uint8_t> compact_dex_data; - std::unique_ptr<const DexFile> compact_dex(CreateFakeDex(/*compact_dex*/true, + std::unique_ptr<const DexFile> compact_dex(CreateFakeDex(/*compact_dex=*/true, &compact_dex_data)); ASSERT_TRUE(compact_dex != nullptr); static constexpr uint16_t kRegisterSize = 2; diff --git a/libdexfile/dex/compact_dex_file.cc b/libdexfile/dex/compact_dex_file.cc index 302b59ee91..641c523158 100644 --- a/libdexfile/dex/compact_dex_file.cc +++ b/libdexfile/dex/compact_dex_file.cc @@ -100,7 +100,7 @@ CompactDexFile::CompactDexFile(const uint8_t* base, location_checksum, oat_dex_file, std::move(container), - /*is_compact_dex*/ true), + /*is_compact_dex=*/ true), debug_info_offsets_(DataBegin() + GetHeader().debug_info_offsets_pos_, GetHeader().debug_info_base_, GetHeader().debug_info_offsets_table_offset_) {} diff --git a/libdexfile/dex/compact_dex_file_test.cc b/libdexfile/dex/compact_dex_file_test.cc index 517c5873ed..799967e255 100644 --- a/libdexfile/dex/compact_dex_file_test.cc +++ b/libdexfile/dex/compact_dex_file_test.cc @@ -68,11 +68,11 @@ TEST(CompactDexFileTest, CodeItemFields) { uint16_t out_outs_size; uint16_t out_tries_size; uint32_t out_insns_size_in_code_units; - code_item->DecodeFields</*kDecodeOnlyInstructionCount*/false>(&out_insns_size_in_code_units, - &out_registers_size, - &out_ins_size, - &out_outs_size, - &out_tries_size); + code_item->DecodeFields</*kDecodeOnlyInstructionCount=*/false>(&out_insns_size_in_code_units, + &out_registers_size, + &out_ins_size, + &out_outs_size, + &out_tries_size); ASSERT_EQ(registers_size, out_registers_size); ASSERT_EQ(ins_size, out_ins_size); ASSERT_EQ(outs_size, out_outs_size); @@ -80,11 +80,11 @@ TEST(CompactDexFileTest, CodeItemFields) { ASSERT_EQ(insns_size_in_code_units, out_insns_size_in_code_units); ++out_insns_size_in_code_units; // Force value to change. - code_item->DecodeFields</*kDecodeOnlyInstructionCount*/true>(&out_insns_size_in_code_units, - /*registers_size*/ nullptr, - /*ins_size*/ nullptr, - /*outs_size*/ nullptr, - /*tries_size*/ nullptr); + code_item->DecodeFields</*kDecodeOnlyInstructionCount=*/true>(&out_insns_size_in_code_units, + /*registers_size=*/ nullptr, + /*ins_size=*/ nullptr, + /*outs_size=*/ nullptr, + /*tries_size=*/ nullptr); ASSERT_EQ(insns_size_in_code_units, out_insns_size_in_code_units); }; static constexpr uint32_t kMax32 = std::numeric_limits<uint32_t>::max(); diff --git a/libdexfile/dex/dex_file_loader.cc b/libdexfile/dex/dex_file_loader.cc index 4aafc665ee..3667c8c289 100644 --- a/libdexfile/dex/dex_file_loader.cc +++ b/libdexfile/dex/dex_file_loader.cc @@ -222,16 +222,16 @@ std::unique_ptr<const DexFile> DexFileLoader::Open(const uint8_t* base, std::string* error_msg) const { return OpenCommon(base, size, - /*data_base*/ nullptr, - /*data_size*/ 0, + /*data_base=*/ nullptr, + /*data_size=*/ 0, location, location_checksum, oat_dex_file, verify, verify_checksum, error_msg, - /*container*/ nullptr, - /*verify_result*/ nullptr); + /*container=*/ nullptr, + /*verify_result=*/ nullptr); } std::unique_ptr<const DexFile> DexFileLoader::OpenWithDataSection( @@ -255,8 +255,8 @@ std::unique_ptr<const DexFile> DexFileLoader::OpenWithDataSection( verify, verify_checksum, error_msg, - /*container*/ nullptr, - /*verify_result*/ nullptr); + /*container=*/ nullptr, + /*verify_result=*/ nullptr); } bool DexFileLoader::OpenAll( @@ -290,7 +290,7 @@ bool DexFileLoader::OpenAll( size, location, dex_header->checksum_, - /*oat_dex_file*/ nullptr, + /*oat_dex_file=*/ nullptr, verify, verify_checksum, error_msg)); @@ -410,11 +410,11 @@ std::unique_ptr<const DexFile> DexFileLoader::OpenOneDexFileFromZip( std::unique_ptr<const DexFile> dex_file = OpenCommon( map.data(), map.size(), - /*data_base*/ nullptr, - /*data_size*/ 0u, + /*data_base=*/ nullptr, + /*data_size=*/ 0u, location, zip_entry->GetCrc32(), - /*oat_dex_file*/ nullptr, + /*oat_dex_file=*/ nullptr, verify, verify_checksum, error_msg, diff --git a/libdexfile/dex/dex_file_loader_test.cc b/libdexfile/dex/dex_file_loader_test.cc index 53786171cc..9c61d1ac5f 100644 --- a/libdexfile/dex/dex_file_loader_test.cc +++ b/libdexfile/dex/dex_file_loader_test.cc @@ -221,7 +221,7 @@ static bool OpenDexFilesBase64(const char* base64, bool success = dex_file_loader.OpenAll(dex_bytes->data(), dex_bytes->size(), location, - /* verify */ true, + /* verify= */ true, kVerifyChecksum, error_code, error_msg, @@ -256,9 +256,9 @@ static std::unique_ptr<const DexFile> OpenDexFileInMemoryBase64(const char* base dex_bytes->size(), location, location_checksum, - /* oat_dex_file */ nullptr, - /* verify */ true, - /* verify_checksum */ true, + /* oat_dex_file= */ nullptr, + /* verify= */ true, + /* verify_checksum= */ true, &error_message)); if (expect_success) { CHECK(dex_file != nullptr) << error_message; @@ -348,7 +348,7 @@ TEST_F(DexFileLoaderTest, Version40Rejected) { ASSERT_FALSE(dex_file_loader.OpenAll(dex_bytes.data(), dex_bytes.size(), kLocationString, - /* verify */ true, + /* verify= */ true, kVerifyChecksum, &error_code, &error_msg, @@ -367,7 +367,7 @@ TEST_F(DexFileLoaderTest, Version41Rejected) { ASSERT_FALSE(dex_file_loader.OpenAll(dex_bytes.data(), dex_bytes.size(), kLocationString, - /* verify */ true, + /* verify= */ true, kVerifyChecksum, &error_code, &error_msg, @@ -386,7 +386,7 @@ TEST_F(DexFileLoaderTest, ZeroLengthDexRejected) { ASSERT_FALSE(dex_file_loader.OpenAll(dex_bytes.data(), dex_bytes.size(), kLocationString, - /* verify */ true, + /* verify= */ true, kVerifyChecksum, &error_code, &error_msg, diff --git a/libdexfile/dex/dex_file_verifier.cc b/libdexfile/dex/dex_file_verifier.cc index f273c84027..499a89b2ab 100644 --- a/libdexfile/dex/dex_file_verifier.cc +++ b/libdexfile/dex/dex_file_verifier.cc @@ -341,42 +341,43 @@ bool DexFileVerifier::CheckHeader() { bool result = CheckValidOffsetAndSize(header_->link_off_, header_->link_size_, - 0 /* unaligned */, + /* alignment= */ 0, "link") && CheckValidOffsetAndSize(header_->map_off_, header_->map_off_, - 4, + /* alignment= */ 4, "map") && CheckValidOffsetAndSize(header_->string_ids_off_, header_->string_ids_size_, - 4, + /* alignment= */ 4, "string-ids") && CheckValidOffsetAndSize(header_->type_ids_off_, header_->type_ids_size_, - 4, + /* alignment= */ 4, "type-ids") && CheckSizeLimit(header_->type_ids_size_, DexFile::kDexNoIndex16, "type-ids") && CheckValidOffsetAndSize(header_->proto_ids_off_, header_->proto_ids_size_, - 4, + /* alignment= */ 4, "proto-ids") && CheckSizeLimit(header_->proto_ids_size_, DexFile::kDexNoIndex16, "proto-ids") && CheckValidOffsetAndSize(header_->field_ids_off_, header_->field_ids_size_, - 4, + /* alignment= */ 4, "field-ids") && CheckValidOffsetAndSize(header_->method_ids_off_, header_->method_ids_size_, - 4, + /* alignment= */ 4, "method-ids") && CheckValidOffsetAndSize(header_->class_defs_off_, header_->class_defs_size_, - 4, + /* alignment= */ 4, "class-defs") && CheckValidOffsetAndSize(header_->data_off_, header_->data_size_, - 0, // Unaligned, spec doesn't talk about it, even though size - // is supposed to be a multiple of 4. + // Unaligned, spec doesn't talk about it, even though size + // is supposed to be a multiple of 4. + /* alignment= */ 0, "data"); return result; } @@ -1197,7 +1198,7 @@ bool DexFileVerifier::CheckIntraClassDataItem() { ClassAccessor::Method method(*dex_file_, field.ptr_pos_); if (!CheckIntraClassDataItemMethods(&method, accessor.NumDirectMethods(), - nullptr /* direct_it */, + /* direct_method= */ nullptr, 0u, &have_class, &class_type_index, diff --git a/libdexfile/dex/dex_file_verifier_test.cc b/libdexfile/dex/dex_file_verifier_test.cc index a22a457dbe..c3180f0660 100644 --- a/libdexfile/dex/dex_file_verifier_test.cc +++ b/libdexfile/dex/dex_file_verifier_test.cc @@ -107,8 +107,8 @@ static std::unique_ptr<const DexFile> OpenDexFileBase64(const char* base64, bool success = dex_file_loader.OpenAll(dex_bytes.get(), length, location, - /* verify */ true, - /* verify_checksum */ true, + /* verify= */ true, + /* verify_checksum= */ true, &error_code, error_msg, &tmp); @@ -1621,13 +1621,13 @@ TEST_F(DexFileVerifierTest, Checksum) { dex_file->Begin(), dex_file->Size(), "good checksum, no verify", - /*verify_checksum*/ false, + /*verify_checksum=*/ false, &error_msg)); EXPECT_TRUE(DexFileVerifier::Verify(dex_file.get(), dex_file->Begin(), dex_file->Size(), "good checksum, verify", - /*verify_checksum*/ true, + /*verify_checksum=*/ true, &error_msg)); // Bad checksum: !verify_checksum passes verify_checksum fails. @@ -1638,13 +1638,13 @@ TEST_F(DexFileVerifierTest, Checksum) { dex_file->Begin(), dex_file->Size(), "bad checksum, no verify", - /*verify_checksum*/ false, + /*verify_checksum=*/ false, &error_msg)); EXPECT_FALSE(DexFileVerifier::Verify(dex_file.get(), dex_file->Begin(), dex_file->Size(), "bad checksum, verify", - /*verify_checksum*/ true, + /*verify_checksum=*/ true, &error_msg)); EXPECT_NE(error_msg.find("Bad checksum"), std::string::npos) << error_msg; } @@ -1691,7 +1691,7 @@ TEST_F(DexFileVerifierTest, BadStaticMethodName) { dex_file->Begin(), dex_file->Size(), "bad static method name", - /*verify_checksum*/ true, + /*verify_checksum=*/ true, &error_msg)); } @@ -1735,7 +1735,7 @@ TEST_F(DexFileVerifierTest, BadVirtualMethodName) { dex_file->Begin(), dex_file->Size(), "bad virtual method name", - /*verify_checksum*/ true, + /*verify_checksum=*/ true, &error_msg)); } @@ -1779,7 +1779,7 @@ TEST_F(DexFileVerifierTest, BadClinitSignature) { dex_file->Begin(), dex_file->Size(), "bad clinit signature", - /*verify_checksum*/ true, + /*verify_checksum=*/ true, &error_msg)); } @@ -1823,7 +1823,7 @@ TEST_F(DexFileVerifierTest, BadClinitSignatureAgain) { dex_file->Begin(), dex_file->Size(), "bad clinit signature", - /*verify_checksum*/ true, + /*verify_checksum=*/ true, &error_msg)); } @@ -1860,7 +1860,7 @@ TEST_F(DexFileVerifierTest, BadInitSignature) { dex_file->Begin(), dex_file->Size(), "bad init signature", - /*verify_checksum*/ true, + /*verify_checksum=*/ true, &error_msg)); } @@ -2063,7 +2063,7 @@ TEST_F(DexFileVerifierTest, InvokeCustomDexSamples) { dex_file->Begin(), dex_file->Size(), "good checksum, verify", - /*verify_checksum*/ true, + /*verify_checksum=*/ true, &error_msg)); // TODO(oth): Test corruptions (b/35308502) } @@ -2110,7 +2110,7 @@ TEST_F(DexFileVerifierTest, BadStaticFieldInitialValuesArray) { dex_file->Begin(), dex_file->Size(), "bad static field initial values array", - /*verify_checksum*/ true, + /*verify_checksum=*/ true, &error_msg)); } @@ -2166,7 +2166,7 @@ TEST_F(DexFileVerifierTest, GoodStaticFieldInitialValuesArray) { dex_file->Begin(), dex_file->Size(), "good static field initial values array", - /*verify_checksum*/ true, + /*verify_checksum=*/ true, &error_msg)); } diff --git a/libdexfile/dex/dex_instruction_test.cc b/libdexfile/dex/dex_instruction_test.cc index 6ce9dbafc8..02400f4a14 100644 --- a/libdexfile/dex/dex_instruction_test.cc +++ b/libdexfile/dex/dex_instruction_test.cc @@ -71,10 +71,13 @@ static void Build4rcc(uint16_t num_args, uint16_t method_idx, uint16_t proto_idx TEST(Instruction, PropertiesOf45cc) { uint16_t instruction[4]; - Build45cc(4u /* num_vregs */, 16u /* method_idx */, 32u /* proto_idx */, - 0xcafe /* arg_regs */, instruction); + Build45cc(/* num_args= */ 4u, + /* method_idx= */ 16u, + /* proto_idx= */ 32u, + /* arg_regs= */ 0xcafe, + instruction); - DexInstructionIterator ins(instruction, /*dex_pc*/ 0u); + DexInstructionIterator ins(instruction, /*dex_pc=*/ 0u); ASSERT_EQ(4u, ins->SizeInCodeUnits()); ASSERT_TRUE(ins->HasVRegA()); @@ -106,10 +109,13 @@ TEST(Instruction, PropertiesOf45cc) { TEST(Instruction, PropertiesOf4rcc) { uint16_t instruction[4]; - Build4rcc(4u /* num_vregs */, 16u /* method_idx */, 32u /* proto_idx */, - 0xcafe /* arg_regs */, instruction); + Build4rcc(/* num_args= */ 4u, + /* method_idx= */ 16u, + /* proto_idx= */ 32u, + /* arg_regs_start= */ 0xcafe, + instruction); - DexInstructionIterator ins(instruction, /*dex_pc*/ 0u); + DexInstructionIterator ins(instruction, /*dex_pc=*/ 0u); ASSERT_EQ(4u, ins->SizeInCodeUnits()); ASSERT_TRUE(ins->HasVRegA()); diff --git a/libdexfile/dex/type_lookup_table.cc b/libdexfile/dex/type_lookup_table.cc index 00ec358b02..7d80a2e7f7 100644 --- a/libdexfile/dex/type_lookup_table.cc +++ b/libdexfile/dex/type_lookup_table.cc @@ -94,7 +94,7 @@ TypeLookupTable TypeLookupTable::Open(const uint8_t* dex_data_pointer, DCHECK_ALIGNED(raw_data, alignof(Entry)); const Entry* entries = reinterpret_cast<const Entry*>(raw_data); size_t mask_bits = CalculateMaskBits(num_class_defs); - return TypeLookupTable(dex_data_pointer, mask_bits, entries, /* owned_entries */ nullptr); + return TypeLookupTable(dex_data_pointer, mask_bits, entries, /* owned_entries= */ nullptr); } uint32_t TypeLookupTable::Lookup(const char* str, uint32_t hash) const { diff --git a/libprofile/profile/profile_compilation_info.cc b/libprofile/profile/profile_compilation_info.cc index 2ebde5e06d..6bd49a43eb 100644 --- a/libprofile/profile/profile_compilation_info.cc +++ b/libprofile/profile/profile_compilation_info.cc @@ -190,8 +190,8 @@ bool ProfileCompilationInfo::AddClasses(const std::set<DexCacheResolvedClasses>& bool ProfileCompilationInfo::MergeWith(const std::string& filename) { std::string error; int flags = O_RDONLY | O_NOFOLLOW | O_CLOEXEC; - ScopedFlock profile_file = LockedFile::Open(filename.c_str(), flags, - /*block*/false, &error); + ScopedFlock profile_file = + LockedFile::Open(filename.c_str(), flags, /*block=*/false, &error); if (profile_file.get() == nullptr) { LOG(WARNING) << "Couldn't lock the profile file " << filename << ": " << error; @@ -221,8 +221,8 @@ bool ProfileCompilationInfo::Load(const std::string& filename, bool clear_if_inv // There's no need to fsync profile data right away. We get many chances // to write it again in case something goes wrong. We can rely on a simple // close(), no sync, and let to the kernel decide when to write to disk. - ScopedFlock profile_file = LockedFile::Open(filename.c_str(), flags, - /*block*/false, &error); + ScopedFlock profile_file = + LockedFile::Open(filename.c_str(), flags, /*block=*/false, &error); if (profile_file.get() == nullptr) { LOG(WARNING) << "Couldn't lock the profile file " << filename << ": " << error; @@ -259,8 +259,8 @@ bool ProfileCompilationInfo::Save(const std::string& filename, uint64_t* bytes_w // There's no need to fsync profile data right away. We get many chances // to write it again in case something goes wrong. We can rely on a simple // close(), no sync, and let to the kernel decide when to write to disk. - ScopedFlock profile_file = LockedFile::Open(filename.c_str(), flags, - /*block*/false, &error); + ScopedFlock profile_file = + LockedFile::Open(filename.c_str(), flags, /*block=*/false, &error); if (profile_file.get() == nullptr) { LOG(WARNING) << "Couldn't lock the profile file " << filename << ": " << error; return false; @@ -1393,8 +1393,8 @@ bool ProfileCompilationInfo::RemapProfileIndex( // verify_checksum is false because we want to differentiate between a missing dex data and // a mismatched checksum. const DexFileData* dex_data = FindDexData(other_profile_line_header.dex_location, - 0u, - false /* verify_checksum */); + /* checksum= */ 0u, + /* verify_checksum= */ false); if ((dex_data != nullptr) && (dex_data->checksum != other_profile_line_header.checksum)) { LOG(WARNING) << "Checksum mismatch for dex " << other_profile_line_header.dex_location; return false; @@ -1481,8 +1481,8 @@ bool ProfileCompilationInfo::MergeWith(const ProfileCompilationInfo& other, // verify_checksum is false because we want to differentiate between a missing dex data and // a mismatched checksum. const DexFileData* dex_data = FindDexData(other_dex_data->profile_key, - 0u, - /* verify_checksum */ false); + /* checksum= */ 0u, + /* verify_checksum= */ false); if ((dex_data != nullptr) && (dex_data->checksum != other_dex_data->checksum)) { LOG(WARNING) << "Checksum mismatch for dex " << other_dex_data->profile_key; return false; @@ -1829,7 +1829,7 @@ bool ProfileCompilationInfo::GenerateTestProfile(int fd, flags |= ((m & 1) != 0) ? MethodHotness::kFlagPostStartup : MethodHotness::kFlagStartup; info.AddMethodIndex(static_cast<MethodHotness::Flag>(flags), profile_key, - /*method_idx*/ 0, + /*checksum=*/ 0, method_idx, max_method); } @@ -1975,20 +1975,20 @@ void ProfileCompilationInfo::DexFileData::SetMethodHotness(size_t index, MethodHotness::Flag flags) { DCHECK_LT(index, num_method_ids); if ((flags & MethodHotness::kFlagStartup) != 0) { - method_bitmap.StoreBit(MethodBitIndex(/*startup*/ true, index), /*value*/ true); + method_bitmap.StoreBit(MethodBitIndex(/*startup=*/ true, index), /*value=*/ true); } if ((flags & MethodHotness::kFlagPostStartup) != 0) { - method_bitmap.StoreBit(MethodBitIndex(/*startup*/ false, index), /*value*/ true); + method_bitmap.StoreBit(MethodBitIndex(/*startup=*/ false, index), /*value=*/ true); } } ProfileCompilationInfo::MethodHotness ProfileCompilationInfo::DexFileData::GetHotnessInfo( uint32_t dex_method_index) const { MethodHotness ret; - if (method_bitmap.LoadBit(MethodBitIndex(/*startup*/ true, dex_method_index))) { + if (method_bitmap.LoadBit(MethodBitIndex(/*startup=*/ true, dex_method_index))) { ret.AddFlag(MethodHotness::kFlagStartup); } - if (method_bitmap.LoadBit(MethodBitIndex(/*startup*/ false, dex_method_index))) { + if (method_bitmap.LoadBit(MethodBitIndex(/*startup=*/ false, dex_method_index))) { ret.AddFlag(MethodHotness::kFlagPostStartup); } auto it = method_map.find(dex_method_index); diff --git a/libprofile/profile/profile_compilation_info_test.cc b/libprofile/profile/profile_compilation_info_test.cc index 417abaa435..a2bfe5028d 100644 --- a/libprofile/profile/profile_compilation_info_test.cc +++ b/libprofile/profile/profile_compilation_info_test.cc @@ -43,22 +43,22 @@ class ProfileCompilationInfoTest : public CommonArtTest { protected: bool AddMethod(const std::string& dex_location, uint32_t checksum, - uint16_t method_index, + uint16_t method_idx, ProfileCompilationInfo* info) { return info->AddMethodIndex(Hotness::kFlagHot, dex_location, checksum, - method_index, + method_idx, kMaxMethodIds); } bool AddMethod(const std::string& dex_location, uint32_t checksum, - uint16_t method_index, + uint16_t method_idx, const ProfileCompilationInfo::OfflineProfileMethodInfo& pmi, ProfileCompilationInfo* info) { return info->AddMethod( - dex_location, checksum, method_index, kMaxMethodIds, pmi, Hotness::kFlagPostStartup); + dex_location, checksum, method_idx, kMaxMethodIds, pmi, Hotness::kFlagPostStartup); } bool AddClass(const std::string& dex_location, @@ -115,9 +115,9 @@ class ProfileCompilationInfoTest : public CommonArtTest { ProfileCompilationInfo::OfflineProfileMethodInfo pmi(ic_map); - pmi.dex_references.emplace_back("dex_location1", /* checksum */1, kMaxMethodIds); - pmi.dex_references.emplace_back("dex_location2", /* checksum */2, kMaxMethodIds); - pmi.dex_references.emplace_back("dex_location3", /* checksum */3, kMaxMethodIds); + pmi.dex_references.emplace_back("dex_location1", /* checksum= */1, kMaxMethodIds); + pmi.dex_references.emplace_back("dex_location2", /* checksum= */2, kMaxMethodIds); + pmi.dex_references.emplace_back("dex_location3", /* checksum= */3, kMaxMethodIds); return pmi; } @@ -148,8 +148,8 @@ class ProfileCompilationInfoTest : public CommonArtTest { ScratchFile profile; ProfileCompilationInfo saved_info; for (uint16_t i = 0; i < 10; i++) { - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, /* method_idx */ i, &saved_info)); - ASSERT_TRUE(AddMethod("dex_location2", /* checksum */ 2, /* method_idx */ i, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, /* method_idx= */ i, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location2", /* checksum= */ 2, /* method_idx= */ i, &saved_info)); } ASSERT_TRUE(saved_info.Save(GetFd(profile))); ASSERT_EQ(0, profile.GetFile()->Flush()); @@ -207,8 +207,8 @@ TEST_F(ProfileCompilationInfoTest, SaveFd) { ProfileCompilationInfo saved_info; // Save a few methods. for (uint16_t i = 0; i < 10; i++) { - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, /* method_idx */ i, &saved_info)); - ASSERT_TRUE(AddMethod("dex_location2", /* checksum */ 2, /* method_idx */ i, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, /* method_idx= */ i, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location2", /* checksum= */ 2, /* method_idx= */ i, &saved_info)); } ASSERT_TRUE(saved_info.Save(GetFd(profile))); ASSERT_EQ(0, profile.GetFile()->Flush()); @@ -221,9 +221,9 @@ TEST_F(ProfileCompilationInfoTest, SaveFd) { // Save more methods. for (uint16_t i = 0; i < 100; i++) { - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, /* method_idx */ i, &saved_info)); - ASSERT_TRUE(AddMethod("dex_location2", /* checksum */ 2, /* method_idx */ i, &saved_info)); - ASSERT_TRUE(AddMethod("dex_location3", /* checksum */ 3, /* method_idx */ i, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, /* method_idx= */ i, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location2", /* checksum= */ 2, /* method_idx= */ i, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location3", /* checksum= */ 3, /* method_idx= */ i, &saved_info)); } ASSERT_TRUE(profile.GetFile()->ResetOffset()); ASSERT_TRUE(saved_info.Save(GetFd(profile))); @@ -240,19 +240,19 @@ TEST_F(ProfileCompilationInfoTest, AddMethodsAndClassesFail) { ScratchFile profile; ProfileCompilationInfo info; - ASSERT_TRUE(AddMethod("dex_location", /* checksum */ 1, /* method_idx */ 1, &info)); + ASSERT_TRUE(AddMethod("dex_location", /* checksum= */ 1, /* method_idx= */ 1, &info)); // Trying to add info for an existing file but with a different checksum. - ASSERT_FALSE(AddMethod("dex_location", /* checksum */ 2, /* method_idx */ 2, &info)); + ASSERT_FALSE(AddMethod("dex_location", /* checksum= */ 2, /* method_idx= */ 2, &info)); } TEST_F(ProfileCompilationInfoTest, MergeFail) { ScratchFile profile; ProfileCompilationInfo info1; - ASSERT_TRUE(AddMethod("dex_location", /* checksum */ 1, /* method_idx */ 1, &info1)); + ASSERT_TRUE(AddMethod("dex_location", /* checksum= */ 1, /* method_idx= */ 1, &info1)); // Use the same file, change the checksum. ProfileCompilationInfo info2; - ASSERT_TRUE(AddMethod("dex_location", /* checksum */ 2, /* method_idx */ 2, &info2)); + ASSERT_TRUE(AddMethod("dex_location", /* checksum= */ 2, /* method_idx= */ 2, &info2)); ASSERT_FALSE(info1.MergeWith(info2)); } @@ -262,10 +262,10 @@ TEST_F(ProfileCompilationInfoTest, MergeFdFail) { ScratchFile profile; ProfileCompilationInfo info1; - ASSERT_TRUE(AddMethod("dex_location", /* checksum */ 1, /* method_idx */ 1, &info1)); + ASSERT_TRUE(AddMethod("dex_location", /* checksum= */ 1, /* method_idx= */ 1, &info1)); // Use the same file, change the checksum. ProfileCompilationInfo info2; - ASSERT_TRUE(AddMethod("dex_location", /* checksum */ 2, /* method_idx */ 2, &info2)); + ASSERT_TRUE(AddMethod("dex_location", /* checksum= */ 2, /* method_idx= */ 2, &info2)); ASSERT_TRUE(info1.Save(profile.GetFd())); ASSERT_EQ(0, profile.GetFile()->Flush()); @@ -280,13 +280,13 @@ TEST_F(ProfileCompilationInfoTest, SaveMaxMethods) { ProfileCompilationInfo saved_info; // Save the maximum number of methods for (uint16_t i = 0; i < std::numeric_limits<uint16_t>::max(); i++) { - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, /* method_idx */ i, &saved_info)); - ASSERT_TRUE(AddMethod("dex_location2", /* checksum */ 2, /* method_idx */ i, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, /* method_idx= */ i, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location2", /* checksum= */ 2, /* method_idx= */ i, &saved_info)); } // Save the maximum number of classes for (uint16_t i = 0; i < std::numeric_limits<uint16_t>::max(); i++) { - ASSERT_TRUE(AddClass("dex_location1", /* checksum */ 1, dex::TypeIndex(i), &saved_info)); - ASSERT_TRUE(AddClass("dex_location2", /* checksum */ 2, dex::TypeIndex(i), &saved_info)); + ASSERT_TRUE(AddClass("dex_location1", /* checksum= */ 1, dex::TypeIndex(i), &saved_info)); + ASSERT_TRUE(AddClass("dex_location2", /* checksum= */ 2, dex::TypeIndex(i), &saved_info)); } ASSERT_TRUE(saved_info.Save(GetFd(profile))); @@ -390,7 +390,7 @@ TEST_F(ProfileCompilationInfoTest, UnexpectedContent) { ProfileCompilationInfo saved_info; // Save the maximum number of methods for (uint16_t i = 0; i < 10; i++) { - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, /* method_idx */ i, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, /* method_idx= */ i, &saved_info)); } ASSERT_TRUE(saved_info.Save(GetFd(profile))); @@ -415,9 +415,9 @@ TEST_F(ProfileCompilationInfoTest, SaveInlineCaches) { for (uint16_t method_idx = 0; method_idx < 10; method_idx++) { // Add a method which is part of the same dex file as one of the // class from the inline caches. - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, method_idx, pmi, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, method_idx, pmi, &saved_info)); // Add a method which is outside the set of dex files. - ASSERT_TRUE(AddMethod("dex_location4", /* checksum */ 4, method_idx, pmi, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location4", /* checksum= */ 4, method_idx, pmi, &saved_info)); } ASSERT_TRUE(saved_info.Save(GetFd(profile))); @@ -431,11 +431,11 @@ TEST_F(ProfileCompilationInfoTest, SaveInlineCaches) { ASSERT_TRUE(loaded_info.Equals(saved_info)); std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> loaded_pmi1 = - loaded_info.GetMethod("dex_location1", /* checksum */ 1, /* method_idx */ 3); + loaded_info.GetMethod("dex_location1", /* dex_checksum= */ 1, /* dex_method_index= */ 3); ASSERT_TRUE(loaded_pmi1 != nullptr); ASSERT_TRUE(*loaded_pmi1 == pmi); std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> loaded_pmi2 = - loaded_info.GetMethod("dex_location4", /* checksum */ 4, /* method_idx */ 3); + loaded_info.GetMethod("dex_location4", /* dex_checksum= */ 4, /* dex_method_index= */ 3); ASSERT_TRUE(loaded_pmi2 != nullptr); ASSERT_TRUE(*loaded_pmi2 == pmi); } @@ -448,7 +448,7 @@ TEST_F(ProfileCompilationInfoTest, MegamorphicInlineCaches) { // Add methods with inline caches. for (uint16_t method_idx = 0; method_idx < 10; method_idx++) { - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, method_idx, pmi, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, method_idx, pmi, &saved_info)); } ASSERT_TRUE(saved_info.Save(GetFd(profile))); @@ -459,7 +459,7 @@ TEST_F(ProfileCompilationInfoTest, MegamorphicInlineCaches) { ProfileCompilationInfo::OfflineProfileMethodInfo pmi_extra = GetOfflineProfileMethodInfo(); MakeMegamorphic(&pmi_extra); for (uint16_t method_idx = 0; method_idx < 10; method_idx++) { - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, method_idx, pmi, &saved_info_extra)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, method_idx, pmi, &saved_info_extra)); } ASSERT_TRUE(profile.GetFile()->ResetOffset()); @@ -477,7 +477,7 @@ TEST_F(ProfileCompilationInfoTest, MegamorphicInlineCaches) { ASSERT_TRUE(loaded_info.Equals(saved_info)); std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> loaded_pmi1 = - loaded_info.GetMethod("dex_location1", /* checksum */ 1, /* method_idx */ 3); + loaded_info.GetMethod("dex_location1", /* dex_checksum= */ 1, /* dex_method_index= */ 3); ASSERT_TRUE(loaded_pmi1 != nullptr); ASSERT_TRUE(*loaded_pmi1 == pmi_extra); @@ -491,7 +491,7 @@ TEST_F(ProfileCompilationInfoTest, MissingTypesInlineCaches) { // Add methods with inline caches. for (uint16_t method_idx = 0; method_idx < 10; method_idx++) { - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, method_idx, pmi, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, method_idx, pmi, &saved_info)); } ASSERT_TRUE(saved_info.Save(GetFd(profile))); @@ -502,7 +502,7 @@ TEST_F(ProfileCompilationInfoTest, MissingTypesInlineCaches) { ProfileCompilationInfo::OfflineProfileMethodInfo pmi_extra = GetOfflineProfileMethodInfo(); MakeMegamorphic(&pmi_extra); for (uint16_t method_idx = 5; method_idx < 10; method_idx++) { - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, method_idx, pmi, &saved_info_extra)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, method_idx, pmi, &saved_info_extra)); } // Mark all inline caches with missing types and add them to the profile again. @@ -510,7 +510,7 @@ TEST_F(ProfileCompilationInfoTest, MissingTypesInlineCaches) { ProfileCompilationInfo::OfflineProfileMethodInfo missing_types = GetOfflineProfileMethodInfo(); SetIsMissingTypes(&missing_types); for (uint16_t method_idx = 0; method_idx < 10; method_idx++) { - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, method_idx, pmi, &saved_info_extra)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, method_idx, pmi, &saved_info_extra)); } ASSERT_TRUE(profile.GetFile()->ResetOffset()); @@ -528,7 +528,7 @@ TEST_F(ProfileCompilationInfoTest, MissingTypesInlineCaches) { ASSERT_TRUE(loaded_info.Equals(saved_info)); std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> loaded_pmi1 = - loaded_info.GetMethod("dex_location1", /* checksum */ 1, /* method_idx */ 3); + loaded_info.GetMethod("dex_location1", /* dex_checksum= */ 1, /* dex_method_index= */ 3); ASSERT_TRUE(loaded_pmi1 != nullptr); ASSERT_TRUE(*loaded_pmi1 == pmi_extra); } @@ -542,8 +542,8 @@ TEST_F(ProfileCompilationInfoTest, InvalidChecksumInInlineCache) { // Modify the checksum to trigger a mismatch. pmi2.dex_references[0].dex_checksum++; - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, /*method_idx*/ 0, pmi1, &info)); - ASSERT_FALSE(AddMethod("dex_location2", /* checksum */ 2, /*method_idx*/ 0, pmi2, &info)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, /*method_idx=*/ 0, pmi1, &info)); + ASSERT_FALSE(AddMethod("dex_location2", /* checksum= */ 2, /*method_idx=*/ 0, pmi2, &info)); } // Verify that profiles behave correctly even if the methods are added in a different @@ -556,8 +556,8 @@ TEST_F(ProfileCompilationInfoTest, MergeInlineCacheTriggerReindex) { ProfileCompilationInfo::InlineCacheMap* ic_map = CreateInlineCacheMap(); ProfileCompilationInfo::OfflineProfileMethodInfo pmi(ic_map); - pmi.dex_references.emplace_back("dex_location1", /* checksum */ 1, kMaxMethodIds); - pmi.dex_references.emplace_back("dex_location2", /* checksum */ 2, kMaxMethodIds); + pmi.dex_references.emplace_back("dex_location1", /* checksum= */ 1, kMaxMethodIds); + pmi.dex_references.emplace_back("dex_location2", /* checksum= */ 2, kMaxMethodIds); for (uint16_t dex_pc = 1; dex_pc < 5; dex_pc++) { ProfileCompilationInfo::DexPcData dex_pc_data(allocator_.get()); dex_pc_data.AddClass(0, dex::TypeIndex(0)); @@ -567,8 +567,8 @@ TEST_F(ProfileCompilationInfoTest, MergeInlineCacheTriggerReindex) { ProfileCompilationInfo::InlineCacheMap* ic_map_reindexed = CreateInlineCacheMap(); ProfileCompilationInfo::OfflineProfileMethodInfo pmi_reindexed(ic_map_reindexed); - pmi_reindexed.dex_references.emplace_back("dex_location2", /* checksum */ 2, kMaxMethodIds); - pmi_reindexed.dex_references.emplace_back("dex_location1", /* checksum */ 1, kMaxMethodIds); + pmi_reindexed.dex_references.emplace_back("dex_location2", /* checksum= */ 2, kMaxMethodIds); + pmi_reindexed.dex_references.emplace_back("dex_location1", /* checksum= */ 1, kMaxMethodIds); for (uint16_t dex_pc = 1; dex_pc < 5; dex_pc++) { ProfileCompilationInfo::DexPcData dex_pc_data(allocator_.get()); dex_pc_data.AddClass(1, dex::TypeIndex(0)); @@ -579,15 +579,15 @@ TEST_F(ProfileCompilationInfoTest, MergeInlineCacheTriggerReindex) { // Profile 1 and Profile 2 get the same methods but in different order. // This will trigger a different dex numbers. for (uint16_t method_idx = 0; method_idx < 10; method_idx++) { - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, method_idx, pmi, &info)); - ASSERT_TRUE(AddMethod("dex_location2", /* checksum */ 2, method_idx, pmi, &info)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, method_idx, pmi, &info)); + ASSERT_TRUE(AddMethod("dex_location2", /* checksum= */ 2, method_idx, pmi, &info)); } for (uint16_t method_idx = 0; method_idx < 10; method_idx++) { ASSERT_TRUE(AddMethod( - "dex_location2", /* checksum */ 2, method_idx, pmi_reindexed, &info_reindexed)); + "dex_location2", /* checksum= */ 2, method_idx, pmi_reindexed, &info_reindexed)); ASSERT_TRUE(AddMethod( - "dex_location1", /* checksum */ 1, method_idx, pmi_reindexed, &info_reindexed)); + "dex_location1", /* checksum= */ 1, method_idx, pmi_reindexed, &info_reindexed)); } ProfileCompilationInfo info_backup; @@ -597,11 +597,11 @@ TEST_F(ProfileCompilationInfoTest, MergeInlineCacheTriggerReindex) { ASSERT_TRUE(info.Equals(info_backup)); for (uint16_t method_idx = 0; method_idx < 10; method_idx++) { std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> loaded_pmi1 = - info.GetMethod("dex_location1", /* checksum */ 1, method_idx); + info.GetMethod("dex_location1", /* dex_checksum= */ 1, method_idx); ASSERT_TRUE(loaded_pmi1 != nullptr); ASSERT_TRUE(*loaded_pmi1 == pmi); std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> loaded_pmi2 = - info.GetMethod("dex_location2", /* checksum */ 2, method_idx); + info.GetMethod("dex_location2", /* dex_checksum= */ 2, method_idx); ASSERT_TRUE(loaded_pmi2 != nullptr); ASSERT_TRUE(*loaded_pmi2 == pmi); } @@ -612,34 +612,34 @@ TEST_F(ProfileCompilationInfoTest, AddMoreDexFileThanLimit) { // Save a few methods. for (uint16_t i = 0; i < std::numeric_limits<uint8_t>::max(); i++) { std::string dex_location = std::to_string(i); - ASSERT_TRUE(AddMethod(dex_location, /* checksum */ 1, /* method_idx */ i, &info)); + ASSERT_TRUE(AddMethod(dex_location, /* checksum= */ 1, /* method_idx= */ i, &info)); } // We only support at most 255 dex files. ASSERT_FALSE(AddMethod( - /*dex_location*/ "256", /* checksum */ 1, /* method_idx */ 0, &info)); + /*dex_location=*/ "256", /* checksum= */ 1, /* method_idx= */ 0, &info)); } TEST_F(ProfileCompilationInfoTest, MegamorphicInlineCachesMerge) { // Create a megamorphic inline cache. ProfileCompilationInfo::InlineCacheMap* ic_map = CreateInlineCacheMap(); ProfileCompilationInfo::OfflineProfileMethodInfo pmi(ic_map); - pmi.dex_references.emplace_back("dex_location1", /* checksum */ 1, kMaxMethodIds); + pmi.dex_references.emplace_back("dex_location1", /* checksum= */ 1, kMaxMethodIds); ProfileCompilationInfo::DexPcData dex_pc_data(allocator_.get()); dex_pc_data.SetIsMegamorphic(); ic_map->Put(/*dex_pc*/ 0, dex_pc_data); ProfileCompilationInfo info_megamorphic; ASSERT_TRUE(AddMethod("dex_location1", - /*checksum*/ 1, - /*method_idx*/ 0, + /*checksum=*/ 1, + /*method_idx=*/ 0, pmi, &info_megamorphic)); // Create a profile with no inline caches (for the same method). ProfileCompilationInfo info_no_inline_cache; ASSERT_TRUE(AddMethod("dex_location1", - /*checksum*/ 1, - /*method_idx*/ 0, + /*checksum=*/ 1, + /*method_idx=*/ 0, &info_no_inline_cache)); // Merge the megamorphic cache into the empty one. @@ -653,23 +653,23 @@ TEST_F(ProfileCompilationInfoTest, MissingTypesInlineCachesMerge) { // Create an inline cache with missing types ProfileCompilationInfo::InlineCacheMap* ic_map = CreateInlineCacheMap(); ProfileCompilationInfo::OfflineProfileMethodInfo pmi(ic_map); - pmi.dex_references.emplace_back("dex_location1", /* checksum */ 1, kMaxMethodIds); + pmi.dex_references.emplace_back("dex_location1", /* checksum= */ 1, kMaxMethodIds); ProfileCompilationInfo::DexPcData dex_pc_data(allocator_.get()); dex_pc_data.SetIsMissingTypes(); ic_map->Put(/*dex_pc*/ 0, dex_pc_data); ProfileCompilationInfo info_megamorphic; ASSERT_TRUE(AddMethod("dex_location1", - /*checksum*/ 1, - /*method_idx*/ 0, + /*checksum=*/ 1, + /*method_idx=*/ 0, pmi, &info_megamorphic)); // Create a profile with no inline caches (for the same method). ProfileCompilationInfo info_no_inline_cache; ASSERT_TRUE(AddMethod("dex_location1", - /*checksum*/ 1, - /*method_idx*/ 0, + /*checksum=*/ 1, + /*method_idx=*/ 0, &info_no_inline_cache)); // Merge the missing type cache into the empty one. @@ -766,26 +766,26 @@ TEST_F(ProfileCompilationInfoTest, SampledMethodsTest) { TEST_F(ProfileCompilationInfoTest, LoadFromZipCompress) { TestProfileLoadFromZip("primary.prof", ZipWriter::kCompress | ZipWriter::kAlign32, - /*should_succeed*/true); + /*should_succeed=*/true); } TEST_F(ProfileCompilationInfoTest, LoadFromZipUnCompress) { TestProfileLoadFromZip("primary.prof", ZipWriter::kAlign32, - /*should_succeed*/true); + /*should_succeed=*/true); } TEST_F(ProfileCompilationInfoTest, LoadFromZipUnAligned) { TestProfileLoadFromZip("primary.prof", 0, - /*should_succeed*/true); + /*should_succeed=*/true); } TEST_F(ProfileCompilationInfoTest, LoadFromZipFailBadZipEntry) { TestProfileLoadFromZip("invalid.profile.entry", 0, - /*should_succeed*/true, - /*should_succeed_with_empty_profile*/true); + /*should_succeed=*/true, + /*should_succeed_with_empty_profile=*/true); } TEST_F(ProfileCompilationInfoTest, LoadFromZipFailBadProfile) { @@ -835,7 +835,7 @@ TEST_F(ProfileCompilationInfoTest, UpdateProfileKeyOk) { info.AddMethodIndex(Hotness::kFlagHot, old_name, dex->GetLocationChecksum(), - /* method_idx */ 0, + /* method_idx= */ 0, dex->NumMethodIds()); } @@ -845,7 +845,7 @@ TEST_F(ProfileCompilationInfoTest, UpdateProfileKeyOk) { // Verify that we find the methods when searched with the original dex files. for (const std::unique_ptr<const DexFile>& dex : dex_files) { std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> loaded_pmi = - info.GetMethod(dex->GetLocation(), dex->GetLocationChecksum(), /* method_idx */ 0); + info.GetMethod(dex->GetLocation(), dex->GetLocationChecksum(), /* dex_method_index= */ 0); ASSERT_TRUE(loaded_pmi != nullptr); } } @@ -856,9 +856,9 @@ TEST_F(ProfileCompilationInfoTest, UpdateProfileKeyOkButNoUpdate) { ProfileCompilationInfo info; info.AddMethodIndex(Hotness::kFlagHot, "my.app", - /* checksum */ 123, - /* method_idx */ 0, - /* num_method_ids */ 10); + /* checksum= */ 123, + /* method_idx= */ 0, + /* num_method_ids= */ 10); // Update the profile keys based on the original dex files ASSERT_TRUE(info.UpdateProfileKeys(dex_files)); @@ -867,13 +867,13 @@ TEST_F(ProfileCompilationInfoTest, UpdateProfileKeyOkButNoUpdate) { // location. for (const std::unique_ptr<const DexFile>& dex : dex_files) { std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> loaded_pmi = - info.GetMethod(dex->GetLocation(), dex->GetLocationChecksum(), /* method_idx */ 0); + info.GetMethod(dex->GetLocation(), dex->GetLocationChecksum(), /* dex_method_index= */ 0); ASSERT_TRUE(loaded_pmi == nullptr); } // Verify that we can find the original entry. std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> loaded_pmi = - info.GetMethod("my.app", /* checksum */ 123, /* method_idx */ 0); + info.GetMethod("my.app", /* dex_checksum= */ 123, /* dex_method_index= */ 0); ASSERT_TRUE(loaded_pmi != nullptr); } @@ -892,7 +892,7 @@ TEST_F(ProfileCompilationInfoTest, UpdateProfileKeyFail) { info.AddMethodIndex(Hotness::kFlagHot, old_name, dex->GetLocationChecksum(), - /* method_idx */ 0, + /* method_idx= */ 0, dex->NumMethodIds()); } @@ -900,8 +900,8 @@ TEST_F(ProfileCompilationInfoTest, UpdateProfileKeyFail) { // This will cause the rename to fail because an existing entry would already have that name. info.AddMethodIndex(Hotness::kFlagHot, dex_files[0]->GetLocation(), - /* checksum */ 123, - /* method_idx */ 0, + /* checksum= */ 123, + /* method_idx= */ 0, dex_files[0]->NumMethodIds()); ASSERT_FALSE(info.UpdateProfileKeys(dex_files)); @@ -916,10 +916,10 @@ TEST_F(ProfileCompilationInfoTest, FilteredLoading) { // Add methods with inline caches. for (uint16_t method_idx = 0; method_idx < 10; method_idx++) { // Add a method which is part of the same dex file as one of the class from the inline caches. - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, method_idx, pmi, &saved_info)); - ASSERT_TRUE(AddMethod("dex_location2", /* checksum */ 2, method_idx, pmi, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, method_idx, pmi, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location2", /* checksum= */ 2, method_idx, pmi, &saved_info)); // Add a method which is outside the set of dex files. - ASSERT_TRUE(AddMethod("dex_location4", /* checksum */ 4, method_idx, pmi, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location4", /* checksum= */ 4, method_idx, pmi, &saved_info)); } ASSERT_TRUE(saved_info.Save(GetFd(profile))); @@ -941,8 +941,12 @@ TEST_F(ProfileCompilationInfoTest, FilteredLoading) { // Dex location 2 and 4 should have been filtered out for (uint16_t method_idx = 0; method_idx < 10; method_idx++) { - ASSERT_TRUE(nullptr == loaded_info.GetMethod("dex_location2", /* checksum */ 2, method_idx)); - ASSERT_TRUE(nullptr == loaded_info.GetMethod("dex_location4", /* checksum */ 4, method_idx)); + ASSERT_TRUE(nullptr == loaded_info.GetMethod("dex_location2", + /* dex_checksum= */ 2, + method_idx)); + ASSERT_TRUE(nullptr == loaded_info.GetMethod("dex_location4", + /* dex_checksum= */ 4, + method_idx)); } // Dex location 1 should have all all the inline caches referencing dex location 2 set to @@ -950,7 +954,7 @@ TEST_F(ProfileCompilationInfoTest, FilteredLoading) { for (uint16_t method_idx = 0; method_idx < 10; method_idx++) { // The methods for dex location 1 should be in the profile data. std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> loaded_pmi1 = - loaded_info.GetMethod("dex_location1", /* checksum */ 1, /* method_idx */ method_idx); + loaded_info.GetMethod("dex_location1", /* dex_checksum= */ 1, method_idx); ASSERT_TRUE(loaded_pmi1 != nullptr); // Verify the inline cache. @@ -989,8 +993,8 @@ TEST_F(ProfileCompilationInfoTest, FilteredLoading) { ProfileCompilationInfo::OfflineProfileMethodInfo expected_pmi(ic_map); // The dex references should not have dex_location2 in the list. - expected_pmi.dex_references.emplace_back("dex_location1", /* checksum */1, kMaxMethodIds); - expected_pmi.dex_references.emplace_back("dex_location3", /* checksum */3, kMaxMethodIds); + expected_pmi.dex_references.emplace_back("dex_location1", /* checksum= */1, kMaxMethodIds); + expected_pmi.dex_references.emplace_back("dex_location3", /* checksum= */3, kMaxMethodIds); // Now check that we get back what we expect. ASSERT_TRUE(*loaded_pmi1 == expected_pmi); @@ -1006,10 +1010,10 @@ TEST_F(ProfileCompilationInfoTest, FilteredLoadingRemoveAll) { // Add methods with inline caches. for (uint16_t method_idx = 0; method_idx < 10; method_idx++) { // Add a method which is part of the same dex file as one of the class from the inline caches. - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, method_idx, pmi, &saved_info)); - ASSERT_TRUE(AddMethod("dex_location2", /* checksum */ 2, method_idx, pmi, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, method_idx, pmi, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location2", /* checksum= */ 2, method_idx, pmi, &saved_info)); // Add a method which is outside the set of dex files. - ASSERT_TRUE(AddMethod("dex_location4", /* checksum */ 4, method_idx, pmi, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location4", /* checksum= */ 4, method_idx, pmi, &saved_info)); } ASSERT_TRUE(saved_info.Save(GetFd(profile))); @@ -1038,9 +1042,9 @@ TEST_F(ProfileCompilationInfoTest, FilteredLoadingKeepAll) { for (uint16_t method_idx = 0; method_idx < 10; method_idx++) { // Add a method which is part of the same dex file as one of the // class from the inline caches. - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, method_idx, pmi, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, method_idx, pmi, &saved_info)); // Add a method which is outside the set of dex files. - ASSERT_TRUE(AddMethod("dex_location4", /* checksum */ 4, method_idx, pmi, &saved_info)); + ASSERT_TRUE(AddMethod("dex_location4", /* checksum= */ 4, method_idx, pmi, &saved_info)); } ASSERT_TRUE(saved_info.Save(GetFd(profile))); @@ -1060,13 +1064,13 @@ TEST_F(ProfileCompilationInfoTest, FilteredLoadingKeepAll) { for (uint16_t method_idx = 0; method_idx < 10; method_idx++) { std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> loaded_pmi1 = - loaded_info.GetMethod("dex_location1", /* checksum */ 1, method_idx); + loaded_info.GetMethod("dex_location1", /* dex_checksum= */ 1, method_idx); ASSERT_TRUE(loaded_pmi1 != nullptr); ASSERT_TRUE(*loaded_pmi1 == pmi); } for (uint16_t method_idx = 0; method_idx < 10; method_idx++) { std::unique_ptr<ProfileCompilationInfo::OfflineProfileMethodInfo> loaded_pmi2 = - loaded_info.GetMethod("dex_location4", /* checksum */ 4, method_idx); + loaded_info.GetMethod("dex_location4", /* dex_checksum= */ 4, method_idx); ASSERT_TRUE(loaded_pmi2 != nullptr); ASSERT_TRUE(*loaded_pmi2 == pmi); } @@ -1081,8 +1085,8 @@ TEST_F(ProfileCompilationInfoTest, FilteredLoadingWithClasses) { ProfileCompilationInfo saved_info; uint16_t item_count = 1000; for (uint16_t i = 0; i < item_count; i++) { - ASSERT_TRUE(AddClass("dex_location1", /* checksum */ 1, dex::TypeIndex(i), &saved_info)); - ASSERT_TRUE(AddClass("dex_location2", /* checksum */ 2, dex::TypeIndex(i), &saved_info)); + ASSERT_TRUE(AddClass("dex_location1", /* checksum= */ 1, dex::TypeIndex(i), &saved_info)); + ASSERT_TRUE(AddClass("dex_location2", /* checksum= */ 2, dex::TypeIndex(i), &saved_info)); } ASSERT_TRUE(saved_info.Save(GetFd(profile))); @@ -1101,7 +1105,7 @@ TEST_F(ProfileCompilationInfoTest, FilteredLoadingWithClasses) { // Compute the expectation. ProfileCompilationInfo expected_info; for (uint16_t i = 0; i < item_count; i++) { - ASSERT_TRUE(AddClass("dex_location2", /* checksum */ 2, dex::TypeIndex(i), &expected_info)); + ASSERT_TRUE(AddClass("dex_location2", /* checksum= */ 2, dex::TypeIndex(i), &expected_info)); } // Validate the expectation. @@ -1112,7 +1116,7 @@ TEST_F(ProfileCompilationInfoTest, FilteredLoadingWithClasses) { TEST_F(ProfileCompilationInfoTest, ClearData) { ProfileCompilationInfo info; for (uint16_t i = 0; i < 10; i++) { - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, /* method_idx */ i, &info)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, /* method_idx= */ i, &info)); } ASSERT_FALSE(IsEmpty(info)); info.ClearData(); @@ -1122,7 +1126,7 @@ TEST_F(ProfileCompilationInfoTest, ClearData) { TEST_F(ProfileCompilationInfoTest, ClearDataAndSave) { ProfileCompilationInfo info; for (uint16_t i = 0; i < 10; i++) { - ASSERT_TRUE(AddMethod("dex_location1", /* checksum */ 1, /* method_idx */ i, &info)); + ASSERT_TRUE(AddMethod("dex_location1", /* checksum= */ 1, /* method_idx= */ i, &info)); } info.ClearData(); diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 321a447767..467542df61 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -1860,14 +1860,13 @@ class ImageDumper { oat_file = runtime->GetOatFileManager().FindOpenedOatFileFromOatLocation(oat_location); } if (oat_file == nullptr) { - oat_file = OatFile::Open(/* zip_fd= */ -1, + oat_file = OatFile::Open(/*zip_fd=*/ -1, oat_location, oat_location, - /* requested_base= */ nullptr, - /* executable= */ false, - /* low_4gb= */ false, - /* abs_dex_location= */ nullptr, - /* reservation= */ nullptr, + /*executable=*/ false, + /*low_4gb=*/ false, + /*abs_dex_location=*/ nullptr, + /*reservation=*/ nullptr, &error_msg); } if (oat_file == nullptr) { @@ -2758,14 +2757,13 @@ static int DumpImages(Runtime* runtime, OatDumperOptions* options, std::ostream* // We need to map the oat file in the low 4gb or else the fixup wont be able to fit oat file // pointers into 32 bit pointer sized ArtMethods. std::string error_msg; - std::unique_ptr<OatFile> oat_file(OatFile::Open(/* zip_fd= */ -1, + std::unique_ptr<OatFile> oat_file(OatFile::Open(/*zip_fd=*/ -1, options->app_oat_, options->app_oat_, - /* requested_base= */ nullptr, - /* executable= */ false, - /* low_4gb= */ true, - /* abs_dex_location= */ nullptr, - /* reservation= */ nullptr, + /*executable=*/ false, + /*low_4gb=*/ true, + /*abs_dex_location=*/ nullptr, + /*reservation=*/ nullptr, &error_msg)); if (oat_file == nullptr) { LOG(ERROR) << "Failed to open oat file " << options->app_oat_ << " with error " << error_msg; @@ -2882,14 +2880,13 @@ static int DumpOat(Runtime* runtime, << "oatdump might fail if the oat file does not contain the dex code."; } std::string error_msg; - std::unique_ptr<OatFile> oat_file(OatFile::Open(/* zip_fd= */ -1, + std::unique_ptr<OatFile> oat_file(OatFile::Open(/*zip_fd=*/ -1, oat_filename, oat_filename, - /* requested_base= */ nullptr, - /* executable= */ false, - /* low_4gb= */ false, + /*executable=*/ false, + /*low_4gb=*/ false, dex_filename, - /* reservation= */ nullptr, + /*reservation=*/ nullptr, &error_msg)); if (oat_file == nullptr) { LOG(ERROR) << "Failed to open oat file from '" << oat_filename << "': " << error_msg; @@ -2908,14 +2905,13 @@ static int SymbolizeOat(const char* oat_filename, std::string& output_name, bool no_bits) { std::string error_msg; - std::unique_ptr<OatFile> oat_file(OatFile::Open(/* zip_fd= */ -1, + std::unique_ptr<OatFile> oat_file(OatFile::Open(/*zip_fd=*/ -1, oat_filename, oat_filename, - /* requested_base= */ nullptr, - /* executable= */ false, - /* low_4gb= */ false, + /*executable=*/ false, + /*low_4gb=*/ false, dex_filename, - /* reservation= */ nullptr, + /*reservation=*/ nullptr, &error_msg)); if (oat_file == nullptr) { LOG(ERROR) << "Failed to open oat file from '" << oat_filename << "': " << error_msg; @@ -2956,14 +2952,13 @@ class IMTDumper { if (oat_filename != nullptr) { std::string error_msg; - std::unique_ptr<OatFile> oat_file(OatFile::Open(/* zip_fd= */ -1, + std::unique_ptr<OatFile> oat_file(OatFile::Open(/*zip_fd=*/ -1, oat_filename, oat_filename, - /* requested_base= */ nullptr, - /* executable= */ false, + /*executable=*/ false, /*low_4gb=*/false, dex_filename, - /* reservation= */ nullptr, + /*reservation=*/ nullptr, &error_msg)); if (oat_file == nullptr) { LOG(ERROR) << "Failed to open oat file from '" << oat_filename << "': " << error_msg; diff --git a/openjdkjvmti/OpenjdkJvmTi.cc b/openjdkjvmti/OpenjdkJvmTi.cc index 48f326a54d..4bc33b68ca 100644 --- a/openjdkjvmti/OpenjdkJvmTi.cc +++ b/openjdkjvmti/OpenjdkJvmTi.cc @@ -1195,7 +1195,7 @@ class JvmtiFunctions { #undef ADD_CAPABILITY gEventHandler->HandleChangedCapabilities(ArtJvmTiEnv::AsArtJvmTiEnv(env), changed, - /*added*/true); + /*added=*/true); return ret; } @@ -1219,7 +1219,7 @@ class JvmtiFunctions { #undef DEL_CAPABILITY gEventHandler->HandleChangedCapabilities(ArtJvmTiEnv::AsArtJvmTiEnv(env), changed, - /*added*/false); + /*added=*/false); return OK; } diff --git a/openjdkjvmti/deopt_manager.cc b/openjdkjvmti/deopt_manager.cc index d20c756522..8bac38a355 100644 --- a/openjdkjvmti/deopt_manager.cc +++ b/openjdkjvmti/deopt_manager.cc @@ -289,7 +289,7 @@ class ScopedDeoptimizationContext : public art::ValueObject { uninterruptible_cause_ = critical_section_.Enter(art::gc::kGcCauseInstrumentation, art::gc::kCollectorTypeCriticalSection); art::Runtime::Current()->GetThreadList()->SuspendAll("JMVTI Deoptimizing methods", - /*long_suspend*/ false); + /*long_suspend=*/ false); } ~ScopedDeoptimizationContext() diff --git a/openjdkjvmti/events.cc b/openjdkjvmti/events.cc index 300a0094d4..48df53a143 100644 --- a/openjdkjvmti/events.cc +++ b/openjdkjvmti/events.cc @@ -517,7 +517,7 @@ class JvmtiMethodTraceListener final : public art::instrumentation::Instrumentat self, jnienv, art::jni::EncodeArtMethod(method), - /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE), + /*was_popped_by_exception=*/ static_cast<jboolean>(JNI_FALSE), val); } } @@ -545,7 +545,7 @@ class JvmtiMethodTraceListener final : public art::instrumentation::Instrumentat self, jnienv, art::jni::EncodeArtMethod(method), - /*was_popped_by_exception*/ static_cast<jboolean>(JNI_FALSE), + /*was_popped_by_exception=*/ static_cast<jboolean>(JNI_FALSE), val); } } @@ -572,7 +572,7 @@ class JvmtiMethodTraceListener final : public art::instrumentation::Instrumentat self, jnienv, art::jni::EncodeArtMethod(method), - /*was_popped_by_exception*/ static_cast<jboolean>(JNI_TRUE), + /*was_popped_by_exception=*/ static_cast<jboolean>(JNI_TRUE), val); // Match RI behavior of just throwing away original exception if a new one is thrown. if (LIKELY(!self->IsExceptionPending())) { @@ -777,7 +777,7 @@ class JvmtiMethodTraceListener final : public art::instrumentation::Instrumentat context.get(), /*out*/ out_method, /*out*/ dex_pc); - clf.WalkStack(/* include_transitions */ false); + clf.WalkStack(/* include_transitions= */ false); } // Call-back when an exception is thrown. @@ -793,8 +793,8 @@ class JvmtiMethodTraceListener final : public art::instrumentation::Instrumentat FindCatchMethodsFromThrow(self, exception_object, &catch_method, &catch_pc); uint32_t dex_pc = 0; art::ArtMethod* method = self->GetCurrentMethod(&dex_pc, - /* check_suspended */ true, - /* abort_on_error */ art::kIsDebugBuild); + /* check_suspended= */ true, + /* abort_on_error= */ art::kIsDebugBuild); ScopedLocalRef<jobject> exception(jnienv, AddLocalRef<jobject>(jnienv, exception_object.Get())); RunEventCallback<ArtJvmtiEvent::kException>( @@ -819,8 +819,8 @@ class JvmtiMethodTraceListener final : public art::instrumentation::Instrumentat art::JNIEnvExt* jnienv = self->GetJniEnv(); uint32_t dex_pc; art::ArtMethod* method = self->GetCurrentMethod(&dex_pc, - /* check_suspended */ true, - /* abort_on_error */ art::kIsDebugBuild); + /* check_suspended= */ true, + /* abort_on_error= */ art::kIsDebugBuild); ScopedLocalRef<jobject> exception(jnienv, AddLocalRef<jobject>(jnienv, exception_object.Get())); RunEventCallback<ArtJvmtiEvent::kExceptionCatch>( diff --git a/openjdkjvmti/fixed_up_dex_file.cc b/openjdkjvmti/fixed_up_dex_file.cc index aedec270b5..6745d91d53 100644 --- a/openjdkjvmti/fixed_up_dex_file.cc +++ b/openjdkjvmti/fixed_up_dex_file.cc @@ -67,7 +67,9 @@ static void DoDexUnquicken(const art::DexFile& new_dex_file, const art::DexFile& original_dex_file) { const art::VdexFile* vdex = GetVdex(original_dex_file); if (vdex != nullptr) { - vdex->UnquickenDexFile(new_dex_file, original_dex_file, /* decompile_return_instruction */true); + vdex->UnquickenDexFile(new_dex_file, + original_dex_file, + /* decompile_return_instruction= */ true); } new_dex_file.UnhideApis(); } @@ -79,7 +81,7 @@ static void DCheckVerifyDexFile(const art::DexFile& dex) { dex.Begin(), dex.Size(), "FixedUpDexFile_Verification.dex", - /*verify_checksum*/ true, + /*verify_checksum=*/ true, &error)) { LOG(FATAL) << "Failed to verify de-quickened dex file: " << error; } @@ -113,9 +115,9 @@ std::unique_ptr<FixedUpDexFile> FixedUpDexFile::Create(const art::DexFile& origi options.class_filter_.insert(descriptor); } art::DexLayout dex_layout(options, - /*info*/ nullptr, - /*out_file*/ nullptr, - /*header*/ nullptr); + /*info=*/ nullptr, + /*out_file=*/ nullptr, + /*header=*/ nullptr); std::unique_ptr<art::DexContainer> dex_container; bool result = dex_layout.ProcessDexFile( original.GetLocation().c_str(), @@ -136,11 +138,11 @@ std::unique_ptr<FixedUpDexFile> FixedUpDexFile::Create(const art::DexFile& origi new_dex_file = dex_file_loader.Open( data.data(), data.size(), - /*location*/"Unquickening_dexfile.dex", - /*location_checksum*/0, - /*oat_dex_file*/nullptr, - /*verify*/false, - /*verify_checksum*/false, + /*location=*/"Unquickening_dexfile.dex", + /*location_checksum=*/0, + /*oat_dex_file=*/nullptr, + /*verify=*/false, + /*verify_checksum=*/false, &error); if (new_dex_file == nullptr) { diff --git a/openjdkjvmti/object_tagging.cc b/openjdkjvmti/object_tagging.cc index 1562fb6eb6..0a51bf2f6b 100644 --- a/openjdkjvmti/object_tagging.cc +++ b/openjdkjvmti/object_tagging.cc @@ -43,6 +43,34 @@ namespace openjdkjvmti { // Instantiate for jlong = JVMTI tags. template class JvmtiWeakTable<jlong>; +void ObjectTagTable::Allow() { + JvmtiWeakTable<jlong>::Allow(); + SendDelayedFreeEvents(); +} + +void ObjectTagTable::Broadcast(bool broadcast_for_checkpoint) { + JvmtiWeakTable<jlong>::Broadcast(broadcast_for_checkpoint); + if (!broadcast_for_checkpoint) { + SendDelayedFreeEvents(); + } +} + +void ObjectTagTable::SendDelayedFreeEvents() { + std::vector<jlong> to_send; + { + art::MutexLock mu(art::Thread::Current(), lock_); + to_send.swap(null_tags_); + } + for (jlong t : to_send) { + SendSingleFreeEvent(t); + } +} + +void ObjectTagTable::SendSingleFreeEvent(jlong tag) { + event_handler_->DispatchEventOnEnv<ArtJvmtiEvent::kObjectFree>( + jvmti_env_, art::Thread::Current(), tag); +} + bool ObjectTagTable::Set(art::mirror::Object* obj, jlong new_tag) { if (new_tag == 0) { jlong tmp; @@ -50,6 +78,7 @@ bool ObjectTagTable::Set(art::mirror::Object* obj, jlong new_tag) { } return JvmtiWeakTable<jlong>::Set(obj, new_tag); } + bool ObjectTagTable::SetLocked(art::mirror::Object* obj, jlong new_tag) { if (new_tag == 0) { jlong tmp; @@ -61,9 +90,10 @@ bool ObjectTagTable::SetLocked(art::mirror::Object* obj, jlong new_tag) { bool ObjectTagTable::DoesHandleNullOnSweep() { return event_handler_->IsEventEnabledAnywhere(ArtJvmtiEvent::kObjectFree); } + void ObjectTagTable::HandleNullSweep(jlong tag) { - event_handler_->DispatchEventOnEnv<ArtJvmtiEvent::kObjectFree>( - jvmti_env_, art::Thread::Current(), tag); + art::MutexLock mu(art::Thread::Current(), lock_); + null_tags_.push_back(tag); } } // namespace openjdkjvmti diff --git a/openjdkjvmti/object_tagging.h b/openjdkjvmti/object_tagging.h index 4181302f3a..ca05a05541 100644 --- a/openjdkjvmti/object_tagging.h +++ b/openjdkjvmti/object_tagging.h @@ -48,7 +48,18 @@ class EventHandler; class ObjectTagTable final : public JvmtiWeakTable<jlong> { public: ObjectTagTable(EventHandler* event_handler, ArtJvmTiEnv* env) - : event_handler_(event_handler), jvmti_env_(env) {} + : lock_("Object tag table lock", art::LockLevel::kGenericBottomLock), + event_handler_(event_handler), + jvmti_env_(env) {} + + // Denotes that weak-refs are visible on all threads. Used by semi-space. + void Allow() override + REQUIRES_SHARED(art::Locks::mutator_lock_) + REQUIRES(!allow_disallow_lock_); + // Used by cms and the checkpoint system. + void Broadcast(bool broadcast_for_checkpoint) override + REQUIRES_SHARED(art::Locks::mutator_lock_) + REQUIRES(!allow_disallow_lock_); bool Set(art::mirror::Object* obj, jlong tag) override REQUIRES_SHARED(art::Locks::mutator_lock_) @@ -77,6 +88,16 @@ class ObjectTagTable final : public JvmtiWeakTable<jlong> { void HandleNullSweep(jlong tag) override; private: + void SendDelayedFreeEvents() + REQUIRES_SHARED(art::Locks::mutator_lock_) + REQUIRES(!allow_disallow_lock_); + + void SendSingleFreeEvent(jlong tag) + REQUIRES_SHARED(art::Locks::mutator_lock_) + REQUIRES(!allow_disallow_lock_, !lock_); + + art::Mutex lock_ BOTTOM_MUTEX_ACQUIRED_AFTER; + std::vector<jlong> null_tags_ GUARDED_BY(lock_); EventHandler* event_handler_; ArtJvmTiEnv* jvmti_env_; }; diff --git a/openjdkjvmti/ti_class.cc b/openjdkjvmti/ti_class.cc index f6113dfecc..3d33487970 100644 --- a/openjdkjvmti/ti_class.cc +++ b/openjdkjvmti/ti_class.cc @@ -113,8 +113,8 @@ static std::unique_ptr<const art::DexFile> MakeSingleDexFile(art::Thread* self, std::unique_ptr<const art::DexFile> dex_file(dex_file_loader.Open(map_name, checksum, std::move(map), - /*verify*/true, - /*verify_checksum*/true, + /*verify=*/true, + /*verify_checksum=*/true, &error_msg)); if (dex_file.get() == nullptr) { LOG(WARNING) << "Unable to load modified dex file for " << descriptor << ": " << error_msg; diff --git a/openjdkjvmti/ti_class_definition.cc b/openjdkjvmti/ti_class_definition.cc index 895e73450e..9e8288f997 100644 --- a/openjdkjvmti/ti_class_definition.cc +++ b/openjdkjvmti/ti_class_definition.cc @@ -246,17 +246,17 @@ void ArtClassDefinition::InitWithDex(GetOriginalDexFile get_original, mmap_name += name_; std::string error; dex_data_mmap_ = art::MemMap::MapAnonymous(mmap_name.c_str(), - /* addr */ nullptr, + /* addr= */ nullptr, dequick_size, PROT_NONE, - /*low_4gb*/ false, + /*low_4gb=*/ false, &error); mmap_name += "-TEMP"; temp_mmap_ = art::MemMap::MapAnonymous(mmap_name.c_str(), - /* addr */ nullptr, + /* addr= */ nullptr, dequick_size, PROT_READ | PROT_WRITE, - /*low_4gb*/ false, + /*low_4gb=*/ false, &error); if (UNLIKELY(dex_data_mmap_.IsValid() && temp_mmap_.IsValid())) { // Need to save the initial dexfile so we don't need to search for it in the fault-handler. diff --git a/openjdkjvmti/ti_extension.cc b/openjdkjvmti/ti_extension.cc index c61d6e585c..c628a325eb 100644 --- a/openjdkjvmti/ti_extension.cc +++ b/openjdkjvmti/ti_extension.cc @@ -424,7 +424,7 @@ jvmtiError ExtensionUtil::SetExtensionEventCallback(jvmtiEnv* env, } } return event_handler->SetEvent(art_env, - /*event_thread*/nullptr, + /*thread=*/nullptr, static_cast<ArtJvmtiEvent>(extension_event_index), mode); } diff --git a/openjdkjvmti/ti_heap.cc b/openjdkjvmti/ti_heap.cc index f19d0a0134..01ef4c6286 100644 --- a/openjdkjvmti/ti_heap.cc +++ b/openjdkjvmti/ti_heap.cc @@ -981,7 +981,9 @@ class FollowReferencesHelper final { // TODO: We don't have this info. if (thread != nullptr) { ref_info->jni_local.depth = 0; - art::ArtMethod* method = thread->GetCurrentMethod(nullptr, false /* abort_on_error */); + art::ArtMethod* method = thread->GetCurrentMethod(nullptr, + /* check_suspended= */ true, + /* abort_on_error= */ false); if (method != nullptr) { ref_info->jni_local.method = art::jni::EncodeArtMethod(method); } @@ -1012,7 +1014,7 @@ class FollowReferencesHelper final { ref_info->stack_local.slot = static_cast<jint>(java_info.GetVReg()); const art::StackVisitor* visitor = java_info.GetVisitor(); ref_info->stack_local.location = - static_cast<jlocation>(visitor->GetDexPc(false /* abort_on_failure */)); + static_cast<jlocation>(visitor->GetDexPc(/* abort_on_failure= */ false)); ref_info->stack_local.depth = static_cast<jint>(visitor->GetFrameDepth()); art::ArtMethod* method = visitor->GetMethod(); if (method != nullptr) { @@ -1447,7 +1449,7 @@ jvmtiError HeapUtil::GetLoadedClasses(jvmtiEnv* env, } jvmtiError HeapUtil::ForceGarbageCollection(jvmtiEnv* env ATTRIBUTE_UNUSED) { - art::Runtime::Current()->GetHeap()->CollectGarbage(/* clear_soft_references */ false); + art::Runtime::Current()->GetHeap()->CollectGarbage(/* clear_soft_references= */ false); return ERR(NONE); } diff --git a/openjdkjvmti/ti_method.cc b/openjdkjvmti/ti_method.cc index 295894157c..7d69c89d1e 100644 --- a/openjdkjvmti/ti_method.cc +++ b/openjdkjvmti/ti_method.cc @@ -547,7 +547,7 @@ class CommonLocalVariableClosure : public art::Closure { return; } bool needs_instrument = !visitor.IsShadowFrame(); - uint32_t pc = visitor.GetDexPc(/*abort_on_failure*/ false); + uint32_t pc = visitor.GetDexPc(/*abort_on_failure=*/ false); if (pc == art::dex::kDexNoIndex) { // Cannot figure out current PC. result_ = ERR(OPAQUE_FRAME); diff --git a/openjdkjvmti/ti_monitor.cc b/openjdkjvmti/ti_monitor.cc index f71328a6b6..aac7233303 100644 --- a/openjdkjvmti/ti_monitor.cc +++ b/openjdkjvmti/ti_monitor.cc @@ -191,7 +191,7 @@ class JvmtiMonitor { // Reaquire the mutex/monitor, also go to sleep if we were suspended. // TODO Give an extension to wait without suspension as well. - MonitorEnter(self, /*suspend*/ true); + MonitorEnter(self, /*suspend=*/ true); CHECK(owner_.load(std::memory_order_relaxed) == self); DCHECK_EQ(1u, count_); // Reset the count. @@ -261,7 +261,7 @@ jvmtiError MonitorUtil::RawMonitorEnterNoSuspend(jvmtiEnv* env ATTRIBUTE_UNUSED, JvmtiMonitor* monitor = DecodeMonitor(id); art::Thread* self = art::Thread::Current(); - monitor->MonitorEnter(self, /*suspend*/false); + monitor->MonitorEnter(self, /*suspend=*/false); return ERR(NONE); } @@ -274,7 +274,7 @@ jvmtiError MonitorUtil::RawMonitorEnter(jvmtiEnv* env ATTRIBUTE_UNUSED, jrawMoni JvmtiMonitor* monitor = DecodeMonitor(id); art::Thread* self = art::Thread::Current(); - monitor->MonitorEnter(self, /*suspend*/true); + monitor->MonitorEnter(self, /*suspend=*/true); return ERR(NONE); } diff --git a/openjdkjvmti/ti_object.cc b/openjdkjvmti/ti_object.cc index 89ce35256d..344ae88546 100644 --- a/openjdkjvmti/ti_object.cc +++ b/openjdkjvmti/ti_object.cc @@ -92,7 +92,7 @@ jvmtiError ObjectUtil::GetObjectMonitorUsage( { art::ScopedObjectAccess soa(self); // Now we know we have the shared lock. art::ScopedThreadSuspension sts(self, art::kNative); - art::ScopedSuspendAll ssa("GetObjectMonitorUsage", /*long_suspend*/false); + art::ScopedSuspendAll ssa("GetObjectMonitorUsage", /*long_suspend=*/false); art::ObjPtr<art::mirror::Object> target(self->DecodeJObject(obj)); // This gets the list of threads trying to lock or wait on the monitor. art::MonitorInfo info(target.Ptr()); diff --git a/openjdkjvmti/ti_redefine.cc b/openjdkjvmti/ti_redefine.cc index db2b143022..7525c021f5 100644 --- a/openjdkjvmti/ti_redefine.cc +++ b/openjdkjvmti/ti_redefine.cc @@ -152,7 +152,7 @@ class ObsoleteMethodStackVisitor : public art::StackVisitor { const std::unordered_set<art::ArtMethod*>& obsoleted_methods, ObsoleteMap* obsolete_maps) : StackVisitor(thread, - /*context*/nullptr, + /*context=*/nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames), allocator_(allocator), obsoleted_methods_(obsoleted_methods), @@ -305,10 +305,10 @@ art::MemMap Redefiner::MoveDataToMemMap(const std::string& original_location, std::string* error_msg) { art::MemMap map = art::MemMap::MapAnonymous( StringPrintf("%s-transformed", original_location.c_str()).c_str(), - /* addr */ nullptr, + /* addr= */ nullptr, data.size(), PROT_READ|PROT_WRITE, - /*low_4gb*/ false, + /*low_4gb=*/ false, error_msg); if (LIKELY(map.IsValid())) { memcpy(map.Begin(), data.data(), data.size()); @@ -445,8 +445,8 @@ jvmtiError Redefiner::AddRedefinition(ArtJvmTiEnv* env, const ArtClassDefinition std::unique_ptr<const art::DexFile> dex_file(dex_file_loader.Open(name, checksum, std::move(map), - /*verify*/true, - /*verify_checksum*/true, + /*verify=*/true, + /*verify_checksum=*/true, error_msg_)); if (dex_file.get() == nullptr) { os << "Unable to load modified dex file for " << def.GetName() << ": " << *error_msg_; @@ -1117,10 +1117,10 @@ bool Redefiner::ClassRedefinition::CheckVerification(const RedefinitionDataIter& dex_file_.get(), hs.NewHandle(iter.GetNewDexCache()), hs.NewHandle(GetClassLoader()), - dex_file_->GetClassDef(0), /*class_def*/ - nullptr, /*compiler_callbacks*/ - true, /*allow_soft_failures*/ - /*log_level*/ + /*class_def=*/ dex_file_->GetClassDef(0), + /*callbacks=*/ nullptr, + /*allow_soft_failures=*/ true, + /*log_level=*/ art::verifier::HardFailLogMode::kLogWarning, art::Runtime::Current()->GetTargetSdkVersion(), &error); @@ -1288,7 +1288,7 @@ bool Redefiner::FinishAllRemainingAllocations(RedefinitionDataHolder& holder) { } void Redefiner::ClassRedefinition::ReleaseDexFile() { - dex_file_.release(); + dex_file_.release(); // NOLINT b/117926937 } void Redefiner::ReleaseAllDexFiles() { @@ -1367,7 +1367,7 @@ jvmtiError Redefiner::Run() { // TODO We might want to give this its own suspended state! // TODO This isn't right. We need to change state without any chance of suspend ideally! art::ScopedThreadSuspension sts(self_, art::ThreadState::kNative); - art::ScopedSuspendAll ssa("Final installation of redefined Classes!", /*long_suspend*/true); + art::ScopedSuspendAll ssa("Final installation of redefined Classes!", /*long_suspend=*/true); for (RedefinitionDataIter data = holder.begin(); data != holder.end(); ++data) { art::ScopedAssertNoThreadSuspension nts("Updating runtime objects for redefinition"); ClassRedefinition& redef = data.GetRedefinition(); diff --git a/openjdkjvmti/ti_search.cc b/openjdkjvmti/ti_search.cc index 1189b1dec5..427869e798 100644 --- a/openjdkjvmti/ti_search.cc +++ b/openjdkjvmti/ti_search.cc @@ -229,8 +229,12 @@ jvmtiError SearchUtil::AddToBootstrapClassLoaderSearch(jvmtiEnv* env ATTRIBUTE_U std::string error_msg; std::vector<std::unique_ptr<const art::DexFile>> dex_files; const art::ArtDexFileLoader dex_file_loader; - if (!dex_file_loader.Open( - segment, segment, /* verify */ true, /* verify_checksum */ true, &error_msg, &dex_files)) { + if (!dex_file_loader.Open(segment, + segment, + /* verify= */ true, + /* verify_checksum= */ true, + &error_msg, + &dex_files)) { LOG(WARNING) << "Could not open " << segment << " for boot classpath extension: " << error_msg; return ERR(ILLEGAL_ARGUMENT); } diff --git a/openjdkjvmti/ti_stack.cc b/openjdkjvmti/ti_stack.cc index 5a98755c67..1279f3bde5 100644 --- a/openjdkjvmti/ti_stack.cc +++ b/openjdkjvmti/ti_stack.cc @@ -150,7 +150,7 @@ struct GetStackTraceVectorClosure : public art::Closure { frames.push_back(info); }; auto visitor = MakeStackTraceVisitor(self, start_input, stop_input, frames_fn); - visitor.WalkStack(/* include_transitions */ false); + visitor.WalkStack(/* include_transitions= */ false); start_result = visitor.start; stop_result = visitor.stop; @@ -218,7 +218,7 @@ struct GetStackTraceDirectClosure : public art::Closure { ++index; }; auto visitor = MakeStackTraceVisitor(self, start_input, stop_input, frames_fn); - visitor.WalkStack(/* include_transitions */ false); + visitor.WalkStack(/* include_transitions= */ false); } jvmtiFrameInfo* frame_buffer; @@ -330,7 +330,7 @@ struct GetAllStackTracesVectorClosure : public art::Closure { thread_frames->push_back(info); }; auto visitor = MakeStackTraceVisitor(thread, 0u, stop_input, frames_fn); - visitor.WalkStack(/* include_transitions */ false); + visitor.WalkStack(/* include_transitions= */ false); } art::Barrier barrier; @@ -910,7 +910,7 @@ struct MonitorInfoClosure : public art::Closure { art::Locks::mutator_lock_->AssertSharedHeld(art::Thread::Current()); // Find the monitors on the stack. MonitorVisitor visitor(target); - visitor.WalkStack(/* include_transitions */ false); + visitor.WalkStack(/* include_transitions= */ false); // Find any other monitors, including ones acquired in native code. art::RootInfo root_info(art::kRootVMInternal); target->GetJniEnv()->VisitMonitorRoots(&visitor, root_info); diff --git a/openjdkjvmti/ti_thread.cc b/openjdkjvmti/ti_thread.cc index a0e5b5c926..2131120a11 100644 --- a/openjdkjvmti/ti_thread.cc +++ b/openjdkjvmti/ti_thread.cc @@ -812,7 +812,7 @@ jvmtiError ThreadUtil::RunAgentThread(jvmtiEnv* jvmti_env, runtime->EndThreadBirth(); return ERR(INTERNAL); } - data.release(); + data.release(); // NOLINT pthreads API. return ERR(NONE); } @@ -857,7 +857,7 @@ jvmtiError ThreadUtil::SuspendOther(art::Thread* self, bool timeout = true; art::Thread* ret_target = art::Runtime::Current()->GetThreadList()->SuspendThreadByPeer( target_jthread, - /* request_suspension */ true, + /* request_suspension= */ true, art::SuspendReason::kForUserCode, &timeout); if (ret_target == nullptr && !timeout) { diff --git a/openjdkjvmti/transform.cc b/openjdkjvmti/transform.cc index d87ca56b85..653f944d7c 100644 --- a/openjdkjvmti/transform.cc +++ b/openjdkjvmti/transform.cc @@ -76,7 +76,7 @@ class TransformationFaultHandler final : public art::FaultHandler { art::LockLevel::kSignalHandlingLock), class_definition_initialized_cond_("JVMTI Initialized class definitions condition", uninitialized_class_definitions_lock_) { - manager->AddHandler(this, /* generated_code */ false); + manager->AddHandler(this, /* generated_code= */ false); } ~TransformationFaultHandler() { diff --git a/runtime/Android.bp b/runtime/Android.bp index 33ad987ad6..bedeaf7803 100644 --- a/runtime/Android.bp +++ b/runtime/Android.bp @@ -379,6 +379,7 @@ libart_cc_defaults { ], header_libs: [ "art_cmdlineparser_headers", + "cpp-define-generator-definitions", "libnativehelper_header_only", "jni_platform_headers", ], @@ -639,7 +640,6 @@ art_cc_test { ], header_libs: [ "art_cmdlineparser_headers", // For parsed_options_test. - "cpp-define-generator-definitions", ], include_dirs: [ "external/zlib", diff --git a/runtime/arch/arch_test.cc b/runtime/arch/arch_test.cc index dcc3affb6b..12ad84b2dd 100644 --- a/runtime/arch/arch_test.cc +++ b/runtime/arch/arch_test.cc @@ -17,17 +17,11 @@ #include <stdint.h> #include "art_method-inl.h" -#include "asm_defines.h" #include "base/callee_save_type.h" #include "entrypoints/quick/callee_save_frame.h" #include "common_runtime_test.h" #include "quick/quick_method_frame_info.h" -// Static asserts to check the values of generated #defines for assembly. -#define ASM_DEFINE(NAME, EXPR) static_assert((NAME) == (EXPR), "Unexpected value of " #NAME); -#include "asm_defines.def" -#undef ASM_DEFINE - namespace art { class ArchTest : public CommonRuntimeTest { diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc index b2ddff3f6a..c11e3d1e6e 100644 --- a/runtime/base/mutex.cc +++ b/runtime/base/mutex.cc @@ -1028,7 +1028,11 @@ bool ConditionVariable::TimedWait(Thread* self, int64_t ms, int32_t ns) { guard_.recursion_count_ = 0; timespec ts; InitTimeSpec(true, clock, ms, ns, &ts); - int rc = TEMP_FAILURE_RETRY(pthread_cond_timedwait(&cond_, &guard_.mutex_, &ts)); + int rc; + while ((rc = pthread_cond_timedwait(&cond_, &guard_.mutex_, &ts)) == EINTR) { + continue; + } + if (rc == ETIMEDOUT) { timed_out = true; } else if (rc != 0) { diff --git a/runtime/class_linker.h b/runtime/class_linker.h index 996427e7c6..b6f1f865d6 100644 --- a/runtime/class_linker.h +++ b/runtime/class_linker.h @@ -111,7 +111,9 @@ class AllocatorVisitor { class ClassLinker { public: - static constexpr bool kAppImageMayContainStrings = true; + // Disabled until AppImageLoadingHelper::UpdateInternStrings does the missing GC card marks. + // Bug: 117846779 + static constexpr bool kAppImageMayContainStrings = false; explicit ClassLinker(InternTable* intern_table); virtual ~ClassLinker(); diff --git a/runtime/class_loader_context.cc b/runtime/class_loader_context.cc index 4da0091884..5c8d68527b 100644 --- a/runtime/class_loader_context.cc +++ b/runtime/class_loader_context.cc @@ -64,10 +64,10 @@ ClassLoaderContext::~ClassLoaderContext() { // make sure we do not de-allocate them. for (ClassLoaderInfo& info : class_loader_chain_) { for (std::unique_ptr<OatFile>& oat_file : info.opened_oat_files) { - oat_file.release(); + oat_file.release(); // NOLINT b/117926937 } for (std::unique_ptr<const DexFile>& dex_file : info.opened_dex_files) { - dex_file.release(); + dex_file.release(); // NOLINT b/117926937 } } } diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h index a5157df36b..14605623e5 100644 --- a/runtime/common_runtime_test.h +++ b/runtime/common_runtime_test.h @@ -191,6 +191,12 @@ class CheckJniAbortCatcher { DISALLOW_COPY_AND_ASSIGN(CheckJniAbortCatcher); }; +#define TEST_DISABLED() \ + if ((true)) { \ + printf("WARNING: TEST DISABLED\n"); \ + return; \ + } + #define TEST_DISABLED_FOR_ARM() \ if (kRuntimeISA == InstructionSet::kArm || kRuntimeISA == InstructionSet::kThumb2) { \ printf("WARNING: TEST DISABLED FOR ARM\n"); \ diff --git a/runtime/dexopt_test.cc b/runtime/dexopt_test.cc index 462620f53a..429ecd3c32 100644 --- a/runtime/dexopt_test.cc +++ b/runtime/dexopt_test.cc @@ -123,14 +123,13 @@ void DexoptTest::GenerateOatForTest(const std::string& dex_location, ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg; // Verify the odex file was generated as expected. - std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1, oat_location.c_str(), oat_location.c_str(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, + /*executable=*/ false, + /*low_4gb=*/ false, dex_location.c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(odex_file.get() != nullptr) << error_msg; EXPECT_EQ(filter, odex_file->GetCompilerFilter()); @@ -159,7 +158,7 @@ void DexoptTest::GenerateOdexForTest(const std::string& dex_location, GenerateOatForTest(dex_location, odex_location, filter, - /* with_alternate_image */ false, + /*with_alternate_image=*/ false, compilation_reason); } @@ -177,7 +176,7 @@ void DexoptTest::GenerateOatForTest(const char* dex_location, } void DexoptTest::GenerateOatForTest(const char* dex_location, CompilerFilter::Filter filter) { - GenerateOatForTest(dex_location, filter, /* with_alternate_image */ false); + GenerateOatForTest(dex_location, filter, /*with_alternate_image=*/ false); } void DexoptTest::ReserveImageSpace() { diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h index 62b3d001ba..35bfa91aed 100644 --- a/runtime/entrypoints/entrypoint_utils-inl.h +++ b/runtime/entrypoints/entrypoint_utils-inl.h @@ -530,7 +530,13 @@ ALWAYS_INLINE ArtMethod* FindMethodToCall(uint32_t method_idx, UNREACHABLE(); } case kInterface: { - uint32_t imt_index = ImTable::GetImtIndex(resolved_method); + size_t imt_index; + InterpreterCache* tls_cache = self->GetInterpreterCache(); + if (UNLIKELY(!tls_cache->Get(resolved_method, &imt_index))) { + imt_index = ImTable::GetImtIndex(resolved_method); + tls_cache->Set(resolved_method, imt_index); + } + DCHECK_EQ(imt_index, ImTable::GetImtIndex(resolved_method)); PointerSize pointer_size = class_linker->GetImagePointerSize(); ObjPtr<mirror::Class> klass = (*this_object)->GetClass(); ArtMethod* imt_method = klass->GetImt(pointer_size)->Get(imt_index, pointer_size); diff --git a/runtime/entrypoints_order_test.cc b/runtime/entrypoints_order_test.cc index 50c65ea505..f45197834f 100644 --- a/runtime/entrypoints_order_test.cc +++ b/runtime/entrypoints_order_test.cc @@ -127,9 +127,7 @@ class EntrypointsOrderTest : public CommonRuntimeTest { EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, thread_local_objects, jni_entrypoints, sizeof(size_t)); // Skip across the entrypoints structures. - EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, mterp_current_ibase, mterp_default_ibase, sizeof(void*)); - EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, mterp_default_ibase, mterp_alt_ibase, sizeof(void*)); - EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, mterp_alt_ibase, rosalloc_runs, sizeof(void*)); + EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, mterp_current_ibase, rosalloc_runs, sizeof(void*)); EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, rosalloc_runs, thread_local_alloc_stack_top, sizeof(void*) * kNumRosAllocThreadLocalSizeBracketsInThread); EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, thread_local_alloc_stack_top, thread_local_alloc_stack_end, diff --git a/runtime/gc/collector/semi_space.cc b/runtime/gc/collector/semi_space.cc index 8cd484fc48..c58b59de48 100644 --- a/runtime/gc/collector/semi_space.cc +++ b/runtime/gc/collector/semi_space.cc @@ -251,6 +251,7 @@ void SemiSpace::MarkingPhase() { ReaderMutexLock mu(self_, *Locks::heap_bitmap_lock_); SweepSystemWeaks(); } + Runtime::Current()->BroadcastForNewSystemWeaks(); Runtime::Current()->GetClassLinker()->CleanupClassLoaders(); // Revoke buffers before measuring how many objects were moved since the TLABs need to be revoked // before they are properly counted. diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index a97e94c85b..6e6023d68c 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -184,7 +184,7 @@ static bool FindImageFilenameImpl(const char* image_location, bool have_android_data = false; *dalvik_cache_exists = false; GetDalvikCache(GetInstructionSetString(image_isa), - /* create_if_absent */ true, + /*create_if_absent=*/ true, dalvik_cache, &have_android_data, dalvik_cache_exists, @@ -389,7 +389,7 @@ class ImageSpace::Loader { /*inout*/MemMap* oat_reservation, /*out*/std::string* error_msg) REQUIRES_SHARED(Locks::mutator_lock_) { - TimingLogger logger(__PRETTY_FUNCTION__, /* precise= */ true, VLOG_IS_ON(image)); + TimingLogger logger(__PRETTY_FUNCTION__, /*precise=*/ true, VLOG_IS_ON(image)); std::unique_ptr<ImageSpace> space = Init(image_filename, image_location, validate_oat_file, @@ -429,9 +429,9 @@ class ImageSpace::Loader { image_header->GetImageMethod(ImageHeader::kSaveEverythingMethodForSuspendCheck)); VLOG(image) << "ImageSpace::Loader::InitAppImage exiting " << *space.get(); - if (VLOG_IS_ON(image)) { - logger.Dump(LOG_STREAM(INFO)); - } + } + if (VLOG_IS_ON(image)) { + logger.Dump(LOG_STREAM(INFO)); } return space; } @@ -554,7 +554,7 @@ class ImageSpace::Loader { MAP_PRIVATE, file->Fd(), image_bitmap_offset, - /* low_4gb */ false, + /*low_4gb=*/ false, image_filename, error_msg); if (!image_bitmap_map.IsValid()) { @@ -640,10 +640,10 @@ class ImageSpace::Loader { PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, - /* start= */ 0, - /* low_4gb= */ true, + /*start=*/ 0, + /*low_4gb=*/ true, image_filename, - /* reuse= */ false, + /*reuse=*/ false, image_reservation, error_msg); } @@ -662,8 +662,8 @@ class ImageSpace::Loader { address, image_header.GetImageSize(), PROT_READ | PROT_WRITE, - /* low_4gb= */ true, - /* reuse= */ false, + /*low_4gb=*/ true, + /*reuse=*/ false, image_reservation, error_msg); if (map.IsValid()) { @@ -673,8 +673,8 @@ class ImageSpace::Loader { PROT_READ, MAP_PRIVATE, fd, - /* start= */ 0, - /* low_4gb= */ false, + /*start=*/ 0, + /*low_4gb=*/ false, image_filename, error_msg); if (!temp_map.IsValid()) { @@ -1262,13 +1262,12 @@ class ImageSpace::Loader { if (oat_reservation != nullptr) { oat_data_begin += oat_reservation->Begin() - image_header.GetOatFileBegin(); } - std::unique_ptr<OatFile> oat_file(OatFile::Open(/* zip_fd= */ -1, + std::unique_ptr<OatFile> oat_file(OatFile::Open(/*zip_fd=*/ -1, oat_filename, oat_filename, - oat_data_begin, !Runtime::Current()->IsAotCompiler(), - /* low_4gb= */ false, - /* abs_dex_location= */ nullptr, + /*low_4gb=*/ false, + /*abs_dex_location=*/ nullptr, oat_reservation, error_msg)); if (oat_file == nullptr) { @@ -1278,6 +1277,7 @@ class ImageSpace::Loader { error_msg->c_str()); return nullptr; } + CHECK(oat_data_begin == oat_file->Begin()); uint32_t oat_checksum = oat_file->GetOatHeader().GetChecksum(); uint32_t image_oat_checksum = image_header.GetOatChecksum(); if (oat_checksum != image_oat_checksum) { @@ -1342,7 +1342,7 @@ class ImageSpace::BootImageLoader { /*out*/std::vector<std::unique_ptr<space::ImageSpace>>* boot_image_spaces, /*out*/MemMap* extra_reservation, /*out*/std::string* error_msg) REQUIRES_SHARED(Locks::mutator_lock_) { - TimingLogger logger(__PRETTY_FUNCTION__, /* precise= */ true, VLOG_IS_ON(image)); + TimingLogger logger(__PRETTY_FUNCTION__, /*precise=*/ true, VLOG_IS_ON(image)); std::string filename = GetSystemImageFilename(image_location_.c_str(), image_isa_); std::vector<std::string> locations; if (!GetBootClassPathImageLocations(image_location_, filename, &locations, error_msg)) { @@ -1381,7 +1381,7 @@ class ImageSpace::BootImageLoader { filename = GetSystemImageFilename(location.c_str(), image_isa_); spaces.push_back(Load(location, filename, - /* validate_oat_file= */ false, + /*validate_oat_file=*/ false, &logger, &image_reservation, &oat_reservation, @@ -1397,9 +1397,9 @@ class ImageSpace::BootImageLoader { MaybeRelocateSpaces(spaces, &logger); InitRuntimeMethods(spaces); *extra_reservation = std::move(local_extra_reservation); + VLOG(image) << "ImageSpace::BootImageLoader::InitFromDalvikCache exiting " << *spaces.front(); boot_image_spaces->swap(spaces); - VLOG(image) << "ImageSpace::BootImageLoader::InitFromDalvikCache exiting " << *spaces.front(); if (VLOG_IS_ON(image)) { logger.Dump(LOG_STREAM(INFO)); } @@ -1412,7 +1412,7 @@ class ImageSpace::BootImageLoader { /*out*/std::vector<std::unique_ptr<space::ImageSpace>>* boot_image_spaces, /*out*/MemMap* extra_reservation, /*out*/std::string* error_msg) REQUIRES_SHARED(Locks::mutator_lock_) { - TimingLogger logger(__PRETTY_FUNCTION__, /* precise= */ true, VLOG_IS_ON(image)); + TimingLogger logger(__PRETTY_FUNCTION__, /*precise=*/ true, VLOG_IS_ON(image)); DCHECK(DalvikCacheExists()); std::vector<std::string> locations; if (!GetBootClassPathImageLocations(image_location_, cache_filename_, &locations, error_msg)) { @@ -1529,7 +1529,7 @@ class ImageSpace::BootImageLoader { PatchedObjectsMap(uint8_t* image_space_begin, size_t size) : image_space_begin_(image_space_begin), data_(new uint8_t[BitsToBytesRoundUp(NumLocations(size))]), - visited_objects_(data_.get(), /* bit_start= */ 0u, NumLocations(size)) { + visited_objects_(data_.get(), /*bit_start=*/ 0u, NumLocations(size)) { DCHECK_ALIGNED(image_space_begin_, kObjectAlignment); std::memset(data_.get(), 0, BitsToBytesRoundUp(NumLocations(size))); } @@ -1540,7 +1540,7 @@ class ImageSpace::BootImageLoader { ALWAYS_INLINE void MarkVisited(mirror::Object* object) { DCHECK(!IsVisited(object)); - visited_objects_.StoreBit(GetIndex(object), /* value= */ true); + visited_objects_.StoreBit(GetIndex(object), /*value=*/ true); } private: @@ -1565,7 +1565,7 @@ class ImageSpace::BootImageLoader { : diff_(diff) {} void Visit(ArtField* field) override REQUIRES_SHARED(Locks::mutator_lock_) { - PatchGcRoot</* kMayBeNull */ false>(diff_, &field->DeclaringClassRoot()); + PatchGcRoot</*kMayBeNull=*/ false>(diff_, &field->DeclaringClassRoot()); } private: @@ -1630,7 +1630,7 @@ class ImageSpace::BootImageLoader { static_assert(IsAligned<kHeapReferenceSize>(kObjectAlignment), "Object alignment check."); // First, patch the `klass->klass_`, known to be a reference to the j.l.Class.class. // This should be the only reference field in j.l.Object and we assert that below. - PatchReferenceField</* kMayBeNull */ false>(klass, mirror::Object::ClassOffset()); + PatchReferenceField</*kMayBeNull=*/ false>(klass, mirror::Object::ClassOffset()); // Then patch the reference instance fields described by j.l.Class.class. // Use the sizeof(Object) to determine where these reference fields start; // this is the same as `class_class->GetFirstReferenceInstanceFieldOffset()` @@ -1684,19 +1684,19 @@ class ImageSpace::BootImageLoader { void VisitPointerArray(mirror::PointerArray* pointer_array) REQUIRES_SHARED(Locks::mutator_lock_) { // Fully patch the pointer array, including the `klass_` field. - PatchReferenceField</* kMayBeNull */ false>(pointer_array, mirror::Object::ClassOffset()); + PatchReferenceField</*kMayBeNull=*/ false>(pointer_array, mirror::Object::ClassOffset()); int32_t length = pointer_array->GetLength<kVerifyNone>(); for (int32_t i = 0; i != length; ++i) { ArtMethod** method_entry = reinterpret_cast<ArtMethod**>( pointer_array->ElementAddress<kVerifyNone>(i, kPointerSize)); - PatchNativePointer<kPointerSize, /* kMayBeNull */ false>(diff_, method_entry); + PatchNativePointer<kPointerSize, /*kMayBeNull=*/ false>(diff_, method_entry); } } void VisitObject(mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_) { // Visit all reference fields. - object->VisitReferences</* kVisitNativeRoots */ false, + object->VisitReferences</*kVisitNativeRoots=*/ false, kVerifyNone, kWithoutReadBarrier>(*this, *this); // This function should not be called for classes. @@ -1713,7 +1713,7 @@ class ImageSpace::BootImageLoader { ALWAYS_INLINE void operator()(ObjPtr<mirror::Class> klass, mirror::Reference* ref) const REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(klass->IsTypeOfReferenceClass()); - this->operator()(ref, mirror::Reference::ReferentOffset(), /* is_static= */ false); + this->operator()(ref, mirror::Reference::ReferentOffset(), /*is_static=*/ false); } // Ignore class native roots; not called from VisitReferences() for kVisitNativeRoots == false. void VisitRootIfNonNull(mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED) @@ -1752,8 +1752,8 @@ class ImageSpace::BootImageLoader { DCHECK(kMayBeNull || old_value != nullptr); if (!kMayBeNull || old_value != nullptr) { mirror::Object* new_value = RelocatedAddress(old_value, diff_); - object->SetFieldObjectWithoutWriteBarrier</* kTransactionActive */ false, - /* kCheckTransaction */ true, + object->SetFieldObjectWithoutWriteBarrier</*kTransactionActive=*/ false, + /*kCheckTransaction=*/ true, kVerifyNone>(offset, new_value); } } @@ -1838,9 +1838,9 @@ class ImageSpace::BootImageLoader { if (image_header.GetInternedStringsSection().Size() != 0u) { const uint8_t* data = space->Begin() + image_header.GetInternedStringsSection().Offset(); size_t read_count; - InternTable::UnorderedSet temp_set(data, /* make_copy_of_data= */ false, &read_count); + InternTable::UnorderedSet temp_set(data, /*make_copy_of_data=*/ false, &read_count); for (GcRoot<mirror::String>& slot : temp_set) { - PatchGcRoot</* kMayBeNull */ false>(diff, &slot); + PatchGcRoot</*kMayBeNull=*/ false>(diff, &slot); } } @@ -1849,7 +1849,7 @@ class ImageSpace::BootImageLoader { if (image_header.GetClassTableSection().Size() != 0u) { uint8_t* data = space->Begin() + image_header.GetClassTableSection().Offset(); size_t read_count; - ClassTable::ClassSet temp_set(data, /* make_copy_of_data= */ false, &read_count); + ClassTable::ClassSet temp_set(data, /*make_copy_of_data=*/ false, &read_count); DCHECK(!temp_set.empty()); ClassTableVisitor class_table_visitor(diff); for (ClassTable::TableSlot& slot : temp_set) { @@ -1937,8 +1937,8 @@ class ImageSpace::BootImageLoader { ObjPtr<mirror::Executable>::DownCast(MakeObjPtr(object)); ArtMethod* unpatched_method = as_executable->GetArtMethod<kVerifyNone>(); ArtMethod* patched_method = RelocatedAddress(unpatched_method, diff); - as_executable->SetArtMethod</* kTransactionActive */ false, - /* kCheckTransaction */ true, + as_executable->SetArtMethod</*kTransactionActive=*/ false, + /*kCheckTransaction=*/ true, kVerifyNone>(patched_method); } } @@ -2021,8 +2021,8 @@ class ImageSpace::BootImageLoader { // descriptor (and the associated exclusive lock) to be released when // we leave Create. ScopedFlock image = LockedFile::Open(image_filename.c_str(), - rw_lock ? (O_CREAT | O_RDWR) : O_RDONLY /* flags */, - true /* block */, + /*flags=*/ rw_lock ? (O_CREAT | O_RDWR) : O_RDONLY, + /*block=*/ true, error_msg); VLOG(startup) << "Using image file " << image_filename.c_str() << " for image location " @@ -2036,7 +2036,7 @@ class ImageSpace::BootImageLoader { return Loader::Init(image_filename.c_str(), image_location.c_str(), validate_oat_file, - /* oat_file= */ nullptr, + /*oat_file=*/ nullptr, logger, image_reservation, oat_reservation, @@ -2050,14 +2050,13 @@ class ImageSpace::BootImageLoader { /*out*/ std::vector<std::string>* all_locations, /*out*/ std::string* error_msg) { std::string oat_filename = ImageHeader::GetOatLocationFromImageLocation(image_filename); - std::unique_ptr<OatFile> oat_file(OatFile::Open(/* zip_fd= */ -1, + std::unique_ptr<OatFile> oat_file(OatFile::Open(/*zip_fd=*/ -1, oat_filename, oat_filename, - /* requested_base= */ nullptr, - /* executable= */ false, - /* low_4gb= */ false, - /* abs_dex_location= */ nullptr, - /* reservation= */ nullptr, + /*executable=*/ false, + /*low_4gb=*/ false, + /*abs_dex_location=*/ nullptr, + /*reservation=*/ nullptr, error_msg)); if (oat_file == nullptr) { *error_msg = StringPrintf("Failed to open oat file '%s' for image file %s: %s", @@ -2111,9 +2110,9 @@ class ImageSpace::BootImageLoader { reinterpret_cast32<uint8_t*>(addr), total_size, PROT_NONE, - /* low_4gb= */ true, - /* reuse= */ false, - /* reservation= */ nullptr, + /*low_4gb=*/ true, + /*reuse=*/ false, + /*reservation=*/ nullptr, error_msg); if (!image_reservation->IsValid()) { return false; @@ -2286,7 +2285,7 @@ bool ImageSpace::LoadBootImage( // Step 2: Check if we have an existing image in the dalvik cache. if (loader.HasCache()) { std::string local_error_msg; - if (loader.LoadFromDalvikCache(/* validate_oat_file= */ true, + if (loader.LoadFromDalvikCache(/*validate_oat_file=*/ true, extra_reservation_size, boot_image_spaces, extra_reservation, @@ -2306,7 +2305,7 @@ bool ImageSpace::LoadBootImage( bool compilation_success = GenerateImage(loader.GetCacheFilename(), image_isa, &local_error_msg); if (compilation_success) { - if (loader.LoadFromDalvikCache(/* validate_oat_file= */ false, + if (loader.LoadFromDalvikCache(/*validate_oat_file=*/ false, extra_reservation_size, boot_image_spaces, extra_reservation, @@ -2367,10 +2366,10 @@ std::unique_ptr<ImageSpace> ImageSpace::CreateFromAppImage(const char* image, std::string* error_msg) { return Loader::InitAppImage(image, image, - /* validate_oat_file= */ false, + /*validate_oat_file=*/ false, oat_file, - /* image_reservation= */ nullptr, - /* oat_reservation= */ nullptr, + /*image_reservation=*/ nullptr, + /*oat_reservation=*/ nullptr, error_msg); } diff --git a/runtime/gc/space/image_space.h b/runtime/gc/space/image_space.h index 4db6fdce1d..b940d88de8 100644 --- a/runtime/gc/space/image_space.h +++ b/runtime/gc/space/image_space.h @@ -148,16 +148,6 @@ class ImageSpace : public MemMapSpace { return Begin() + GetImageHeader().GetImageSize(); } - // Return the start of the associated oat file. - uint8_t* GetOatFileBegin() const { - return GetImageHeader().GetOatFileBegin(); - } - - // Return the end of the associated oat file. - uint8_t* GetOatFileEnd() const { - return GetImageHeader().GetOatFileEnd(); - } - void DumpSections(std::ostream& os) const; // De-initialize the image-space by undoing the effects in Init(). diff --git a/runtime/gc/space/image_space_test.cc b/runtime/gc/space/image_space_test.cc index cc70788725..0a35bce0fd 100644 --- a/runtime/gc/space/image_space_test.cc +++ b/runtime/gc/space/image_space_test.cc @@ -43,14 +43,13 @@ TEST_F(DexoptTest, ValidateOatFile) { args.push_back("--oat-file=" + oat_location); ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg; - std::unique_ptr<OatFile> oat(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> oat(OatFile::Open(/*zip_fd=*/ -1, oat_location.c_str(), oat_location.c_str(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, - /* abs_dex_location */ nullptr, - /* reservation */ nullptr, + /*executable=*/ false, + /*low_4gb=*/ false, + /*abs_dex_location=*/ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(oat != nullptr) << error_msg; diff --git a/runtime/gc/verification.cc b/runtime/gc/verification.cc index 2c31c65514..0281eeedb9 100644 --- a/runtime/gc/verification.cc +++ b/runtime/gc/verification.cc @@ -88,6 +88,7 @@ void Verification::LogHeapCorruption(ObjPtr<mirror::Object> holder, // Lowest priority logging first: PrintFileToLog("/proc/self/maps", android::base::LogSeverity::FATAL_WITHOUT_ABORT); MemMap::DumpMaps(LOG_STREAM(FATAL_WITHOUT_ABORT), /* terse */ true); + Runtime::Current()->GetHeap()->DumpSpaces(LOG_STREAM(FATAL_WITHOUT_ABORT)); // Buffer the output in the string stream since it is more important than the stack traces // and we want it to have log priority. The stack traces are printed from Runtime::Abort // which is called from LOG(FATAL) but before the abort message. diff --git a/runtime/intern_table-inl.h b/runtime/intern_table-inl.h index d8e5da8209..8c7fb42952 100644 --- a/runtime/intern_table-inl.h +++ b/runtime/intern_table-inl.h @@ -19,6 +19,9 @@ #include "intern_table.h" +// Required for ToModifiedUtf8 below. +#include "mirror/string-inl.h" + namespace art { template <typename Visitor> @@ -48,9 +51,12 @@ inline size_t InternTable::AddTableFromMemory(const uint8_t* ptr, const Visitor& inline void InternTable::Table::AddInternStrings(UnorderedSet&& intern_strings) { static constexpr bool kCheckDuplicates = kIsDebugBuild; if (kCheckDuplicates) { + // Avoid doing read barriers since the space might not yet be added to the heap. + // See b/117803941 for (GcRoot<mirror::String>& string : intern_strings) { - CHECK(Find(string.Read()) == nullptr) - << "Already found " << string.Read()->ToModifiedUtf8() << " in the intern table"; + CHECK(Find(string.Read<kWithoutReadBarrier>()) == nullptr) + << "Already found " << string.Read<kWithoutReadBarrier>()->ToModifiedUtf8() + << " in the intern table"; } } // Insert at the front since we add new interns into the back. diff --git a/runtime/interpreter/interpreter_cache.h b/runtime/interpreter/interpreter_cache.h index b4966fd615..355058f4f6 100644 --- a/runtime/interpreter/interpreter_cache.h +++ b/runtime/interpreter/interpreter_cache.h @@ -25,25 +25,29 @@ namespace art { -class Instruction; class Thread; // Small fast thread-local cache for the interpreter. -// The key for the cache is the dex instruction pointer. -// The interpretation of the value depends on the opcode. -// Presence of entry might imply some performance pre-conditions. +// It can hold arbitrary pointer-sized key-value pair. +// The interpretation of the value depends on the key. +// Presence of entry might imply some pre-conditions. // All operations must be done from the owning thread, // or at a point when the owning thread is suspended. // -// The values stored for opcodes in the cache currently are: +// The key-value pairs stored in the cache currently are: // iget/iput: The field offset. The field must be non-volatile. // sget/sput: The ArtField* pointer. The field must be non-volitile. +// invoke: The ArtMethod* pointer (before vtable indirection, etc). +// ArtMethod*: The ImtIndex of the method. +// +// We ensure consistency of the cache by clearing it +// whenever any dex file is unloaded. // // Aligned to 16-bytes to make it easier to get the address of the cache // from assembly (it ensures that the offset is valid immediate value). class ALIGNED(16) InterpreterCache { // Aligned since we load the whole entry in single assembly instruction. - typedef std::pair<const Instruction*, size_t> Entry ALIGNED(2 * sizeof(size_t)); + typedef std::pair<const void*, size_t> Entry ALIGNED(2 * sizeof(size_t)); public: // 2x size increase/decrease corresponds to ~0.5% interpreter performance change. @@ -59,7 +63,7 @@ class ALIGNED(16) InterpreterCache { // Clear the whole cache. It requires the owning thread for DCHECKs. void Clear(Thread* owning_thread); - ALWAYS_INLINE bool Get(const Instruction* key, /* out */ size_t* value) { + ALWAYS_INLINE bool Get(const void* key, /* out */ size_t* value) { DCHECK(IsCalledFromOwningThread()); Entry& entry = data_[IndexOf(key)]; if (LIKELY(entry.first == key)) { @@ -69,7 +73,7 @@ class ALIGNED(16) InterpreterCache { return false; } - ALWAYS_INLINE void Set(const Instruction* key, size_t value) { + ALWAYS_INLINE void Set(const void* key, size_t value) { DCHECK(IsCalledFromOwningThread()); data_[IndexOf(key)] = Entry{key, value}; } @@ -77,7 +81,7 @@ class ALIGNED(16) InterpreterCache { private: bool IsCalledFromOwningThread(); - static ALWAYS_INLINE size_t IndexOf(const Instruction* key) { + static ALWAYS_INLINE size_t IndexOf(const void* key) { static_assert(IsPowerOfTwo(kSize), "Size must be power of two"); size_t index = (reinterpret_cast<uintptr_t>(key) >> 2) & (kSize - 1); DCHECK_LT(index, kSize); diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h index 1e4239edfd..26bfba9ffc 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -123,7 +123,7 @@ bool DoCall(ArtMethod* called_method, Thread* self, ShadowFrame& shadow_frame, // Handles all invoke-XXX/range instructions except for invoke-polymorphic[/range]. // Returns true on success, otherwise throws an exception and returns false. -template<InvokeType type, bool is_range, bool do_access_check, bool fast_invoke = false> +template<InvokeType type, bool is_range, bool do_access_check, bool is_mterp> static ALWAYS_INLINE bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst, @@ -169,29 +169,30 @@ static ALWAYS_INLINE bool DoInvoke(Thread* self, CHECK(self->IsExceptionPending()); result->SetJ(0); return false; - } else if (UNLIKELY(!called_method->IsInvokable())) { + } + if (UNLIKELY(!called_method->IsInvokable())) { called_method->ThrowInvocationTimeError(); result->SetJ(0); return false; - } else { - jit::Jit* jit = Runtime::Current()->GetJit(); - if (jit != nullptr && (type == kVirtual || type == kInterface)) { - jit->InvokeVirtualOrInterface(receiver, sf_method, shadow_frame.GetDexPC(), called_method); - } - // The fast invoke is used from mterp for some invoke variants. - // The non-fast version is used from switch interpreter and it might not support intrinsics. - // TODO: Unify both paths. - if (fast_invoke) { - if (called_method->IsIntrinsic()) { - if (MterpHandleIntrinsic(&shadow_frame, called_method, inst, inst_data, - shadow_frame.GetResultRegister())) { - return !self->IsExceptionPending(); - } + } + + jit::Jit* jit = Runtime::Current()->GetJit(); + if (jit != nullptr && (type == kVirtual || type == kInterface)) { + jit->InvokeVirtualOrInterface(receiver, sf_method, shadow_frame.GetDexPC(), called_method); + } + + if (is_mterp && !is_range && called_method->IsIntrinsic()) { + if (MterpHandleIntrinsic(&shadow_frame, called_method, inst, inst_data, + shadow_frame.GetResultRegister())) { + if (jit != nullptr && sf_method != nullptr) { + jit->NotifyInterpreterToCompiledCodeTransition(self, sf_method); } + return !self->IsExceptionPending(); } - return DoCall<is_range, do_access_check>(called_method, self, shadow_frame, inst, inst_data, - result); } + + return DoCall<is_range, do_access_check>(called_method, self, shadow_frame, inst, inst_data, + result); } static inline ObjPtr<mirror::MethodHandle> ResolveMethodHandle(Thread* self, diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc index cb64ff402a..d9f76eee6e 100644 --- a/runtime/interpreter/interpreter_switch_impl.cc +++ b/runtime/interpreter/interpreter_switch_impl.cc @@ -1669,70 +1669,70 @@ ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx) } case Instruction::INVOKE_VIRTUAL: { PREAMBLE(); - bool success = DoInvoke<kVirtual, false, do_access_check>( + bool success = DoInvoke<kVirtual, false, do_access_check, /*is_mterp=*/ false>( self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success); break; } case Instruction::INVOKE_VIRTUAL_RANGE: { PREAMBLE(); - bool success = DoInvoke<kVirtual, true, do_access_check>( + bool success = DoInvoke<kVirtual, true, do_access_check, /*is_mterp=*/ false>( self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success); break; } case Instruction::INVOKE_SUPER: { PREAMBLE(); - bool success = DoInvoke<kSuper, false, do_access_check>( + bool success = DoInvoke<kSuper, false, do_access_check, /*is_mterp=*/ false>( self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success); break; } case Instruction::INVOKE_SUPER_RANGE: { PREAMBLE(); - bool success = DoInvoke<kSuper, true, do_access_check>( + bool success = DoInvoke<kSuper, true, do_access_check, /*is_mterp=*/ false>( self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success); break; } case Instruction::INVOKE_DIRECT: { PREAMBLE(); - bool success = DoInvoke<kDirect, false, do_access_check>( + bool success = DoInvoke<kDirect, false, do_access_check, /*is_mterp=*/ false>( self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success); break; } case Instruction::INVOKE_DIRECT_RANGE: { PREAMBLE(); - bool success = DoInvoke<kDirect, true, do_access_check>( + bool success = DoInvoke<kDirect, true, do_access_check, /*is_mterp=*/ false>( self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success); break; } case Instruction::INVOKE_INTERFACE: { PREAMBLE(); - bool success = DoInvoke<kInterface, false, do_access_check>( + bool success = DoInvoke<kInterface, false, do_access_check, /*is_mterp=*/ false>( self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success); break; } case Instruction::INVOKE_INTERFACE_RANGE: { PREAMBLE(); - bool success = DoInvoke<kInterface, true, do_access_check>( + bool success = DoInvoke<kInterface, true, do_access_check, /*is_mterp=*/ false>( self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success); break; } case Instruction::INVOKE_STATIC: { PREAMBLE(); - bool success = DoInvoke<kStatic, false, do_access_check>( + bool success = DoInvoke<kStatic, false, do_access_check, /*is_mterp=*/ false>( self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success); break; } case Instruction::INVOKE_STATIC_RANGE: { PREAMBLE(); - bool success = DoInvoke<kStatic, true, do_access_check>( + bool success = DoInvoke<kStatic, true, do_access_check, /*is_mterp=*/ false>( self, shadow_frame, inst, inst_data, &result_register); POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success); break; diff --git a/runtime/interpreter/mterp/arm/floating_point.S b/runtime/interpreter/mterp/arm/floating_point.S index b6ede54f86..6bf54e8de0 100644 --- a/runtime/interpreter/mterp/arm/floating_point.S +++ b/runtime/interpreter/mterp/arm/floating_point.S @@ -326,9 +326,9 @@ %def op_double_to_long(): % unopWide(instr="bl d2l_doconv") -% add_helper("helper_code", op_double_to_long_helper_code) +% add_helper(op_double_to_long_helper) -%def op_double_to_long_helper_code(): +%def op_double_to_long_helper(): /* * Convert the double in r0/r1 to a long in r0/r1. * @@ -368,9 +368,9 @@ d2l_maybeNaN: %def op_float_to_long(): % unopWider(instr="bl f2l_doconv") -% add_helper("helper_code", op_float_to_long_helper_code) +% add_helper(op_float_to_long_helper) -%def op_float_to_long_helper_code(): +%def op_float_to_long_helper(): /* * Convert the float in r0 to a long in r0/r1. * diff --git a/runtime/interpreter/mterp/arm/main.S b/runtime/interpreter/mterp/arm/main.S index 62c38bfd96..f5fdf148d2 100644 --- a/runtime/interpreter/mterp/arm/main.S +++ b/runtime/interpreter/mterp/arm/main.S @@ -404,21 +404,20 @@ ENTRY ExecuteMterpImpl // cfi info continues, and covers the whole mterp implementation. END ExecuteMterpImpl -%def alt_stub(): -/* - * Inter-instruction transfer stub. Call out to MterpCheckBefore to handle - * any interesting requests and then jump to the real instruction - * handler. Note that the call to MterpCheckBefore is done as a tail call. - */ +%def dchecks_before_helper(): + // Call C++ to do debug checks and return to the handler using tail call. .extern MterpCheckBefore - ldr rIBASE, [rSELF, #THREAD_CURRENT_IBASE_OFFSET] @ refresh IBASE. - adr lr, .L_ALT_${opcode} - sub lr, lr, #(.L_ALT_${opcode} - .L_${opcode}) @ Addr of primary handler. mov r0, rSELF add r1, rFP, #OFF_FP_SHADOWFRAME mov r2, rPC b MterpCheckBefore @ (self, shadow_frame, dex_pc_ptr) @ Tail call. +%def opcode_pre(): +% add_helper(dchecks_before_helper, "Mterp_dchecks_before_helper") + #if !defined(NDEBUG) + bl Mterp_dchecks_before_helper + #endif + %def fallback(): /* Transfer stub to alternate interpreter */ b MterpFallback @@ -733,13 +732,6 @@ MterpProfileActive: .global artMterpAsmInstructionEnd artMterpAsmInstructionEnd: -%def instruction_end_alt(): - - .type artMterpAsmAltInstructionEnd, #object - .hidden artMterpAsmAltInstructionEnd - .global artMterpAsmAltInstructionEnd -artMterpAsmAltInstructionEnd: - %def instruction_start(): .type artMterpAsmInstructionStart, #object @@ -748,14 +740,6 @@ artMterpAsmAltInstructionEnd: artMterpAsmInstructionStart = .L_op_nop .text -%def instruction_start_alt(): - - .type artMterpAsmAltInstructionStart, #object - .hidden artMterpAsmAltInstructionStart - .global artMterpAsmAltInstructionStart -artMterpAsmAltInstructionStart = .L_ALT_op_nop - .text - %def opcode_start(): ENTRY Mterp_${opcode} %def opcode_end(): diff --git a/runtime/interpreter/mterp/arm/object.S b/runtime/interpreter/mterp/arm/object.S index 13009eaefc..092aa9ef4e 100644 --- a/runtime/interpreter/mterp/arm/object.S +++ b/runtime/interpreter/mterp/arm/object.S @@ -43,7 +43,7 @@ mov r2, rINST, lsr #12 @ B GET_VREG r2, r2 @ object we're operating on cmp r0, rPC -% slow_path_label = add_helper("slow_path", lambda: field(helper)) +% slow_path_label = add_helper(lambda: field(helper)) bne ${slow_path_label} @ cache miss cmp r2, #0 beq common_errNullObject @ null object diff --git a/runtime/interpreter/mterp/arm64/main.S b/runtime/interpreter/mterp/arm64/main.S index f248265579..1b72e79f68 100644 --- a/runtime/interpreter/mterp/arm64/main.S +++ b/runtime/interpreter/mterp/arm64/main.S @@ -429,20 +429,20 @@ ENTRY ExecuteMterpImpl // cfi info continues, and covers the whole mterp implementation. END ExecuteMterpImpl -%def alt_stub(): -/* - * Inter-instruction transfer stub. Call out to MterpCheckBefore to handle - * any interesting requests and then jump to the real instruction - * handler. Note that the call to MterpCheckBefore is done as a tail call. - */ +%def dchecks_before_helper(): + // Call C++ to do debug checks and return to the handler using tail call. .extern MterpCheckBefore - ldr xIBASE, [xSELF, #THREAD_CURRENT_IBASE_OFFSET] // refresh IBASE. - adr lr, artMterpAsmInstructionStart + (${opnum} * 128) // Addr of primary handler. mov x0, xSELF add x1, xFP, #OFF_FP_SHADOWFRAME mov x2, xPC b MterpCheckBefore // (self, shadow_frame, dex_pc_ptr) Note: tail call. +%def opcode_pre(): +% add_helper(dchecks_before_helper, "Mterp_dchecks_before_helper") + #if !defined(NDEBUG) + bl Mterp_dchecks_before_helper + #endif + %def footer(): .cfi_endproc END MterpHelpers @@ -766,13 +766,6 @@ MterpProfileActive: .global artMterpAsmInstructionEnd artMterpAsmInstructionEnd: -%def instruction_end_alt(): - - .type artMterpAsmAltInstructionEnd, #object - .hidden artMterpAsmAltInstructionEnd - .global artMterpAsmAltInstructionEnd -artMterpAsmAltInstructionEnd: - %def instruction_start(): .type artMterpAsmInstructionStart, #object @@ -781,14 +774,6 @@ artMterpAsmAltInstructionEnd: artMterpAsmInstructionStart = .L_op_nop .text -%def instruction_start_alt(): - - .type artMterpAsmAltInstructionStart, #object - .hidden artMterpAsmAltInstructionStart - .global artMterpAsmAltInstructionStart -artMterpAsmAltInstructionStart = .L_ALT_op_nop - .text - %def opcode_start(): ENTRY Mterp_${opcode} %def opcode_end(): diff --git a/runtime/interpreter/mterp/arm64/object.S b/runtime/interpreter/mterp/arm64/object.S index 3d44731cce..3cc688e5e2 100644 --- a/runtime/interpreter/mterp/arm64/object.S +++ b/runtime/interpreter/mterp/arm64/object.S @@ -41,7 +41,7 @@ lsr w2, wINST, #12 // B GET_VREG w2, w2 // object we're operating on cmp x0, xPC -% slow_path_label = add_helper("slow_path", lambda: field(helper)) +% slow_path_label = add_helper(lambda: field(helper)) b.ne ${slow_path_label} // cache miss cbz w2, common_errNullObject // null object % if is_wide: diff --git a/runtime/interpreter/mterp/common/gen_setup.py b/runtime/interpreter/mterp/common/gen_setup.py index a693383a78..cfa5e2e2ef 100644 --- a/runtime/interpreter/mterp/common/gen_setup.py +++ b/runtime/interpreter/mterp/common/gen_setup.py @@ -22,8 +22,8 @@ import sys, re from cStringIO import StringIO out = StringIO() # File-like in-memory buffer. -handler_size_bytes = "128" -handler_size_bits = "7" +handler_size_bytes = "MTERP_HANDLER_SIZE" +handler_size_bits = "MTERP_HANDLER_SIZE_LOG2" opcode = "" opnum = "" @@ -33,38 +33,34 @@ def write_line(line): def balign(): write_line(" .balign {}".format(handler_size_bytes)) -def write_opcode(num, name, write_method, is_alt): +def write_opcode(num, name, write_method): global opnum, opcode opnum, opcode = str(num), name - if is_alt: - name = "ALT_" + name write_line("/* ------------------------------ */") balign() write_line(".L_{1}: /* {0:#04x} */".format(num, name)) - if is_alt: - alt_stub() - else: - opcode_start() - write_method() - opcode_end() + opcode_start() + opcode_pre() + write_method() + opcode_end() write_line("") opnum, opcode = None, None -generated_helpers = list() +generated_helpers = {} # This method generates a helper using the provided writer method. # The output is temporarily redirected to in-memory buffer. -# It returns the symbol which can be used to jump to the helper. -def add_helper(name_suffix, write_helper): +def add_helper(write_helper, name = None): + if name == None: + name = "Mterp_" + opcode + "_helper" global out old_out = out out = StringIO() - name = "Mterp_" + opcode + "_" + name_suffix helper_start(name) write_helper() helper_end(name) out.seek(0) - generated_helpers.append(out.read()) + generated_helpers[name] = out.read() out = old_out return name @@ -76,19 +72,14 @@ def generate(output_filename): entry() instruction_start() - opcodes(is_alt = False) + opcodes() balign() instruction_end() - for helper in generated_helpers: + for name, helper in sorted(generated_helpers.items()): out.write(helper) helpers() - instruction_start_alt() - opcodes(is_alt = True) - balign() - instruction_end_alt() - footer() out.seek(0) diff --git a/runtime/interpreter/mterp/gen_mterp.py b/runtime/interpreter/mterp/gen_mterp.py index ad6e836177..5d25955701 100755 --- a/runtime/interpreter/mterp/gen_mterp.py +++ b/runtime/interpreter/mterp/gen_mterp.py @@ -58,9 +58,9 @@ def generate_script(output_filename, input_filenames): script = StringIO() # File-like in-memory buffer. script.write("# DO NOT EDIT: This file was generated by gen-mterp.py.\n") script.write(open(SCRIPT_SETUP_CODE, "r").read()) - script.write("def opcodes(is_alt):\n") + script.write("def opcodes():\n") for i, opcode in enumerate(getOpcodeList()): - script.write(' write_opcode({0}, "{1}", {1}, is_alt)\n'.format(i, opcode)) + script.write(' write_opcode({0}, "{1}", {1})\n'.format(i, opcode)) # Read all template files and translate them into python code. for input_filename in sorted(input_filenames): diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc index c385fb9417..be985ff12d 100644 --- a/runtime/interpreter/mterp/mterp.cc +++ b/runtime/interpreter/mterp/mterp.cc @@ -34,11 +34,11 @@ namespace interpreter { void CheckMterpAsmConstants() { /* * If we're using computed goto instruction transitions, make sure - * none of the handlers overflows the 128-byte limit. This won't tell + * none of the handlers overflows the byte limit. This won't tell * which one did, but if any one is too big the total size will * overflow. */ - const int width = 128; + const int width = kMterpHandlerSize; int interp_size = (uintptr_t) artMterpAsmInstructionEnd - (uintptr_t) artMterpAsmInstructionStart; if ((interp_size == 0) || (interp_size != (art::kNumPackedOpcodes * width))) { @@ -48,11 +48,7 @@ void CheckMterpAsmConstants() { } void InitMterpTls(Thread* self) { - self->SetMterpDefaultIBase(artMterpAsmInstructionStart); - self->SetMterpAltIBase(artMterpAsmAltInstructionStart); - self->SetMterpCurrentIBase((kTraceExecutionEnabled || kTestExportPC) ? - artMterpAsmAltInstructionStart : - artMterpAsmInstructionStart); + self->SetMterpCurrentIBase(artMterpAsmInstructionStart); } /* @@ -177,7 +173,7 @@ extern "C" size_t MterpInvokeVirtual(Thread* self, REQUIRES_SHARED(Locks::mutator_lock_) { JValue* result_register = shadow_frame->GetResultRegister(); const Instruction* inst = Instruction::At(dex_pc_ptr); - return DoInvoke<kVirtual, /*is_range*/ false, /*access_check*/ false, /*fast_invoke*/ true>( + return DoInvoke<kVirtual, /*is_range=*/ false, /*do_access_check=*/ false, /*is_mterp=*/ true>( self, *shadow_frame, inst, inst_data, result_register); } @@ -188,7 +184,7 @@ extern "C" size_t MterpInvokeSuper(Thread* self, REQUIRES_SHARED(Locks::mutator_lock_) { JValue* result_register = shadow_frame->GetResultRegister(); const Instruction* inst = Instruction::At(dex_pc_ptr); - return DoInvoke<kSuper, /*is_range*/ false, /*access_check*/ false>( + return DoInvoke<kSuper, /*is_range=*/ false, /*do_access_check=*/ false, /*is_mterp=*/ true>( self, *shadow_frame, inst, inst_data, result_register); } @@ -199,7 +195,7 @@ extern "C" size_t MterpInvokeInterface(Thread* self, REQUIRES_SHARED(Locks::mutator_lock_) { JValue* result_register = shadow_frame->GetResultRegister(); const Instruction* inst = Instruction::At(dex_pc_ptr); - return DoInvoke<kInterface, /*is_range*/ false, /*access_check*/ false>( + return DoInvoke<kInterface, /*is_range=*/ false, /*do_access_check=*/ false, /*is_mterp=*/ true>( self, *shadow_frame, inst, inst_data, result_register); } @@ -210,7 +206,7 @@ extern "C" size_t MterpInvokeDirect(Thread* self, REQUIRES_SHARED(Locks::mutator_lock_) { JValue* result_register = shadow_frame->GetResultRegister(); const Instruction* inst = Instruction::At(dex_pc_ptr); - return DoInvoke<kDirect, /*is_range*/ false, /*access_check*/ false, /*fast_invoke*/ true>( + return DoInvoke<kDirect, /*is_range=*/ false, /*do_access_check=*/ false, /*is_mterp=*/ true>( self, *shadow_frame, inst, inst_data, result_register); } @@ -221,7 +217,7 @@ extern "C" size_t MterpInvokeStatic(Thread* self, REQUIRES_SHARED(Locks::mutator_lock_) { JValue* result_register = shadow_frame->GetResultRegister(); const Instruction* inst = Instruction::At(dex_pc_ptr); - return DoInvoke<kStatic, /*is_range*/ false, /*access_check*/ false, /*fast_invoke*/ true>( + return DoInvoke<kStatic, /*is_range=*/ false, /*do_access_check=*/ false, /*is_mterp=*/ true>( self, *shadow_frame, inst, inst_data, result_register); } @@ -254,7 +250,7 @@ extern "C" size_t MterpInvokeVirtualRange(Thread* self, REQUIRES_SHARED(Locks::mutator_lock_) { JValue* result_register = shadow_frame->GetResultRegister(); const Instruction* inst = Instruction::At(dex_pc_ptr); - return DoInvoke<kVirtual, /*is_range*/ true, /*access_check*/ false>( + return DoInvoke<kVirtual, /*is_range=*/ true, /*do_access_check=*/ false, /*is_mterp=*/ true>( self, *shadow_frame, inst, inst_data, result_register); } @@ -265,7 +261,7 @@ extern "C" size_t MterpInvokeSuperRange(Thread* self, REQUIRES_SHARED(Locks::mutator_lock_) { JValue* result_register = shadow_frame->GetResultRegister(); const Instruction* inst = Instruction::At(dex_pc_ptr); - return DoInvoke<kSuper, /*is_range*/ true, /*access_check*/ false>( + return DoInvoke<kSuper, /*is_range=*/ true, /*do_access_check=*/ false, /*is_mterp=*/ true>( self, *shadow_frame, inst, inst_data, result_register); } @@ -276,7 +272,7 @@ extern "C" size_t MterpInvokeInterfaceRange(Thread* self, REQUIRES_SHARED(Locks::mutator_lock_) { JValue* result_register = shadow_frame->GetResultRegister(); const Instruction* inst = Instruction::At(dex_pc_ptr); - return DoInvoke<kInterface, /*is_range*/ true, /*access_check*/ false>( + return DoInvoke<kInterface, /*is_range=*/ true, /*do_access_check=*/ false, /*is_mterp=*/ true>( self, *shadow_frame, inst, inst_data, result_register); } @@ -287,7 +283,7 @@ extern "C" size_t MterpInvokeDirectRange(Thread* self, REQUIRES_SHARED(Locks::mutator_lock_) { JValue* result_register = shadow_frame->GetResultRegister(); const Instruction* inst = Instruction::At(dex_pc_ptr); - return DoInvoke<kDirect, /*is_range*/ true, /*access_check*/ false>( + return DoInvoke<kDirect, /*is_range=*/ true, /*do_access_check=*/ false, /*is_mterp=*/ true>( self, *shadow_frame, inst, inst_data, result_register); } @@ -298,7 +294,7 @@ extern "C" size_t MterpInvokeStaticRange(Thread* self, REQUIRES_SHARED(Locks::mutator_lock_) { JValue* result_register = shadow_frame->GetResultRegister(); const Instruction* inst = Instruction::At(dex_pc_ptr); - return DoInvoke<kStatic, /*is_range*/ true, /*access_check*/ false>( + return DoInvoke<kStatic, /*is_range=*/ true, /*do_access_check=*/ false, /*is_mterp=*/ true>( self, *shadow_frame, inst, inst_data, result_register); } diff --git a/runtime/interpreter/mterp/mterp.h b/runtime/interpreter/mterp/mterp.h index 1a56d26813..81a53c84fb 100644 --- a/runtime/interpreter/mterp/mterp.h +++ b/runtime/interpreter/mterp/mterp.h @@ -25,8 +25,6 @@ */ extern "C" void* artMterpAsmInstructionStart[]; extern "C" void* artMterpAsmInstructionEnd[]; -extern "C" void* artMterpAsmAltInstructionStart[]; -extern "C" void* artMterpAsmAltInstructionEnd[]; namespace art { @@ -50,6 +48,8 @@ constexpr uintptr_t kExportPCPoison = 0xdead00ff; // Set true to enable poison testing of ExportPC. Uses Alt interpreter. constexpr bool kTestExportPC = false; +constexpr size_t kMterpHandlerSize = 128; + } // namespace interpreter } // namespace art diff --git a/runtime/interpreter/mterp/x86/arithmetic.S b/runtime/interpreter/mterp/x86/arithmetic.S index a9fa0fc68f..3b5f0beb89 100644 --- a/runtime/interpreter/mterp/x86/arithmetic.S +++ b/runtime/interpreter/mterp/x86/arithmetic.S @@ -25,6 +25,9 @@ jne .L${opcode}_32 movl $special, $result jmp .L${opcode}_finish +% add_helper(lambda: bindiv_helper(result, rem)) + +%def bindiv_helper(result, rem): .L${opcode}_32: cltd idivl %ecx @@ -69,7 +72,9 @@ SET_VREG $result, rINST mov LOCAL0(%esp), rIBASE ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 +% add_helper(lambda: bindiv2addr_helper(result)) +%def bindiv2addr_helper(result): .L${opcode}_continue_div2addr: cltd idivl %ecx @@ -137,7 +142,7 @@ %def binop(result="%eax", instr=""): /* * Generic 32-bit binary operation. Provide an "instr" line that - * specifies an instruction that performs "result = eax op (rFP,%ecx,4)". + * specifies an instruction that performs "result = eax op VREG_ADDRESS(%ecx)". * This could be an x86 instruction or a function call. (If the result * comes back in a register other than eax, you can override "result".) * @@ -148,7 +153,7 @@ movzbl 2(rPC), %eax # eax <- BB movzbl 3(rPC), %ecx # ecx <- CC GET_VREG %eax, %eax # eax <- vBB - $instr # ex: addl (rFP,%ecx,4),%eax + $instr # ex: addl VREG_ADDRESS(%ecx),%eax SET_VREG $result, rINST ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -182,7 +187,7 @@ sarl $$4, rINST # rINST <- B GET_VREG %eax, rINST # eax <- vB andb $$0xf, %cl # ecx <- A - $instr # for ex: addl %eax,(rFP,%ecx,4) + $instr # for ex: addl %eax,VREG_ADDRESS(%ecx) CLEAR_REF %ecx ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 @@ -235,8 +240,8 @@ movl rIBASE, LOCAL0(%esp) # save rIBASE GET_VREG rIBASE, %eax # rIBASE <- v[BB+0] GET_VREG_HIGH %eax, %eax # eax <- v[BB+1] - $instr1 # ex: addl (rFP,%ecx,4),rIBASE - $instr2 # ex: adcl 4(rFP,%ecx,4),%eax + $instr1 # ex: addl VREG_ADDRESS(%ecx),rIBASE + $instr2 # ex: adcl VREG_HIGH_ADDRESS(%ecx),%eax SET_VREG rIBASE, rINST # v[AA+0] <- rIBASE movl LOCAL0(%esp), rIBASE # restore rIBASE SET_VREG_HIGH %eax, rINST # v[AA+1] <- eax @@ -302,7 +307,9 @@ mov %eax, VREG_REF_HIGH_ADDRESS(%ecx) .endif ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 +% add_helper(lambda: cvtfp_int_helper(tgtlong)) +%def cvtfp_int_helper(tgtlong): .L${opcode}_special_case: fnstsw %ax sahf @@ -348,10 +355,10 @@ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 %def op_add_int(): -% binop(instr="addl (rFP,%ecx,4), %eax") +% binop(instr="addl VREG_ADDRESS(%ecx), %eax") %def op_add_int_2addr(): -% binop2addr(instr="addl %eax, (rFP,%ecx,4)") +% binop2addr(instr="addl %eax, VREG_ADDRESS(%ecx)") %def op_add_int_lit16(): % binopLit16(instr="addl %ecx, %eax") @@ -360,16 +367,16 @@ % binopLit8(instr="addl %ecx, %eax") %def op_add_long(): -% binopWide(instr1="addl (rFP,%ecx,4), rIBASE", instr2="adcl 4(rFP,%ecx,4), %eax") +% binopWide(instr1="addl VREG_ADDRESS(%ecx), rIBASE", instr2="adcl VREG_HIGH_ADDRESS(%ecx), %eax") %def op_add_long_2addr(): % binopWide2addr(instr1="addl %eax, (rFP,rINST,4)", instr2="adcl %ecx, 4(rFP,rINST,4)") %def op_and_int(): -% binop(instr="andl (rFP,%ecx,4), %eax") +% binop(instr="andl VREG_ADDRESS(%ecx), %eax") %def op_and_int_2addr(): -% binop2addr(instr="andl %eax, (rFP,%ecx,4)") +% binop2addr(instr="andl %eax, VREG_ADDRESS(%ecx)") %def op_and_int_lit16(): % binopLit16(instr="andl %ecx, %eax") @@ -378,7 +385,7 @@ % binopLit8(instr="andl %ecx, %eax") %def op_and_long(): -% binopWide(instr1="andl (rFP,%ecx,4), rIBASE", instr2="andl 4(rFP,%ecx,4), %eax") +% binopWide(instr1="andl VREG_ADDRESS(%ecx), rIBASE", instr2="andl VREG_HIGH_ADDRESS(%ecx), %eax") %def op_and_long_2addr(): % binopWide2addr(instr1="andl %eax, (rFP,rINST,4)", instr2="andl %ecx, 4(rFP,rINST,4)") @@ -510,7 +517,7 @@ movzbl 3(rPC), %ecx # ecx <- CC GET_VREG %eax, %eax # eax <- vBB mov rIBASE, LOCAL0(%esp) - imull (rFP,%ecx,4), %eax # trashes rIBASE/edx + imull VREG_ADDRESS(%ecx), %eax # trashes rIBASE/edx mov LOCAL0(%esp), rIBASE SET_VREG %eax, rINST ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -522,7 +529,7 @@ GET_VREG %eax, rINST # eax <- vB andb $$0xf, %cl # ecx <- A movl rIBASE, rINST - imull (rFP,%ecx,4), %eax # trashes rIBASE/edx + imull VREG_ADDRESS(%ecx), %eax # trashes rIBASE/edx movl rINST, rIBASE SET_VREG %eax, %ecx ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 @@ -571,7 +578,7 @@ mov rFP, LOCAL1(%esp) # save FP mov rIBASE, LOCAL2(%esp) # save rIBASE leal (rFP,%eax,4), %esi # esi <- &v[B] - leal (rFP,%ecx,4), rFP # rFP <- &v[C] + leal VREG_ADDRESS(%ecx), rFP # rFP <- &v[C] movl 4(%esi), %ecx # ecx <- Bmsw imull (rFP), %ecx # ecx <- (Bmsw*Clsw) movl 4(rFP), %eax # eax <- Cmsw @@ -659,10 +666,10 @@ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 %def op_or_int(): -% binop(instr="orl (rFP,%ecx,4), %eax") +% binop(instr="orl VREG_ADDRESS(%ecx), %eax") %def op_or_int_2addr(): -% binop2addr(instr="orl %eax, (rFP,%ecx,4)") +% binop2addr(instr="orl %eax, VREG_ADDRESS(%ecx)") %def op_or_int_lit16(): % binopLit16(instr="orl %ecx, %eax") @@ -671,7 +678,7 @@ % binopLit8(instr="orl %ecx, %eax") %def op_or_long(): -% binopWide(instr1="orl (rFP,%ecx,4), rIBASE", instr2="orl 4(rFP,%ecx,4), %eax") +% binopWide(instr1="orl VREG_ADDRESS(%ecx), rIBASE", instr2="orl VREG_HIGH_ADDRESS(%ecx), %eax") %def op_or_long_2addr(): % binopWide2addr(instr1="orl %eax, (rFP,rINST,4)", instr2="orl %ecx, 4(rFP,rINST,4)") @@ -838,13 +845,13 @@ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 %def op_sub_int(): -% binop(instr="subl (rFP,%ecx,4), %eax") +% binop(instr="subl VREG_ADDRESS(%ecx), %eax") %def op_sub_int_2addr(): -% binop2addr(instr="subl %eax, (rFP,%ecx,4)") +% binop2addr(instr="subl %eax, VREG_ADDRESS(%ecx)") %def op_sub_long(): -% binopWide(instr1="subl (rFP,%ecx,4), rIBASE", instr2="sbbl 4(rFP,%ecx,4), %eax") +% binopWide(instr1="subl VREG_ADDRESS(%ecx), rIBASE", instr2="sbbl VREG_HIGH_ADDRESS(%ecx), %eax") %def op_sub_long_2addr(): % binopWide2addr(instr1="subl %eax, (rFP,rINST,4)", instr2="sbbl %ecx, 4(rFP,rINST,4)") @@ -918,10 +925,10 @@ ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 %def op_xor_int(): -% binop(instr="xorl (rFP,%ecx,4), %eax") +% binop(instr="xorl VREG_ADDRESS(%ecx), %eax") %def op_xor_int_2addr(): -% binop2addr(instr="xorl %eax, (rFP,%ecx,4)") +% binop2addr(instr="xorl %eax, VREG_ADDRESS(%ecx)") %def op_xor_int_lit16(): % binopLit16(instr="xorl %ecx, %eax") @@ -930,7 +937,7 @@ % binopLit8(instr="xorl %ecx, %eax") %def op_xor_long(): -% binopWide(instr1="xorl (rFP,%ecx,4), rIBASE", instr2="xorl 4(rFP,%ecx,4), %eax") +% binopWide(instr1="xorl VREG_ADDRESS(%ecx), rIBASE", instr2="xorl VREG_HIGH_ADDRESS(%ecx), %eax") %def op_xor_long_2addr(): % binopWide2addr(instr1="xorl %eax, (rFP,rINST,4)", instr2="xorl %ecx, 4(rFP,rINST,4)") diff --git a/runtime/interpreter/mterp/x86/main.S b/runtime/interpreter/mterp/x86/main.S index b44f168686..04b653e24b 100644 --- a/runtime/interpreter/mterp/x86/main.S +++ b/runtime/interpreter/mterp/x86/main.S @@ -273,47 +273,47 @@ unspecified registers or condition codes. #define VREG_REF_HIGH_ADDRESS(_vreg) 4(rREFS,_vreg,4) .macro GET_VREG _reg _vreg - movl (rFP,\_vreg,4), \_reg + movl VREG_ADDRESS(\_vreg), \_reg .endm /* Read wide value to xmm. */ .macro GET_WIDE_FP_VREG _reg _vreg - movq (rFP,\_vreg,4), \_reg + movq VREG_ADDRESS(\_vreg), \_reg .endm .macro SET_VREG _reg _vreg - movl \_reg, (rFP,\_vreg,4) - movl MACRO_LITERAL(0), (rREFS,\_vreg,4) + movl \_reg, VREG_ADDRESS(\_vreg) + movl MACRO_LITERAL(0), VREG_REF_ADDRESS(\_vreg) .endm /* Write wide value from xmm. xmm is clobbered. */ .macro SET_WIDE_FP_VREG _reg _vreg - movq \_reg, (rFP,\_vreg,4) + movq \_reg, VREG_ADDRESS(\_vreg) pxor \_reg, \_reg - movq \_reg, (rREFS,\_vreg,4) + movq \_reg, VREG_REF_ADDRESS(\_vreg) .endm .macro SET_VREG_OBJECT _reg _vreg - movl \_reg, (rFP,\_vreg,4) - movl \_reg, (rREFS,\_vreg,4) + movl \_reg, VREG_ADDRESS(\_vreg) + movl \_reg, VREG_REF_ADDRESS(\_vreg) .endm .macro GET_VREG_HIGH _reg _vreg - movl 4(rFP,\_vreg,4), \_reg + movl VREG_HIGH_ADDRESS(\_vreg), \_reg .endm .macro SET_VREG_HIGH _reg _vreg - movl \_reg, 4(rFP,\_vreg,4) - movl MACRO_LITERAL(0), 4(rREFS,\_vreg,4) + movl \_reg, VREG_HIGH_ADDRESS(\_vreg) + movl MACRO_LITERAL(0), VREG_REF_HIGH_ADDRESS(\_vreg) .endm .macro CLEAR_REF _vreg - movl MACRO_LITERAL(0), (rREFS,\_vreg,4) + movl MACRO_LITERAL(0), VREG_REF_ADDRESS(\_vreg) .endm .macro CLEAR_WIDE_REF _vreg - movl MACRO_LITERAL(0), (rREFS,\_vreg,4) - movl MACRO_LITERAL(0), 4(rREFS,\_vreg,4) + movl MACRO_LITERAL(0), VREG_REF_ADDRESS(\_vreg) + movl MACRO_LITERAL(0), VREG_REF_HIGH_ADDRESS(\_vreg) .endm /* @@ -410,26 +410,24 @@ ENTRY ExecuteMterpImpl // cfi info continues, and covers the whole mterp implementation. END ExecuteMterpImpl -%def alt_stub(): -/* - * Inter-instruction transfer stub. Call out to MterpCheckBefore to handle - * any interesting requests and then jump to the real instruction - * handler. Unlike the Arm handler, we can't do this as a tail call - * because rIBASE is caller save and we need to reload it. - * - * Note that unlike in the Arm implementation, we should never arrive - * here with a zero breakFlag because we always refresh rIBASE on - * return. - */ +%def dchecks_before_helper(): + // Call C++ to do debug checks and return to the handler using tail call. .extern MterpCheckBefore + popl %eax # Return address (the instuction handler). movl rSELF, %ecx movl %ecx, OUT_ARG0(%esp) - leal OFF_FP_SHADOWFRAME(rFP), %eax - movl %eax, OUT_ARG1(%esp) + leal OFF_FP_SHADOWFRAME(rFP), %ecx + movl %ecx, OUT_ARG1(%esp) movl rPC, OUT_ARG2(%esp) - call SYMBOL(MterpCheckBefore) # (self, shadow_frame, dex_pc_ptr) + pushl %eax # Return address for the tail call. + jmp SYMBOL(MterpCheckBefore) # (self, shadow_frame, dex_pc_ptr) + +%def opcode_pre(): +% add_helper(dchecks_before_helper, "Mterp_dchecks_before_helper") + #if !defined(NDEBUG) + call SYMBOL(Mterp_dchecks_before_helper) REFRESH_IBASE - jmp .L_op_nop+(${opnum}*${handler_size_bytes}) + #endif %def fallback(): /* Transfer stub to alternate interpreter */ @@ -773,13 +771,6 @@ MRestoreFrame: .global SYMBOL(artMterpAsmInstructionEnd) SYMBOL(artMterpAsmInstructionEnd): -%def instruction_end_alt(): - - OBJECT_TYPE(artMterpAsmAltInstructionEnd) - ASM_HIDDEN SYMBOL(artMterpAsmAltInstructionEnd) - .global SYMBOL(artMterpAsmAltInstructionEnd) -SYMBOL(artMterpAsmAltInstructionEnd): - %def instruction_start(): OBJECT_TYPE(artMterpAsmInstructionStart) @@ -788,14 +779,6 @@ SYMBOL(artMterpAsmAltInstructionEnd): SYMBOL(artMterpAsmInstructionStart) = .L_op_nop .text -%def instruction_start_alt(): - - OBJECT_TYPE(artMterpAsmAltInstructionStart) - ASM_HIDDEN SYMBOL(artMterpAsmAltInstructionStart) - .global SYMBOL(artMterpAsmAltInstructionStart) - .text -SYMBOL(artMterpAsmAltInstructionStart) = .L_ALT_op_nop - %def opcode_start(): ENTRY Mterp_${opcode} %def opcode_end(): diff --git a/runtime/interpreter/mterp/x86_64/arithmetic.S b/runtime/interpreter/mterp/x86_64/arithmetic.S index ffe2008993..263f82b9f6 100644 --- a/runtime/interpreter/mterp/x86_64/arithmetic.S +++ b/runtime/interpreter/mterp/x86_64/arithmetic.S @@ -137,7 +137,7 @@ movzbq 2(rPC), %rax # rax <- BB movzbq 3(rPC), %rcx # rcx <- CC GET_VREG %eax, %rax # eax <- vBB - $instr # ex: addl (rFP,%rcx,4),%eax + $instr # ex: addl VREG_ADDRESS(%rcx),%eax SET_VREG $result, rINSTq ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -228,7 +228,7 @@ movzbq 2(rPC), %rax # eax <- BB movzbq 3(rPC), %rcx # ecx <- CC GET_WIDE_VREG %rax, %rax # rax <- v[BB] - $instr # ex: addq (rFP,%rcx,4),%rax + $instr # ex: addq VREG_ADDRESS(%rcx),%rax SET_WIDE_VREG %rax, rINSTq # v[AA] <- rax ADVANCE_PC_FETCH_AND_GOTO_NEXT 2 @@ -241,7 +241,7 @@ sarl $$4, rINST # rINST <- B andb $$0xf, %cl # ecx <- A GET_WIDE_VREG %rax, rINSTq # rax <- vB - $instr # for ex: addq %rax,(rFP,%rcx,4) + $instr # for ex: addq %rax,VREG_ADDRESS(%rcx) CLEAR_WIDE_REF %rcx ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 @@ -317,10 +317,10 @@ $instr ADVANCE_PC_FETCH_AND_GOTO_NEXT 1 %def op_add_int(): -% binop(instr="addl (rFP,%rcx,4), %eax") +% binop(instr="addl VREG_ADDRESS(%rcx), %eax") %def op_add_int_2addr(): -% binop2addr(instr="addl %eax, (rFP,%rcx,4)") +% binop2addr(instr="addl %eax, VREG_ADDRESS(%rcx)") %def op_add_int_lit16(): % binopLit16(instr="addl %ecx, %eax") @@ -329,16 +329,16 @@ $instr % binopLit8(instr="addl %ecx, %eax") %def op_add_long(): -% binopWide(instr="addq (rFP,%rcx,4), %rax") +% binopWide(instr="addq VREG_ADDRESS(%rcx), %rax") %def op_add_long_2addr(): -% binopWide2addr(instr="addq %rax, (rFP,%rcx,4)") +% binopWide2addr(instr="addq %rax, VREG_ADDRESS(%rcx)") %def op_and_int(): -% binop(instr="andl (rFP,%rcx,4), %eax") +% binop(instr="andl VREG_ADDRESS(%rcx), %eax") %def op_and_int_2addr(): -% binop2addr(instr="andl %eax, (rFP,%rcx,4)") +% binop2addr(instr="andl %eax, VREG_ADDRESS(%rcx)") %def op_and_int_lit16(): % binopLit16(instr="andl %ecx, %eax") @@ -347,10 +347,10 @@ $instr % binopLit8(instr="andl %ecx, %eax") %def op_and_long(): -% binopWide(instr="andq (rFP,%rcx,4), %rax") +% binopWide(instr="andq VREG_ADDRESS(%rcx), %rax") %def op_and_long_2addr(): -% binopWide2addr(instr="andq %rax, (rFP,%rcx,4)") +% binopWide2addr(instr="andq %rax, VREG_ADDRESS(%rcx)") %def op_cmp_long(): /* @@ -413,7 +413,7 @@ $instr % op_move() %def op_mul_int(): -% binop(instr="imull (rFP,%rcx,4), %eax") +% binop(instr="imull VREG_ADDRESS(%rcx), %eax") %def op_mul_int_2addr(): /* mul vA, vB */ @@ -432,7 +432,7 @@ $instr % binopLit8(instr="imull %ecx, %eax") %def op_mul_long(): -% binopWide(instr="imulq (rFP,%rcx,4), %rax") +% binopWide(instr="imulq VREG_ADDRESS(%rcx), %rax") %def op_mul_long_2addr(): /* mul vA, vB */ @@ -457,10 +457,10 @@ $instr % unop(instr=" notq %rax", wide="1") %def op_or_int(): -% binop(instr="orl (rFP,%rcx,4), %eax") +% binop(instr="orl VREG_ADDRESS(%rcx), %eax") %def op_or_int_2addr(): -% binop2addr(instr="orl %eax, (rFP,%rcx,4)") +% binop2addr(instr="orl %eax, VREG_ADDRESS(%rcx)") %def op_or_int_lit16(): % binopLit16(instr="orl %ecx, %eax") @@ -469,10 +469,10 @@ $instr % binopLit8(instr="orl %ecx, %eax") %def op_or_long(): -% binopWide(instr="orq (rFP,%rcx,4), %rax") +% binopWide(instr="orq VREG_ADDRESS(%rcx), %rax") %def op_or_long_2addr(): -% binopWide2addr(instr="orq %rax, (rFP,%rcx,4)") +% binopWide2addr(instr="orq %rax, VREG_ADDRESS(%rcx)") %def op_rem_int(): % bindiv(result="%edx", second="%ecx", wide="0", suffix="l", rem="1") @@ -530,16 +530,16 @@ $instr % shop2addr(instr="sarq %cl, %rax", wide="1") %def op_sub_int(): -% binop(instr="subl (rFP,%rcx,4), %eax") +% binop(instr="subl VREG_ADDRESS(%rcx), %eax") %def op_sub_int_2addr(): -% binop2addr(instr="subl %eax, (rFP,%rcx,4)") +% binop2addr(instr="subl %eax, VREG_ADDRESS(%rcx)") %def op_sub_long(): -% binopWide(instr="subq (rFP,%rcx,4), %rax") +% binopWide(instr="subq VREG_ADDRESS(%rcx), %rax") %def op_sub_long_2addr(): -% binopWide2addr(instr="subq %rax, (rFP,%rcx,4)") +% binopWide2addr(instr="subq %rax, VREG_ADDRESS(%rcx)") %def op_ushr_int(): % binop1(instr="shrl %cl, %eax") @@ -557,10 +557,10 @@ $instr % shop2addr(instr="shrq %cl, %rax", wide="1") %def op_xor_int(): -% binop(instr="xorl (rFP,%rcx,4), %eax") +% binop(instr="xorl VREG_ADDRESS(%rcx), %eax") %def op_xor_int_2addr(): -% binop2addr(instr="xorl %eax, (rFP,%rcx,4)") +% binop2addr(instr="xorl %eax, VREG_ADDRESS(%rcx)") %def op_xor_int_lit16(): % binopLit16(instr="xorl %ecx, %eax") @@ -569,7 +569,7 @@ $instr % binopLit8(instr="xorl %ecx, %eax") %def op_xor_long(): -% binopWide(instr="xorq (rFP,%rcx,4), %rax") +% binopWide(instr="xorq VREG_ADDRESS(%rcx), %rax") %def op_xor_long_2addr(): -% binopWide2addr(instr="xorq %rax, (rFP,%rcx,4)") +% binopWide2addr(instr="xorq %rax, VREG_ADDRESS(%rcx)") diff --git a/runtime/interpreter/mterp/x86_64/main.S b/runtime/interpreter/mterp/x86_64/main.S index 900923da6d..e283bbee3f 100644 --- a/runtime/interpreter/mterp/x86_64/main.S +++ b/runtime/interpreter/mterp/x86_64/main.S @@ -256,50 +256,52 @@ unspecified registers or condition codes. * Get/set the 32-bit value from a Dalvik register. */ #define VREG_ADDRESS(_vreg) (rFP,_vreg,4) +#define VREG_HIGH_ADDRESS(_vreg) 4(rFP,_vreg,4) #define VREG_REF_ADDRESS(_vreg) (rREFS,_vreg,4) +#define VREG_REF_HIGH_ADDRESS(_vreg) 4(rREFS,_vreg,4) .macro GET_VREG _reg _vreg - movl (rFP,\_vreg,4), \_reg + movl VREG_ADDRESS(\_vreg), \_reg .endm /* Read wide value. */ .macro GET_WIDE_VREG _reg _vreg - movq (rFP,\_vreg,4), \_reg + movq VREG_ADDRESS(\_vreg), \_reg .endm .macro SET_VREG _reg _vreg - movl \_reg, (rFP,\_vreg,4) - movl MACRO_LITERAL(0), (rREFS,\_vreg,4) + movl \_reg, VREG_ADDRESS(\_vreg) + movl MACRO_LITERAL(0), VREG_REF_ADDRESS(\_vreg) .endm /* Write wide value. reg is clobbered. */ .macro SET_WIDE_VREG _reg _vreg - movq \_reg, (rFP,\_vreg,4) + movq \_reg, VREG_ADDRESS(\_vreg) xorq \_reg, \_reg - movq \_reg, (rREFS,\_vreg,4) + movq \_reg, VREG_REF_ADDRESS(\_vreg) .endm .macro SET_VREG_OBJECT _reg _vreg - movl \_reg, (rFP,\_vreg,4) - movl \_reg, (rREFS,\_vreg,4) + movl \_reg, VREG_ADDRESS(\_vreg) + movl \_reg, VREG_REF_ADDRESS(\_vreg) .endm .macro GET_VREG_HIGH _reg _vreg - movl 4(rFP,\_vreg,4), \_reg + movl VREG_HIGH_ADDRESS(\_vreg), \_reg .endm .macro SET_VREG_HIGH _reg _vreg - movl \_reg, 4(rFP,\_vreg,4) - movl MACRO_LITERAL(0), 4(rREFS,\_vreg,4) + movl \_reg, VREG_HIGH_ADDRESS(\_vreg) + movl MACRO_LITERAL(0), VREG_REF_HIGH_ADDRESS(\_vreg) .endm .macro CLEAR_REF _vreg - movl MACRO_LITERAL(0), (rREFS,\_vreg,4) + movl MACRO_LITERAL(0), VREG_REF_ADDRESS(\_vreg) .endm .macro CLEAR_WIDE_REF _vreg - movl MACRO_LITERAL(0), (rREFS,\_vreg,4) - movl MACRO_LITERAL(0), 4(rREFS,\_vreg,4) + movl MACRO_LITERAL(0), VREG_REF_ADDRESS(\_vreg) + movl MACRO_LITERAL(0), VREG_REF_HIGH_ADDRESS(\_vreg) .endm /* @@ -393,24 +395,22 @@ ENTRY ExecuteMterpImpl // cfi info continues, and covers the whole mterp implementation. END ExecuteMterpImpl -%def alt_stub(): -/* - * Inter-instruction transfer stub. Call out to MterpCheckBefore to handle - * any interesting requests and then jump to the real instruction - * handler. Unlike the Arm handler, we can't do this as a tail call - * because rIBASE is caller save and we need to reload it. - * - * Note that unlike in the Arm implementation, we should never arrive - * here with a zero breakFlag because we always refresh rIBASE on - * return. - */ +%def dchecks_before_helper(): + // Call C++ to do debug checks and return to the handler using tail call. .extern MterpCheckBefore + popq %rax # Return address (the instuction handler). REFRESH_IBASE movq rSELF, OUT_ARG0 leaq OFF_FP_SHADOWFRAME(rFP), OUT_ARG1 movq rPC, OUT_ARG2 - call SYMBOL(MterpCheckBefore) # (self, shadow_frame, dex_pc_ptr) - jmp .L_op_nop+(${opnum}*${handler_size_bytes}) + pushq %rax # Return address for the tail call. + jmp SYMBOL(MterpCheckBefore) # (self, shadow_frame, dex_pc_ptr) + +%def opcode_pre(): +% add_helper(dchecks_before_helper, "Mterp_dchecks_before_helper") + #if !defined(NDEBUG) + call SYMBOL(Mterp_dchecks_before_helper) + #endif %def fallback(): /* Transfer stub to alternate interpreter */ @@ -726,13 +726,6 @@ MRestoreFrame: .global SYMBOL(artMterpAsmInstructionEnd) SYMBOL(artMterpAsmInstructionEnd): -%def instruction_end_alt(): - - OBJECT_TYPE(artMterpAsmAltInstructionEnd) - ASM_HIDDEN SYMBOL(artMterpAsmAltInstructionEnd) - .global SYMBOL(artMterpAsmAltInstructionEnd) -SYMBOL(artMterpAsmAltInstructionEnd): - %def instruction_start(): OBJECT_TYPE(artMterpAsmInstructionStart) @@ -741,14 +734,6 @@ SYMBOL(artMterpAsmAltInstructionEnd): SYMBOL(artMterpAsmInstructionStart) = .L_op_nop .text -%def instruction_start_alt(): - - OBJECT_TYPE(artMterpAsmAltInstructionStart) - ASM_HIDDEN SYMBOL(artMterpAsmAltInstructionStart) - .global SYMBOL(artMterpAsmAltInstructionStart) - .text -SYMBOL(artMterpAsmAltInstructionStart) = .L_ALT_op_nop - %def opcode_start(): ENTRY Mterp_${opcode} %def opcode_end(): diff --git a/runtime/jdwp/jdwp_handler.cc b/runtime/jdwp/jdwp_handler.cc index 0a54e38698..d31f166869 100644 --- a/runtime/jdwp/jdwp_handler.cc +++ b/runtime/jdwp/jdwp_handler.cc @@ -1344,13 +1344,14 @@ static JdwpError ER_Set(JdwpState* state, Request* request, ExpandBuf* pReply) VLOG(jdwp) << StringPrintf(" --> event requestId=%#x", requestId); /* add it to the list */ + // TODO: RegisterEvent() should take std::unique_ptr<>. JdwpError err = state->RegisterEvent(pEvent.get()); if (err != ERR_NONE) { /* registration failed, probably because event is bogus */ LOG(WARNING) << "WARNING: event request rejected"; return err; } - pEvent.release(); + pEvent.release(); // NOLINT b/117926937 return ERR_NONE; } diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc index 36f9b1aaeb..6becd36bf1 100644 --- a/runtime/native/dalvik_system_DexFile.cc +++ b/runtime/native/dalvik_system_DexFile.cc @@ -112,7 +112,7 @@ static jlongArray ConvertDexFilesToJavaArray(JNIEnv* env, // Now release all the unique_ptrs. for (auto& dex_file : vec) { - dex_file.release(); + dex_file.release(); // NOLINT } return long_array; @@ -295,7 +295,7 @@ static jobject DexFile_openDexFileNative(JNIEnv* env, ScopedObjectAccess soa(env); for (auto& dex_file : dex_files) { if (linker->IsDexFileRegistered(soa.Self(), *dex_file)) { - dex_file.release(); + dex_file.release(); // NOLINT } } } diff --git a/runtime/oat.h b/runtime/oat.h index 963725a050..5c5a02dff5 100644 --- a/runtime/oat.h +++ b/runtime/oat.h @@ -32,8 +32,8 @@ class InstructionSetFeatures; class PACKED(4) OatHeader { public: static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' }; - // Last oat version changed reason: Remove PIC option from oat files. - static constexpr uint8_t kOatVersion[] = { '1', '6', '2', '\0' }; + // Last oat version changed reason: Remove interpreter alt tables. + static constexpr uint8_t kOatVersion[] = { '1', '6', '3', '\0' }; static constexpr const char* kImageLocationKey = "image-location"; static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline"; diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc index 5b965090d2..f16c46bdea 100644 --- a/runtime/oat_file.cc +++ b/runtime/oat_file.cc @@ -101,7 +101,6 @@ class OatFileBase : public OatFile { const std::string& vdex_filename, const std::string& elf_filename, const std::string& location, - uint8_t* requested_base, bool writable, bool executable, bool low_4gb, @@ -115,7 +114,6 @@ class OatFileBase : public OatFile { int oat_fd, const std::string& vdex_filename, const std::string& oat_filename, - uint8_t* requested_base, bool writable, bool executable, bool low_4gb, @@ -156,9 +154,7 @@ class OatFileBase : public OatFile { /*inout*/MemMap* reservation, // Where to load if not null. /*out*/std::string* error_msg) = 0; - bool ComputeFields(uint8_t* requested_base, - const std::string& file_path, - std::string* error_msg); + bool ComputeFields(const std::string& file_path, std::string* error_msg); virtual void PreSetup(const std::string& elf_filename) = 0; @@ -187,7 +183,6 @@ OatFileBase* OatFileBase::OpenOatFile(int zip_fd, const std::string& vdex_filename, const std::string& elf_filename, const std::string& location, - uint8_t* requested_base, bool writable, bool executable, bool low_4gb, @@ -207,7 +202,7 @@ OatFileBase* OatFileBase::OpenOatFile(int zip_fd, return nullptr; } - if (!ret->ComputeFields(requested_base, elf_filename, error_msg)) { + if (!ret->ComputeFields(elf_filename, error_msg)) { return nullptr; } @@ -230,7 +225,6 @@ OatFileBase* OatFileBase::OpenOatFile(int zip_fd, int oat_fd, const std::string& vdex_location, const std::string& oat_location, - uint8_t* requested_base, bool writable, bool executable, bool low_4gb, @@ -248,7 +242,7 @@ OatFileBase* OatFileBase::OpenOatFile(int zip_fd, return nullptr; } - if (!ret->ComputeFields(requested_base, oat_location, error_msg)) { + if (!ret->ComputeFields(oat_location, error_msg)) { return nullptr; } @@ -271,7 +265,7 @@ bool OatFileBase::LoadVdex(const std::string& vdex_filename, std::string* error_msg) { vdex_ = VdexFile::OpenAtAddress(vdex_begin_, vdex_end_ - vdex_begin_, - vdex_begin_ != nullptr /* mmap_reuse */, + /*mmap_reuse=*/ vdex_begin_ != nullptr, vdex_filename, writable, low_4gb, @@ -299,13 +293,13 @@ bool OatFileBase::LoadVdex(int vdex_fd, } else { vdex_ = VdexFile::OpenAtAddress(vdex_begin_, vdex_end_ - vdex_begin_, - vdex_begin_ != nullptr /* mmap_reuse */, + /*mmap_reuse=*/ vdex_begin_ != nullptr, vdex_fd, s.st_size, vdex_filename, writable, low_4gb, - false /* unquicken */, + /*unquicken=*/ false, error_msg); if (vdex_.get() == nullptr) { *error_msg = "Failed opening vdex file."; @@ -316,9 +310,7 @@ bool OatFileBase::LoadVdex(int vdex_fd, return true; } -bool OatFileBase::ComputeFields(uint8_t* requested_base, - const std::string& file_path, - std::string* error_msg) { +bool OatFileBase::ComputeFields(const std::string& file_path, std::string* error_msg) { std::string symbol_error_msg; begin_ = FindDynamicSymbolAddress("oatdata", &symbol_error_msg); if (begin_ == nullptr) { @@ -327,16 +319,6 @@ bool OatFileBase::ComputeFields(uint8_t* requested_base, symbol_error_msg.c_str()); return false; } - if (requested_base != nullptr && begin_ != requested_base) { - // Host can fail this check. Do not dump there to avoid polluting the output. - if (kIsTargetBuild && (kIsDebugBuild || VLOG_IS_ON(oat))) { - PrintFileToLog("/proc/self/maps", android::base::LogSeverity::WARNING); - } - *error_msg = StringPrintf("Failed to find oatdata symbol at expected address: " - "oatdata=%p != expected=%p. See process maps in the log.", - begin_, requested_base); - return false; - } end_ = FindDynamicSymbolAddress("oatlastword", &symbol_error_msg); if (end_ == nullptr) { *error_msg = StringPrintf("Failed to find oatlastword symbol in '%s' %s", @@ -649,15 +631,15 @@ bool OatFileBase::Setup(int zip_fd, const char* abs_dex_location, std::string* e if (zip_fd != -1) { loaded = dex_file_loader.OpenZip(zip_fd, dex_file_location, - /* verify */ false, - /* verify_checksum */ false, + /*verify=*/ false, + /*verify_checksum=*/ false, error_msg, uncompressed_dex_files_.get()); } else { loaded = dex_file_loader.Open(dex_file_location.c_str(), dex_file_location, - /* verify */ false, - /* verify_checksum */ false, + /*verify=*/ false, + /*verify_checksum=*/ false, error_msg, uncompressed_dex_files_.get()); } @@ -1323,7 +1305,7 @@ ElfOatFile* ElfOatFile::OpenElfFile(int zip_fd, } // Complete the setup. - if (!oat_file->ComputeFields(/* requested_base */ nullptr, file->GetPath(), error_msg)) { + if (!oat_file->ComputeFields(file->GetPath(), error_msg)) { return nullptr; } @@ -1407,10 +1389,9 @@ bool ElfOatFile::ElfFileOpen(File* file, /*inout*/MemMap* reservation, /*out*/std::string* error_msg) { ScopedTrace trace(__PRETTY_FUNCTION__); - // TODO: rename requested_base to oat_data_begin elf_file_.reset(ElfFile::Open(file, writable, - /*program_header_only*/true, + /*program_header_only=*/ true, low_4gb, error_msg)); if (elf_file_ == nullptr) { @@ -1458,7 +1439,7 @@ OatFile* OatFile::OpenWithElfFile(int zip_fd, const std::string& location, const char* abs_dex_location, std::string* error_msg) { - std::unique_ptr<ElfOatFile> oat_file(new ElfOatFile(location, false /* executable */)); + std::unique_ptr<ElfOatFile> oat_file(new ElfOatFile(location, /*executable=*/ false)); return oat_file->InitializeFromElfFile(zip_fd, elf_file, vdex_file, abs_dex_location, error_msg) ? oat_file.release() : nullptr; @@ -1467,7 +1448,6 @@ OatFile* OatFile::OpenWithElfFile(int zip_fd, OatFile* OatFile::Open(int zip_fd, const std::string& oat_filename, const std::string& oat_location, - uint8_t* requested_base, bool executable, bool low_4gb, const char* abs_dex_location, @@ -1494,8 +1474,7 @@ OatFile* OatFile::Open(int zip_fd, vdex_filename, oat_filename, oat_location, - requested_base, - false /* writable */, + /*writable=*/ false, executable, low_4gb, abs_dex_location, @@ -1524,8 +1503,7 @@ OatFile* OatFile::Open(int zip_fd, vdex_filename, oat_filename, oat_location, - requested_base, - false /* writable */, + /*writable=*/ false, executable, low_4gb, abs_dex_location, @@ -1538,7 +1516,6 @@ OatFile* OatFile::Open(int zip_fd, int vdex_fd, int oat_fd, const std::string& oat_location, - uint8_t* requested_base, bool executable, bool low_4gb, const char* abs_dex_location, @@ -1553,8 +1530,7 @@ OatFile* OatFile::Open(int zip_fd, oat_fd, vdex_location, oat_location, - requested_base, - false /* writable */, + /*writable=*/ false, executable, low_4gb, abs_dex_location, @@ -1572,11 +1548,11 @@ OatFile* OatFile::OpenWritable(int zip_fd, return ElfOatFile::OpenElfFile(zip_fd, file, location, - /* writable */ true, - /* executable */ false, - /*low_4gb*/false, + /*writable=*/ true, + /*executable=*/ false, + /*low_4gb=*/false, abs_dex_location, - /* reservation */ nullptr, + /*reservation=*/ nullptr, error_msg); } @@ -1589,11 +1565,11 @@ OatFile* OatFile::OpenReadable(int zip_fd, return ElfOatFile::OpenElfFile(zip_fd, file, location, - /* writable */ false, - /* executable */ false, - /*low_4gb*/false, + /*writable=*/ false, + /*executable=*/ false, + /*low_4gb=*/false, abs_dex_location, - /* reservation */ nullptr, + /*reservation=*/ nullptr, error_msg); } diff --git a/runtime/oat_file.h b/runtime/oat_file.h index b3736e6514..ba08e5e38b 100644 --- a/runtime/oat_file.h +++ b/runtime/oat_file.h @@ -85,7 +85,6 @@ class OatFile { static OatFile* Open(int zip_fd, const std::string& filename, const std::string& location, - uint8_t* requested_base, bool executable, bool low_4gb, const char* abs_dex_location, @@ -99,7 +98,6 @@ class OatFile { int vdex_fd, int oat_fd, const std::string& oat_location, - uint8_t* requested_base, bool executable, bool low_4gb, const char* abs_dex_location, diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc index 009abdb85c..754aa406db 100644 --- a/runtime/oat_file_assistant.cc +++ b/runtime/oat_file_assistant.cc @@ -76,9 +76,9 @@ OatFileAssistant::OatFileAssistant(const char* dex_location, isa, load_executable, only_load_system_executable, - -1 /* vdex_fd */, - -1 /* oat_fd */, - -1 /* zip_fd */) {} + /*vdex_fd=*/ -1, + /*oat_fd=*/ -1, + /*zip_fd=*/ -1) {} OatFileAssistant::OatFileAssistant(const char* dex_location, @@ -124,7 +124,7 @@ OatFileAssistant::OatFileAssistant(const char* dex_location, // Get the oat filename. std::string oat_file_name; if (DexLocationToOatFilename(dex_location_, isa_, &oat_file_name, &error_msg)) { - oat_.Reset(oat_file_name, false /* use_fd */); + oat_.Reset(oat_file_name, /*use_fd=*/ false); } else { LOG(WARNING) << "Failed to determine oat file name for dex location " << dex_location_ << ": " << error_msg; @@ -575,7 +575,6 @@ OatFileAssistant::ImageInfo::GetRuntimeImageInfo(InstructionSet isa, std::string } info->oat_checksum = image_header->GetOatChecksum(); - info->oat_data_begin = reinterpret_cast<uintptr_t>(image_header->GetOatDataBegin()); info->patch_delta = image_header->GetPatchDelta(); return info; } @@ -693,9 +692,9 @@ OatFileAssistant::OatStatus OatFileAssistant::OatFileInfo::Status() { vdex = VdexFile::Open(vdex_fd_, s.st_size, vdex_filename, - false /*writable*/, - false /*low_4gb*/, - false /* unquicken */, + /*writable=*/ false, + /*low_4gb=*/ false, + /*unquicken=*/ false, &error_msg); } } @@ -779,22 +778,20 @@ const OatFile* OatFileAssistant::OatFileInfo::GetFile() { vdex_fd_, oat_fd_, filename_.c_str(), - /* requested_base */ nullptr, executable, - /* low_4gb */ false, + /*low_4gb=*/ false, oat_file_assistant_->dex_location_.c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); } } else { - file_.reset(OatFile::Open(/* zip_fd */ -1, + file_.reset(OatFile::Open(/*zip_fd=*/ -1, filename_.c_str(), filename_.c_str(), - /* requested_base */ nullptr, executable, - /* low_4gb */ false, + /*low_4gb=*/ false, oat_file_assistant_->dex_location_.c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); } if (file_.get() == nullptr) { @@ -924,7 +921,7 @@ void OatFileAssistant::GetOptimizationStatus( std::string* out_compilation_reason) { // It may not be possible to load an oat file executable (e.g., selinux restrictions). Load // non-executable and check the status manually. - OatFileAssistant oat_file_assistant(filename.c_str(), isa, false /* load_executable */); + OatFileAssistant oat_file_assistant(filename.c_str(), isa, /*load_executable=*/ false); std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); if (oat_file == nullptr) { diff --git a/runtime/oat_file_assistant.h b/runtime/oat_file_assistant.h index 3da1a221ae..590ae2254c 100644 --- a/runtime/oat_file_assistant.h +++ b/runtime/oat_file_assistant.h @@ -247,7 +247,6 @@ class OatFileAssistant { private: struct ImageInfo { uint32_t oat_checksum = 0; - uintptr_t oat_data_begin = 0; int32_t patch_delta = 0; std::string location; diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc index a9ef9a3fa9..b9e9d384c2 100644 --- a/runtime/oat_file_manager.cc +++ b/runtime/oat_file_manager.cc @@ -84,7 +84,7 @@ void OatFileManager::UnRegisterAndDeleteOatFile(const OatFile* oat_file) { auto it = oat_files_.find(compare); CHECK(it != oat_files_.end()); oat_files_.erase(it); - compare.release(); + compare.release(); // NOLINT b/117926937 } const OatFile* OatFileManager::FindOpenedOatFileFromDexLocation( @@ -567,7 +567,7 @@ std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat( if (added_image_space) { // Successfully added image space to heap, release the map so that it does not get // freed. - image_space.release(); + image_space.release(); // NOLINT b/117926937 // Register for tracking. for (const auto& dex_file : dex_files) { diff --git a/runtime/oat_file_test.cc b/runtime/oat_file_test.cc index 51d8fca6c5..b54711322b 100644 --- a/runtime/oat_file_test.cc +++ b/runtime/oat_file_test.cc @@ -74,14 +74,13 @@ TEST_F(OatFileTest, LoadOat) { std::string error_msg; ASSERT_TRUE(OatFileAssistant::DexLocationToOatFilename( dex_location, kRuntimeISA, &oat_location, &error_msg)) << error_msg; - std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1, oat_location.c_str(), oat_location.c_str(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, + /*executable=*/ false, + /*low_4gb=*/ false, dex_location.c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(odex_file.get() != nullptr); @@ -102,14 +101,13 @@ TEST_F(OatFileTest, ChangingMultiDexUncompressed) { // Ensure we can load that file. Just a precondition. { - std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1, oat_location.c_str(), oat_location.c_str(), - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, + /*executable=*/ false, + /*low_4gb=*/ false, dex_location.c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); ASSERT_TRUE(odex_file != nullptr); ASSERT_EQ(2u, odex_file->GetOatDexFiles().size()); @@ -119,14 +117,13 @@ TEST_F(OatFileTest, ChangingMultiDexUncompressed) { Copy(GetTestDexFileName("MainUncompressed"), dex_location); // And try to load again. - std::unique_ptr<OatFile> odex_file(OatFile::Open(/* zip_fd */ -1, + std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1, oat_location, oat_location, - /* requested_base */ nullptr, - /* executable */ false, - /* low_4gb */ false, + /*executable=*/ false, + /*low_4gb=*/ false, dex_location.c_str(), - /* reservation */ nullptr, + /*reservation=*/ nullptr, &error_msg)); EXPECT_TRUE(odex_file == nullptr); EXPECT_NE(std::string::npos, error_msg.find("expected 2 uncompressed dex files, but found 1")) diff --git a/runtime/runtime.cc b/runtime/runtime.cc index b3a2bdd936..4d77b9d993 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -165,6 +165,11 @@ #include <android/set_abort_message.h> #endif +// Static asserts to check the values of generated assembly-support macros. +#define ASM_DEFINE(NAME, EXPR) static_assert((NAME) == (EXPR), "Unexpected value of " #NAME); +#include "asm_defines.def" +#undef ASM_DEFINE + namespace art { // If a signal isn't handled properly, enable a handler that attempts to dump the Java stack. diff --git a/runtime/thread.cc b/runtime/thread.cc index 68c82295a6..b3492e1e31 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -729,7 +729,7 @@ void Thread::CreateNativeThread(JNIEnv* env, jobject java_peer, size_t stack_siz // JNIEnvExt we created. // Note: we can't check for tmp_jni_env == nullptr, as that would require synchronization // between the threads. - child_jni_env_ext.release(); + child_jni_env_ext.release(); // NOLINT pthreads API. return; } } @@ -3374,8 +3374,13 @@ void Thread::QuickDeliverException() { // Note: we do this *after* reporting the exception to instrumentation in case it now requires // deoptimization. It may happen if a debugger is attached and requests new events (single-step, // breakpoint, ...) when the exception is reported. + // + // Note we need to check for both force_frame_pop and force_retry_instruction. The first is + // expected to happen fairly regularly but the second can only happen if we are using + // instrumentation trampolines (for example with DDMS tracing). That forces us to do deopt later + // and see every frame being popped. We don't need to handle it any differently. ShadowFrame* cf; - bool force_frame_pop = false; + bool force_deopt; { NthCallerVisitor visitor(this, 0, false); visitor.WalkStack(); @@ -3383,7 +3388,8 @@ void Thread::QuickDeliverException() { if (cf == nullptr) { cf = FindDebuggerShadowFrame(visitor.GetFrameId()); } - force_frame_pop = cf != nullptr && cf->GetForcePopFrame(); + bool force_frame_pop = cf != nullptr && cf->GetForcePopFrame(); + bool force_retry_instr = cf != nullptr && cf->GetForceRetryInstruction(); if (kIsDebugBuild && force_frame_pop) { NthCallerVisitor penultimate_visitor(this, 1, false); penultimate_visitor.WalkStack(); @@ -3396,8 +3402,9 @@ void Thread::QuickDeliverException() { << "Force pop frame without retry instruction found. penultimate frame is null: " << (penultimate_frame == nullptr ? "true" : "false"); } + force_deopt = force_frame_pop || force_retry_instr; } - if (Dbg::IsForcedInterpreterNeededForException(this) || force_frame_pop) { + if (Dbg::IsForcedInterpreterNeededForException(this) || force_deopt) { NthCallerVisitor visitor(this, 0, false); visitor.WalkStack(); if (Runtime::Current()->IsAsyncDeoptimizeable(visitor.caller_pc)) { @@ -3405,16 +3412,18 @@ void Thread::QuickDeliverException() { const DeoptimizationMethodType method_type = DeoptimizationMethodType::kDefault; // Save the exception into the deoptimization context so it can be restored // before entering the interpreter. - if (force_frame_pop) { + if (force_deopt) { VLOG(deopt) << "Deopting " << cf->GetMethod()->PrettyMethod() << " for frame-pop"; DCHECK(Runtime::Current()->AreNonStandardExitsEnabled()); // Get rid of the exception since we are doing a framepop instead. + LOG(WARNING) << "Suppressing pending exception for retry-instruction/frame-pop: " + << exception->Dump(); ClearException(); } PushDeoptimizationContext( JValue(), false /* is_reference */, - (force_frame_pop ? nullptr : exception), + (force_deopt ? nullptr : exception), false /* from_code */, method_type); artDeoptimize(this); diff --git a/runtime/thread.h b/runtime/thread.h index 47a3af2564..d7dc5aeacb 100644 --- a/runtime/thread.h +++ b/runtime/thread.h @@ -743,18 +743,6 @@ class Thread { } template<PointerSize pointer_size> - static constexpr ThreadOffset<pointer_size> MterpDefaultIBaseOffset() { - return ThreadOffsetFromTlsPtr<pointer_size>( - OFFSETOF_MEMBER(tls_ptr_sized_values, mterp_default_ibase)); - } - - template<PointerSize pointer_size> - static constexpr ThreadOffset<pointer_size> MterpAltIBaseOffset() { - return ThreadOffsetFromTlsPtr<pointer_size>( - OFFSETOF_MEMBER(tls_ptr_sized_values, mterp_alt_ibase)); - } - - template<PointerSize pointer_size> static constexpr ThreadOffset<pointer_size> ExceptionOffset() { return ThreadOffsetFromTlsPtr<pointer_size>(OFFSETOF_MEMBER(tls_ptr_sized_values, exception)); } @@ -1199,30 +1187,14 @@ class Thread { bool ProtectStack(bool fatal_on_error = true); bool UnprotectStack(); - void SetMterpDefaultIBase(void* ibase) { - tlsPtr_.mterp_default_ibase = ibase; - } - void SetMterpCurrentIBase(void* ibase) { tlsPtr_.mterp_current_ibase = ibase; } - void SetMterpAltIBase(void* ibase) { - tlsPtr_.mterp_alt_ibase = ibase; - } - - const void* GetMterpDefaultIBase() const { - return tlsPtr_.mterp_default_ibase; - } - const void* GetMterpCurrentIBase() const { return tlsPtr_.mterp_current_ibase; } - const void* GetMterpAltIBase() const { - return tlsPtr_.mterp_alt_ibase; - } - bool HandlingSignal() const { return tls32_.handling_signal_; } @@ -1599,8 +1571,7 @@ class Thread { last_no_thread_suspension_cause(nullptr), checkpoint_function(nullptr), thread_local_start(nullptr), thread_local_pos(nullptr), thread_local_end(nullptr), thread_local_limit(nullptr), - thread_local_objects(0), mterp_current_ibase(nullptr), mterp_default_ibase(nullptr), - mterp_alt_ibase(nullptr), thread_local_alloc_stack_top(nullptr), + thread_local_objects(0), mterp_current_ibase(nullptr), thread_local_alloc_stack_top(nullptr), thread_local_alloc_stack_end(nullptr), flip_function(nullptr), method_verifier(nullptr), thread_local_mark_stack(nullptr), async_exception(nullptr) { @@ -1737,10 +1708,8 @@ class Thread { JniEntryPoints jni_entrypoints; QuickEntryPoints quick_entrypoints; - // Mterp jump table bases. + // Mterp jump table base. void* mterp_current_ibase; - void* mterp_default_ibase; - void* mterp_alt_ibase; // There are RosAlloc::kNumThreadLocalSizeBrackets thread-local size brackets per thread. void* rosalloc_runs[kNumRosAllocThreadLocalSizeBracketsInThread]; diff --git a/test/905-object-free/src/art/Test905.java b/test/905-object-free/src/art/Test905.java index 62b6e62669..dddd1aa69f 100644 --- a/test/905-object-free/src/art/Test905.java +++ b/test/905-object-free/src/art/Test905.java @@ -16,10 +16,53 @@ package art; +import java.lang.ref.PhantomReference; +import java.lang.ref.ReferenceQueue; import java.util.ArrayList; import java.util.Arrays; public class Test905 { + // Taken from jdwp tests. + public static class MarkerObj { + public static int cnt = 0; + public void finalize() { cnt++; } + } + public static class GcMarker { + private final ReferenceQueue mQueue; + private final ArrayList<PhantomReference> mList; + public GcMarker() { + mQueue = new ReferenceQueue(); + mList = new ArrayList<PhantomReference>(3); + } + public void add(Object referent) { + mList.add(new PhantomReference(referent, mQueue)); + } + public void waitForGc() { + waitForGc(mList.size()); + } + public void waitForGc(int numberOfExpectedFinalizations) { + if (numberOfExpectedFinalizations > mList.size()) { + throw new IllegalArgumentException("wait condition will never be met"); + } + // Request finalization of objects, and subsequent reference enqueueing. + // Repeat until reference queue reaches expected size. + do { + System.runFinalization(); + Runtime.getRuntime().gc(); + try { Thread.sleep(10); } catch (Exception e) {} + } while (isLive(numberOfExpectedFinalizations)); + } + private boolean isLive(int numberOfExpectedFinalizations) { + int numberFinalized = 0; + for (int i = 0, n = mList.size(); i < n; i++) { + if (mList.get(i).isEnqueued()) { + numberFinalized++; + } + } + return numberFinalized < numberOfExpectedFinalizations; + } + } + public static void run() throws Exception { doTest(); } @@ -44,7 +87,7 @@ public class Test905 { allocate(l, 1); l.clear(); - Runtime.getRuntime().gc(); + gcAndWait(); getAndPrintTags(); System.out.println("---"); @@ -56,12 +99,12 @@ public class Test905 { } l.clear(); - Runtime.getRuntime().gc(); + gcAndWait(); getAndPrintTags(); System.out.println("---"); - Runtime.getRuntime().gc(); + gcAndWait(); getAndPrintTags(); System.out.println("---"); @@ -80,7 +123,7 @@ public class Test905 { for (int i = 1; i <= 100000; ++i) { stressAllocate(i); } - Runtime.getRuntime().gc(); + gcAndWait(); long[] freedTags1 = getCollectedTags(0); long[] freedTags2 = getCollectedTags(1); System.out.println("Free counts " + freedTags1.length + " " + freedTags2.length); @@ -103,6 +146,17 @@ public class Test905 { System.out.println(Arrays.toString(freedTags)); } + private static GcMarker getMarker() { + GcMarker m = new GcMarker(); + m.add(new MarkerObj()); + return m; + } + + private static void gcAndWait() { + GcMarker marker = getMarker(); + marker.waitForGc(); + } + private static native void setupObjectFreeCallback(); private static native void enableFreeTracking(boolean enable); private static native long[] getCollectedTags(int index); diff --git a/test/StringLiterals/StringLiterals.java b/test/StringLiterals/StringLiterals.java new file mode 100644 index 0000000000..9ab37ca3de --- /dev/null +++ b/test/StringLiterals/StringLiterals.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2018 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. + */ + +class StringLiterals { + static class StartupClass { + static { + System.out.println("Startup init"); + } + } + + static class OtherClass { + static { + System.out.println("Other class init"); + } + } + + void startUpMethod() { + String resource = "abcd.apk"; + System.out.println("Starting up"); + System.out.println("Loading " + resource); + } + + void otherMethod() { + System.out.println("Unexpected error"); + System.out.println("Shutting down!"); + } +} diff --git a/test/knownfailures.json b/test/knownfailures.json index d769b48bfd..f4f45ce177 100644 --- a/test/knownfailures.json +++ b/test/knownfailures.json @@ -1114,11 +1114,5 @@ "variant": "target & gcstress & debug", "bug": "b/117597114", "description": ["Looks timing dependent"] - }, - { - "tests": ["920-objects"], - "variant": "jit-on-first-use", - "bug": "b/117638896", - "description": ["SIGSEGVs on jit-on-first-use configuration."] } ] diff --git a/tools/ahat/Android.mk b/tools/ahat/Android.mk index 32e5b5525f..dcd910597d 100644 --- a/tools/ahat/Android.mk +++ b/tools/ahat/Android.mk @@ -104,9 +104,17 @@ $(AHAT_TEST_DUMP_PROGUARD_MAP): PRIVATE_AHAT_SOURCE_PROGUARD_MAP := $(proguard_d $(AHAT_TEST_DUMP_PROGUARD_MAP): $(proguard_dictionary) cp $(PRIVATE_AHAT_SOURCE_PROGUARD_MAP) $@ +ifeq (true,$(HOST_PREFER_32_BIT)) + AHAT_TEST_DALVIKVM_DEP := $(HOST_OUT_EXECUTABLES)/dalvikvm32 + AHAT_TEST_DALVIKVM_ARG := --32 +else + AHAT_TEST_DALVIKVM_DEP := $(HOST_OUT_EXECUTABLES)/dalvikvm64 + AHAT_TEST_DALVIKVM_ARG := --64 +endif + # Run ahat-test-dump.jar to generate test-dump.hprof and test-dump-base.hprof AHAT_TEST_DUMP_DEPENDENCIES := \ - $(HOST_OUT_EXECUTABLES)/dalvikvm64 \ + $(AHAT_TEST_DALVIKVM_DEP) \ $(ART_HOST_SHARED_LIBRARY_DEBUG_DEPENDENCIES) \ $(HOST_OUT_EXECUTABLES)/art \ $(HOST_CORE_IMG_OUT_BASE)$(CORE_IMG_SUFFIX) @@ -114,20 +122,24 @@ AHAT_TEST_DUMP_DEPENDENCIES := \ $(AHAT_TEST_DUMP_HPROF): PRIVATE_AHAT_TEST_ART := $(HOST_OUT_EXECUTABLES)/art $(AHAT_TEST_DUMP_HPROF): PRIVATE_AHAT_TEST_DUMP_JAR := $(AHAT_TEST_DUMP_JAR) $(AHAT_TEST_DUMP_HPROF): PRIVATE_AHAT_TEST_ANDROID_DATA := $(AHAT_TEST_DUMP_ANDROID_DATA) +$(AHAT_TEST_DUMP_HPROF): PRIVATE_AHAT_TEST_DALVIKVM_ARG := $(AHAT_TEST_DALVIKVM_ARG) $(AHAT_TEST_DUMP_HPROF): $(AHAT_TEST_DUMP_JAR) $(AHAT_TEST_DUMP_DEPENDENCIES) rm -rf $(PRIVATE_AHAT_TEST_ANDROID_DATA) mkdir -p $(PRIVATE_AHAT_TEST_ANDROID_DATA) ANDROID_DATA=$(PRIVATE_AHAT_TEST_ANDROID_DATA) \ - $(PRIVATE_AHAT_TEST_ART) -d --64 -cp $(PRIVATE_AHAT_TEST_DUMP_JAR) Main $@ + $(PRIVATE_AHAT_TEST_ART) -d $(PRIVATE_AHAT_TEST_DALVIKVM_ARG) \ + -cp $(PRIVATE_AHAT_TEST_DUMP_JAR) Main $@ $(AHAT_TEST_DUMP_BASE_HPROF): PRIVATE_AHAT_TEST_ART := $(HOST_OUT_EXECUTABLES)/art $(AHAT_TEST_DUMP_BASE_HPROF): PRIVATE_AHAT_TEST_DUMP_JAR := $(AHAT_TEST_DUMP_JAR) $(AHAT_TEST_DUMP_BASE_HPROF): PRIVATE_AHAT_TEST_ANDROID_DATA := $(AHAT_TEST_DUMP_BASE_ANDROID_DATA) +$(AHAT_TEST_DUMP_BASE_HPROF): PRIVATE_AHAT_TEST_DALVIKVM_ARG := $(AHAT_TEST_DALVIKVM_ARG) $(AHAT_TEST_DUMP_BASE_HPROF): $(AHAT_TEST_DUMP_JAR) $(AHAT_TEST_DUMP_DEPENDENCIES) rm -rf $(PRIVATE_AHAT_TEST_ANDROID_DATA) mkdir -p $(PRIVATE_AHAT_TEST_ANDROID_DATA) ANDROID_DATA=$(PRIVATE_AHAT_TEST_ANDROID_DATA) \ - $(PRIVATE_AHAT_TEST_ART) -d --64 -cp $(PRIVATE_AHAT_TEST_DUMP_JAR) Main $@ --base + $(PRIVATE_AHAT_TEST_ART) -d $(PRIVATE_AHAT_TEST_DALVIKVM_ARG) \ + -cp $(PRIVATE_AHAT_TEST_DUMP_JAR) Main $@ --base # --- ahat-ri-test-dump.jar ------- include $(CLEAR_VARS) diff --git a/tools/class2greylist/src/com/android/class2greylist/AnnotationVisitor.java b/tools/class2greylist/src/com/android/class2greylist/AnnotationVisitor.java index b805b307a3..57ccbdc54e 100644 --- a/tools/class2greylist/src/com/android/class2greylist/AnnotationVisitor.java +++ b/tools/class2greylist/src/com/android/class2greylist/AnnotationVisitor.java @@ -77,6 +77,9 @@ public class AnnotationVisitor extends EmptyVisitor { mStatus.debug("Member has annotation %s for which we have a handler", a.getAnnotationType()); mAnnotationHandlers.get(a.getAnnotationType()).handleAnnotation(a, context); + } else { + mStatus.debug("Member has annotation %s for which we do not have a handler", + a.getAnnotationType()); } } } diff --git a/tools/class2greylist/src/com/android/class2greylist/Class2Greylist.java b/tools/class2greylist/src/com/android/class2greylist/Class2Greylist.java index 53157a323e..870f85a2c3 100644 --- a/tools/class2greylist/src/com/android/class2greylist/Class2Greylist.java +++ b/tools/class2greylist/src/com/android/class2greylist/Class2Greylist.java @@ -17,7 +17,9 @@ package com.android.class2greylist; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Joiner; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import com.google.common.io.Files; @@ -41,6 +43,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Predicate; /** * Build time tool for extracting a list of members from jar files that have the @UsedByApps @@ -48,16 +51,20 @@ import java.util.Set; */ public class Class2Greylist { - private static final String GREYLIST_ANNOTATION = "Landroid/annotation/UnsupportedAppUsage;"; + private static final Set<String> GREYLIST_ANNOTATIONS = + ImmutableSet.of( + "Landroid/annotation/UnsupportedAppUsage;", + "Ldalvik/annotation/compat/UnsupportedAppUsage;"); private static final Set<String> WHITELIST_ANNOTATIONS = ImmutableSet.of(); private final Status mStatus; private final String mPublicApiListFile; private final String[] mPerSdkOutputFiles; private final String mWhitelistFile; + private final String mCsvMetadataFile; private final String[] mJarFiles; private final GreylistConsumer mOutput; - private final Set<Integer> mAllowedSdkVersions; + private final Predicate<Integer> mAllowedSdkVersions; private final Set<String> mPublicApis; @@ -95,10 +102,17 @@ public class Class2Greylist { .hasArgs(0) .create('m')); options.addOption(OptionBuilder + .withLongOpt("write-metadata-csv") + .hasArgs(1) + .withDescription("Specify a file to write API metaadata to. This is a CSV file " + + "containing any annotation properties for all members. Do not use in " + + "conjunction with --write-greylist or --write-whitelist.") + .create('c')); + options.addOption(OptionBuilder .withLongOpt("help") .hasArgs(0) .withDescription("Show this help") - .create("h")); + .create('h')); CommandLineParser parser = new GnuParser(); CommandLine cmd; @@ -132,6 +146,7 @@ public class Class2Greylist { cmd.getOptionValue('p', null), cmd.getOptionValues('g'), cmd.getOptionValue('w', null), + cmd.getOptionValue('c', null), jarFiles); c2gl.main(); } catch (IOException e) { @@ -149,22 +164,33 @@ public class Class2Greylist { @VisibleForTesting Class2Greylist(Status status, String publicApiListFile, String[] perSdkLevelOutputFiles, - String whitelistOutputFile, String[] jarFiles) throws IOException { + String whitelistOutputFile, String csvMetadataFile, String[] jarFiles) + throws IOException { mStatus = status; mPublicApiListFile = publicApiListFile; mPerSdkOutputFiles = perSdkLevelOutputFiles; mWhitelistFile = whitelistOutputFile; + mCsvMetadataFile = csvMetadataFile; mJarFiles = jarFiles; - if (mPerSdkOutputFiles != null) { + if (mCsvMetadataFile != null) { + mOutput = new CsvGreylistConsumer(mStatus, mCsvMetadataFile); + mAllowedSdkVersions = x -> true; + } else { Map<Integer, String> outputFiles = readGreylistMap(mStatus, mPerSdkOutputFiles); mOutput = new FileWritingGreylistConsumer(mStatus, outputFiles, mWhitelistFile); - mAllowedSdkVersions = outputFiles.keySet(); - } else { - // TODO remove this once per-SDK greylist support integrated into the build. - // Right now, mPerSdkOutputFiles is always null as the build never passes the - // corresponding command lind flags. Once the build is updated, can remove this. - mOutput = new SystemOutGreylistConsumer(); - mAllowedSdkVersions = new HashSet<>(Arrays.asList(null, 26, 28)); + mAllowedSdkVersions = new Predicate<Integer>(){ + @Override + public boolean test(Integer i) { + return outputFiles.keySet().contains(i); + } + + @Override + public String toString() { + // we reply on this toString behaviour for readable error messages in + // GreylistAnnotationHandler + return Joiner.on(",").join(outputFiles.keySet()); + } + }; } if (mPublicApiListFile != null) { @@ -176,10 +202,11 @@ public class Class2Greylist { } private Map<String, AnnotationHandler> createAnnotationHandlers() { - return ImmutableMap.<String, AnnotationHandler>builder() - .put(GreylistAnnotationHandler.ANNOTATION_NAME, - new GreylistAnnotationHandler( - mStatus, mOutput, mPublicApis, mAllowedSdkVersions)) + Builder<String, AnnotationHandler> builder = ImmutableMap.builder(); + GreylistAnnotationHandler greylistAnnotationHandler = new GreylistAnnotationHandler( + mStatus, mOutput, mPublicApis, mAllowedSdkVersions); + GREYLIST_ANNOTATIONS.forEach(a -> builder.put(a, greylistAnnotationHandler)); + return builder .put(CovariantReturnTypeHandler.ANNOTATION_NAME, new CovariantReturnTypeHandler(mOutput, mPublicApis)) .put(CovariantReturnTypeMultiHandler.ANNOTATION_NAME, diff --git a/tools/class2greylist/src/com/android/class2greylist/CsvGreylistConsumer.java b/tools/class2greylist/src/com/android/class2greylist/CsvGreylistConsumer.java new file mode 100644 index 0000000000..7d28b317f0 --- /dev/null +++ b/tools/class2greylist/src/com/android/class2greylist/CsvGreylistConsumer.java @@ -0,0 +1,35 @@ +package com.android.class2greylist; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.util.Map; + +public class CsvGreylistConsumer implements GreylistConsumer { + + private final Status mStatus; + private final CsvWriter mCsvWriter; + + public CsvGreylistConsumer(Status status, String csvMetadataFile) throws FileNotFoundException { + mStatus = status; + mCsvWriter = new CsvWriter( + new PrintStream(new FileOutputStream(new File(csvMetadataFile)))); + } + + @Override + public void greylistEntry(String signature, Integer maxTargetSdk, + Map<String, String> annotationProperties) { + annotationProperties.put("signature", signature); + mCsvWriter.addRow(annotationProperties); + } + + @Override + public void whitelistEntry(String signature) { + } + + @Override + public void close() { + mCsvWriter.close(); + } +} diff --git a/tools/class2greylist/src/com/android/class2greylist/CsvWriter.java b/tools/class2greylist/src/com/android/class2greylist/CsvWriter.java new file mode 100644 index 0000000000..3cfec30f23 --- /dev/null +++ b/tools/class2greylist/src/com/android/class2greylist/CsvWriter.java @@ -0,0 +1,49 @@ +package com.android.class2greylist; + +import com.google.common.base.Joiner; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Helper class for writing data to a CSV file. + * + * This class does not write anything to its output until it is closed, so it can gather a set of + * all columns before writing the header row. + */ +public class CsvWriter { + + private final PrintStream mOutput; + private final ArrayList<Map<String, String>> mContents; + private final Set<String> mColumns; + + public CsvWriter(PrintStream out) { + mOutput = out; + mContents = new ArrayList<>(); + mColumns = new HashSet<>(); + } + + public void addRow(Map<String, String> values) { + mColumns.addAll(values.keySet()); + mContents.add(values); + } + + public void close() { + List<String> columns = new ArrayList<>(mColumns); + columns.sort(Comparator.naturalOrder()); + mOutput.println(columns.stream().collect(Collectors.joining(","))); + for (Map<String, String> row : mContents) { + mOutput.println(columns.stream().map(column -> row.getOrDefault(column, "")).collect( + Collectors.joining(","))); + } + mOutput.close(); + } + + +} diff --git a/tools/class2greylist/src/com/android/class2greylist/FileWritingGreylistConsumer.java b/tools/class2greylist/src/com/android/class2greylist/FileWritingGreylistConsumer.java index bfd23102b9..b3ed1b16f9 100644 --- a/tools/class2greylist/src/com/android/class2greylist/FileWritingGreylistConsumer.java +++ b/tools/class2greylist/src/com/android/class2greylist/FileWritingGreylistConsumer.java @@ -44,7 +44,8 @@ public class FileWritingGreylistConsumer implements GreylistConsumer { } @Override - public void greylistEntry(String signature, Integer maxTargetSdk) { + public void greylistEntry( + String signature, Integer maxTargetSdk, Map<String, String> annotationProperties) { PrintStream p = mSdkToPrintStreamMap.get(maxTargetSdk); if (p == null) { mStatus.error("No output file for signature %s with maxTargetSdk of %d", signature, diff --git a/tools/class2greylist/src/com/android/class2greylist/GreylistAnnotationHandler.java b/tools/class2greylist/src/com/android/class2greylist/GreylistAnnotationHandler.java index 460f2c3c22..72c0ea4206 100644 --- a/tools/class2greylist/src/com/android/class2greylist/GreylistAnnotationHandler.java +++ b/tools/class2greylist/src/com/android/class2greylist/GreylistAnnotationHandler.java @@ -11,6 +11,8 @@ import org.apache.bcel.classfile.FieldOrMethod; import org.apache.bcel.classfile.Method; import org.apache.bcel.classfile.SimpleElementValue; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import java.util.function.Predicate; @@ -27,8 +29,6 @@ import java.util.function.Predicate; */ public class GreylistAnnotationHandler implements AnnotationHandler { - public static final String ANNOTATION_NAME = "Landroid/annotation/UnsupportedAppUsage;"; - // properties of greylist annotations: private static final String EXPECTED_SIGNATURE = "expectedSignature"; private static final String MAX_TARGET_SDK = "maxTargetSdk"; @@ -36,7 +36,7 @@ public class GreylistAnnotationHandler implements AnnotationHandler { private final Status mStatus; private final Predicate<GreylistMember> mGreylistFilter; private final GreylistConsumer mGreylistConsumer; - private final Set<Integer> mValidMaxTargetSdkValues; + private final Predicate<Integer> mValidMaxTargetSdkValues; /** * Represents a member of a class file (a field or method). @@ -73,7 +73,7 @@ public class GreylistAnnotationHandler implements AnnotationHandler { Status status, GreylistConsumer greylistConsumer, Set<String> publicApis, - Set<Integer> validMaxTargetSdkValues) { + Predicate<Integer> validMaxTargetSdkValues) { this(status, greylistConsumer, member -> !(member.bridge && publicApis.contains(member.signature)), validMaxTargetSdkValues); @@ -84,7 +84,7 @@ public class GreylistAnnotationHandler implements AnnotationHandler { Status status, GreylistConsumer greylistConsumer, Predicate<GreylistMember> greylistFilter, - Set<Integer> validMaxTargetSdkValues) { + Predicate<Integer> validMaxTargetSdkValues) { mStatus = status; mGreylistConsumer = greylistConsumer; mGreylistFilter = greylistFilter; @@ -101,6 +101,7 @@ public class GreylistAnnotationHandler implements AnnotationHandler { } String signature = context.getMemberDescriptor(); Integer maxTargetSdk = null; + Map<String, String> allValues = new HashMap<String, String>(); for (ElementValuePair property : annotation.getElementValuePairs()) { switch (property.getNameString()) { case EXPECTED_SIGNATURE: @@ -110,9 +111,10 @@ public class GreylistAnnotationHandler implements AnnotationHandler { maxTargetSdk = verifyAndGetMaxTargetSdk(context, property); break; } + allValues.put(property.getNameString(), property.getValue().stringifyValue()); } if (mGreylistFilter.test(new GreylistMember(signature, bridge, maxTargetSdk))) { - mGreylistConsumer.greylistEntry(signature, maxTargetSdk); + mGreylistConsumer.greylistEntry(signature, maxTargetSdk, allValues); } } @@ -131,13 +133,14 @@ public class GreylistAnnotationHandler implements AnnotationHandler { if (property.getValue().getElementValueType() != ElementValue.PRIMITIVE_INT) { context.reportError("Expected property %s to be of type int; got %d", property.getNameString(), property.getValue().getElementValueType()); + return null; } int value = ((SimpleElementValue) property.getValue()).getValueInt(); - if (!mValidMaxTargetSdkValues.contains(value)) { + if (!mValidMaxTargetSdkValues.test(value)) { context.reportError("Invalid value for %s: got %d, expected one of [%s]", property.getNameString(), value, - Joiner.on(",").join(mValidMaxTargetSdkValues)); + mValidMaxTargetSdkValues); return null; } return value; diff --git a/tools/class2greylist/src/com/android/class2greylist/GreylistConsumer.java b/tools/class2greylist/src/com/android/class2greylist/GreylistConsumer.java index fd855e88ed..afded37e66 100644 --- a/tools/class2greylist/src/com/android/class2greylist/GreylistConsumer.java +++ b/tools/class2greylist/src/com/android/class2greylist/GreylistConsumer.java @@ -1,5 +1,7 @@ package com.android.class2greylist; +import java.util.Map; + public interface GreylistConsumer { /** * Handle a new greylist entry. @@ -7,7 +9,8 @@ public interface GreylistConsumer { * @param signature Signature of the member. * @param maxTargetSdk maxTargetSdk value from the annotation, or null if none set. */ - void greylistEntry(String signature, Integer maxTargetSdk); + void greylistEntry( + String signature, Integer maxTargetSdk, Map<String, String> annotationProperties); /** * Handle a new whitelist entry. diff --git a/tools/class2greylist/src/com/android/class2greylist/SystemOutGreylistConsumer.java b/tools/class2greylist/src/com/android/class2greylist/SystemOutGreylistConsumer.java index ad5ad705b4..f86ac6ec68 100644 --- a/tools/class2greylist/src/com/android/class2greylist/SystemOutGreylistConsumer.java +++ b/tools/class2greylist/src/com/android/class2greylist/SystemOutGreylistConsumer.java @@ -1,8 +1,11 @@ package com.android.class2greylist; +import java.util.Map; + public class SystemOutGreylistConsumer implements GreylistConsumer { @Override - public void greylistEntry(String signature, Integer maxTargetSdk) { + public void greylistEntry( + String signature, Integer maxTargetSdk, Map<String, String> annotationValues) { System.out.println(signature); } diff --git a/tools/class2greylist/test/Android.mk b/tools/class2greylist/test/Android.mk index 23f4156f6d..f35e74c63d 100644 --- a/tools/class2greylist/test/Android.mk +++ b/tools/class2greylist/test/Android.mk @@ -21,7 +21,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_MODULE := class2greylisttest -LOCAL_STATIC_JAVA_LIBRARIES := class2greylistlib truth-host-prebuilt mockito-host junit-host +LOCAL_STATIC_JAVA_LIBRARIES := class2greylistlib truth-host-prebuilt mockito-host junit-host objenesis # tag this module as a cts test artifact LOCAL_COMPATIBILITY_SUITE := general-tests @@ -29,4 +29,4 @@ LOCAL_COMPATIBILITY_SUITE := general-tests include $(BUILD_HOST_JAVA_LIBRARY) # Build the test APKs using their own makefiles -include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file +include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tools/class2greylist/test/src/com/android/class2greylist/GreylistAnnotationHandlerTest.java b/tools/class2greylist/test/src/com/android/class2greylist/GreylistAnnotationHandlerTest.java index 1a4bfb8283..edf2ecd84d 100644 --- a/tools/class2greylist/test/src/com/android/class2greylist/GreylistAnnotationHandlerTest.java +++ b/tools/class2greylist/test/src/com/android/class2greylist/GreylistAnnotationHandlerTest.java @@ -60,7 +60,7 @@ public class GreylistAnnotationHandlerTest extends AnnotationHandlerTestBase { Predicate<GreylistAnnotationHandler.GreylistMember> greylistFilter, Set<Integer> validMaxTargetSdkValues) { return new GreylistAnnotationHandler( - mStatus, mConsumer, greylistFilter, validMaxTargetSdkValues); + mStatus, mConsumer, greylistFilter, x -> validMaxTargetSdkValues.contains(x)); } @Test @@ -80,7 +80,7 @@ public class GreylistAnnotationHandlerTest extends AnnotationHandlerTestBase { assertNoErrors(); ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class); - verify(mConsumer, times(1)).greylistEntry(greylist.capture(), any()); + verify(mConsumer, times(1)).greylistEntry(greylist.capture(), any(), any()); assertThat(greylist.getValue()).isEqualTo("La/b/Class;->method()V"); } @@ -101,7 +101,7 @@ public class GreylistAnnotationHandlerTest extends AnnotationHandlerTestBase { assertNoErrors(); ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class); - verify(mConsumer, times(1)).greylistEntry(greylist.capture(), any()); + verify(mConsumer, times(1)).greylistEntry(greylist.capture(), any(), any()); assertThat(greylist.getValue()).isEqualTo("La/b/Class;-><init>()V"); } @@ -122,7 +122,7 @@ public class GreylistAnnotationHandlerTest extends AnnotationHandlerTestBase { assertNoErrors(); ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class); - verify(mConsumer, times(1)).greylistEntry(greylist.capture(), any()); + verify(mConsumer, times(1)).greylistEntry(greylist.capture(), any(), any()); assertThat(greylist.getValue()).isEqualTo("La/b/Class;->i:I"); } @@ -143,7 +143,7 @@ public class GreylistAnnotationHandlerTest extends AnnotationHandlerTestBase { assertNoErrors(); ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class); - verify(mConsumer, times(1)).greylistEntry(greylist.capture(), any()); + verify(mConsumer, times(1)).greylistEntry(greylist.capture(), any(), any()); assertThat(greylist.getValue()).isEqualTo("La/b/Class;->method()V"); } @@ -184,7 +184,7 @@ public class GreylistAnnotationHandlerTest extends AnnotationHandlerTestBase { assertNoErrors(); ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class); - verify(mConsumer, times(1)).greylistEntry(greylist.capture(), any()); + verify(mConsumer, times(1)).greylistEntry(greylist.capture(), any(), any()); assertThat(greylist.getValue()).isEqualTo("La/b/Class$Inner;->method()V"); } @@ -202,7 +202,7 @@ public class GreylistAnnotationHandlerTest extends AnnotationHandlerTestBase { ).visit(); assertNoErrors(); - verify(mConsumer, never()).greylistEntry(any(String.class), any()); + verify(mConsumer, never()).greylistEntry(any(String.class), any(), any()); } @Test @@ -222,7 +222,7 @@ public class GreylistAnnotationHandlerTest extends AnnotationHandlerTestBase { assertNoErrors(); ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class); - verify(mConsumer, times(1)).greylistEntry(greylist.capture(), any()); + verify(mConsumer, times(1)).greylistEntry(greylist.capture(), any(), any()); assertThat(greylist.getValue()).isEqualTo("La/b/Class;->method(Ljava/lang/String;)V"); } @@ -252,7 +252,7 @@ public class GreylistAnnotationHandlerTest extends AnnotationHandlerTestBase { assertNoErrors(); ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class); // A bridge method is generated for the above, so we expect 2 greylist entries. - verify(mConsumer, times(2)).greylistEntry(greylist.capture(), any()); + verify(mConsumer, times(2)).greylistEntry(greylist.capture(), any(), any()); assertThat(greylist.getAllValues()).containsExactly( "La/b/Class;->method(Ljava/lang/Object;)V", "La/b/Class;->method(Ljava/lang/String;)V"); @@ -284,7 +284,7 @@ public class GreylistAnnotationHandlerTest extends AnnotationHandlerTestBase { assertNoErrors(); ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class); // A bridge method is generated for the above, so we expect 2 greylist entries. - verify(mConsumer, times(2)).greylistEntry(greylist.capture(), any()); + verify(mConsumer, times(2)).greylistEntry(greylist.capture(), any(), any()); assertThat(greylist.getAllValues()).containsExactly( "La/b/Class;->method(Ljava/lang/Object;)V", "La/b/Class;->method(Ljava/lang/String;)V"); @@ -322,7 +322,7 @@ public class GreylistAnnotationHandlerTest extends AnnotationHandlerTestBase { assertNoErrors(); ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class); // A bridge method is generated for the above, so we expect 2 greylist entries. - verify(mConsumer, times(2)).greylistEntry(greylist.capture(), any()); + verify(mConsumer, times(2)).greylistEntry(greylist.capture(), any(), any()); assertThat(greylist.getAllValues()).containsExactly( "La/b/Class;->method(Ljava/lang/Object;)V", "La/b/Base;->method(Ljava/lang/Object;)V"); @@ -355,14 +355,14 @@ public class GreylistAnnotationHandlerTest extends AnnotationHandlerTestBase { mStatus, mConsumer, publicApis, - emptySet())); + x -> false)); new AnnotationVisitor(mJavac.getCompiledClass("a.b.Base"), mStatus, handlerMap).visit(); new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), mStatus, handlerMap).visit(); assertNoErrors(); ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class); // The bridge method generated for the above, is a public API so should be excluded - verify(mConsumer, times(1)).greylistEntry(greylist.capture(), any()); + verify(mConsumer, times(1)).greylistEntry(greylist.capture(), any(), any()); assertThat(greylist.getValue()).isEqualTo("La/b/Class;->method(Ljava/lang/String;)V"); } @@ -384,7 +384,7 @@ public class GreylistAnnotationHandlerTest extends AnnotationHandlerTestBase { new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), mStatus, handlerMap).visit(); assertNoErrors(); ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class); - verify(mConsumer, times(1)).greylistEntry(greylist.capture(), any()); + verify(mConsumer, times(1)).greylistEntry(greylist.capture(), any(), any()); assertThat(greylist.getValue()).isEqualTo("La/b/Class;->field:I"); } @@ -423,7 +423,7 @@ public class GreylistAnnotationHandlerTest extends AnnotationHandlerTestBase { new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), mStatus, handlerMap).visit(); assertNoErrors(); ArgumentCaptor<Integer> maxTargetSdk = ArgumentCaptor.forClass(Integer.class); - verify(mConsumer, times(1)).greylistEntry(any(), maxTargetSdk.capture()); + verify(mConsumer, times(1)).greylistEntry(any(), maxTargetSdk.capture(), any()); assertThat(maxTargetSdk.getValue()).isEqualTo(1); } @@ -445,7 +445,7 @@ public class GreylistAnnotationHandlerTest extends AnnotationHandlerTestBase { new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), mStatus, handlerMap).visit(); assertNoErrors(); ArgumentCaptor<Integer> maxTargetSdk = ArgumentCaptor.forClass(Integer.class); - verify(mConsumer, times(1)).greylistEntry(any(), maxTargetSdk.capture()); + verify(mConsumer, times(1)).greylistEntry(any(), maxTargetSdk.capture(), any()); assertThat(maxTargetSdk.getValue()).isEqualTo(null); } @@ -468,4 +468,37 @@ public class GreylistAnnotationHandlerTest extends AnnotationHandlerTestBase { verify(mStatus, times(1)).error(any(), any()); } + @Test + public void testAnnotationPropertiesIntoMap() throws IOException { + mJavac.addSource("annotation.Anno2", Joiner.on('\n').join( + "package annotation;", + "import static java.lang.annotation.RetentionPolicy.CLASS;", + "import java.lang.annotation.Retention;", + "@Retention(CLASS)", + "public @interface Anno2 {", + " String expectedSignature() default \"\";", + " int maxTargetSdk() default Integer.MAX_VALUE;", + " long trackingBug() default 0;", + "}")); + mJavac.addSource("a.b.Class", Joiner.on('\n').join( + "package a.b;", + "import annotation.Anno2;", + "public class Class {", + " @Anno2(maxTargetSdk=2, trackingBug=123456789)", + " public int field;", + "}")); + assertThat(mJavac.compile()).isTrue(); + new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), mStatus, + ImmutableMap.of("Lannotation/Anno2;", createGreylistHandler(x -> true, + ImmutableSet.of(2))) + ).visit(); + + assertNoErrors(); + ArgumentCaptor<Map<String, String>> properties = ArgumentCaptor.forClass(Map.class); + verify(mConsumer, times(1)).greylistEntry(any(), any(), properties.capture()); + assertThat(properties.getValue()).containsExactly( + "maxTargetSdk", "2", + "trackingBug", "123456789"); + } + } diff --git a/tools/cpp-define-generator/asm_defines.cc b/tools/cpp-define-generator/asm_defines.cc index c105c1a7ce..b79e1ae26e 100644 --- a/tools/cpp-define-generator/asm_defines.cc +++ b/tools/cpp-define-generator/asm_defines.cc @@ -31,6 +31,6 @@ #define ASM_DEFINE(NAME, EXPR) \ void AsmDefineHelperFor_##NAME() { \ asm volatile("\n.ascii \">>" #NAME " %0 %1<<\"" \ - :: "i" (static_cast<int64_t>(EXPR)), "i" (EXPR < 0 ? 1 : 0)); \ + :: "i" (static_cast<int64_t>(EXPR)), "i" ((EXPR) < 0 ? 1 : 0)); \ } #include "asm_defines.def" diff --git a/tools/cpp-define-generator/globals.def b/tools/cpp-define-generator/globals.def index 2324f5168e..6443a0c517 100644 --- a/tools/cpp-define-generator/globals.def +++ b/tools/cpp-define-generator/globals.def @@ -22,6 +22,7 @@ #include "dex/modifiers.h" #include "gc/accounting/card_table.h" #include "gc/heap.h" +#include "interpreter/mterp/mterp.h" #include "jit/jit.h" #include "mirror/object.h" #include "mirror/object_reference.h" @@ -50,6 +51,10 @@ ASM_DEFINE(JIT_HOTNESS_DISABLE, art::jit::kJitHotnessDisabled) ASM_DEFINE(MIN_LARGE_OBJECT_THRESHOLD, art::gc::Heap::kMinLargeObjectThreshold) +ASM_DEFINE(MTERP_HANDLER_SIZE, + art::interpreter::kMterpHandlerSize) +ASM_DEFINE(MTERP_HANDLER_SIZE_LOG2, + art::WhichPowerOf2(art::interpreter::kMterpHandlerSize)) ASM_DEFINE(OBJECT_ALIGNMENT_MASK, art::kObjectAlignment - 1) ASM_DEFINE(OBJECT_ALIGNMENT_MASK_TOGGLED, diff --git a/tools/cpp-define-generator/thread.def b/tools/cpp-define-generator/thread.def index 2dd90fae3f..7b19076828 100644 --- a/tools/cpp-define-generator/thread.def +++ b/tools/cpp-define-generator/thread.def @@ -18,16 +18,12 @@ #include "thread.h" #endif -ASM_DEFINE(THREAD_ALT_IBASE_OFFSET, - art::Thread::MterpAltIBaseOffset<art::kRuntimePointerSize>().Int32Value()) ASM_DEFINE(THREAD_CARD_TABLE_OFFSET, art::Thread::CardTableOffset<art::kRuntimePointerSize>().Int32Value()) ASM_DEFINE(THREAD_CHECKPOINT_REQUEST, art::kCheckpointRequest) ASM_DEFINE(THREAD_CURRENT_IBASE_OFFSET, art::Thread::MterpCurrentIBaseOffset<art::kRuntimePointerSize>().Int32Value()) -ASM_DEFINE(THREAD_DEFAULT_IBASE_OFFSET, - art::Thread::MterpDefaultIBaseOffset<art::kRuntimePointerSize>().Int32Value()) ASM_DEFINE(THREAD_EMPTY_CHECKPOINT_REQUEST, art::kEmptyCheckpointRequest) ASM_DEFINE(THREAD_EXCEPTION_OFFSET, diff --git a/tools/jfuzz/jfuzz.cc b/tools/jfuzz/jfuzz.cc index a97a99ce4b..b8a646d8fb 100644 --- a/tools/jfuzz/jfuzz.cc +++ b/tools/jfuzz/jfuzz.cc @@ -562,11 +562,11 @@ class JFuzz { case 1: if (emitArrayVariable(tp)) return; - // FALL-THROUGH + [[fallthrough]]; case 2: if (emitLocalVariable(tp)) return; - // FALL-THROUGH + [[fallthrough]]; default: emitFieldVariable(tp); break; |