diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-05-16 01:00:33 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-05-16 01:00:33 +0000 |
commit | 6fbd27b23506e8c7da39e3b20b495392ca46633d (patch) | |
tree | c8203ae56d19d66a5e1af4c263ee87719bf9dc56 | |
parent | 62ee2ebbfda8902a9be9447f2e64b7931ce06be5 (diff) | |
parent | 2336c21dacaab373f310ef0e1075f5ab38512082 (diff) | |
download | art-sdk-release.tar.gz |
Snap for 11847757 from 2336c21dacaab373f310ef0e1075f5ab38512082 to sdk-releasesdk-release
Change-Id: Ic098c1cc55814634144755e321e05464e7c16231
48 files changed, 390 insertions, 286 deletions
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg index c5b3c9c18d..d43a1e90ba 100644 --- a/PREUPLOAD.cfg +++ b/PREUPLOAD.cfg @@ -3,10 +3,6 @@ check_generated_tests_up_to_date = tools/test_presubmit.py hidden_api_txt_checksorted_hook = ${REPO_ROOT}/tools/platform-compat/hiddenapi/checksorted_sha.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT} -# TODO(b/189484095): Port libnativebridge tests to atest and enable in presubmit -# so we don't need the custom runtests script and this check. -check_libnativebridge_test_field = libnativebridge/tests/preupload_check_test_tag.sh ${PREUPLOAD_COMMIT_MESSAGE} ${PREUPLOAD_FILES} - check_expectation_jsons = tools/check_presubmit_json_expectations.sh ${REPO_ROOT} ${PREUPLOAD_FILES} [Builtin Hooks] diff --git a/TEST_MAPPING b/TEST_MAPPING index 3f5c50f694..3d144250fd 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -4305,6 +4305,9 @@ }, { "name": "art-run-test-2273-checker-unreachable-intrinsics" + }, + { + "name": "libnativebridge-tests" } ] } diff --git a/artd/artd.cc b/artd/artd.cc index 3eef99d7a8..d87588bbc9 100644 --- a/artd/artd.cc +++ b/artd/artd.cc @@ -116,7 +116,6 @@ using ::android::base::make_scope_guard; using ::android::base::ReadFileToString; using ::android::base::Result; using ::android::base::Split; -using ::android::base::StringReplace; using ::android::base::Tokenize; using ::android::base::WriteStringToFd; using ::android::base::WriteStringToFile; @@ -446,8 +445,11 @@ Result<File> ExtractEmbeddedProfileToFd(const std::string& dex_path) { // Reopen the memfd with readonly to make SELinux happy when the fd is passed to a child process // who doesn't have write permission. (b/303909581) std::string path = ART_FORMAT("/proc/self/fd/{}", memfd.Fd()); - File memfd_readonly( - open(path.c_str(), O_RDONLY), memfd_name, /*check_usage=*/false, /*read_only_mode=*/true); + // NOLINTNEXTLINE - O_CLOEXEC is omitted on purpose + File memfd_readonly(open(path.c_str(), O_RDONLY), + memfd_name, + /*check_usage=*/false, + /*read_only_mode=*/true); if (!memfd_readonly.IsOpened()) { return ErrnoErrorf("Failed to open file '{}' ('{}')", path, memfd_name); } @@ -485,19 +487,19 @@ std::ostream& operator<<(std::ostream& os, const FdLogger& fd_logger) { } // namespace #define RETURN_FATAL_IF_PRE_REBOOT(options) \ - if (options.is_pre_reboot) { \ + if ((options).is_pre_reboot) { \ return Fatal("This method is not supported in Pre-reboot Dexopt mode"); \ } #define RETURN_FATAL_IF_NOT_PRE_REBOOT(options) \ - if (!options.is_pre_reboot) { \ + if (!(options).is_pre_reboot) { \ return Fatal("This method is only supported in Pre-reboot Dexopt mode"); \ } #define RETURN_FATAL_IF_ARG_IS_PRE_REBOOT_IMPL(expected, arg, log_name) \ { \ auto&& __return_fatal_tmp = PreRebootFlag(arg); \ - if (expected != __return_fatal_tmp) { \ + if ((expected) != __return_fatal_tmp) { \ return Fatal(ART_FORMAT("Expected flag 'isPreReboot' in argument '{}' to be {}, got {}", \ log_name, \ expected, \ @@ -506,7 +508,7 @@ std::ostream& operator<<(std::ostream& os, const FdLogger& fd_logger) { } #define RETURN_FATAL_IF_PRE_REBOOT_MISMATCH(options, arg, log_name) \ - RETURN_FATAL_IF_ARG_IS_PRE_REBOOT_IMPL(options.is_pre_reboot, arg, log_name) + RETURN_FATAL_IF_ARG_IS_PRE_REBOOT_IMPL((options).is_pre_reboot, arg, log_name) #define RETURN_FATAL_IF_ARG_IS_PRE_REBOOT(arg, log_name) \ RETURN_FATAL_IF_ARG_IS_PRE_REBOOT_IMPL(false, arg, log_name) diff --git a/artd/file_utils.cc b/artd/file_utils.cc index 195daf6162..c1977fb1bb 100644 --- a/artd/file_utils.cc +++ b/artd/file_utils.cc @@ -234,10 +234,13 @@ android::base::Result<void> MoveAllOrAbandon( const std::vector<std::pair<std::string, std::string>>& files_to_move, const std::vector<std::string>& files_to_remove) { std::vector<std::pair<std::string_view, std::string_view>> files_to_move_view; - std::vector<std::string_view> files_to_remove_view; + files_to_move_view.reserve(files_to_move.size()); for (const auto& [src, dst] : files_to_move) { files_to_move_view.emplace_back(src, dst); } + + std::vector<std::string_view> files_to_remove_view; + files_to_remove_view.reserve(files_to_remove.size()); for (const std::string& file : files_to_remove) { files_to_remove_view.emplace_back(file); } diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc index 8ed43b1d3e..d8c7a6531e 100644 --- a/compiler/optimizing/intrinsics_arm64.cc +++ b/compiler/optimizing/intrinsics_arm64.cc @@ -3445,27 +3445,26 @@ void IntrinsicCodeGeneratorARM64::VisitDoubleIsInfinite(HInvoke* invoke) { GenIsInfinite(invoke->GetLocations(), /* is64bit= */ true, GetVIXLAssembler()); } -#define VISIT_INTRINSIC(name, low, high, type, start_index) \ - void IntrinsicLocationsBuilderARM64::Visit ##name ##ValueOf(HInvoke* invoke) { \ - InvokeRuntimeCallingConvention calling_convention; \ - IntrinsicVisitor::ComputeValueOfLocations( \ - invoke, \ - codegen_, \ - low, \ - high - low + 1, \ - calling_convention.GetReturnLocation(DataType::Type::kReference), \ - Location::RegisterLocation(calling_convention.GetRegisterAt(0).GetCode())); \ - } \ - void IntrinsicCodeGeneratorARM64::Visit ##name ##ValueOf(HInvoke* invoke) { \ - IntrinsicVisitor::ValueOfInfo info = \ - IntrinsicVisitor::ComputeValueOfInfo( \ - invoke, \ - codegen_->GetCompilerOptions(), \ - WellKnownClasses::java_lang_ ##name ##_value, \ - low, \ - high - low + 1, \ - start_index); \ - HandleValueOf(invoke, info, type); \ +#define VISIT_INTRINSIC(name, low, high, type, start_index) \ + void IntrinsicLocationsBuilderARM64::Visit##name##ValueOf(HInvoke* invoke) { \ + InvokeRuntimeCallingConvention calling_convention; \ + IntrinsicVisitor::ComputeValueOfLocations( \ + invoke, \ + codegen_, \ + low, \ + (high) - (low) + 1, \ + calling_convention.GetReturnLocation(DataType::Type::kReference), \ + Location::RegisterLocation(calling_convention.GetRegisterAt(0).GetCode())); \ + } \ + void IntrinsicCodeGeneratorARM64::Visit##name##ValueOf(HInvoke* invoke) { \ + IntrinsicVisitor::ValueOfInfo info = \ + IntrinsicVisitor::ComputeValueOfInfo(invoke, \ + codegen_->GetCompilerOptions(), \ + WellKnownClasses::java_lang_##name##_value, \ + low, \ + (high) - (low) + 1, \ + start_index); \ + HandleValueOf(invoke, info, type); \ } BOXED_TYPES(VISIT_INTRINSIC) #undef VISIT_INTRINSIC diff --git a/compiler/optimizing/intrinsics_arm_vixl.cc b/compiler/optimizing/intrinsics_arm_vixl.cc index 25e35540ab..ecc9732816 100644 --- a/compiler/optimizing/intrinsics_arm_vixl.cc +++ b/compiler/optimizing/intrinsics_arm_vixl.cc @@ -2305,27 +2305,25 @@ void IntrinsicCodeGeneratorARMVIXL::VisitMathFloor(HInvoke* invoke) { __ Vrintm(F64, OutputDRegister(invoke), InputDRegisterAt(invoke, 0)); } -#define VISIT_INTRINSIC(name, low, high, type, start_index) \ - void IntrinsicLocationsBuilderARMVIXL::Visit ##name ##ValueOf(HInvoke* invoke) { \ - InvokeRuntimeCallingConventionARMVIXL calling_convention; \ - IntrinsicVisitor::ComputeValueOfLocations( \ - invoke, \ - codegen_, \ - low, \ - high - low + 1, \ - LocationFrom(r0), \ - LocationFrom(calling_convention.GetRegisterAt(0))); \ - } \ - void IntrinsicCodeGeneratorARMVIXL::Visit ##name ##ValueOf(HInvoke* invoke) { \ - IntrinsicVisitor::ValueOfInfo info = \ - IntrinsicVisitor::ComputeValueOfInfo( \ - invoke, \ - codegen_->GetCompilerOptions(), \ - WellKnownClasses::java_lang_ ##name ##_value, \ - low, \ - high - low + 1, \ - start_index); \ - HandleValueOf(invoke, info, type); \ +#define VISIT_INTRINSIC(name, low, high, type, start_index) \ + void IntrinsicLocationsBuilderARMVIXL::Visit##name##ValueOf(HInvoke* invoke) { \ + InvokeRuntimeCallingConventionARMVIXL calling_convention; \ + IntrinsicVisitor::ComputeValueOfLocations(invoke, \ + codegen_, \ + low, \ + (high) - (low) + 1, \ + LocationFrom(r0), \ + LocationFrom(calling_convention.GetRegisterAt(0))); \ + } \ + void IntrinsicCodeGeneratorARMVIXL::Visit##name##ValueOf(HInvoke* invoke) { \ + IntrinsicVisitor::ValueOfInfo info = \ + IntrinsicVisitor::ComputeValueOfInfo(invoke, \ + codegen_->GetCompilerOptions(), \ + WellKnownClasses::java_lang_##name##_value, \ + low, \ + (high) - (low) + 1, \ + start_index); \ + HandleValueOf(invoke, info, type); \ } BOXED_TYPES(VISIT_INTRINSIC) #undef VISIT_INTRINSIC diff --git a/compiler/optimizing/intrinsics_riscv64.cc b/compiler/optimizing/intrinsics_riscv64.cc index 9aa4b9415b..0a9ac872db 100644 --- a/compiler/optimizing/intrinsics_riscv64.cc +++ b/compiler/optimizing/intrinsics_riscv64.cc @@ -636,27 +636,26 @@ void IntrinsicCodeGeneratorRISCV64::VisitLongDivideUnsigned(HInvoke* invoke) { GenerateDivideUnsigned(invoke, codegen_); } -#define VISIT_INTRINSIC(name, low, high, type, start_index) \ - void IntrinsicLocationsBuilderRISCV64::Visit ##name ##ValueOf(HInvoke* invoke) { \ - InvokeRuntimeCallingConvention calling_convention; \ - IntrinsicVisitor::ComputeValueOfLocations( \ - invoke, \ - codegen_, \ - low, \ - high - low + 1, \ - calling_convention.GetReturnLocation(DataType::Type::kReference), \ - Location::RegisterLocation(calling_convention.GetRegisterAt(0))); \ - } \ - void IntrinsicCodeGeneratorRISCV64::Visit ##name ##ValueOf(HInvoke* invoke) { \ - IntrinsicVisitor::ValueOfInfo info = \ - IntrinsicVisitor::ComputeValueOfInfo( \ - invoke, \ - codegen_->GetCompilerOptions(), \ - WellKnownClasses::java_lang_ ##name ##_value, \ - low, \ - high - low + 1, \ - start_index); \ - HandleValueOf(invoke, info, type); \ +#define VISIT_INTRINSIC(name, low, high, type, start_index) \ + void IntrinsicLocationsBuilderRISCV64::Visit##name##ValueOf(HInvoke* invoke) { \ + InvokeRuntimeCallingConvention calling_convention; \ + IntrinsicVisitor::ComputeValueOfLocations( \ + invoke, \ + codegen_, \ + low, \ + (high) - (low) + 1, \ + calling_convention.GetReturnLocation(DataType::Type::kReference), \ + Location::RegisterLocation(calling_convention.GetRegisterAt(0))); \ + } \ + void IntrinsicCodeGeneratorRISCV64::Visit##name##ValueOf(HInvoke* invoke) { \ + IntrinsicVisitor::ValueOfInfo info = \ + IntrinsicVisitor::ComputeValueOfInfo(invoke, \ + codegen_->GetCompilerOptions(), \ + WellKnownClasses::java_lang_##name##_value, \ + low, \ + (high) - (low) + 1, \ + start_index); \ + HandleValueOf(invoke, info, type); \ } BOXED_TYPES(VISIT_INTRINSIC) #undef VISIT_INTRINSIC @@ -767,8 +766,8 @@ void IntrinsicCodeGeneratorRISCV64::VisitReferenceGetReferent(HInvoke* invoke) { out, obj.AsRegister<XRegister>(), referent_offset, - /*maybe_temp=*/ locations->GetTemp(0), - /*needs_null_check=*/ false); + /*temp=*/locations->GetTemp(0), + /*needs_null_check=*/false); } else { codegen_->GetInstructionVisitor()->Load( out, obj.AsRegister<XRegister>(), referent_offset, DataType::Type::kReference); diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc index 62efeb1d8c..63dd963a9f 100644 --- a/compiler/optimizing/intrinsics_x86.cc +++ b/compiler/optimizing/intrinsics_x86.cc @@ -3380,28 +3380,27 @@ static void RequestBaseMethodAddressInRegister(HInvoke* invoke) { } } -#define VISIT_INTRINSIC(name, low, high, type, start_index) \ - void IntrinsicLocationsBuilderX86::Visit ##name ##ValueOf(HInvoke* invoke) { \ - InvokeRuntimeCallingConvention calling_convention; \ - IntrinsicVisitor::ComputeValueOfLocations( \ - invoke, \ - codegen_, \ - low, \ - high - low + 1, \ - Location::RegisterLocation(EAX), \ - Location::RegisterLocation(calling_convention.GetRegisterAt(0))); \ - RequestBaseMethodAddressInRegister(invoke); \ - } \ - void IntrinsicCodeGeneratorX86::Visit ##name ##ValueOf(HInvoke* invoke) { \ - IntrinsicVisitor::ValueOfInfo info = \ - IntrinsicVisitor::ComputeValueOfInfo( \ - invoke, \ - codegen_->GetCompilerOptions(), \ - WellKnownClasses::java_lang_ ##name ##_value, \ - low, \ - high - low + 1, \ - start_index); \ - HandleValueOf(invoke, info, type); \ +#define VISIT_INTRINSIC(name, low, high, type, start_index) \ + void IntrinsicLocationsBuilderX86::Visit##name##ValueOf(HInvoke* invoke) { \ + InvokeRuntimeCallingConvention calling_convention; \ + IntrinsicVisitor::ComputeValueOfLocations( \ + invoke, \ + codegen_, \ + low, \ + (high) - (low) + 1, \ + Location::RegisterLocation(EAX), \ + Location::RegisterLocation(calling_convention.GetRegisterAt(0))); \ + RequestBaseMethodAddressInRegister(invoke); \ + } \ + void IntrinsicCodeGeneratorX86::Visit##name##ValueOf(HInvoke* invoke) { \ + IntrinsicVisitor::ValueOfInfo info = \ + IntrinsicVisitor::ComputeValueOfInfo(invoke, \ + codegen_->GetCompilerOptions(), \ + WellKnownClasses::java_lang_##name##_value, \ + low, \ + (high) - (low) + 1, \ + start_index); \ + HandleValueOf(invoke, info, type); \ } BOXED_TYPES(VISIT_INTRINSIC) #undef VISIT_INTRINSIC diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc index b5ddaaa0b7..131460d605 100644 --- a/compiler/optimizing/intrinsics_x86_64.cc +++ b/compiler/optimizing/intrinsics_x86_64.cc @@ -3180,27 +3180,26 @@ void IntrinsicCodeGeneratorX86_64::VisitLongNumberOfTrailingZeros(HInvoke* invok GenTrailingZeros(GetAssembler(), codegen_, invoke, /* is_long= */ true); } -#define VISIT_INTRINSIC(name, low, high, type, start_index) \ - void IntrinsicLocationsBuilderX86_64::Visit ##name ##ValueOf(HInvoke* invoke) { \ - InvokeRuntimeCallingConvention calling_convention; \ - IntrinsicVisitor::ComputeValueOfLocations( \ - invoke, \ - codegen_, \ - low, \ - high - low + 1, \ - Location::RegisterLocation(RAX), \ - Location::RegisterLocation(calling_convention.GetRegisterAt(0))); \ - } \ - void IntrinsicCodeGeneratorX86_64::Visit ##name ##ValueOf(HInvoke* invoke) { \ - IntrinsicVisitor::ValueOfInfo info = \ - IntrinsicVisitor::ComputeValueOfInfo( \ - invoke, \ - codegen_->GetCompilerOptions(), \ - WellKnownClasses::java_lang_ ##name ##_value, \ - low, \ - high - low + 1, \ - start_index); \ - HandleValueOf(invoke, info, type); \ +#define VISIT_INTRINSIC(name, low, high, type, start_index) \ + void IntrinsicLocationsBuilderX86_64::Visit##name##ValueOf(HInvoke* invoke) { \ + InvokeRuntimeCallingConvention calling_convention; \ + IntrinsicVisitor::ComputeValueOfLocations( \ + invoke, \ + codegen_, \ + low, \ + (high) - (low) + 1, \ + Location::RegisterLocation(RAX), \ + Location::RegisterLocation(calling_convention.GetRegisterAt(0))); \ + } \ + void IntrinsicCodeGeneratorX86_64::Visit##name##ValueOf(HInvoke* invoke) { \ + IntrinsicVisitor::ValueOfInfo info = \ + IntrinsicVisitor::ComputeValueOfInfo(invoke, \ + codegen_->GetCompilerOptions(), \ + WellKnownClasses::java_lang_##name##_value, \ + low, \ + (high) - (low) + 1, \ + start_index); \ + HandleValueOf(invoke, info, type); \ } BOXED_TYPES(VISIT_INTRINSIC) #undef VISIT_INTRINSIC diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc index 68e0690766..1419338066 100644 --- a/dex2oat/linker/oat_writer.cc +++ b/dex2oat/linker/oat_writer.cc @@ -488,7 +488,7 @@ bool OatWriter::AddVdexDexFilesSource(const VdexFile& vdex_file, const char* loc } // Add dex file source from raw memory. -bool OatWriter::AddRawDexFileSource(std::shared_ptr<DexFileContainer> container, +bool OatWriter::AddRawDexFileSource(const std::shared_ptr<DexFileContainer>& container, const uint8_t* dex_file_begin, const char* location, uint32_t location_checksum) { diff --git a/dex2oat/linker/oat_writer.h b/dex2oat/linker/oat_writer.h index 43c9bc77ff..dc441a11d8 100644 --- a/dex2oat/linker/oat_writer.h +++ b/dex2oat/linker/oat_writer.h @@ -147,11 +147,10 @@ class OatWriter { File&& dex_file_fd, const char* location); // Add dex file source from raw memory. - bool AddRawDexFileSource( - std::shared_ptr<DexFileContainer> container, - const uint8_t* dex_file_begin, - const char* location, - uint32_t location_checksum); + bool AddRawDexFileSource(const std::shared_ptr<DexFileContainer>& container, + const uint8_t* dex_file_begin, + const char* location, + uint32_t location_checksum); // Add dex file source(s) from a vdex file. bool AddVdexDexFilesSource( const VdexFile& vdex_file, diff --git a/dexopt_chroot_setup/dexopt_chroot_setup.cc b/dexopt_chroot_setup/dexopt_chroot_setup.cc index 5c4d4ea151..35343c5b3c 100644 --- a/dexopt_chroot_setup/dexopt_chroot_setup.cc +++ b/dexopt_chroot_setup/dexopt_chroot_setup.cc @@ -66,7 +66,6 @@ using ::android::base::ReadFileToString; using ::android::base::Result; using ::android::base::SetProperty; using ::android::base::Split; -using ::android::base::StringReplace; using ::android::base::Tokenize; using ::android::base::WaitForProperty; using ::android::fs_mgr::FstabEntry; @@ -83,7 +82,7 @@ const NoDestructor<std::string> kBindMountTmpDir( constexpr mode_t kChrootDefaultMode = 0755; constexpr std::chrono::milliseconds kSnapshotCtlTimeout = std::chrono::seconds(60); -bool IsOtaUpdate(const std::optional<std::string> ota_slot) { return ota_slot.has_value(); } +bool IsOtaUpdate(const std::optional<std::string>& ota_slot) { return ota_slot.has_value(); } Result<void> Run(std::string_view log_name, const std::vector<std::string>& args) { LOG(INFO) << "Running " << log_name << ": " << Join(args, /*separator=*/" "); diff --git a/dexopt_chroot_setup/dexopt_chroot_setup_test.cc b/dexopt_chroot_setup/dexopt_chroot_setup_test.cc index 9ee33dfece..bfa38e0aa0 100644 --- a/dexopt_chroot_setup/dexopt_chroot_setup_test.cc +++ b/dexopt_chroot_setup/dexopt_chroot_setup_test.cc @@ -74,7 +74,7 @@ class DexoptChrootSetupTest : public CommonArtTest { GTEST_SKIP() << "A real Pre-reboot Dexopt is running"; } - ASSERT_TRUE(WaitForProperty("dev.bootcomplete", "1", /*timeout=*/std::chrono::minutes(3))); + ASSERT_TRUE(WaitForProperty("dev.bootcomplete", "1", /*relative_timeout=*/std::chrono::minutes(3))); test_skipped = false; diff --git a/libartbase/base/unix_file/fd_file_test.cc b/libartbase/base/unix_file/fd_file_test.cc index 0f56f7b03f..d5c3056393 100644 --- a/libartbase/base/unix_file/fd_file_test.cc +++ b/libartbase/base/unix_file/fd_file_test.cc @@ -227,8 +227,8 @@ TEST_F(FdFileTest, Rename) { // Move the file via a rename. art::ScratchFile dest; - std::string new_filename = dest.GetFilename(); - std::string old_filename = src->GetFilename(); + const std::string& new_filename = dest.GetFilename(); + const std::string& old_filename = src->GetFilename(); ASSERT_TRUE(src->GetFile()->Rename(new_filename)); // Confirm the FdFile path has correctly updated. diff --git a/libartservice/service/java/com/android/server/art/BackgroundDexoptJobStatsReporter.java b/libartservice/service/java/com/android/server/art/BackgroundDexoptJobStatsReporter.java index def1feb353..106b1c6c2a 100644 --- a/libartservice/service/java/com/android/server/art/BackgroundDexoptJobStatsReporter.java +++ b/libartservice/service/java/com/android/server/art/BackgroundDexoptJobStatsReporter.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2023 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. + */ + package com.android.server.art; import static com.android.server.art.model.ArtFlags.BatchDexoptPass; @@ -18,7 +34,7 @@ import java.util.Optional; import java.util.stream.Collectors; /** - * This is an helper class to report the background DexOpt job metrics to StatsD. + * This is a helper class to report the background DexOpt job metrics to StatsD. * * @hide */ diff --git a/libartservice/service/java/com/android/server/art/PreRebootDexoptJob.java b/libartservice/service/java/com/android/server/art/PreRebootDexoptJob.java index eca05c995b..c890198d96 100644 --- a/libartservice/service/java/com/android/server/art/PreRebootDexoptJob.java +++ b/libartservice/service/java/com/android/server/art/PreRebootDexoptJob.java @@ -38,6 +38,7 @@ import com.android.server.art.model.ArtFlags; import com.android.server.art.model.ArtServiceJobInterface; import com.android.server.art.prereboot.PreRebootDriver; +import java.time.Duration; import java.util.Objects; import java.util.concurrent.CompletableFuture; @@ -140,6 +141,8 @@ public class PreRebootDexoptJob implements ArtServiceJobInterface { .setRequiresDeviceIdle(true) .setRequiresCharging(true) .setRequiresBatteryNotLow(true) + // The latency is to wait for update_engine to finish. + .setMinimumLatency(Duration.ofMinutes(10).toMillis()) .build(); /* @JobScheduler.Result */ int result = mInjector.getJobScheduler().schedule(info); diff --git a/libdexfile/dex/dex_file_loader.h b/libdexfile/dex/dex_file_loader.h index ec7f8ba977..9b5f7d56cd 100644 --- a/libdexfile/dex/dex_file_loader.h +++ b/libdexfile/dex/dex_file_loader.h @@ -94,7 +94,7 @@ class DexFileLoader { std::optional<uint32_t> checksum; for (; *i < dex_files.size(); ++(*i)) { const auto* dex_file = &*dex_files[*i]; - bool is_primary_dex = !IsMultiDexLocation(dex_file->GetLocation().c_str()); + bool is_primary_dex = !IsMultiDexLocation(dex_file->GetLocation()); if (!checksum.has_value()) { // First dex file. CHECK(is_primary_dex) << dex_file->GetLocation(); // Expect primary dex. } else if (is_primary_dex) { // Later dex file. diff --git a/libdexfile/dex/fuzzer_corpus_test.cc b/libdexfile/dex/fuzzer_corpus_test.cc index 6b1bb130c9..15aa6dd657 100644 --- a/libdexfile/dex/fuzzer_corpus_test.cc +++ b/libdexfile/dex/fuzzer_corpus_test.cc @@ -113,7 +113,7 @@ TEST_F(FuzzerCorpusTest, VerifyCorpusDexFiles) { const bool expected_success = valid_dex_files.find(name) != valid_dex_files.end(); VerifyDexFile( - reinterpret_cast<const uint8_t*>(data.data()), data.size(), name.c_str(), expected_success); + reinterpret_cast<const uint8_t*>(data.data()), data.size(), name, expected_success); } ASSERT_TRUE(error >= -1) << "failed iterating " << filename << " : " << ErrorCodeString(error); diff --git a/libnativebridge/tests/Android.bp b/libnativebridge/tests/Android.bp index ca054516f6..85bdf9967c 100644 --- a/libnativebridge/tests/Android.bp +++ b/libnativebridge/tests/Android.bp @@ -27,8 +27,9 @@ cc_defaults { name: "libnativebridge-test-case-defaults", defaults: [ "art_defaults", - "art_test_defaults", + "art_test_common_defaults", ], + host_supported: true, // TODO(mast): Split up art_gtest_defaults so that it can be used for the // following without pulling in lots of libs. target: { @@ -115,19 +116,10 @@ cc_test { }, }, - // native_bridge.cc doesn't support reloading the native bridge after - // unloading, so each test needs to be its own process. - test_per_src: true, - - // Disable pre-submit host unit-testing for this test module, as - // it is not compatible with TradeFed (because of the use of the - // `test_per_src` feature above) and meant to be executed with the - // `runtests.sh` script instead. - test_options: { - unit_test: false, - }, + isolated: true, srcs: [ + "NativeBridgeTest.cpp", "NativeBridgeApi.c", "CodeCacheCreate_test.cpp", "CodeCacheExists_test.cpp", @@ -153,8 +145,25 @@ cc_test { ], shared_libs: [ + "libbase", "liblog", "libnativebridge", + "libnativebridge6prezygotefork", + "libnativebridge7criticalnative", + + // Ideally these would only need to be listed in data_libs, but they + // are dlopen'd by libnativebridge, not by libnativebridge-tests, + // and the linker can't find them relative to /system/lib64/libnativebridge.so. + // Linking them here causes them to be loaded from alongside + // libnativebridge-tests when it is executed, and then the later dlopen + // returns the handle to the already-loaded library. + "libnativebridge-test-case", + "libnativebridge2-test-case", + "libnativebridge3-test-case", + "libnativebridge6-test-case", + "libnativebridge7-test-case", + ], + data_libs: [ "libnativebridge-test-case", "libnativebridge2-test-case", "libnativebridge3-test-case", @@ -163,7 +172,10 @@ cc_test { "libnativebridge6prezygotefork", "libnativebridge7criticalnative", ], - header_libs: ["libbase_headers"], + + test_suites: [ + "general-tests", + ], } // Very basic tests in CTS to verify backed-by API coverage of the exported API diff --git a/libnativebridge/tests/CodeCacheCreate_test.cpp b/libnativebridge/tests/CodeCacheCreate_test.cpp index 1bd309c5c8..57b1abc4c5 100644 --- a/libnativebridge/tests/CodeCacheCreate_test.cpp +++ b/libnativebridge/tests/CodeCacheCreate_test.cpp @@ -26,25 +26,25 @@ namespace android { // exist. TEST_F(NativeBridgeTest, CodeCacheCreate) { // Make sure that code_cache does not exist - rmdir(kCodeCache); + rmdir(codeCache()); struct stat st; - ASSERT_EQ(-1, stat(kCodeCache, &st)); + ASSERT_EQ(-1, stat(codeCache(), &st)); ASSERT_EQ(ENOENT, errno); // Init ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary, nullptr)); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); + ASSERT_TRUE(PreInitializeNativeBridge(appDataDir(), "isa")); ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); ASSERT_FALSE(NativeBridgeError()); // Check that code_cache was created - ASSERT_EQ(0, stat(kCodeCache, &st)); + ASSERT_EQ(0, stat(codeCache(), &st)); ASSERT_TRUE(S_ISDIR(st.st_mode)); // Clean up UnloadNativeBridge(); - ASSERT_EQ(0, rmdir(kCodeCache)); + ASSERT_EQ(0, rmdir(codeCache())); ASSERT_FALSE(NativeBridgeError()); } diff --git a/libnativebridge/tests/CodeCacheExists_test.cpp b/libnativebridge/tests/CodeCacheExists_test.cpp index 8ba01586b5..c740bec79c 100644 --- a/libnativebridge/tests/CodeCacheExists_test.cpp +++ b/libnativebridge/tests/CodeCacheExists_test.cpp @@ -27,26 +27,26 @@ namespace android { TEST_F(NativeBridgeTest, CodeCacheExists) { // Make sure that code_cache does not exists struct stat st; - ASSERT_EQ(-1, stat(kCodeCache, &st)); + ASSERT_EQ(-1, stat(codeCache(), &st)); ASSERT_EQ(ENOENT, errno); // Create the code_cache - ASSERT_EQ(0, mkdir(kCodeCache, S_IRWXU | S_IRWXG | S_IXOTH)); + ASSERT_EQ(0, mkdir(codeCache(), S_IRWXU | S_IRWXG | S_IXOTH)); // Init ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary, nullptr)); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); + ASSERT_TRUE(PreInitializeNativeBridge(appDataDir(), "isa")); ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); ASSERT_FALSE(NativeBridgeError()); // Check that the code cache is still there - ASSERT_EQ(0, stat(kCodeCache, &st)); + ASSERT_EQ(0, stat(codeCache(), &st)); ASSERT_TRUE(S_ISDIR(st.st_mode)); // Clean up UnloadNativeBridge(); - ASSERT_EQ(0, rmdir(kCodeCache)); + ASSERT_EQ(0, rmdir(codeCache())); ASSERT_FALSE(NativeBridgeError()); } diff --git a/libnativebridge/tests/CodeCacheStatFail_test.cpp b/libnativebridge/tests/CodeCacheStatFail_test.cpp index 4ea519ee96..768f07944c 100644 --- a/libnativebridge/tests/CodeCacheStatFail_test.cpp +++ b/libnativebridge/tests/CodeCacheStatFail_test.cpp @@ -26,26 +26,26 @@ namespace android { // Tests that the bridge is initialized without errors if the code_cache is // existed as a file. TEST_F(NativeBridgeTest, CodeCacheStatFail) { - int fd = creat(kCodeCache, O_RDWR); - ASSERT_NE(-1, fd); - close(fd); - - struct stat st; - ASSERT_EQ(-1, stat(kCodeCacheStatFail, &st)); - ASSERT_EQ(ENOTDIR, errno); - - // Init - ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary, nullptr)); - ASSERT_TRUE(PreInitializeNativeBridge(kCodeCacheStatFail, "isa")); - ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_FALSE(NativeBridgeError()); - - // Clean up - UnloadNativeBridge(); - - ASSERT_FALSE(NativeBridgeError()); - unlink(kCodeCache); + int fd = creat(codeCache(), O_RDWR); + ASSERT_NE(-1, fd); + close(fd); + + struct stat st; + ASSERT_EQ(-1, stat(codeCacheStatFail(), &st)); + ASSERT_EQ(ENOTDIR, errno); + + // Init + ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary, nullptr)); + ASSERT_TRUE(PreInitializeNativeBridge(codeCacheStatFail(), "isa")); + ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); + ASSERT_TRUE(NativeBridgeAvailable()); + ASSERT_FALSE(NativeBridgeError()); + + // Clean up + UnloadNativeBridge(); + + ASSERT_FALSE(NativeBridgeError()); + unlink(codeCache()); } } // namespace android diff --git a/libnativebridge/tests/CompleteFlow_test.cpp b/libnativebridge/tests/CompleteFlow_test.cpp index b033792301..a4a6f20df9 100644 --- a/libnativebridge/tests/CompleteFlow_test.cpp +++ b/libnativebridge/tests/CompleteFlow_test.cpp @@ -24,7 +24,7 @@ TEST_F(NativeBridgeTest, CompleteFlow) { // Init ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); + ASSERT_TRUE(PreInitializeNativeBridge(appDataDir(), "isa")); ASSERT_TRUE(NativeBridgeAvailable()); ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); @@ -41,7 +41,7 @@ TEST_F(NativeBridgeTest, CompleteFlow) { ASSERT_FALSE(NativeBridgeError()); // Clean-up code_cache - ASSERT_EQ(0, rmdir(kCodeCache)); + ASSERT_EQ(0, rmdir(codeCache())); } } // namespace android diff --git a/libnativebridge/tests/NativeBridge2Signal_test.cpp b/libnativebridge/tests/NativeBridge2Signal_test.cpp index 0573a5a680..a1663caeba 100644 --- a/libnativebridge/tests/NativeBridge2Signal_test.cpp +++ b/libnativebridge/tests/NativeBridge2Signal_test.cpp @@ -25,7 +25,7 @@ TEST_F(NativeBridgeTest, V2_Signal) { // Init ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary2, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); + ASSERT_TRUE(PreInitializeNativeBridge(appDataDir(), "isa")); ASSERT_TRUE(NativeBridgeAvailable()); ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); @@ -34,7 +34,7 @@ TEST_F(NativeBridgeTest, V2_Signal) { ASSERT_NE(nullptr, NativeBridgeGetSignalHandler(SIGSEGV)); // Clean-up code_cache - ASSERT_EQ(0, rmdir(kCodeCache)); + ASSERT_EQ(0, rmdir(codeCache())); } } // namespace android diff --git a/libnativebridge/tests/NativeBridge3CreateNamespace_test.cpp b/libnativebridge/tests/NativeBridge3CreateNamespace_test.cpp index db7dd31cfb..2b709e05ab 100644 --- a/libnativebridge/tests/NativeBridge3CreateNamespace_test.cpp +++ b/libnativebridge/tests/NativeBridge3CreateNamespace_test.cpp @@ -22,7 +22,7 @@ TEST_F(NativeBridgeTest, V3_CreateNamespace) { // Init ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary3, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); + ASSERT_TRUE(PreInitializeNativeBridge(appDataDir(), "isa")); ASSERT_TRUE(NativeBridgeAvailable()); ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); @@ -32,7 +32,7 @@ TEST_F(NativeBridgeTest, V3_CreateNamespace) { 0, nullptr, nullptr)); // Clean-up code_cache - ASSERT_EQ(0, rmdir(kCodeCache)); + ASSERT_EQ(0, rmdir(codeCache())); } } // namespace android diff --git a/libnativebridge/tests/NativeBridge3GetError_test.cpp b/libnativebridge/tests/NativeBridge3GetError_test.cpp index afd0a7d511..e74e664881 100644 --- a/libnativebridge/tests/NativeBridge3GetError_test.cpp +++ b/libnativebridge/tests/NativeBridge3GetError_test.cpp @@ -22,7 +22,7 @@ TEST_F(NativeBridgeTest, V3_GetError) { // Init ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary3, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); + ASSERT_TRUE(PreInitializeNativeBridge(appDataDir(), "isa")); ASSERT_TRUE(NativeBridgeAvailable()); ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); @@ -31,7 +31,7 @@ TEST_F(NativeBridgeTest, V3_GetError) { ASSERT_EQ(nullptr, NativeBridgeGetError()); // Clean-up code_cache - ASSERT_EQ(0, rmdir(kCodeCache)); + ASSERT_EQ(0, rmdir(codeCache())); } } // namespace android diff --git a/libnativebridge/tests/NativeBridge3InitAnonymousNamespace_test.cpp b/libnativebridge/tests/NativeBridge3InitAnonymousNamespace_test.cpp index f82c9e9e4c..2449939362 100644 --- a/libnativebridge/tests/NativeBridge3InitAnonymousNamespace_test.cpp +++ b/libnativebridge/tests/NativeBridge3InitAnonymousNamespace_test.cpp @@ -22,7 +22,7 @@ TEST_F(NativeBridgeTest, V3_InitAnonymousNamespace) { // Init ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary3, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); + ASSERT_TRUE(PreInitializeNativeBridge(appDataDir(), "isa")); ASSERT_TRUE(NativeBridgeAvailable()); ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); @@ -31,7 +31,7 @@ TEST_F(NativeBridgeTest, V3_InitAnonymousNamespace) { ASSERT_EQ(true, NativeBridgeInitAnonymousNamespace(nullptr, nullptr)); // Clean-up code_cache - ASSERT_EQ(0, rmdir(kCodeCache)); + ASSERT_EQ(0, rmdir(codeCache())); } } // namespace android diff --git a/libnativebridge/tests/NativeBridge3IsPathSupported_test.cpp b/libnativebridge/tests/NativeBridge3IsPathSupported_test.cpp index 4cbc0e8758..fd162c099d 100644 --- a/libnativebridge/tests/NativeBridge3IsPathSupported_test.cpp +++ b/libnativebridge/tests/NativeBridge3IsPathSupported_test.cpp @@ -22,7 +22,7 @@ TEST_F(NativeBridgeTest, V3_IsPathSupported) { // Init ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary3, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); + ASSERT_TRUE(PreInitializeNativeBridge(appDataDir(), "isa")); ASSERT_TRUE(NativeBridgeAvailable()); ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); @@ -31,7 +31,7 @@ TEST_F(NativeBridgeTest, V3_IsPathSupported) { ASSERT_EQ(true, NativeBridgeIsPathSupported(nullptr)); // Clean-up code_cache - ASSERT_EQ(0, rmdir(kCodeCache)); + ASSERT_EQ(0, rmdir(codeCache())); } } // namespace android diff --git a/libnativebridge/tests/NativeBridge3LoadLibraryExt_test.cpp b/libnativebridge/tests/NativeBridge3LoadLibraryExt_test.cpp index 3d6676811a..eeb27e8431 100644 --- a/libnativebridge/tests/NativeBridge3LoadLibraryExt_test.cpp +++ b/libnativebridge/tests/NativeBridge3LoadLibraryExt_test.cpp @@ -22,7 +22,7 @@ TEST_F(NativeBridgeTest, V3_LoadLibraryExt) { // Init ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary3, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); + ASSERT_TRUE(PreInitializeNativeBridge(appDataDir(), "isa")); ASSERT_TRUE(NativeBridgeAvailable()); ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); @@ -31,7 +31,7 @@ TEST_F(NativeBridgeTest, V3_LoadLibraryExt) { ASSERT_EQ(nullptr, NativeBridgeLoadLibraryExt(nullptr, 0, nullptr)); // Clean-up code_cache - ASSERT_EQ(0, rmdir(kCodeCache)); + ASSERT_EQ(0, rmdir(codeCache())); } } // namespace android diff --git a/libnativebridge/tests/NativeBridge3UnloadLibrary_test.cpp b/libnativebridge/tests/NativeBridge3UnloadLibrary_test.cpp index a366edcdce..39bf251f65 100644 --- a/libnativebridge/tests/NativeBridge3UnloadLibrary_test.cpp +++ b/libnativebridge/tests/NativeBridge3UnloadLibrary_test.cpp @@ -22,7 +22,7 @@ TEST_F(NativeBridgeTest, V3_UnloadLibrary) { // Init ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary3, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); + ASSERT_TRUE(PreInitializeNativeBridge(appDataDir(), "isa")); ASSERT_TRUE(NativeBridgeAvailable()); ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); @@ -31,7 +31,7 @@ TEST_F(NativeBridgeTest, V3_UnloadLibrary) { ASSERT_EQ(0, NativeBridgeUnloadLibrary(nullptr)); // Clean-up code_cache - ASSERT_EQ(0, rmdir(kCodeCache)); + ASSERT_EQ(0, rmdir(codeCache())); } } // namespace android diff --git a/libnativebridge/tests/NativeBridge6PreZygoteFork_test.cpp b/libnativebridge/tests/NativeBridge6PreZygoteFork_test.cpp index ba6a007a93..b40e7bd79e 100644 --- a/libnativebridge/tests/NativeBridge6PreZygoteFork_test.cpp +++ b/libnativebridge/tests/NativeBridge6PreZygoteFork_test.cpp @@ -23,7 +23,7 @@ TEST_F(NativeBridgeTest, V6_PreZygoteFork) { // Init ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary6, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); + ASSERT_TRUE(PreInitializeNativeBridge(appDataDir(), "isa")); ASSERT_TRUE(NativeBridgeAvailable()); ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); diff --git a/libnativebridge/tests/NativeBridge7CriticalNative_test.cpp b/libnativebridge/tests/NativeBridge7CriticalNative_test.cpp index 5662214f40..a8c9bb65c4 100644 --- a/libnativebridge/tests/NativeBridge7CriticalNative_test.cpp +++ b/libnativebridge/tests/NativeBridge7CriticalNative_test.cpp @@ -23,7 +23,7 @@ TEST_F(NativeBridgeTest, V7_CriticalNative) { // Init ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary7, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); + ASSERT_TRUE(PreInitializeNativeBridge(appDataDir(), "isa")); ASSERT_TRUE(NativeBridgeAvailable()); ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); ASSERT_TRUE(NativeBridgeAvailable()); diff --git a/libnativebridge/tests/NativeBridgeTest.cpp b/libnativebridge/tests/NativeBridgeTest.cpp new file mode 100644 index 0000000000..633ff79fcb --- /dev/null +++ b/libnativebridge/tests/NativeBridgeTest.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdint.h> +#include <stdio.h> + +extern "C" bool GetInitialArgs(const char*** args, size_t* num_args) { + // Disable default parallelism to make debugging easier, these tests are small. + static const char* initial_args[1] = {"-j1"}; + *args = initial_args; + *num_args = 1; + return true; +} diff --git a/libnativebridge/tests/NativeBridgeTest.h b/libnativebridge/tests/NativeBridgeTest.h index 6413233006..782e58424b 100644 --- a/libnativebridge/tests/NativeBridgeTest.h +++ b/libnativebridge/tests/NativeBridgeTest.h @@ -19,12 +19,13 @@ #define LOG_TAG "NativeBridge_test" -#include <nativebridge/native_bridge.h> +#include <android-base/file.h> #include <gtest/gtest.h> +#include <nativebridge/native_bridge.h> + +#include <string> constexpr const char* kNativeBridgeLibrary = "libnativebridge-test-case.so"; -constexpr const char* kCodeCache = "./code_cache"; -constexpr const char* kCodeCacheStatFail = "./code_cache/temp"; constexpr const char* kNativeBridgeLibrary2 = "libnativebridge2-test-case.so"; constexpr const char* kNativeBridgeLibrary3 = "libnativebridge3-test-case.so"; constexpr const char* kNativeBridgeLibrary6 = "libnativebridge6-test-case.so"; @@ -33,6 +34,23 @@ constexpr const char* kNativeBridgeLibrary7 = "libnativebridge7-test-case.so"; namespace android { class NativeBridgeTest : public testing::Test { + protected: + NativeBridgeTest() : tempDir() { + appDataDir_ = std::string(tempDir.path); + codeCache_ = appDataDir_ + "/code_cache"; + codeCacheStatFail_ = codeCache_ + "/temp"; + } + + const char* appDataDir() { return appDataDir_.c_str(); } + + const char* codeCache() { return codeCache_.c_str(); } + + const char* codeCacheStatFail() { return codeCacheStatFail_.c_str(); } + + TemporaryDir tempDir; + std::string appDataDir_; + std::string codeCache_; + std::string codeCacheStatFail_; }; }; // namespace android diff --git a/libnativebridge/tests/preupload_check_test_tag.sh b/libnativebridge/tests/preupload_check_test_tag.sh deleted file mode 100755 index 1c8cd4b62c..0000000000 --- a/libnativebridge/tests/preupload_check_test_tag.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -# A simple preupload check that the runtests.sh script has been run for the -# libnativebridge tests if that library has been changed. -# TODO(b/189484095): Port these tests to atest and enable in presubmit so we -# don't need the custom script to run them. - -commit_message="$1" -shift - -nativebridge_change=false -for file; do - [[ $file = libnativebridge/* ]] && nativebridge_change=true -done - -if $nativebridge_change; then - if grep '^Test: art/libnativebridge/tests/runtests.sh' <<< $commit_message ; then :; else - echo "Please run art/libnativebridge/tests/runtests.sh and add the tag:" 1>&2 - echo "Test: art/libnativebridge/tests/runtests.sh [--skip-host|--skip-target]" 1>&2 - exit 1 - fi -fi diff --git a/libnativeloader/Android.bp b/libnativeloader/Android.bp index 5e43915f04..236f27fb92 100644 --- a/libnativeloader/Android.bp +++ b/libnativeloader/Android.bp @@ -66,19 +66,6 @@ art_cc_library { "libbase", ], target: { - // Library search path needed for running host tests remotely (from testcases directory). - linux_glibc_x86: { - ldflags: [ - "-Wl,-rpath,$ORIGIN/../art_common/out/host/linux-x86/lib", - "-Wl,--enable-new-dtags", - ], - }, - linux_glibc_x86_64: { - ldflags: [ - "-Wl,-rpath,$ORIGIN/../art_common/out/host/linux-x86/lib64", - "-Wl,--enable-new-dtags", - ], - }, android: { srcs: [ "library_namespaces.cpp", diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp index ea06b2041f..13a4c2a482 100644 --- a/libnativeloader/native_loader.cpp +++ b/libnativeloader/native_loader.cpp @@ -420,8 +420,8 @@ void* OpenNativeLibrary(JNIEnv* env, /*is_shared=*/false, empty_dex_path, library_path_j, - /*permitted_path=*/nullptr, - /*uses_library_list=*/nullptr); + /*permitted_path_j=*/nullptr, + /*uses_library_list_j=*/nullptr); if (!isolated_ns.ok()) { ALOGD("Failed to create isolated ns for %s (caller=%s)", path, diff --git a/libnativeloader/public_libraries.cpp b/libnativeloader/public_libraries.cpp index 390c2987d6..c26b8f6bc4 100644 --- a/libnativeloader/public_libraries.cpp +++ b/libnativeloader/public_libraries.cpp @@ -166,8 +166,8 @@ static std::string InitDefaultPublicLibraries(bool for_preload) { if (!for_preload) { // Remove the public libs provided by apexes because these libs are available // from apex namespaces. - for (const std::pair<std::string, std::string>& p : apex_public_libraries()) { - std::vector<std::string> public_libs = base::Split(p.second, ":"); + for (const auto& [_, library_list] : apex_public_libraries()) { + std::vector<std::string> public_libs = base::Split(library_list, ":"); sonames->erase(std::remove_if(sonames->begin(), sonames->end(), [&public_libs](const std::string& v) { diff --git a/libprofile/profile/profile_compilation_info_test.cc b/libprofile/profile/profile_compilation_info_test.cc index 25c560b78e..f2df896c70 100644 --- a/libprofile/profile/profile_compilation_info_test.cc +++ b/libprofile/profile/profile_compilation_info_test.cc @@ -1498,7 +1498,7 @@ TEST_F(ProfileCompilationInfoTest, AddMethodsProfileMethodInfoInlineCaches) { // Add inline caches with the methods. The profile should record only the one for the hot method. std::vector<TypeReference> types = {}; - ProfileMethodInfo::ProfileInlineCache ic(/*dex_pc=*/ 0, /*missing_types=*/ true, types); + ProfileMethodInfo::ProfileInlineCache ic(/*pc=*/0, /*missing_types=*/true, types); std::vector<ProfileMethodInfo::ProfileInlineCache> inline_caches = {ic}; info.AddMethod(ProfileMethodInfo(hot, inline_caches), Hotness::kFlagHot, diff --git a/runtime/Android.bp b/runtime/Android.bp index e8fb912789..45d416f0cc 100644 --- a/runtime/Android.bp +++ b/runtime/Android.bp @@ -652,6 +652,7 @@ cc_defaults { "liblz4", "liblzma", // libelffile dependency; must be repeated here since it's a static lib. "libnativebridge", + "libnativeloader", "libodrstatslog", ], target: { @@ -661,6 +662,11 @@ cc_defaults { "-Wno-unused-command-line-argument", ], }, + android: { + whole_static_libs: [ + "libPlatformProperties", // libnativeloader dependency. + ], + }, }, } @@ -677,7 +683,6 @@ cc_defaults { "libart-runtime", "libelffile", "libsigchain_fake", - "libnativeloader", ], } @@ -694,7 +699,6 @@ cc_defaults { "libartd-runtime", "libelffiled", "libsigchain_fake", - "libnativeloader", ], } diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc index 7ea9efb0f9..eae56a45b3 100644 --- a/runtime/jit/jit_code_cache.cc +++ b/runtime/jit/jit_code_cache.cc @@ -445,8 +445,7 @@ void JitCodeCache::SweepRootTables(IsMarkedVisitor* visitor) { } } // Walk over inline caches to clear entries containing unloaded classes. - for (auto it : profiling_infos_) { - ProfilingInfo* info = it.second; + for (const auto& [_, info] : profiling_infos_) { InlineCache* caches = info->GetInlineCaches(); for (size_t i = 0; i < info->number_of_inline_caches_; ++i) { InlineCache* cache = &caches[i]; @@ -514,8 +513,8 @@ void JitCodeCache::FreeAllMethodHeaders( CHECK_EQ(compiled_methods.count(addr), 1u) << "Extra debug info: " << addr << " " << name; }); if (!debug_info.empty()) { // If debug-info generation is enabled. - for (auto it : compiled_methods) { - CHECK_EQ(debug_info.count(it.first), 1u) << "No debug info: " << it.second->PrettyMethod(); + for (const auto& [addr, method] : compiled_methods) { + CHECK_EQ(debug_info.count(addr), 1u) << "No debug info: " << method->PrettyMethod(); } CHECK_EQ(compiled_methods.size(), debug_info.size()); } @@ -1774,23 +1773,21 @@ void JitCodeCache::Dump(std::ostream& os) { void JitCodeCache::DumpAllCompiledMethods(std::ostream& os) { MutexLock mu(Thread::Current(), *Locks::jit_lock_); - for (auto it : method_code_map_) { // Includes OSR methods. - ArtMethod* meth = it.second; - const void* code_ptr = it.first; + for (const auto& [code_ptr, meth] : method_code_map_) { // Includes OSR methods. OatQuickMethodHeader* header = OatQuickMethodHeader::FromCodePointer(code_ptr); os << meth->PrettyMethod() << "@" << std::hex << code_ptr << "-" << reinterpret_cast<uintptr_t>(code_ptr) + header->GetCodeSize() << '\n'; } os << "JNIStubs: \n"; - for (auto it : jni_stubs_map_) { - const void* code_ptr = it.second.GetCode(); + for (const auto& [_, data] : jni_stubs_map_) { + const void* code_ptr = data.GetCode(); if (code_ptr == nullptr) { continue; } OatQuickMethodHeader* header = OatQuickMethodHeader::FromCodePointer(code_ptr); os << std::hex << code_ptr << "-" << reinterpret_cast<uintptr_t>(code_ptr) + header->GetCodeSize() << " "; - for (ArtMethod* m : it.second.GetMethods()) { + for (ArtMethod* m : data.GetMethods()) { os << m->PrettyMethod() << ";"; } os << "\n"; @@ -1860,13 +1857,13 @@ void JitCodeCache::VisitAllMethods(const std::function<void(const void*, ArtMeth } } } - for (auto it : method_code_map_) { // Includes OSR methods. + for (const auto& it : method_code_map_) { // Includes OSR methods. cb(it.first, it.second); } - for (auto it : saved_compiled_methods_map_) { + for (const auto& it : saved_compiled_methods_map_) { cb(it.second, it.first); } - for (auto it : zygote_map_) { + for (const auto& it : zygote_map_) { if (it.code_ptr != nullptr && it.method != nullptr) { cb(it.code_ptr, it.method); } diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h index 60b8a0512e..09f1c39058 100644 --- a/runtime/mirror/object-inl.h +++ b/runtime/mirror/object-inl.h @@ -570,13 +570,14 @@ inline bool Object::CasFieldWeakSequentiallyConsistent64(MemberOffset field_offs int64_t old_value, int64_t new_value) { VerifyTransaction<kTransactionActive, kCheckTransaction>(); - if (kTransactionActive) { - Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true); - } Verify<kVerifyFlags>(); uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr); - return atomic_addr->CompareAndSetWeakSequentiallyConsistent(old_value, new_value); + bool success = atomic_addr->CompareAndSetWeakSequentiallyConsistent(old_value, new_value); + if (kTransactionActive && success) { + Runtime::Current()->RecordWriteField64(this, field_offset, old_value, /*is_volatile=*/ true); + } + return success; } template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> @@ -584,13 +585,14 @@ inline bool Object::CasFieldStrongSequentiallyConsistent64(MemberOffset field_of int64_t old_value, int64_t new_value) { VerifyTransaction<kTransactionActive, kCheckTransaction>(); - if (kTransactionActive) { - Runtime::Current()->RecordWriteField64(this, field_offset, old_value, true); - } Verify<kVerifyFlags>(); uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); Atomic<int64_t>* atomic_addr = reinterpret_cast<Atomic<int64_t>*>(raw_addr); - return atomic_addr->CompareAndSetStrongSequentiallyConsistent(old_value, new_value); + bool success = atomic_addr->CompareAndSetStrongSequentiallyConsistent(old_value, new_value); + if (kTransactionActive && success) { + Runtime::Current()->RecordWriteField64(this, field_offset, old_value, /*is_volatile=*/ true); + } + return success; } /* @@ -626,13 +628,9 @@ inline void Object::SetFieldObjectWithoutWriteBarrier(MemberOffset field_offset, ObjPtr<Object> new_value) { VerifyTransaction<kTransactionActive, kCheckTransaction>(); if (kTransactionActive) { - ObjPtr<Object> obj; - if (kIsVolatile) { - obj = GetFieldObjectVolatile<Object>(field_offset); - } else { - obj = GetFieldObject<Object>(field_offset); - } - Runtime::Current()->RecordWriteFieldReference(this, field_offset, obj, true); + ObjPtr<Object> old_value = + GetFieldObject<Object, kVerifyFlags, kWithReadBarrier, kIsVolatile>(field_offset); + Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, kIsVolatile); } Verify<kVerifyFlags>(); VerifyWrite<kVerifyFlags>(new_value); @@ -685,14 +683,16 @@ inline bool Object::CasFieldObjectWithoutWriteBarrier(MemberOffset field_offset, std::memory_order memory_order) { VerifyTransaction<kTransactionActive, kCheckTransaction>(); VerifyCAS<kVerifyFlags>(new_value, old_value); - if (kTransactionActive) { - Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true); - } uint32_t old_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(old_value)); uint32_t new_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(new_value)); uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr); - return atomic_addr->CompareAndSet(old_ref, new_ref, mode, memory_order); + bool success = atomic_addr->CompareAndSet(old_ref, new_ref, mode, memory_order); + if (kTransactionActive && success) { + Runtime::Current()->RecordWriteFieldReference( + this, field_offset, old_value, /*is_volatile=*/ true); + } + return success; } template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags> diff --git a/runtime/mirror/object-readbarrier-inl.h b/runtime/mirror/object-readbarrier-inl.h index 15179b93ff..6c201f2277 100644 --- a/runtime/mirror/object-readbarrier-inl.h +++ b/runtime/mirror/object-readbarrier-inl.h @@ -46,16 +46,17 @@ inline bool Object::CasField32(MemberOffset field_offset, if (kCheckTransaction) { DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction()); } - if (kTransactionActive) { - Runtime::Current()->RecordWriteField32(this, field_offset, old_value, true); - } if (kVerifyFlags & kVerifyThis) { VerifyObject(this); } uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value(); AtomicInteger* atomic_addr = reinterpret_cast<AtomicInteger*>(raw_addr); - return atomic_addr->CompareAndSet(old_value, new_value, mode, memory_order); + bool success = atomic_addr->CompareAndSet(old_value, new_value, mode, memory_order); + if (kTransactionActive && success) { + Runtime::Current()->RecordWriteField32(this, field_offset, old_value, /*is_volatile=*/ true); + } + return success; } inline bool Object::CasLockWord(LockWord old_val, diff --git a/runtime/thread.cc b/runtime/thread.cc index 2ebbe1327d..c648f0f55c 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -4846,7 +4846,7 @@ int Thread::GetNativePriority() const { return priority; } -void Thread::AbortInThis(std::string message) { +void Thread::AbortInThis(const std::string& message) { std::string thread_name; Thread::Current()->GetThreadName(thread_name); LOG(ERROR) << message; diff --git a/runtime/thread.h b/runtime/thread.h index 943a7edff3..35e8fe8716 100644 --- a/runtime/thread.h +++ b/runtime/thread.h @@ -1550,7 +1550,7 @@ class EXPORT Thread { // checkpoint. Useful mostly to discover why a thread isn't responding to a suspend request or // checkpoint. The caller should "suspend" (in the Java sense) 'thread' before invoking this, so // 'thread' can't get deallocated before we access it. - NO_RETURN void AbortInThis(std::string message); + NO_RETURN void AbortInThis(const std::string& message); // Returns true if StrictMode events are traced for the current thread. static bool IsSensitiveThread() { diff --git a/runtime/transaction_test.cc b/runtime/transaction_test.cc index db9d123521..e52cef46e0 100644 --- a/runtime/transaction_test.cc +++ b/runtime/transaction_test.cc @@ -357,6 +357,58 @@ TEST_F(TransactionTest, InstanceFieldsTest) { EXPECT_FLOAT_EQ(floatField->GetFloat(h_instance.Get()), static_cast<float>(0.0f)); EXPECT_DOUBLE_EQ(doubleField->GetDouble(h_instance.Get()), static_cast<double>(0.0)); EXPECT_EQ(objectField->GetObject(h_instance.Get()), nullptr); + + // Fail to modify fields with strong CAS inside transaction, then rollback changes. + EnterTransactionMode(); + bool cas_success = h_instance->CasField32</*kTransactionActive=*/ true>( + intField->GetOffset(), + /*old_value=*/ 1, + /*new_value=*/ 2, + CASMode::kStrong, + std::memory_order_seq_cst); + EXPECT_FALSE(cas_success); + cas_success = h_instance->CasFieldStrongSequentiallyConsistent64</*kTransactionActive=*/ true>( + longField->GetOffset(), /*old_value=*/ INT64_C(1), /*new_value=*/ INT64_C(2)); + EXPECT_FALSE(cas_success); + cas_success = h_instance->CasFieldObject</*kTransactionActive=*/ true>( + objectField->GetOffset(), + /*old_value=*/ h_instance.Get(), + /*new_value=*/ nullptr, + CASMode::kStrong, + std::memory_order_seq_cst); + EXPECT_FALSE(cas_success); + RollbackAndExitTransactionMode(); + + // Check values have properly been restored to their original (default) value. + EXPECT_EQ(intField->GetInt(h_instance.Get()), 0); + EXPECT_EQ(longField->GetLong(h_instance.Get()), static_cast<int64_t>(0)); + EXPECT_EQ(objectField->GetObject(h_instance.Get()), nullptr); + + // Fail to modify fields with weak CAS inside transaction, then rollback changes. + EnterTransactionMode(); + cas_success = h_instance->CasField32</*kTransactionActive=*/ true>( + intField->GetOffset(), + /*old_value=*/ 3, + /*new_value=*/ 4, + CASMode::kWeak, + std::memory_order_seq_cst); + EXPECT_FALSE(cas_success); + cas_success = h_instance->CasFieldWeakSequentiallyConsistent64</*kTransactionActive=*/ true>( + longField->GetOffset(), /*old_value=*/ INT64_C(3), /*new_value=*/ INT64_C(4)); + EXPECT_FALSE(cas_success); + cas_success = h_instance->CasFieldObject</*kTransactionActive=*/ true>( + objectField->GetOffset(), + /*old_value=*/ h_klass.Get(), + /*new_value=*/ nullptr, + CASMode::kWeak, + std::memory_order_seq_cst); + EXPECT_FALSE(cas_success); + RollbackAndExitTransactionMode(); + + // Check values have properly been restored to their original (default) value. + EXPECT_EQ(intField->GetInt(h_instance.Get()), 0); + EXPECT_EQ(longField->GetLong(h_instance.Get()), static_cast<int64_t>(0)); + EXPECT_EQ(objectField->GetObject(h_instance.Get()), nullptr); } // Tests static array fields are reset to their default value after transaction rollback. diff --git a/test/Android.bp b/test/Android.bp index 304c72cc10..cefdae887e 100644 --- a/test/Android.bp +++ b/test/Android.bp @@ -252,12 +252,10 @@ art_cc_defaults { // These really are gtests, but the gtest library comes from `libart(d)-gtest.so`. gtest: false, + header_libs: [ + "libnativeloader-headers", + ], shared_libs: [ - // `libnativeloader` must be shared, otherwise host gtests can't load libraries from - // "art_common/out/host", which is present in `libnativeloader` RUNPATH. - // TODO(b/247108425): modify gtests RUNPATH so that `libnativeloader` can be static linked. - "libnativeloader", - // `libart(d)` (`art/runtime/jni/java_vm_ext.cc`) and `libnativehelper` // (`libnativehelper/JniInvocation.c`) define symbols with the same name // (e.g. `JNI_GetDefaultJavaVMInitArgs`). @@ -279,6 +277,12 @@ art_cc_defaults { "heapprofd_client_api", ], }, + host: { + cflags: [ + "-fsanitize-address-use-after-return=never", + "-Wno-unused-command-line-argument", + ], + }, linux: { ldflags: [ // Allow jni_compiler_test to find Java_MyClassNatives_bar @@ -295,10 +299,17 @@ art_cc_defaults { "-Wno-missing-noreturn", ], }, - host: { - cflags: [ - "-fsanitize-address-use-after-return=never", - "-Wno-unused-command-line-argument", + // Library search path needed for running host tests in CI (from testcases directory). + linux_glibc_x86: { + ldflags: [ + "-Wl,-rpath,$ORIGIN/../../art_common/out/host/linux-x86/lib", + "-Wl,--enable-new-dtags", + ], + }, + linux_glibc_x86_64: { + ldflags: [ + "-Wl,-rpath,$ORIGIN/../../art_common/out/host/linux-x86/lib64", + "-Wl,--enable-new-dtags", ], }, }, diff --git a/test/utils/regen-test-files b/test/utils/regen-test-files index 6f30c50a9a..cedf354882 100755 --- a/test/utils/regen-test-files +++ b/test/utils/regen-test-files @@ -253,6 +253,7 @@ art_gtest_user_module_names = [ "art_standalone_odrefresh_tests", "art_standalone_runtime_tests", "art_standalone_sigchain_tests", + "libnativebridge-tests", "libnativeloader_test", ] @@ -272,6 +273,7 @@ art_gtest_module_names = sorted(art_gtest_user_module_names + art_gtest_eng_only # removing them from this set (in order to promote them to # presubmits). art_gtest_postsubmit_only_module_names = [ + "libnativebridge-tests", ] # ART gtests supported in MTS that do not need root access to the device. |