summaryrefslogtreecommitdiff
path: root/dexoptanalyzer
diff options
context:
space:
mode:
Diffstat (limited to 'dexoptanalyzer')
-rw-r--r--dexoptanalyzer/Android.bp6
-rw-r--r--dexoptanalyzer/dexoptanalyzer.cc103
-rw-r--r--dexoptanalyzer/dexoptanalyzer_test.cc56
3 files changed, 25 insertions, 140 deletions
diff --git a/dexoptanalyzer/Android.bp b/dexoptanalyzer/Android.bp
index 1e37b8d8d5..82f0c1a70f 100644
--- a/dexoptanalyzer/Android.bp
+++ b/dexoptanalyzer/Android.bp
@@ -83,8 +83,12 @@ art_cc_binary {
art_cc_defaults {
name: "art_dexoptanalyzer_tests_defaults",
+ static_libs: [
+ "libziparchive",
+ ],
shared_libs: [
- "libbacktrace",
+ "libunwindstack",
+ "libz", // libziparchive dependency; must be repeated here since it's a static lib.
],
data: [
":art-gtest-jars-LinkageTest",
diff --git a/dexoptanalyzer/dexoptanalyzer.cc b/dexoptanalyzer/dexoptanalyzer.cc
index 0cc2cdb03a..b182f68a7f 100644
--- a/dexoptanalyzer/dexoptanalyzer.cc
+++ b/dexoptanalyzer/dexoptanalyzer.cc
@@ -122,9 +122,6 @@ NO_RETURN static void Usage(const char *fmt, ...) {
UsageError(" print a colon-separated list of its dex files to standard output. Dexopt");
UsageError(" needed analysis is not performed when this option is set.");
UsageError("");
- UsageError(" --validate-bcp: validates the boot class path files (.art, .oat, .vdex).");
- UsageError(" Requires --isa and --image options to locate artifacts.");
- UsageError("");
UsageError("Return code:");
UsageError(" To make it easier to integrate with the internal tools this command will make");
UsageError(" available its result (dexoptNeeded) as the exit/return code. i.e. it will not");
@@ -147,10 +144,7 @@ NO_RETURN static void Usage(const char *fmt, ...) {
class DexoptAnalyzer final {
public:
- DexoptAnalyzer() :
- only_flatten_context_(false),
- only_validate_bcp_(false),
- downgrade_(false) {}
+ DexoptAnalyzer() : only_flatten_context_(false), downgrade_(false) {}
void ParseArgs(int argc, char **argv) {
original_argc = argc;
@@ -236,8 +230,6 @@ class DexoptAnalyzer final {
}
} else if (option == "--flatten-class-loader-context") {
only_flatten_context_ = true;
- } else if (option == "--validate-bcp") {
- only_validate_bcp_ = true;
} else {
Usage("Unknown argument '%s'", raw_option);
}
@@ -247,11 +239,16 @@ class DexoptAnalyzer final {
// If we don't receive the image, try to use the default one.
// Tests may specify a different image (e.g. core image).
std::string error_msg;
- image_ = GetDefaultBootImageLocation(&error_msg);
-
+ std::string android_root = GetAndroidRootSafe(&error_msg);
+ if (android_root.empty()) {
+ LOG(ERROR) << error_msg;
+ Usage("--image unspecified and ANDROID_ROOT not set.");
+ }
+ image_ = GetDefaultBootImageLocationSafe(
+ android_root, /*deny_art_apex_data_files=*/false, &error_msg);
if (image_.empty()) {
LOG(ERROR) << error_msg;
- Usage("--image unspecified and ANDROID_ROOT not set or image file does not exist.");
+ Usage("--image unspecified and failed to get default boot image location.");
}
}
}
@@ -324,6 +321,7 @@ class DexoptAnalyzer final {
class_loader_context.get(),
/*load_executable=*/ false,
/*only_load_trusted_executable=*/ false,
+ /*runtime_options=*/ nullptr,
vdex_fd_,
oat_fd_,
zip_fd_);
@@ -362,82 +360,6 @@ class DexoptAnalyzer final {
}
}
- // Validates the boot classpath and boot classpath extensions by checking the image checksums,
- // the oat files and the vdex files.
- //
- // Returns `ReturnCode::kNoDexOptNeeded` when all the files are up-to-date,
- // `ReturnCode::kDex2OatFromScratch` if any of the files are missing or out-of-date, and
- // `ReturnCode::kErrorCannotCreateRuntime` if the files could not be tested due to problem
- // creating a runtime.
- ReturnCode ValidateBcp() const {
- using ImageSpace = gc::space::ImageSpace;
-
- if (!CreateRuntime()) {
- return ReturnCode::kErrorCannotCreateRuntime;
- }
- std::unique_ptr<Runtime> runtime(Runtime::Current());
-
- auto dex_files = ArrayRef<const DexFile* const>(runtime->GetClassLinker()->GetBootClassPath());
- auto boot_image_spaces = ArrayRef<ImageSpace* const>(runtime->GetHeap()->GetBootImageSpaces());
- const std::string checksums = ImageSpace::GetBootClassPathChecksums(boot_image_spaces,
- dex_files);
-
- std::string error_msg;
- const std::vector<std::string>& bcp = runtime->GetBootClassPath();
- const std::vector<std::string>& bcp_locations = runtime->GetBootClassPathLocations();
- const std::vector<int>& bcp_fds = runtime->GetBootClassPathFds();
- const std::vector<std::string>& image_locations = runtime->GetImageLocations();
- const std::string bcp_locations_path = android::base::Join(bcp_locations, ':');
- if (!ImageSpace::VerifyBootClassPathChecksums(checksums,
- bcp_locations_path,
- ArrayRef<const std::string>(image_locations),
- ArrayRef<const std::string>(bcp_locations),
- ArrayRef<const std::string>(bcp),
- ArrayRef<const int>(bcp_fds),
- runtime->GetInstructionSet(),
- &error_msg)) {
- LOG(INFO) << "Failed to verify boot class path checksums: " << error_msg;
- return ReturnCode::kDex2OatFromScratch;
- }
-
- const auto& image_spaces = runtime->GetHeap()->GetBootImageSpaces();
- size_t bcp_component_count = 0;
- for (const auto& image_space : image_spaces) {
- if (!image_space->GetImageHeader().IsValid()) {
- LOG(INFO) << "Image header is not valid: " << image_space->GetImageFilename();
- return ReturnCode::kDex2OatFromScratch;
- }
- const OatFile* oat_file = image_space->GetOatFile();
- if (oat_file == nullptr) {
- const std::string oat_path = ReplaceFileExtension(image_space->GetImageFilename(), "oat");
- LOG(INFO) << "Oat file missing: " << oat_path;
- return ReturnCode::kDex2OatFromScratch;
- }
- if (!oat_file->GetOatHeader().IsValid() ||
- !ImageSpace::ValidateOatFile(*oat_file, &error_msg)) {
- LOG(INFO) << "Oat file is not valid: " << oat_file->GetLocation() << " " << error_msg;
- return ReturnCode::kDex2OatFromScratch;
- }
- const VdexFile* vdex_file = oat_file->GetVdexFile();
- if (vdex_file == nullptr || !vdex_file->IsValid()) {
- LOG(INFO) << "Vdex file is not valid : " << oat_file->GetLocation();
- return ReturnCode::kDex2OatFromScratch;
- }
- bcp_component_count += image_space->GetComponentCount();
- }
-
- // If the number of components encountered in the image spaces does not match the number
- // of components expected from the boot classpath locations then something is missing.
- if (bcp_component_count != bcp_locations.size()) {
- for (size_t i = bcp_component_count; i < bcp_locations.size(); ++i) {
- LOG(INFO) << "Missing image file for " << bcp_locations[i];
- }
- return ReturnCode::kDex2OatFromScratch;
- }
-
- return ReturnCode::kNoDexOptNeeded;
- }
-
ReturnCode FlattenClassLoaderContext() const {
DCHECK(only_flatten_context_);
if (context_str_.empty()) {
@@ -449,15 +371,13 @@ class DexoptAnalyzer final {
Usage("Invalid --class-loader-context '%s'", context_str_.c_str());
}
- std::cout << context->FlattenDexPaths() << std::flush;
+ std::cout << android::base::Join(context->FlattenDexPaths(), ':') << std::flush;
return ReturnCode::kFlattenClassLoaderContextSuccess;
}
ReturnCode Run() const {
if (only_flatten_context_) {
return FlattenClassLoaderContext();
- } else if (only_validate_bcp_) {
- return ValidateBcp();
} else {
return GetDexOptNeeded();
}
@@ -469,7 +389,6 @@ class DexoptAnalyzer final {
CompilerFilter::Filter compiler_filter_;
std::string context_str_;
bool only_flatten_context_;
- bool only_validate_bcp_;
ProfileAnalysisResult profile_analysis_result_;
bool downgrade_;
std::string image_;
diff --git a/dexoptanalyzer/dexoptanalyzer_test.cc b/dexoptanalyzer/dexoptanalyzer_test.cc
index 7abd4baff2..15f71e8fa1 100644
--- a/dexoptanalyzer/dexoptanalyzer_test.cc
+++ b/dexoptanalyzer/dexoptanalyzer_test.cc
@@ -118,7 +118,6 @@ TEST_F(DexoptAnalyzerTest, DexNoOat) {
Copy(GetDexSrc1(), dex_location);
Verify(dex_location, CompilerFilter::kSpeed);
- Verify(dex_location, CompilerFilter::kExtract);
Verify(dex_location, CompilerFilter::kVerify);
Verify(dex_location, CompilerFilter::kSpeedProfile);
Verify(dex_location, CompilerFilter::kSpeed,
@@ -130,11 +129,10 @@ TEST_F(DexoptAnalyzerTest, OatUpToDate) {
std::string dex_location = GetScratchDir() + "/OatUpToDate.jar";
std::string odex_location = GetOdexDir() + "/OatUpToDate.odex";
Copy(GetDexSrc1(), dex_location);
- GenerateOdexForTest(dex_location.c_str(), odex_location.c_str(), CompilerFilter::kSpeed);
+ GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Verify(dex_location, CompilerFilter::kSpeed);
Verify(dex_location, CompilerFilter::kVerify);
- Verify(dex_location, CompilerFilter::kExtract);
Verify(dex_location, CompilerFilter::kEverything);
Verify(dex_location, CompilerFilter::kSpeed,
ProfileAnalysisResult::kDontOptimizeSmallDelta, false, nullptr);
@@ -145,7 +143,7 @@ TEST_F(DexoptAnalyzerTest, ProfileOatUpToDate) {
std::string dex_location = GetScratchDir() + "/ProfileOatUpToDate.jar";
std::string odex_location = GetOdexDir() + "/ProfileOatUpToDate.odex";
Copy(GetDexSrc1(), dex_location);
- GenerateOdexForTest(dex_location.c_str(), odex_location.c_str(), CompilerFilter::kSpeedProfile);
+ GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeedProfile);
Verify(dex_location, CompilerFilter::kSpeedProfile,
ProfileAnalysisResult::kDontOptimizeSmallDelta);
@@ -161,7 +159,7 @@ TEST_F(DexoptAnalyzerTest, VerifyAndEmptyProfiles) {
std::string odex_location = GetOdexDir() + "/VerifyAndEmptyProfiles.odex";
Copy(GetDexSrc1(), dex_location);
- GenerateOdexForTest(dex_location.c_str(), odex_location.c_str(), CompilerFilter::kVerify);
+ GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kVerify);
// If we want to speed-profile something that was verified, do it even if
// the profile analysis returns kDontOptimizeSmallDelta (it means that we do have profile data,
@@ -188,14 +186,12 @@ TEST_F(DexoptAnalyzerTest, Downgrade) {
std::string dex_location = GetScratchDir() + "/Downgrade.jar";
std::string odex_location = GetOdexDir() + "/Downgrade.odex";
Copy(GetDexSrc1(), dex_location);
- GenerateOdexForTest(dex_location.c_str(), odex_location.c_str(), CompilerFilter::kVerify);
+ GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kVerify);
Verify(dex_location, CompilerFilter::kSpeedProfile,
ProfileAnalysisResult::kDontOptimizeSmallDelta, true);
Verify(dex_location, CompilerFilter::kVerify,
ProfileAnalysisResult::kDontOptimizeSmallDelta, true);
- Verify(dex_location, CompilerFilter::kExtract,
- ProfileAnalysisResult::kDontOptimizeSmallDelta, true);
}
// Case: We have a MultiDEX file and up-to-date ODEX file for it.
@@ -204,7 +200,7 @@ TEST_F(DexoptAnalyzerTest, MultiDexOatUpToDate) {
std::string odex_location = GetOdexDir() + "/MultiDexOatUpToDate.odex";
Copy(GetMultiDexSrc1(), dex_location);
- GenerateOdexForTest(dex_location.c_str(), odex_location.c_str(), CompilerFilter::kSpeed);
+ GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Verify(dex_location, CompilerFilter::kSpeed, ProfileAnalysisResult::kDontOptimizeSmallDelta);
}
@@ -216,7 +212,7 @@ TEST_F(DexoptAnalyzerTest, MultiDexSecondaryOutOfDate) {
// Compile code for GetMultiDexSrc1.
Copy(GetMultiDexSrc1(), dex_location);
- GenerateOdexForTest(dex_location.c_str(), odex_location.c_str(), CompilerFilter::kSpeed);
+ GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
// Now overwrite the dex file with GetMultiDexSrc2 so the secondary checksum
// is out of date.
@@ -234,10 +230,9 @@ TEST_F(DexoptAnalyzerTest, OatDexOutOfDate) {
// We create a dex, generate an oat for it, then overwrite the dex with a
// different dex to make the oat out of date.
Copy(GetDexSrc1(), dex_location);
- GenerateOdexForTest(dex_location.c_str(), odex_location.c_str(), CompilerFilter::kSpeed);
+ GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
Copy(GetDexSrc2(), dex_location);
- Verify(dex_location, CompilerFilter::kExtract);
Verify(dex_location, CompilerFilter::kSpeed);
}
@@ -248,34 +243,15 @@ TEST_F(DexoptAnalyzerTest, OatImageOutOfDate) {
std::string odex_location = GetOdexDir() + "/OatImageOutOfDate.odex";
Copy(GetDexSrc1(), dex_location);
- GenerateOatForTest(dex_location.c_str(),
- odex_location.c_str(),
+ GenerateOatForTest(dex_location,
+ odex_location,
CompilerFilter::kSpeed,
/*with_alternate_image=*/true);
- Verify(dex_location, CompilerFilter::kExtract);
Verify(dex_location, CompilerFilter::kVerify);
Verify(dex_location, CompilerFilter::kSpeed);
}
-// Case: We have a DEX file and a verify-at-runtime OAT file out of date with
-// respect to the boot image.
-// It shouldn't matter that the OAT file is out of date, because it is
-// verify-at-runtime.
-TEST_F(DexoptAnalyzerTest, OatVerifyAtRuntimeImageOutOfDate) {
- std::string dex_location = GetScratchDir() + "/OatVerifyAtRuntimeImageOutOfDate.jar";
- std::string odex_location = GetOdexDir() + "/OatVerifyAtRuntimeImageOutOfDate.odex";
-
- Copy(GetDexSrc1(), dex_location);
- GenerateOatForTest(dex_location.c_str(),
- odex_location.c_str(),
- CompilerFilter::kExtract,
- /*with_alternate_image=*/true);
-
- Verify(dex_location, CompilerFilter::kExtract);
- Verify(dex_location, CompilerFilter::kVerify);
-}
-
// Case: We have a DEX file and an ODEX file, but no OAT file.
TEST_F(DexoptAnalyzerTest, DexOdexNoOat) {
std::string dex_location = GetScratchDir() + "/DexOdexNoOat.jar";
@@ -284,7 +260,6 @@ TEST_F(DexoptAnalyzerTest, DexOdexNoOat) {
Copy(GetDexSrc1(), dex_location);
GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kSpeed);
- Verify(dex_location, CompilerFilter::kExtract);
Verify(dex_location, CompilerFilter::kSpeed);
Verify(dex_location, CompilerFilter::kEverything);
}
@@ -297,7 +272,6 @@ TEST_F(DexoptAnalyzerTest, ResourceOnlyDex) {
Copy(GetResourceOnlySrc1(), dex_location);
Verify(dex_location, CompilerFilter::kSpeed);
- Verify(dex_location, CompilerFilter::kExtract);
Verify(dex_location, CompilerFilter::kVerify);
}
@@ -317,18 +291,6 @@ TEST_F(DexoptAnalyzerTest, OdexOatOverlap) {
Verify(dex_location, CompilerFilter::kSpeed);
}
-// Case: We have a DEX file and a VerifyAtRuntime ODEX file, but no OAT file..
-TEST_F(DexoptAnalyzerTest, DexVerifyAtRuntimeOdexNoOat) {
- std::string dex_location = GetScratchDir() + "/DexVerifyAtRuntimeOdexNoOat.jar";
- std::string odex_location = GetOdexDir() + "/DexVerifyAtRuntimeOdexNoOat.odex";
-
- Copy(GetDexSrc1(), dex_location);
- GenerateOdexForTest(dex_location, odex_location, CompilerFilter::kExtract);
-
- Verify(dex_location, CompilerFilter::kExtract);
- Verify(dex_location, CompilerFilter::kSpeed);
-}
-
// Case: Non-standard extension for dex file.
TEST_F(DexoptAnalyzerTest, LongDexExtension) {
std::string dex_location = GetScratchDir() + "/LongDexExtension.jarx";