summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-05-16 01:00:33 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-05-16 01:00:33 +0000
commit6fbd27b23506e8c7da39e3b20b495392ca46633d (patch)
treec8203ae56d19d66a5e1af4c263ee87719bf9dc56
parent62ee2ebbfda8902a9be9447f2e64b7931ce06be5 (diff)
parent2336c21dacaab373f310ef0e1075f5ab38512082 (diff)
downloadart-sdk-release.tar.gz
Snap for 11847757 from 2336c21dacaab373f310ef0e1075f5ab38512082 to sdk-releasesdk-release
Change-Id: Ic098c1cc55814634144755e321e05464e7c16231
-rw-r--r--PREUPLOAD.cfg4
-rw-r--r--TEST_MAPPING3
-rw-r--r--artd/artd.cc16
-rw-r--r--artd/file_utils.cc5
-rw-r--r--compiler/optimizing/intrinsics_arm64.cc41
-rw-r--r--compiler/optimizing/intrinsics_arm_vixl.cc40
-rw-r--r--compiler/optimizing/intrinsics_riscv64.cc45
-rw-r--r--compiler/optimizing/intrinsics_x86.cc43
-rw-r--r--compiler/optimizing/intrinsics_x86_64.cc41
-rw-r--r--dex2oat/linker/oat_writer.cc2
-rw-r--r--dex2oat/linker/oat_writer.h9
-rw-r--r--dexopt_chroot_setup/dexopt_chroot_setup.cc3
-rw-r--r--dexopt_chroot_setup/dexopt_chroot_setup_test.cc2
-rw-r--r--libartbase/base/unix_file/fd_file_test.cc4
-rw-r--r--libartservice/service/java/com/android/server/art/BackgroundDexoptJobStatsReporter.java18
-rw-r--r--libartservice/service/java/com/android/server/art/PreRebootDexoptJob.java3
-rw-r--r--libdexfile/dex/dex_file_loader.h2
-rw-r--r--libdexfile/dex/fuzzer_corpus_test.cc2
-rw-r--r--libnativebridge/tests/Android.bp38
-rw-r--r--libnativebridge/tests/CodeCacheCreate_test.cpp10
-rw-r--r--libnativebridge/tests/CodeCacheExists_test.cpp10
-rw-r--r--libnativebridge/tests/CodeCacheStatFail_test.cpp40
-rw-r--r--libnativebridge/tests/CompleteFlow_test.cpp4
-rw-r--r--libnativebridge/tests/NativeBridge2Signal_test.cpp4
-rw-r--r--libnativebridge/tests/NativeBridge3CreateNamespace_test.cpp4
-rw-r--r--libnativebridge/tests/NativeBridge3GetError_test.cpp4
-rw-r--r--libnativebridge/tests/NativeBridge3InitAnonymousNamespace_test.cpp4
-rw-r--r--libnativebridge/tests/NativeBridge3IsPathSupported_test.cpp4
-rw-r--r--libnativebridge/tests/NativeBridge3LoadLibraryExt_test.cpp4
-rw-r--r--libnativebridge/tests/NativeBridge3UnloadLibrary_test.cpp4
-rw-r--r--libnativebridge/tests/NativeBridge6PreZygoteFork_test.cpp2
-rw-r--r--libnativebridge/tests/NativeBridge7CriticalNative_test.cpp2
-rw-r--r--libnativebridge/tests/NativeBridgeTest.cpp26
-rw-r--r--libnativebridge/tests/NativeBridgeTest.h24
-rwxr-xr-xlibnativebridge/tests/preupload_check_test_tag.sh21
-rw-r--r--libnativeloader/Android.bp13
-rw-r--r--libnativeloader/native_loader.cpp4
-rw-r--r--libnativeloader/public_libraries.cpp4
-rw-r--r--libprofile/profile/profile_compilation_info_test.cc2
-rw-r--r--runtime/Android.bp8
-rw-r--r--runtime/jit/jit_code_cache.cc23
-rw-r--r--runtime/mirror/object-inl.h38
-rw-r--r--runtime/mirror/object-readbarrier-inl.h9
-rw-r--r--runtime/thread.cc2
-rw-r--r--runtime/thread.h2
-rw-r--r--runtime/transaction_test.cc52
-rw-r--r--test/Android.bp29
-rwxr-xr-xtest/utils/regen-test-files2
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.