diff options
author | 2018-08-29 21:10:16 +0000 | |
---|---|---|
committer | 2018-08-30 13:37:02 +0100 | |
commit | 3d8a78a79aaa47be68162cb3e3fb2544f9b624a3 (patch) | |
tree | 0f9790f629c798f5c371e75ae20af60fa39a3203 | |
parent | c497fca9aa25a331af6428aa0fb6b083c6292089 (diff) |
Revert "Revert "Remove OatFileAssistant::MakeUpToDate and friends.""
This reverts commit baf3761013a30b8c5dc1d6179cddaeee0a764311.
Also remove the now deprecated --{no-}dex2oat option.
Change-Id: I502c7011877f43f315abffa9b7d482ef13857125
bug: 111174995
bug: 111342996
35 files changed, 201 insertions, 983 deletions
diff --git a/cmdline/cmdline_parser_test.cc b/cmdline/cmdline_parser_test.cc index a33d53741c..42c6a5ff59 100644 --- a/cmdline/cmdline_parser_test.cc +++ b/cmdline/cmdline_parser_test.cc @@ -558,13 +558,12 @@ TEST_F(CmdlineParserTest, TestIgnoredArguments) { TEST_F(CmdlineParserTest, MultipleArguments) { EXPECT_TRUE(IsResultSuccessful(parser_->Parse( "-help -XX:ForegroundHeapGrowthMultiplier=0.5 " - "-Xnodex2oat -Xmethod-trace -XX:LargeObjectSpace=map"))); + "-Xmethod-trace -XX:LargeObjectSpace=map"))); auto&& map = parser_->ReleaseArgumentsMap(); - EXPECT_EQ(5u, map.Size()); + EXPECT_EQ(4u, map.Size()); EXPECT_KEY_VALUE(map, M::Help, Unit{}); EXPECT_KEY_VALUE(map, M::ForegroundHeapGrowthMultiplier, 0.5); - EXPECT_KEY_VALUE(map, M::Dex2Oat, false); EXPECT_KEY_VALUE(map, M::MethodTrace, Unit{}); EXPECT_KEY_VALUE(map, M::LargeObjectSpace, gc::space::LargeObjectSpaceType::kMap); } // TEST_F diff --git a/runtime/dexopt_test.cc b/runtime/dexopt_test.cc index 9e3159d5e7..127e14e239 100644 --- a/runtime/dexopt_test.cc +++ b/runtime/dexopt_test.cc @@ -20,6 +20,8 @@ #include <backtrace/BacktraceMap.h> #include <gtest/gtest.h> +#include "android-base/stringprintf.h" +#include "android-base/strings.h" #include "base/file_utils.h" #include "base/mem_map.h" #include "common_runtime_test.h" @@ -27,6 +29,7 @@ #include "dex2oat_environment_test.h" #include "dexopt_test.h" #include "gc/space/image_space.h" +#include "hidden_api.h" namespace art { void DexoptTest::SetUp() { @@ -45,6 +48,46 @@ void DexoptTest::PostRuntimeCreate() { ReserveImageSpace(); } +static std::string ImageLocation() { + Runtime* runtime = Runtime::Current(); + const std::vector<gc::space::ImageSpace*>& image_spaces = + runtime->GetHeap()->GetBootImageSpaces(); + if (image_spaces.empty()) { + return ""; + } + return image_spaces[0]->GetImageLocation(); +} + +bool DexoptTest::Dex2Oat(const std::vector<std::string>& args, std::string* error_msg) { + Runtime* runtime = Runtime::Current(); + + std::vector<std::string> argv; + argv.push_back(runtime->GetCompilerExecutable()); + if (runtime->IsJavaDebuggable()) { + argv.push_back("--debuggable"); + } + runtime->AddCurrentRuntimeFeaturesAsDex2OatArguments(&argv); + + if (runtime->GetHiddenApiEnforcementPolicy() != hiddenapi::EnforcementPolicy::kNoChecks) { + argv.push_back("--runtime-arg"); + argv.push_back("-Xhidden-api-checks"); + } + + if (!kIsTargetBuild) { + argv.push_back("--host"); + } + + argv.push_back("--boot-image=" + ImageLocation()); + + std::vector<std::string> compiler_options = runtime->GetCompilerOptions(); + argv.insert(argv.end(), compiler_options.begin(), compiler_options.end()); + + argv.insert(argv.end(), args.begin(), args.end()); + + std::string command_line(android::base::Join(argv, ' ')); + return Exec(argv, error_msg); +} + void DexoptTest::GenerateOatForTest(const std::string& dex_location, const std::string& oat_location_in, CompilerFilter::Filter filter, @@ -96,7 +139,7 @@ void DexoptTest::GenerateOatForTest(const std::string& dex_location, } std::string error_msg; - ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; + ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg; if (!relocate) { // Restore the dalvik cache if needed. diff --git a/runtime/dexopt_test.h b/runtime/dexopt_test.h index df7181a1e7..5dff379a32 100644 --- a/runtime/dexopt_test.h +++ b/runtime/dexopt_test.h @@ -71,6 +71,8 @@ class DexoptTest : public Dex2oatEnvironmentTest { // Generate a standard oat file in the oat location. void GenerateOatForTest(const char* dex_location, CompilerFilter::Filter filter); + static bool Dex2Oat(const std::vector<std::string>& args, std::string* error_msg); + private: // Pre-Relocate the image to a known non-zero offset so we don't have to // deal with the runtime randomly relocating the image by 0 and messing up diff --git a/runtime/gc/space/image_space_test.cc b/runtime/gc/space/image_space_test.cc index d93385de3a..347af4e1fd 100644 --- a/runtime/gc/space/image_space_test.cc +++ b/runtime/gc/space/image_space_test.cc @@ -41,7 +41,7 @@ TEST_F(DexoptTest, ValidateOatFile) { args.push_back("--dex-file=" + multidex1); args.push_back("--dex-file=" + dex2); args.push_back("--oat-file=" + oat_location); - ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; + ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg; std::unique_ptr<OatFile> oat(OatFile::Open(/* zip_fd */ -1, oat_location.c_str(), diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc index f7c74cc23b..e262ff7150 100644 --- a/runtime/oat_file_assistant.cc +++ b/runtime/oat_file_assistant.cc @@ -36,7 +36,6 @@ #include "exec_utils.h" #include "gc/heap.h" #include "gc/space/image_space.h" -#include "hidden_api.h" #include "image.h" #include "oat.h" #include "runtime.h" @@ -182,30 +181,6 @@ bool OatFileAssistant::IsInBootClassPath() { return false; } -bool OatFileAssistant::Lock(std::string* error_msg) { - CHECK(error_msg != nullptr); - CHECK(flock_.get() == nullptr) << "OatFileAssistant::Lock already acquired"; - - // Note the lock will only succeed for secondary dex files and in test - // environment. - // - // The lock *will fail* for all primary apks in a production environment. - // The app does not have permissions to create locks next to its dex location - // (be it system, data or vendor parition). We also cannot use the odex or - // oat location for the same reasoning. - // - // This is best effort and if it fails it's unlikely that we will be able - // to generate oat files anyway. - std::string lock_file_name = dex_location_ + "." + GetInstructionSetString(isa_) + ".flock"; - - flock_ = LockedFile::Open(lock_file_name.c_str(), error_msg); - if (flock_.get() == nullptr) { - unlink(lock_file_name.c_str()); - return false; - } - return true; -} - int OatFileAssistant::GetDexOptNeeded(CompilerFilter::Filter target, bool profile_changed, bool downgrade, @@ -221,72 +196,10 @@ int OatFileAssistant::GetDexOptNeeded(CompilerFilter::Filter target, return -dexopt_needed; } -// Figure out the currently specified compile filter option in the runtime. -// Returns true on success, false if the compiler filter is invalid, in which -// case error_msg describes the problem. -static bool GetRuntimeCompilerFilterOption(CompilerFilter::Filter* filter, - std::string* error_msg) { - CHECK(filter != nullptr); - CHECK(error_msg != nullptr); - - *filter = OatFileAssistant::kDefaultCompilerFilterForDexLoading; - for (StringPiece option : Runtime::Current()->GetCompilerOptions()) { - if (option.starts_with("--compiler-filter=")) { - const char* compiler_filter_string = option.substr(strlen("--compiler-filter=")).data(); - if (!CompilerFilter::ParseCompilerFilter(compiler_filter_string, filter)) { - *error_msg = std::string("Unknown --compiler-filter value: ") - + std::string(compiler_filter_string); - return false; - } - } - } - return true; -} - bool OatFileAssistant::IsUpToDate() { return GetBestInfo().Status() == kOatUpToDate; } -OatFileAssistant::ResultOfAttemptToUpdate -OatFileAssistant::MakeUpToDate(bool profile_changed, - ClassLoaderContext* class_loader_context, - std::string* error_msg) { - // The method doesn't use zip_fd_ and directly opens dex files at dex_locations_. - CHECK_EQ(-1, zip_fd_) << "MakeUpToDate should not be called with zip_fd"; - - CompilerFilter::Filter target; - if (!GetRuntimeCompilerFilterOption(&target, error_msg)) { - return kUpdateNotAttempted; - } - - OatFileInfo& info = GetBestInfo(); - // TODO(calin, jeffhao): the context should really be passed to GetDexOptNeeded: b/62269291. - // This is actually not trivial in the current logic as it will interact with the collision - // check: - // - currently, if the context does not match but we have no collisions we still accept the - // oat file. - // - if GetDexOptNeeded would return kDex2OatFromScratch for a context mismatch and we make - // the oat code up to date the collision check becomes useless. - // - however, MakeUpToDate will not always succeed (e.g. for primary apks, or for dex files - // loaded in other processes). So it boils down to how far do we want to complicate - // the logic in order to enable the use of oat files. Maybe its time to try simplify it. - switch (info.GetDexOptNeeded( - target, profile_changed, /*downgrade*/ false, class_loader_context)) { - case kNoDexOptNeeded: - return kUpdateSucceeded; - - // TODO: For now, don't bother with all the different ways we can call - // dex2oat to generate the oat file. Always generate the oat file as if it - // were kDex2OatFromScratch. - case kDex2OatFromScratch: - case kDex2OatForBootImage: - case kDex2OatForRelocation: - case kDex2OatForFilter: - return GenerateOatFileNoChecks(info, target, class_loader_context, error_msg); - } - UNREACHABLE(); -} - std::unique_ptr<OatFile> OatFileAssistant::GetBestOatFile() { return GetBestInfo().ReleaseFileForUse(); } @@ -615,243 +528,6 @@ static bool DexLocationToOdexNames(const std::string& location, return true; } -// Prepare a subcomponent of the odex directory. -// (i.e. create and set the expected permissions on the path `dir`). -static bool PrepareDirectory(const std::string& dir, std::string* error_msg) { - struct stat dir_stat; - if (TEMP_FAILURE_RETRY(stat(dir.c_str(), &dir_stat)) == 0) { - // The directory exists. Check if it is indeed a directory. - if (!S_ISDIR(dir_stat.st_mode)) { - *error_msg = dir + " is not a dir"; - return false; - } else { - // The dir is already on disk. - return true; - } - } - - // Failed to stat. We need to create the directory. - if (errno != ENOENT) { - *error_msg = "Could not stat isa dir " + dir + ":" + strerror(errno); - return false; - } - - mode_t mode = S_IRWXU | S_IXGRP | S_IXOTH; - if (mkdir(dir.c_str(), mode) != 0) { - *error_msg = "Could not create dir " + dir + ":" + strerror(errno); - return false; - } - if (chmod(dir.c_str(), mode) != 0) { - *error_msg = "Could not create the oat dir " + dir + ":" + strerror(errno); - return false; - } - return true; -} - -// Prepares the odex directory for the given dex location. -static bool PrepareOdexDirectories(const std::string& dex_location, - const std::string& expected_odex_location, - InstructionSet isa, - std::string* error_msg) { - std::string actual_odex_location; - std::string oat_dir; - std::string isa_dir; - if (!DexLocationToOdexNames( - dex_location, isa, &actual_odex_location, &oat_dir, &isa_dir, error_msg)) { - return false; - } - DCHECK_EQ(expected_odex_location, actual_odex_location); - - if (!PrepareDirectory(oat_dir, error_msg)) { - return false; - } - if (!PrepareDirectory(isa_dir, error_msg)) { - return false; - } - return true; -} - -class Dex2oatFileWrapper { - public: - explicit Dex2oatFileWrapper(File* file) - : file_(file), - unlink_file_at_destruction_(true) { - } - - ~Dex2oatFileWrapper() { - if (unlink_file_at_destruction_ && (file_ != nullptr)) { - file_->Erase(/*unlink*/ true); - } - } - - File* GetFile() { return file_.get(); } - - void DisableUnlinkAtDestruction() { - unlink_file_at_destruction_ = false; - } - - private: - std::unique_ptr<File> file_; - bool unlink_file_at_destruction_; -}; - -OatFileAssistant::ResultOfAttemptToUpdate OatFileAssistant::GenerateOatFileNoChecks( - OatFileAssistant::OatFileInfo& info, - CompilerFilter::Filter filter, - const ClassLoaderContext* class_loader_context, - std::string* error_msg) { - CHECK(error_msg != nullptr); - - Runtime* runtime = Runtime::Current(); - if (!runtime->IsDex2OatEnabled()) { - *error_msg = "Generation of oat file for dex location " + dex_location_ - + " not attempted because dex2oat is disabled."; - return kUpdateNotAttempted; - } - - if (info.Filename() == nullptr) { - *error_msg = "Generation of oat file for dex location " + dex_location_ - + " not attempted because the oat file name could not be determined."; - return kUpdateNotAttempted; - } - const std::string& oat_file_name = *info.Filename(); - const std::string& vdex_file_name = GetVdexFilename(oat_file_name); - - // dex2oat ignores missing dex files and doesn't report an error. - // Check explicitly here so we can detect the error properly. - // TODO: Why does dex2oat behave that way? - struct stat dex_path_stat; - if (TEMP_FAILURE_RETRY(stat(dex_location_.c_str(), &dex_path_stat)) != 0) { - *error_msg = "Could not access dex location " + dex_location_ + ":" + strerror(errno); - return kUpdateNotAttempted; - } - - // If this is the odex location, we need to create the odex file layout (../oat/isa/..) - if (!info.IsOatLocation()) { - if (!PrepareOdexDirectories(dex_location_, oat_file_name, isa_, error_msg)) { - return kUpdateNotAttempted; - } - } - - // Set the permissions for the oat and the vdex files. - // The user always gets read and write while the group and others propagate - // the reading access of the original dex file. - mode_t file_mode = S_IRUSR | S_IWUSR | - (dex_path_stat.st_mode & S_IRGRP) | - (dex_path_stat.st_mode & S_IROTH); - - Dex2oatFileWrapper vdex_file_wrapper(OS::CreateEmptyFile(vdex_file_name.c_str())); - File* vdex_file = vdex_file_wrapper.GetFile(); - if (vdex_file == nullptr) { - *error_msg = "Generation of oat file " + oat_file_name - + " not attempted because the vdex file " + vdex_file_name - + " could not be opened."; - return kUpdateNotAttempted; - } - - if (fchmod(vdex_file->Fd(), file_mode) != 0) { - *error_msg = "Generation of oat file " + oat_file_name - + " not attempted because the vdex file " + vdex_file_name - + " could not be made world readable."; - return kUpdateNotAttempted; - } - - Dex2oatFileWrapper oat_file_wrapper(OS::CreateEmptyFile(oat_file_name.c_str())); - File* oat_file = oat_file_wrapper.GetFile(); - if (oat_file == nullptr) { - *error_msg = "Generation of oat file " + oat_file_name - + " not attempted because the oat file could not be created."; - return kUpdateNotAttempted; - } - - if (fchmod(oat_file->Fd(), file_mode) != 0) { - *error_msg = "Generation of oat file " + oat_file_name - + " not attempted because the oat file could not be made world readable."; - return kUpdateNotAttempted; - } - - std::vector<std::string> args; - args.push_back("--dex-file=" + dex_location_); - args.push_back("--output-vdex-fd=" + std::to_string(vdex_file->Fd())); - args.push_back("--oat-fd=" + std::to_string(oat_file->Fd())); - args.push_back("--oat-location=" + oat_file_name); - args.push_back("--compiler-filter=" + CompilerFilter::NameOfFilter(filter)); - const std::string dex2oat_context = class_loader_context == nullptr - ? OatFile::kSpecialSharedLibrary - : class_loader_context->EncodeContextForDex2oat(/*base_dir*/ ""); - args.push_back("--class-loader-context=" + dex2oat_context); - - if (!Dex2Oat(args, error_msg)) { - return kUpdateFailed; - } - - if (vdex_file->FlushCloseOrErase() != 0) { - *error_msg = "Unable to close vdex file " + vdex_file_name; - return kUpdateFailed; - } - - if (oat_file->FlushCloseOrErase() != 0) { - *error_msg = "Unable to close oat file " + oat_file_name; - return kUpdateFailed; - } - - // Mark that the odex file has changed and we should try to reload. - info.Reset(); - // We have compiled successfully. Disable the auto-unlink. - vdex_file_wrapper.DisableUnlinkAtDestruction(); - oat_file_wrapper.DisableUnlinkAtDestruction(); - - return kUpdateSucceeded; -} - -bool OatFileAssistant::Dex2Oat(const std::vector<std::string>& args, - std::string* error_msg) { - Runtime* runtime = Runtime::Current(); - std::string image_location = ImageLocation(); - if (image_location.empty()) { - *error_msg = "No image location found for Dex2Oat."; - return false; - } - - std::vector<std::string> argv; - argv.push_back(runtime->GetCompilerExecutable()); - if (runtime->IsJavaDebuggable()) { - argv.push_back("--debuggable"); - } - runtime->AddCurrentRuntimeFeaturesAsDex2OatArguments(&argv); - - if (!runtime->IsVerificationEnabled()) { - argv.push_back("--compiler-filter=verify-none"); - } - - if (runtime->GetHiddenApiEnforcementPolicy() != hiddenapi::EnforcementPolicy::kNoChecks) { - argv.push_back("--runtime-arg"); - argv.push_back("-Xhidden-api-checks"); - } - - if (runtime->MustRelocateIfPossible()) { - argv.push_back("--runtime-arg"); - argv.push_back("-Xrelocate"); - } else { - argv.push_back("--runtime-arg"); - argv.push_back("-Xnorelocate"); - } - - if (!kIsTargetBuild) { - argv.push_back("--host"); - } - - argv.push_back("--boot-image=" + image_location); - - std::vector<std::string> compiler_options = runtime->GetCompilerOptions(); - argv.insert(argv.end(), compiler_options.begin(), compiler_options.end()); - - argv.insert(argv.end(), args.begin(), args.end()); - - std::string command_line(android::base::Join(argv, ' ')); - return Exec(argv, error_msg); -} - bool OatFileAssistant::DexLocationToOdexFilename(const std::string& location, InstructionSet isa, std::string* odex_filename, @@ -885,16 +561,6 @@ bool OatFileAssistant::DexLocationToOatFilename(const std::string& location, return GetDalvikCacheFilename(location.c_str(), cache_dir.c_str(), oat_filename, error_msg); } -std::string OatFileAssistant::ImageLocation() { - Runtime* runtime = Runtime::Current(); - const std::vector<gc::space::ImageSpace*>& image_spaces = - runtime->GetHeap()->GetBootImageSpaces(); - if (image_spaces.empty()) { - return ""; - } - return image_spaces[0]->GetImageLocation(); -} - const std::vector<uint32_t>* OatFileAssistant::GetRequiredDexChecksums() { if (!required_dex_checksums_attempted_) { required_dex_checksums_attempted_ = true; diff --git a/runtime/oat_file_assistant.h b/runtime/oat_file_assistant.h index a6d0961835..dbfbdf9fbc 100644 --- a/runtime/oat_file_assistant.h +++ b/runtime/oat_file_assistant.h @@ -48,11 +48,6 @@ class ImageSpace; // dex location is in the boot class path. class OatFileAssistant { public: - // The default compile filter to use when optimizing dex file at load time if they - // are out of date. - static const CompilerFilter::Filter kDefaultCompilerFilterForDexLoading = - CompilerFilter::kQuicken; - enum DexOptNeeded { // No dexopt should (or can) be done to update the apk/jar. // Matches Java: dalvik.system.DexFile.NO_DEXOPT_NEEDED = 0 @@ -144,24 +139,6 @@ class OatFileAssistant { // path. bool IsInBootClassPath(); - // Obtains a lock on the target oat file. - // Only one OatFileAssistant object can hold the lock for a target oat file - // at a time. The Lock is released automatically when the OatFileAssistant - // object goes out of scope. The Lock() method must not be called if the - // lock has already been acquired. - // - // Returns true on success. - // Returns false on error, in which case error_msg will contain more - // information on the error. - // - // The 'error_msg' argument must not be null. - // - // This is intended to be used to avoid race conditions when multiple - // processes generate oat files, such as when a foreground Activity and - // a background Service both use DexClassLoaders pointing to the same dex - // file. - bool Lock(std::string* error_msg); - // Return what action needs to be taken to produce up-to-date code for this // dex location. If "downgrade" is set to false, it verifies if the current // compiler filter is at least as good as an oat file generated with the @@ -187,33 +164,6 @@ class OatFileAssistant { // irrespective of the compiler filter of the up-to-date code. bool IsUpToDate(); - // Return code used when attempting to generate updated code. - enum ResultOfAttemptToUpdate { - kUpdateFailed, // We tried making the code up to date, but - // encountered an unexpected failure. - kUpdateNotAttempted, // We wanted to update the code, but determined we - // should not make the attempt. - kUpdateSucceeded // We successfully made the code up to date - // (possibly by doing nothing). - }; - - // Attempts to generate or relocate the oat file as needed to make it up to - // date based on the current runtime and compiler options. - // profile_changed should be true to indicate the profile has recently - // changed for this dex location. - // - // If the dex files need to be made up to date, class_loader_context will be - // passed to dex2oat. - // - // Returns the result of attempting to update the code. - // - // If the result is not kUpdateSucceeded, the value of error_msg will be set - // to a string describing why there was a failure or the update was not - // attempted. error_msg must not be null. - ResultOfAttemptToUpdate MakeUpToDate(bool profile_changed, - ClassLoaderContext* class_loader_context, - std::string* error_msg); - // Returns an oat file that can be used for loading dex files. // Returns null if no suitable oat file was found. // @@ -284,18 +234,6 @@ class OatFileAssistant { // Returns the status of the oat file for the dex location. OatStatus OatFileStatus(); - // Executes dex2oat using the current runtime configuration overridden with - // the given arguments. This does not check to see if dex2oat is enabled in - // the runtime configuration. - // Returns true on success. - // - // If there is a failure, the value of error_msg will be set to a string - // describing why there was failure. error_msg must not be null. - // - // TODO: The OatFileAssistant probably isn't the right place to have this - // function. - static bool Dex2Oat(const std::vector<std::string>& args, std::string* error_msg); - // Constructs the odex file name for the given dex location. // Returns true on success, in which case odex_filename is set to the odex // file name. @@ -436,20 +374,6 @@ class OatFileAssistant { bool file_released_ = false; }; - // Generate the oat file for the given info from the dex file using the - // current runtime compiler options, the specified filter and class loader - // context. - // This does not check the current status before attempting to generate the - // oat file. - // - // If the result is not kUpdateSucceeded, the value of error_msg will be set - // to a string describing why there was a failure or the update was not - // attempted. error_msg must not be null. - ResultOfAttemptToUpdate GenerateOatFileNoChecks(OatFileInfo& info, - CompilerFilter::Filter target, - const ClassLoaderContext* class_loader_context, - std::string* error_msg); - // Return info for the best oat file. OatFileInfo& GetBestInfo(); @@ -473,13 +397,6 @@ class OatFileAssistant { // location. OatStatus GivenOatFileStatus(const OatFile& file); - // Returns the current image location. - // Returns an empty string if the image location could not be retrieved. - // - // TODO: This method should belong with an image file manager, not - // the oat file assistant. - static std::string ImageLocation(); - // Gets the dex checksums required for an up-to-date oat file. // Returns cached_required_dex_checksums if the required checksums were // located. Returns null if the required checksums were not found. The diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc index 0b3c61d474..901bbc4be2 100644 --- a/runtime/oat_file_assistant_test.cc +++ b/runtime/oat_file_assistant_test.cc @@ -41,11 +41,6 @@ namespace art { -static const std::string kSpecialSharedLibrary = "&"; // NOLINT [runtime/string] [4] -static ClassLoaderContext* kSpecialSharedLibraryContext = nullptr; - -static constexpr char kDex2oatCmdLineHiddenApiArg[] = " --runtime-arg -Xhidden-api-checks"; - class OatFileAssistantTest : public DexoptTest { public: void VerifyOptimizationStatus(const std::string& file, @@ -68,14 +63,6 @@ class OatFileAssistantTest : public DexoptTest { } }; -class OatFileAssistantNoDex2OatTest : public DexoptTest { - public: - virtual void SetUpRuntimeOptions(RuntimeOptions* options) { - DexoptTest::SetUpRuntimeOptions(options); - options->push_back(std::make_pair("-Xnodex2oat", nullptr)); - } -}; - class ScopedNonWritable { public: explicit ScopedNonWritable(const std::string& dex_location) { @@ -109,6 +96,97 @@ static bool IsExecutedAsRoot() { return geteuid() == 0; } +// Case: We have a MultiDEX file and up-to-date ODEX file for it with relative +// encoded dex locations. +// Expect: The oat file status is kNoDexOptNeeded. +TEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) { + std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar"; + std::string odex_location = GetOdexDir() + "/RelativeEncodedDexLocation.odex"; + + // Create the dex file + Copy(GetMultiDexSrc1(), dex_location); + + // Create the oat file with relative encoded dex location. + std::vector<std::string> args = { + "--dex-file=" + dex_location, + "--dex-location=" + std::string("RelativeEncodedDexLocation.jar"), + "--oat-file=" + odex_location, + "--compiler-filter=speed" + }; + + std::string error_msg; + ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg; + + // Verify we can load both dex files. + OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true); + + std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); + ASSERT_TRUE(oat_file.get() != nullptr); + EXPECT_TRUE(oat_file->IsExecutable()); + std::vector<std::unique_ptr<const DexFile>> dex_files; + dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); + EXPECT_EQ(2u, dex_files.size()); +} + +TEST_F(OatFileAssistantTest, MakeUpToDateWithContext) { + std::string dex_location = GetScratchDir() + "/TestDex.jar"; + std::string odex_location = GetOdexDir() + "/TestDex.odex"; + std::string context_location = GetScratchDir() + "/ContextDex.jar"; + Copy(GetDexSrc1(), dex_location); + Copy(GetDexSrc2(), context_location); + + OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false); + + std::string context_str = "PCL[" + context_location + "]"; + std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_str); + ASSERT_TRUE(context != nullptr); + ASSERT_TRUE(context->OpenDexFiles(kRuntimeISA, "")); + + std::string error_msg; + std::vector<std::string> args; + args.push_back("--dex-file=" + dex_location); + args.push_back("--oat-file=" + odex_location); + args.push_back("--class-loader-context=" + context_str); + ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg; + + std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); + EXPECT_NE(nullptr, oat_file.get()); + EXPECT_EQ(context->EncodeContextForOatFile(""), + oat_file->GetOatHeader().GetStoreValueByKey(OatHeader::kClassPathKey)); +} + +TEST_F(OatFileAssistantTest, GetDexOptNeededWithUpToDateContextRelative) { + std::string dex_location = GetScratchDir() + "/TestDex.jar"; + std::string odex_location = GetOdexDir() + "/TestDex.odex"; + std::string context_location = GetScratchDir() + "/ContextDex.jar"; + Copy(GetDexSrc1(), dex_location); + Copy(GetDexSrc2(), context_location); + + OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false); + + std::string context_str = "PCL[" + context_location + "]"; + std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_str); + ASSERT_TRUE(context != nullptr); + ASSERT_TRUE(context->OpenDexFiles(kRuntimeISA, "")); + + std::string error_msg; + std::vector<std::string> args; + args.push_back("--dex-file=" + dex_location); + args.push_back("--oat-file=" + odex_location); + args.push_back("--class-loader-context=" + context_str); + ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg; + + // A relative context simulates a dependent split context. + std::unique_ptr<ClassLoaderContext> relative_context = + ClassLoaderContext::Create("PCL[ContextDex.jar]"); + EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded, + oat_file_assistant.GetDexOptNeeded( + CompilerFilter::kDefaultCompilerFilter, + /* downgrade */ false, + /* profile_changed */ false, + relative_context.get())); +} + // Case: We have a DEX file, but no OAT file for it. // Expect: The status is kDex2OatNeeded. TEST_F(OatFileAssistantTest, DexNoOat) { @@ -145,11 +223,6 @@ TEST_F(OatFileAssistantTest, NoDexNoOat) { oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); - // Trying to make the oat file up to date should not fail or crash. - std::string error_msg; - EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, - oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg)); - // Trying to get the best oat file should fail, but not crash. std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); EXPECT_EQ(nullptr, oat_file.get()); @@ -584,37 +657,6 @@ TEST_F(OatFileAssistantTest, StrippedMultiDexNonMainOutOfDate) { EXPECT_EQ(OatFileAssistant::kOatDexOutOfDate, oat_file_assistant.OatFileStatus()); } -// Case: We have a MultiDEX file and up-to-date ODEX file for it with relative -// encoded dex locations. -// Expect: The oat file status is kNoDexOptNeeded. -TEST_F(OatFileAssistantTest, RelativeEncodedDexLocation) { - std::string dex_location = GetScratchDir() + "/RelativeEncodedDexLocation.jar"; - std::string odex_location = GetOdexDir() + "/RelativeEncodedDexLocation.odex"; - - // Create the dex file - Copy(GetMultiDexSrc1(), dex_location); - - // Create the oat file with relative encoded dex location. - std::vector<std::string> args; - args.push_back("--dex-file=" + dex_location); - args.push_back("--dex-location=" + std::string("RelativeEncodedDexLocation.jar")); - args.push_back("--oat-file=" + odex_location); - args.push_back("--compiler-filter=speed"); - - std::string error_msg; - ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg; - - // Verify we can load both dex files. - OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true); - - std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); - ASSERT_TRUE(oat_file.get() != nullptr); - EXPECT_TRUE(oat_file->IsExecutable()); - std::vector<std::unique_ptr<const DexFile>> dex_files; - dex_files = oat_file_assistant.LoadDexFiles(*oat_file, dex_location.c_str()); - EXPECT_EQ(2u, dex_files.size()); -} - // Case: We have a DEX file and an OAT file out of date with respect to the // dex checksum. TEST_F(OatFileAssistantTest, OatDexOutOfDate) { @@ -872,13 +914,6 @@ TEST_F(OatFileAssistantTest, ResourceOnlyDex) { EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus()); EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); - // Make the oat file up to date. This should have no effect. - std::string error_msg; - Runtime::Current()->AddCompilerOption("--compiler-filter=speed"); - EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, - oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg)) << - error_msg; - EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); @@ -1037,35 +1072,6 @@ TEST_F(OatFileAssistantTest, LoadNoExecOatUpToDate) { EXPECT_EQ(1u, dex_files.size()); } -// Case: We don't have a DEX file and can't write the oat file. -// Expect: We should fail to generate the oat file without crashing. -TEST_F(OatFileAssistantTest, GenNoDex) { - if (IsExecutedAsRoot()) { - // We cannot simulate non writable locations when executed as root: b/38000545. - LOG(ERROR) << "Test skipped because it's running as root"; - return; - } - - std::string dex_location = GetScratchDir() + "/GenNoDex.jar"; - - ScopedNonWritable scoped_non_writable(dex_location); - ASSERT_TRUE(scoped_non_writable.IsSuccessful()); - - OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, true); - std::string error_msg; - Runtime::Current()->AddCompilerOption("--compiler-filter=speed"); - // We should get kUpdateSucceeded from MakeUpToDate since there's nothing - // that can be done in this situation. - ASSERT_EQ(OatFileAssistant::kUpdateSucceeded, - oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg)); - - // Verify it didn't create an oat in the default location (dalvik-cache). - OatFileAssistant ofm(dex_location.c_str(), kRuntimeISA, false); - EXPECT_EQ(OatFileAssistant::kOatCannotOpen, ofm.OatFileStatus()); - // Verify it didn't create the odex file in the default location (../oat/isa/...odex) - EXPECT_EQ(OatFileAssistant::kOatCannotOpen, ofm.OdexFileStatus()); -} - // Turn an absolute path into a path relative to the current working // directory. static std::string MakePathRelative(const std::string& target) { @@ -1131,13 +1137,6 @@ TEST_F(OatFileAssistantTest, ShortDexLocation) { EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OdexFileStatus()); EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus()); EXPECT_FALSE(oat_file_assistant.HasOriginalDexFiles()); - - // Trying to make it up to date should have no effect. - std::string error_msg; - Runtime::Current()->AddCompilerOption("--compiler-filter=speed"); - EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, - oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg)); - EXPECT_TRUE(error_msg.empty()); } // Case: Non-standard extension for dex file. @@ -1156,11 +1155,12 @@ TEST_F(OatFileAssistantTest, LongDexExtension) { EXPECT_EQ(OatFileAssistant::kOatCannotOpen, oat_file_assistant.OatFileStatus()); } + // A task to generate a dex location. Used by the RaceToGenerate test. class RaceGenerateTask : public Task { public: - explicit RaceGenerateTask(const std::string& dex_location, const std::string& oat_location) - : dex_location_(dex_location), oat_location_(oat_location), loaded_oat_file_(nullptr) + RaceGenerateTask(const std::string& dex_location, const std::string& oat_location) + : dex_location_(dex_location), oat_location_(oat_location), loaded_oat_file_(nullptr) {} void Run(Thread* self ATTRIBUTE_UNUSED) { @@ -1169,6 +1169,15 @@ class RaceGenerateTask : public Task { std::vector<std::unique_ptr<const DexFile>> dex_files; std::vector<std::string> error_msgs; const OatFile* oat_file = nullptr; + { + // Create the oat file. + std::vector<std::string> args; + args.push_back("--dex-file=" + dex_location_); + args.push_back("--oat-file=" + oat_location_); + std::string error_msg; + ASSERT_TRUE(DexoptTest::Dex2Oat(args, &error_msg)) << error_msg; + } + dex_files = Runtime::Current()->GetOatFileManager().OpenDexFilesFromOat( dex_location_.c_str(), Runtime::Current()->GetSystemClassLoader(), @@ -1176,8 +1185,9 @@ class RaceGenerateTask : public Task { &oat_file, &error_msgs); CHECK(!dex_files.empty()) << android::base::Join(error_msgs, '\n'); - CHECK(dex_files[0]->GetOatDexFile() != nullptr) << dex_files[0]->GetLocation(); - loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile(); + if (dex_files[0]->GetOatDexFile() != nullptr) { + loaded_oat_file_ = dex_files[0]->GetOatDexFile()->GetOatFile(); + } CHECK_EQ(loaded_oat_file_, oat_file); } @@ -1191,12 +1201,8 @@ class RaceGenerateTask : public Task { const OatFile* loaded_oat_file_; }; -// Test the case where multiple processes race to generate an oat file. -// This simulates multiple processes using multiple threads. -// -// We want unique Oat files to be loaded even when there is a race to load. -// TODO: The test case no longer tests locking the way it was intended since we now get multiple -// copies of the same Oat files mapped at different locations. +// Test the case where dex2oat invocations race with multiple processes trying to +// load the oat file. TEST_F(OatFileAssistantTest, RaceToGenerate) { std::string dex_location = GetScratchDir() + "/RaceToGenerate.jar"; std::string oat_location = GetOdexDir() + "/RaceToGenerate.oat"; @@ -1209,31 +1215,32 @@ TEST_F(OatFileAssistantTest, RaceToGenerate) { // take a while to generate. Copy(GetLibCoreDexFileNames()[0], dex_location); - const int kNumThreads = 32; + const size_t kNumThreads = 32; Thread* self = Thread::Current(); ThreadPool thread_pool("Oat file assistant test thread pool", kNumThreads); std::vector<std::unique_ptr<RaceGenerateTask>> tasks; - for (int i = 0; i < kNumThreads; i++) { + for (size_t i = 0; i < kNumThreads; i++) { std::unique_ptr<RaceGenerateTask> task(new RaceGenerateTask(dex_location, oat_location)); thread_pool.AddTask(self, task.get()); tasks.push_back(std::move(task)); } thread_pool.StartWorkers(self); - thread_pool.Wait(self, true, false); + thread_pool.Wait(self, /* do_work */ true, /* may_hold_locks */ false); - // Verify every task got a unique oat file. + // Verify that tasks which got an oat file got a unique one. std::set<const OatFile*> oat_files; for (auto& task : tasks) { const OatFile* oat_file = task->GetLoadedOatFile(); - EXPECT_TRUE(oat_files.find(oat_file) == oat_files.end()); - oat_files.insert(oat_file); + if (oat_file != nullptr) { + EXPECT_TRUE(oat_files.find(oat_file) == oat_files.end()); + oat_files.insert(oat_file); + } } } -// Case: We have a DEX file and an ODEX file, no OAT file, and dex2oat is -// disabled. +// Case: We have a DEX file and an ODEX file, and no OAT file, // Expect: We should load the odex file non-executable. -TEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) { +TEST_F(DexoptTest, LoadDexOdexNoOat) { std::string dex_location = GetScratchDir() + "/LoadDexOdexNoOat.jar"; std::string odex_location = GetOdexDir() + "/LoadDexOdexNoOat.odex"; @@ -1252,10 +1259,9 @@ TEST_F(OatFileAssistantNoDex2OatTest, LoadDexOdexNoOat) { EXPECT_EQ(1u, dex_files.size()); } -// Case: We have a MultiDEX file and an ODEX file, no OAT file, and dex2oat is -// disabled. +// Case: We have a MultiDEX file and an ODEX file, and no OAT file. // Expect: We should load the odex file non-executable. -TEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) { +TEST_F(DexoptTest, LoadMultiDexOdexNoOat) { std::string dex_location = GetScratchDir() + "/LoadMultiDexOdexNoOat.jar"; std::string odex_location = GetOdexDir() + "/LoadMultiDexOdexNoOat.odex"; @@ -1274,36 +1280,6 @@ TEST_F(OatFileAssistantNoDex2OatTest, LoadMultiDexOdexNoOat) { EXPECT_EQ(2u, dex_files.size()); } -TEST_F(OatFileAssistantTest, RuntimeCompilerFilterOptionUsed) { - std::string dex_location = GetScratchDir() + "/RuntimeCompilerFilterOptionUsed.jar"; - Copy(GetDexSrc1(), dex_location); - - OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false); - - std::string error_msg; - Runtime::Current()->AddCompilerOption("--compiler-filter=quicken"); - EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, - oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg)) << - error_msg; - EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded, - oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken)); - EXPECT_EQ(-OatFileAssistant::kDex2OatForFilter, - oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); - - Runtime::Current()->AddCompilerOption("--compiler-filter=speed"); - EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, - oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg)) - << error_msg; - EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, - oat_file_assistant.GetDexOptNeeded(CompilerFilter::kQuicken)); - EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, - oat_file_assistant.GetDexOptNeeded(CompilerFilter::kSpeed)); - - Runtime::Current()->AddCompilerOption("--compiler-filter=bogus"); - EXPECT_EQ(OatFileAssistant::kUpdateNotAttempted, - oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg)); -} - TEST(OatFileAssistantUtilsTest, DexLocationToOdexFilename) { std::string error_msg; std::string odex_file; @@ -1350,112 +1326,6 @@ TEST_F(OatFileAssistantTest, DexOptStatusValues) { } } -// Verify that when no compiler filter is passed the default one from OatFileAssistant is used. -TEST_F(OatFileAssistantTest, DefaultMakeUpToDateFilter) { - std::string dex_location = GetScratchDir() + "/TestDex.jar"; - Copy(GetDexSrc1(), dex_location); - - OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false); - - const CompilerFilter::Filter default_filter = - OatFileAssistant::kDefaultCompilerFilterForDexLoading; - std::string error_msg; - EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, - oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg)) << - error_msg; - EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded, - oat_file_assistant.GetDexOptNeeded(default_filter)); - std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); - EXPECT_NE(nullptr, oat_file.get()); - EXPECT_EQ(default_filter, oat_file->GetCompilerFilter()); -} - -TEST_F(OatFileAssistantTest, MakeUpToDateWithSpecialSharedLibrary) { - std::string dex_location = GetScratchDir() + "/TestDex.jar"; - Copy(GetDexSrc1(), dex_location); - - OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false); - - const CompilerFilter::Filter default_filter = - OatFileAssistant::kDefaultCompilerFilterForDexLoading; - std::string error_msg; - int status = oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg); - EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, status) << error_msg; - EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded, - oat_file_assistant.GetDexOptNeeded(default_filter)); - std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); - EXPECT_NE(nullptr, oat_file.get()); - EXPECT_EQ(kSpecialSharedLibrary, - oat_file->GetOatHeader().GetStoreValueByKey(OatHeader::kClassPathKey)); -} - -TEST_F(OatFileAssistantTest, MakeUpToDateWithContext) { - std::string dex_location = GetScratchDir() + "/TestDex.jar"; - std::string context_location = GetScratchDir() + "/ContextDex.jar"; - Copy(GetDexSrc1(), dex_location); - Copy(GetDexSrc2(), context_location); - - OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false); - - const CompilerFilter::Filter default_filter = - OatFileAssistant::kDefaultCompilerFilterForDexLoading; - std::string error_msg; - std::string context_str = "PCL[" + context_location + "]"; - std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_str); - ASSERT_TRUE(context != nullptr); - ASSERT_TRUE(context->OpenDexFiles(kRuntimeISA, "")); - - int status = oat_file_assistant.MakeUpToDate(false, context.get(), &error_msg); - EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, status) << error_msg; - EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded, - oat_file_assistant.GetDexOptNeeded(default_filter, false, false, context.get())); - - std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); - EXPECT_NE(nullptr, oat_file.get()); - EXPECT_EQ(context->EncodeContextForOatFile(""), - oat_file->GetOatHeader().GetStoreValueByKey(OatHeader::kClassPathKey)); -} - -TEST_F(OatFileAssistantTest, MakeUpToDateWithHiddenApiDisabled) { - hiddenapi::ScopedHiddenApiEnforcementPolicySetting hiddenapi_exemption( - hiddenapi::EnforcementPolicy::kNoChecks); - - std::string dex_location = GetScratchDir() + "/TestDexHiddenApiDisabled.jar"; - Copy(GetDexSrc1(), dex_location); - - OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false); - std::string error_msg; - int status = oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg); - EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, status) << error_msg; - - std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); - EXPECT_NE(nullptr, oat_file.get()); - - const char* cmd_line = oat_file->GetOatHeader().GetStoreValueByKey(OatHeader::kDex2OatCmdLineKey); - EXPECT_NE(nullptr, cmd_line); - EXPECT_EQ(nullptr, strstr(cmd_line, kDex2oatCmdLineHiddenApiArg)); -} - -TEST_F(OatFileAssistantTest, MakeUpToDateWithHiddenApiEnabled) { - hiddenapi::ScopedHiddenApiEnforcementPolicySetting hiddenapi_exemption( - hiddenapi::EnforcementPolicy::kBlacklistOnly); - - std::string dex_location = GetScratchDir() + "/TestDexHiddenApiEnabled.jar"; - Copy(GetDexSrc1(), dex_location); - - OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false); - std::string error_msg; - int status = oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg); - EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, status) << error_msg; - - std::unique_ptr<OatFile> oat_file = oat_file_assistant.GetBestOatFile(); - EXPECT_NE(nullptr, oat_file.get()); - - const char* cmd_line = oat_file->GetOatHeader().GetStoreValueByKey(OatHeader::kDex2OatCmdLineKey); - EXPECT_NE(nullptr, cmd_line); - EXPECT_NE(nullptr, strstr(cmd_line, kDex2oatCmdLineHiddenApiArg)); -} - TEST_F(OatFileAssistantTest, GetDexOptNeededWithOutOfDateContext) { std::string dex_location = GetScratchDir() + "/TestDex.jar"; std::string context_location = GetScratchDir() + "/ContextDex.jar"; @@ -1464,19 +1334,12 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithOutOfDateContext) { OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false); - const CompilerFilter::Filter default_filter = - OatFileAssistant::kDefaultCompilerFilterForDexLoading; std::string error_msg; std::string context_str = "PCL[" + context_location + "]"; std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_str); ASSERT_TRUE(context != nullptr); ASSERT_TRUE(context->OpenDexFiles(kRuntimeISA, "")); - int status = oat_file_assistant.MakeUpToDate(false, context.get(), &error_msg); - EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, status) << error_msg; - EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded, - oat_file_assistant.GetDexOptNeeded(default_filter, false, false, context.get())); - // Update the context by overriding the jar file. Copy(GetMultiDexSrc2(), context_location); std::unique_ptr<ClassLoaderContext> updated_context = ClassLoaderContext::Create(context_str); @@ -1484,88 +1347,10 @@ TEST_F(OatFileAssistantTest, GetDexOptNeededWithOutOfDateContext) { // DexOptNeeded should advise compilation from scratch. EXPECT_EQ(OatFileAssistant::kDex2OatFromScratch, oat_file_assistant.GetDexOptNeeded( - default_filter, false, false, updated_context.get())); -} - -TEST_F(OatFileAssistantTest, GetDexOptNeededWithUpToDateContextRelative) { - std::string dex_location = GetScratchDir() + "/TestDex.jar"; - std::string context_location = GetScratchDir() + "/ContextDex.jar"; - Copy(GetDexSrc1(), dex_location); - Copy(GetDexSrc2(), context_location); - - OatFileAssistant oat_file_assistant(dex_location.c_str(), kRuntimeISA, false); - - const CompilerFilter::Filter default_filter = - OatFileAssistant::kDefaultCompilerFilterForDexLoading; - std::string error_msg; - std::string context_str = "PCL[" + context_location + "]"; - std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_str); - ASSERT_TRUE(context != nullptr); - ASSERT_TRUE(context->OpenDexFiles(kRuntimeISA, "")); - - int status = oat_file_assistant.MakeUpToDate(false, context.get(), &error_msg); - EXPECT_EQ(OatFileAssistant::kUpdateSucceeded, status) << error_msg; - - // A relative context simulates a dependent split context. - std::unique_ptr<ClassLoaderContext> relative_context = - ClassLoaderContext::Create("PCL[ContextDex.jar]"); - EXPECT_EQ(-OatFileAssistant::kNoDexOptNeeded, - oat_file_assistant.GetDexOptNeeded( - default_filter, false, false, relative_context.get())); -} - -TEST_F(OatFileAssistantTest, SystemOdex) { - std::string dex_location = GetScratchDir() + "/OatUpToDate.jar"; - std::string odex_location = GetScratchDir() + "/OatUpToDate.odex"; - std::string system_location = GetAndroidRoot() + "/OatUpToDate.jar"; - - std::string error_msg; - - Copy(GetDexSrc1(), dex_location); - EXPECT_FALSE(LocationIsOnSystem(dex_location.c_str())); - - { - OatFileAssistant oat_file_assistant(dex_location.c_str(), - kRuntimeISA, - true, - false); - int status = oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg); - ASSERT_EQ(OatFileAssistant::kUpdateSucceeded, status) << error_msg; - EXPECT_TRUE(oat_file_assistant.GetBestOatFile()->IsExecutable()); - } - - { - OatFileAssistant oat_file_assistant(dex_location.c_str(), - kRuntimeISA, - true, - true); - int status = oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg); - ASSERT_EQ(OatFileAssistant::kUpdateSucceeded, status) << error_msg; - EXPECT_FALSE(oat_file_assistant.GetBestOatFile()->IsExecutable()); - } - - Copy(GetDexSrc1(), system_location); - EXPECT_TRUE(LocationIsOnSystem(system_location.c_str())); - - { - OatFileAssistant oat_file_assistant(system_location.c_str(), - kRuntimeISA, - true, - false); - int status = oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg); - ASSERT_EQ(OatFileAssistant::kUpdateSucceeded, status) << error_msg; - EXPECT_TRUE(oat_file_assistant.GetBestOatFile()->IsExecutable()); - } - - { - OatFileAssistant oat_file_assistant(system_location.c_str(), - kRuntimeISA, - true, - true); - int status = oat_file_assistant.MakeUpToDate(false, kSpecialSharedLibraryContext, &error_msg); - ASSERT_EQ(OatFileAssistant::kUpdateSucceeded, status) << error_msg; - EXPECT_TRUE(oat_file_assistant.GetBestOatFile()->IsExecutable()); - } + CompilerFilter::kDefaultCompilerFilter, + /* downgrade */ false, + /* profile_changed */ false, + updated_context.get())); } // TODO: More Tests: diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc index 59a1045ba2..bcad4a3428 100644 --- a/runtime/oat_file_manager.cc +++ b/runtime/oat_file_manager.cc @@ -465,57 +465,15 @@ std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat( !runtime->IsAotCompiler(), only_use_system_oat_files_); - // Lock the target oat location to avoid races generating and loading the - // oat file. - std::string error_msg; - if (!oat_file_assistant.Lock(/*out*/&error_msg)) { - // Don't worry too much if this fails. If it does fail, it's unlikely we - // can generate an oat file anyway. - VLOG(class_linker) << "OatFileAssistant::Lock: " << error_msg; - } - - const OatFile* source_oat_file = nullptr; - - if (!oat_file_assistant.IsUpToDate()) { - // Update the oat file on disk if we can, based on the --compiler-filter - // option derived from the current runtime options. - // This may fail, but that's okay. Best effort is all that matters here. - // TODO(calin): b/64530081 b/66984396. Pass a null context to verify and compile - // secondary dex files in isolation (and avoid to extract/verify the main apk - // if it's in the class path). Note this trades correctness for performance - // since the resulting slow down is unacceptable in some cases until b/64530081 - // is fixed. - // We still pass the class loader context when the classpath string of the runtime - // is not empty, which is the situation when ART is invoked standalone. - ClassLoaderContext* actual_context = Runtime::Current()->GetClassPathString().empty() - ? nullptr - : context.get(); - switch (oat_file_assistant.MakeUpToDate(/*profile_changed*/ false, - actual_context, - /*out*/ &error_msg)) { - case OatFileAssistant::kUpdateFailed: - LOG(WARNING) << error_msg; - break; - - case OatFileAssistant::kUpdateNotAttempted: - // Avoid spamming the logs if we decided not to attempt making the oat - // file up to date. - VLOG(oat) << error_msg; - break; - - case OatFileAssistant::kUpdateSucceeded: - // Nothing to do. - break; - } - } - // Get the oat file on disk. std::unique_ptr<const OatFile> oat_file(oat_file_assistant.GetBestOatFile().release()); VLOG(oat) << "OatFileAssistant(" << dex_location << ").GetBestOatFile()=" << reinterpret_cast<uintptr_t>(oat_file.get()) << " (executable=" << (oat_file != nullptr ? oat_file->IsExecutable() : false) << ")"; + const OatFile* source_oat_file = nullptr; CheckCollisionResult check_collision_result = CheckCollisionResult::kPerformedHasCollisions; + std::string error_msg; if ((class_loader != nullptr || dex_elements != nullptr) && oat_file != nullptr) { // Prevent oat files from being loaded if no class_loader or dex_elements are provided. // This can happen when the deprecated DexFile.<init>(String) is called directly, and it diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc index 0d98d90f1e..4d16eb537d 100644 --- a/runtime/parsed_options.cc +++ b/runtime/parsed_options.cc @@ -220,9 +220,6 @@ std::unique_ptr<RuntimeParser> ParsedOptions::MakeParser(bool ignore_unrecognize .Define({"-Xrelocate", "-Xnorelocate"}) .WithValues({true, false}) .IntoKey(M::Relocate) - .Define({"-Xdex2oat", "-Xnodex2oat"}) - .WithValues({true, false}) - .IntoKey(M::Dex2Oat) .Define({"-Ximage-dex2oat", "-Xnoimage-dex2oat"}) .WithValues({true, false}) .IntoKey(M::ImageDex2Oat) diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 243150759b..6878cc08c8 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -216,7 +216,6 @@ Runtime::Runtime() must_relocate_(false), is_concurrent_gc_enabled_(true), is_explicit_gc_disabled_(false), - dex2oat_enabled_(true), image_dex2oat_enabled_(true), default_stack_size_(0), heap_(nullptr), @@ -1195,7 +1194,6 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { must_relocate_ = runtime_options.GetOrDefault(Opt::Relocate); is_zygote_ = runtime_options.Exists(Opt::Zygote); is_explicit_gc_disabled_ = runtime_options.Exists(Opt::DisableExplicitGC); - dex2oat_enabled_ = runtime_options.GetOrDefault(Opt::Dex2Oat); image_dex2oat_enabled_ = runtime_options.GetOrDefault(Opt::ImageDex2Oat); dump_native_stack_on_sig_quit_ = runtime_options.GetOrDefault(Opt::DumpNativeStackOnSigQuit); diff --git a/runtime/runtime.h b/runtime/runtime.h index f98d7b9829..f0bf7548af 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -142,10 +142,6 @@ class Runtime { return must_relocate_; } - bool IsDex2OatEnabled() const { - return dex2oat_enabled_ && IsImageDex2OatEnabled(); - } - bool IsImageDex2OatEnabled() const { return image_dex2oat_enabled_; } @@ -846,7 +842,6 @@ class Runtime { bool must_relocate_; bool is_concurrent_gc_enabled_; bool is_explicit_gc_disabled_; - bool dex2oat_enabled_; bool image_dex2oat_enabled_; std::string compiler_executable_; diff --git a/runtime/runtime_options.def b/runtime/runtime_options.def index 5e12bbce05..ae1e08f10b 100644 --- a/runtime/runtime_options.def +++ b/runtime/runtime_options.def @@ -21,7 +21,7 @@ // This file defines the list of keys for RuntimeOptions. // These can be used with RuntimeOptions.Get/Set/etc, for example: -// RuntimeOptions opt; bool* dex2oat_enabled = opt.Get(RuntimeOptions::Dex2Oat); +// RuntimeOptions opt; bool* image_dex2oat_enabled = opt.Get(RuntimeOptions::ImageDex2Oat); // // Column Descriptions: // <<Type>> <<Key Name>> <<Default Value>> @@ -88,7 +88,6 @@ RUNTIME_OPTIONS_KEY (std::vector<std::string>, \ RUNTIME_OPTIONS_KEY (std::string, JniTrace) RUNTIME_OPTIONS_KEY (std::string, PatchOat) RUNTIME_OPTIONS_KEY (bool, Relocate, kDefaultMustRelocate) -RUNTIME_OPTIONS_KEY (bool, Dex2Oat, true) RUNTIME_OPTIONS_KEY (bool, ImageDex2Oat, true) RUNTIME_OPTIONS_KEY (bool, Interpret, false) // -Xint // Disable the compiler for CC (for now). diff --git a/test/071-dexfile-map-clean/run b/test/071-dexfile-map-clean/run index 9c100ec497..afa2ff7462 100755 --- a/test/071-dexfile-map-clean/run +++ b/test/071-dexfile-map-clean/run @@ -14,13 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Run without dex2oat so that we don't create oat/vdex files -# when trying to load the secondary dex file. - -# In this way, the secondary dex file will be forced to be -# loaded directly. -# -# In addition, make sure we call 'sync' +# Make sure we call 'sync' # before executing dalvikvm because otherwise # it's highly likely the pushed JAR files haven't # been committed to permanent storage yet, @@ -28,4 +22,4 @@ # the memory is dirty (despite being file-backed). # (Note: this was reproducible 100% of the time on # a target angler device). -./default-run "$@" --no-dex2oat --sync +./default-run "$@" --sync diff --git a/test/071-dexfile-map-clean/src/Main.java b/test/071-dexfile-map-clean/src/Main.java index 8a196dd52e..e784ac601c 100644 --- a/test/071-dexfile-map-clean/src/Main.java +++ b/test/071-dexfile-map-clean/src/Main.java @@ -90,19 +90,6 @@ public class Main { return true; } - // This test takes relies on dex2oat being skipped. - // (enforced in 'run' file by using '--no-dex2oat' - // - // This could happen in a non-test situation - // if a secondary dex file is loaded (but not yet maintenance-mode compiled) - // with JIT. - // - // Or it could also happen if a secondary dex file is loaded and forced - // into running into the interpreter (e.g. duplicate classes). - // - // Rather than relying on those weird fallbacks, - // we force the runtime not to dex2oat the dex file to ensure - // this test is repeatable and less brittle. private static void testDexMemoryMaps() throws Exception { // Ensure that the secondary dex file is mapped clean (directly from JAR file). String smaps = new String(Files.readAllBytes(Paths.get("/proc/self/smaps"))); diff --git a/test/116-nodex2oat/expected.txt b/test/116-nodex2oat/expected.txt index 157dfc4ea4..c6c7daa21d 100644 --- a/test/116-nodex2oat/expected.txt +++ b/test/116-nodex2oat/expected.txt @@ -1,9 +1,2 @@ -Run -Xnodex2oat JNI_OnLoad called -Has oat is false, is dex2oat enabled is false. -Run -Xdex2oat -JNI_OnLoad called -Has oat is true, is dex2oat enabled is true. -Run default -JNI_OnLoad called -Has oat is true, is dex2oat enabled is true. +Has oat is false. diff --git a/test/116-nodex2oat/run b/test/116-nodex2oat/run index d7984cece2..9063685fe7 100755 --- a/test/116-nodex2oat/run +++ b/test/116-nodex2oat/run @@ -24,20 +24,4 @@ if [[ "${flags}" == *--prebuild* || "${flags}" != *--no-prebuild* ]] ; then exit 1 fi -# Make sure we can run without an oat file. -echo "Run -Xnodex2oat" -${RUN} ${flags} --runtime-option -Xnodex2oat -return_status1=$? - -# Make sure we can run with the oat file. -echo "Run -Xdex2oat" -${RUN} ${flags} --runtime-option -Xdex2oat -return_status2=$? - -# Make sure we can run with the default settings. -echo "Run default" ${RUN} ${flags} -return_status3=$? - -# Make sure we don't silently ignore an early failure. -(exit $return_status1) && (exit $return_status2) && (exit $return_status3) diff --git a/test/116-nodex2oat/src/Main.java b/test/116-nodex2oat/src/Main.java index 229735f4b8..5491c492a9 100644 --- a/test/116-nodex2oat/src/Main.java +++ b/test/116-nodex2oat/src/Main.java @@ -17,17 +17,8 @@ public class Main { public static void main(String[] args) { System.loadLibrary(args[0]); - System.out.println( - "Has oat is " + hasOatFile() + ", is dex2oat enabled is " + isDex2OatEnabled() + "."); - - if (hasOatFile() && !isDex2OatEnabled()) { - throw new Error("Application with dex2oat disabled runs with an oat file"); - } else if (!hasOatFile() && isDex2OatEnabled()) { - throw new Error("Application with dex2oat enabled runs without an oat file"); - } + System.out.println("Has oat is " + hasOatFile() + "."); } private native static boolean hasOatFile(); - - private native static boolean isDex2OatEnabled(); } diff --git a/test/117-nopatchoat/run b/test/117-nopatchoat/run index 0627fe5069..4c33f7a450 100755 --- a/test/117-nopatchoat/run +++ b/test/117-nopatchoat/run @@ -34,20 +34,4 @@ if [[ "${flags}" == *--no-relocate* ]] ; then exit 1 fi -# Make sure we can run without relocation -echo "Run without dex2oat/patchoat" -${RUN} ${flags} --runtime-option -Xnodex2oat -return_status1=$? - -# Make sure we can run with the oat file. -echo "Run with dexoat/patchoat" -${RUN} ${flags} --runtime-option -Xdex2oat -return_status2=$? - -# Make sure we can run with the default settings. -echo "Run default" ${RUN} ${flags} -return_status3=$? - -# Make sure we don't silently ignore an early failure. -(exit $return_status1) && (exit $return_status2) && (exit $return_status3) diff --git a/test/117-nopatchoat/src/Main.java b/test/117-nopatchoat/src/Main.java index 816eb171a4..ef47ab9ee4 100644 --- a/test/117-nopatchoat/src/Main.java +++ b/test/117-nopatchoat/src/Main.java @@ -23,18 +23,13 @@ public class Main { // Hitting this condition should be rare and ideally we would prevent it from happening but // there is no way to do so without major changes to the run-test framework. boolean executable_correct = (needsRelocation() ? - hasExecutableOat() == (isDex2OatEnabled() || isRelocationDeltaZero()) : + hasExecutableOat() == isRelocationDeltaZero() : hasExecutableOat() == true); System.out.println( - "dex2oat & patchoat are " + ((isDex2OatEnabled()) ? "enabled" : "disabled") + - ", has oat is " + hasOatFile() + ", has executable oat is " + ( + "Has oat is " + hasOatFile() + ", has executable oat is " + ( executable_correct ? "expected" : "not expected") + "."); - if (!hasOatFile() && isDex2OatEnabled()) { - throw new Error("Application with dex2oat enabled runs without an oat file"); - } - System.out.println(functionCall()); } @@ -47,8 +42,6 @@ public class Main { return ret.substring(0, ret.length() - 1); } - private native static boolean isDex2OatEnabled(); - private native static boolean needsRelocation(); private native static boolean hasOatFile(); diff --git a/test/118-noimage-dex2oat/run b/test/118-noimage-dex2oat/run index e1e2577ae3..d68b0a0b2c 100644 --- a/test/118-noimage-dex2oat/run +++ b/test/118-noimage-dex2oat/run @@ -47,12 +47,12 @@ bpath_arg="--runtime-option -Xbootclasspath:${bpath}" # Make sure we can run without an oat file. echo "Run -Xnoimage-dex2oat" -${RUN} ${flags} ${bpath_arg} --runtime-option -Xnoimage-dex2oat --runtime-option -Xnodex2oat +${RUN} ${flags} ${bpath_arg} --runtime-option -Xnoimage-dex2oat return_status1=$? # Make sure we cannot run without an oat file without fallback. echo "Run -Xnoimage-dex2oat -Xno-dex-file-fallback" -${RUN} ${flags} ${bpath_arg} --runtime-option -Xnoimage-dex2oat --runtime-option -Xnodex2oat \ +${RUN} ${flags} ${bpath_arg} --runtime-option -Xnoimage-dex2oat \ --runtime-option -Xno-dex-file-fallback return_status2=$? diff --git a/test/134-nodex2oat-nofallback/run b/test/134-nodex2oat-nofallback/run index 33265ac471..359d22dfa0 100755 --- a/test/134-nodex2oat-nofallback/run +++ b/test/134-nodex2oat-nofallback/run @@ -17,6 +17,6 @@ flags="${@}" # Make sure we cannot run without an oat file without fallback. -${RUN} ${flags} --runtime-option -Xnodex2oat --runtime-option -Xno-dex-file-fallback +${RUN} ${flags} --runtime-option -Xno-dex-file-fallback # Suppress the exit value. This isn't expected to be successful. echo "Exit status:" $? diff --git a/test/134-nodex2oat-nofallback/src/Main.java b/test/134-nodex2oat-nofallback/src/Main.java index 086ffb9295..73f67c4e38 100644 --- a/test/134-nodex2oat-nofallback/src/Main.java +++ b/test/134-nodex2oat-nofallback/src/Main.java @@ -17,17 +17,8 @@ public class Main { public static void main(String[] args) { System.loadLibrary(args[0]); - System.out.println( - "Has oat is " + hasOat() + ", is dex2oat enabled is " + isDex2OatEnabled() + "."); - - if (hasOat() && !isDex2OatEnabled()) { - throw new Error("Application with dex2oat disabled runs with an oat file"); - } else if (!hasOat() && isDex2OatEnabled()) { - throw new Error("Application with dex2oat enabled runs without an oat file"); - } + System.out.println("Has oat is " + hasOat()); } private native static boolean hasOat(); - - private native static boolean isDex2OatEnabled(); } diff --git a/test/138-duplicate-classes-check2/run b/test/138-duplicate-classes-check2/run deleted file mode 100755 index 8494ad9aad..0000000000 --- a/test/138-duplicate-classes-check2/run +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -# -# Copyright (C) 2015 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. - -# We want to run as no-dex-file-fallback to confirm that even though the -ex file has a symbolic -# reference to A, there's no class-def, so we don't detect a collision. -exec ${RUN} --runtime-option -Xno-dex-file-fallback "${@}" diff --git a/test/147-stripped-dex-fallback/run b/test/147-stripped-dex-fallback/run index 37c3e1fd88..1f1d22e64e 100755 --- a/test/147-stripped-dex-fallback/run +++ b/test/147-stripped-dex-fallback/run @@ -21,4 +21,4 @@ if [[ "${flags}" == *--no-prebuild* ]] ; then exit 1 fi -${RUN} ${flags} --strip-dex --runtime-option -Xnodex2oat +${RUN} ${flags} --strip-dex diff --git a/test/667-jit-jni-stub/run b/test/667-jit-jni-stub/run index f235c6bc90..b7ce9132ab 100755 --- a/test/667-jit-jni-stub/run +++ b/test/667-jit-jni-stub/run @@ -16,4 +16,4 @@ # Disable AOT compilation of JNI stubs. # Ensure this test is not subject to unexpected code collection. -${RUN} "${@}" --no-prebuild --no-dex2oat --runtime-option -Xjitinitialsize:32M +${RUN} "${@}" --no-prebuild --runtime-option -Xjitinitialsize:32M diff --git a/test/667-jit-jni-stub/src/Main.java b/test/667-jit-jni-stub/src/Main.java index 794308d6e1..234c5daf4c 100644 --- a/test/667-jit-jni-stub/src/Main.java +++ b/test/667-jit-jni-stub/src/Main.java @@ -18,7 +18,7 @@ public class Main { public static void main(String[] args) throws Exception { System.loadLibrary(args[0]); if (isAotCompiled(Main.class, "hasJit")) { - throw new Error("This test must be run with --no-prebuild --no-dex2oat!"); + throw new Error("This test must be run with --no-prebuild!"); } if (!hasJit()) { return; diff --git a/test/677-fsi/expected.txt b/test/677-fsi/expected.txt index c7fb8fed77..2b073430b6 100644 --- a/test/677-fsi/expected.txt +++ b/test/677-fsi/expected.txt @@ -1,3 +1,2 @@ oat file has dex code, but APK has uncompressed dex code -oat file has dex code, but APK has uncompressed dex code Hello World diff --git a/test/677-fsi2/expected.txt b/test/677-fsi2/expected.txt index de008470fe..557db03de9 100644 --- a/test/677-fsi2/expected.txt +++ b/test/677-fsi2/expected.txt @@ -1,4 +1 @@ -Run default -Hello World -Run without dex2oat Hello World diff --git a/test/677-fsi2/run b/test/677-fsi2/run index 039a6a78f0..651f082863 100644 --- a/test/677-fsi2/run +++ b/test/677-fsi2/run @@ -14,12 +14,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -echo "Run default" ${RUN} $@ --runtime-option -Xonly-use-system-oat-files -return_status1=$? - -echo "Run without dex2oat" -${RUN} $@ --no-dex2oat --runtime-option -Xonly-use-system-oat-files -return_status2=$? - -(exit $return_status1) && (exit $return_status2) diff --git a/test/common/runtime_state.cc b/test/common/runtime_state.cc index 9344b24b5d..da79164f12 100644 --- a/test/common/runtime_state.cc +++ b/test/common/runtime_state.cc @@ -71,13 +71,6 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_runtimeIsSoftFail(JNIEnv* env AT return Runtime::Current()->IsVerificationSoftFail() ? JNI_TRUE : JNI_FALSE; } -// public static native boolean isDex2OatEnabled(); - -extern "C" JNIEXPORT jboolean JNICALL Java_Main_isDex2OatEnabled(JNIEnv* env ATTRIBUTE_UNUSED, - jclass cls ATTRIBUTE_UNUSED) { - return Runtime::Current()->IsDex2OatEnabled(); -} - // public static native boolean hasImage(); extern "C" JNIEXPORT jboolean JNICALL Java_Main_hasImage(JNIEnv* env ATTRIBUTE_UNUSED, diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar index 6555b46c0d..bd58ae37ec 100755 --- a/test/etc/run-test-jar +++ b/test/etc/run-test-jar @@ -59,7 +59,7 @@ USE_JVMTI="n" VERIFY="y" # y=yes,n=no,s=softfail ZYGOTE="" DEX_VERIFY="" -USE_DEX2OAT_AND_PATCHOAT="y" +USE_PATCHOAT="y" INSTRUCTION_SET_FEATURES="" ARGS="" EXTERNAL_LOG_TAGS="n" # if y respect externally set ANDROID_LOG_TAGS. @@ -166,14 +166,9 @@ while true; do shift BOOT_IMAGE="$1" shift - elif [ "x$1" = "x--no-dex2oat" ]; then - DEX2OAT="-Xcompiler:${FALSE_BIN}" - USE_DEX2OAT_AND_PATCHOAT="n" - PREBUILD="n" # Do not use prebuilt odex, either. - shift elif [ "x$1" = "x--no-patchoat" ]; then PATCHOAT="-Xpatchoat:${FALSE_BIN}" - USE_DEX2OAT_AND_PATCHOAT="n" + USE_PATCHOAT="n" shift elif [ "x$1" = "x--relocate" ]; then RELOCATE="y" @@ -813,7 +808,7 @@ RUN_TEST_ASAN_OPTIONS="${RUN_TEST_ASAN_OPTIONS}detect_leaks=0" if [ "$EXTERNAL_LOG_TAGS" = "n" ]; then if [ "$DEV_MODE" = "y" ]; then export ANDROID_LOG_TAGS='*:d' - elif [ "$USE_DEX2OAT_AND_PATCHOAT" = "n" ]; then + elif [ "$USE_PATCHOAT" = "n" ]; then # All tests would log the error of failing dex2oat/patchoat. Be silent here and only # log fatal events. export ANDROID_LOG_TAGS='*:s' diff --git a/test/knownfailures.json b/test/knownfailures.json index f71e9363cb..0a179c7093 100644 --- a/test/knownfailures.json +++ b/test/knownfailures.json @@ -76,7 +76,7 @@ }, { "tests" : "629-vdex-speed", - "variant": "interp-ac | no-dex2oat | interpreter | jit | relocate-npatchoat", + "variant": "interp-ac | interpreter | jit | relocate-npatchoat", "description": "629 requires compilation." }, { @@ -163,7 +163,7 @@ }, { "tests": "147-stripped-dex-fallback", - "variant": "no-dex2oat | no-image | relocate-npatchoat", + "variant": "no-image | relocate-npatchoat", "description": ["147-stripped-dex-fallback is disabled because it", "requires --prebuild."] }, @@ -174,7 +174,7 @@ "119-noimage-patchoat", "137-cfi", "138-duplicate-classes-check2"], - "variant": "no-dex2oat | no-image | relocate-npatchoat", + "variant": "no-image | relocate-npatchoat", "description": ["All these tests check that we have sane behavior if we", "don't have a patchoat or dex2oat. Therefore we", "shouldn't run them in situations where we actually", @@ -649,9 +649,9 @@ }, { "tests": "660-clinit", - "variant": "no-image | no-dex2oat | no-prebuild | jvmti-stress | redefine-stress", + "variant": "no-image | no-prebuild | jvmti-stress | redefine-stress", "description": ["Tests <clinit> for app images, which --no-image, --no-prebuild, ", - "--no-dex2oat, and --redefine-stress do not create"] + "and --redefine-stress do not create"] }, { "tests": ["961-default-iface-resolution-gen", @@ -674,7 +674,7 @@ }, { "tests": "661-oat-writer-layout", - "variant": "interp-ac | interpreter | jit | no-dex2oat | no-prebuild | no-image | trace | redefine-stress | jvmti-stress", + "variant": "interp-ac | interpreter | jit | no-prebuild | no-image | trace | redefine-stress | jvmti-stress", "description": ["Test is designed to only check --compiler-filter=speed"] }, { @@ -1010,7 +1010,7 @@ }, { "tests": "677-fsi", - "variant": "no-dex2oat | no-image | no-prebuild | relocate-npatchoat | jvm", + "variant": "no-image | no-prebuild | relocate-npatchoat | jvm", "description": ["Test requires a successful dex2oat invocation"] }, { diff --git a/test/run-test b/test/run-test index d90eccdf75..ef173026c1 100755 --- a/test/run-test +++ b/test/run-test @@ -148,7 +148,6 @@ jvmti_redefine_stress="false" strace="false" always_clean="no" never_clean="no" -have_dex2oat="yes" have_patchoat="yes" have_image="yes" multi_image_suffix="" @@ -195,9 +194,6 @@ while true; do lib="libdvm.so" runtime="dalvik" shift - elif [ "x$1" = "x--no-dex2oat" ]; then - have_dex2oat="no" - shift elif [ "x$1" = "x--no-patchoat" ]; then have_patchoat="no" shift @@ -580,10 +576,6 @@ if [ "$have_patchoat" = "no" ]; then run_args="${run_args} --no-patchoat" fi -if [ "$have_dex2oat" = "no" ]; then - run_args="${run_args} --no-dex2oat" -fi - if [ ! "$runtime" = "jvm" ]; then run_args="${run_args} --lib $lib" fi @@ -639,11 +631,6 @@ if [ "$bisection_search" = "yes" -a "$prebuild_mode" = "yes" ]; then usage="yes" fi -if [ "$bisection_search" = "yes" -a "$have_dex2oat" = "no" ]; then - err_echo "--bisection-search and --no-dex2oat are mutually exclusive" - usage="yes" -fi - if [ "$bisection_search" = "yes" -a "$have_patchoat" = "no" ]; then err_echo "--bisection-search and --no-patchoat are mutually exclusive" usage="yes" diff --git a/test/testrunner/target_config.py b/test/testrunner/target_config.py index 47b1e4e261..84490bf0e4 100644 --- a/test/testrunner/target_config.py +++ b/test/testrunner/target_config.py @@ -184,7 +184,7 @@ target_config = { 'run-test' : ['--relocate-npatchoat'] }, 'art-no-dex2oat' : { - 'run-test' : ['--no-dex2oat'] + # Deprecated configuration. }, 'art-heap-poisoning' : { 'run-test' : ['--interpreter', diff --git a/test/testrunner/testrunner.py b/test/testrunner/testrunner.py index e8d4290d28..10c8619307 100755 --- a/test/testrunner/testrunner.py +++ b/test/testrunner/testrunner.py @@ -145,7 +145,7 @@ def gather_test_info(): VARIANT_TYPE_DICT['image'] = {'picimage', 'no-image', 'multipicimage'} VARIANT_TYPE_DICT['debuggable'] = {'ndebuggable', 'debuggable'} VARIANT_TYPE_DICT['gc'] = {'gcstress', 'gcverify', 'cms'} - VARIANT_TYPE_DICT['prebuild'] = {'no-prebuild', 'no-dex2oat', 'prebuild'} + VARIANT_TYPE_DICT['prebuild'] = {'no-prebuild', 'prebuild'} VARIANT_TYPE_DICT['cdex_level'] = {'cdex-none', 'cdex-fast'} VARIANT_TYPE_DICT['relocate'] = {'relocate-npatchoat', 'relocate', 'no-relocate'} VARIANT_TYPE_DICT['jni'] = {'jni', 'forcecopy', 'checkjni'} @@ -414,8 +414,6 @@ def run_tests(tests): options_test += ' --prebuild' elif prebuild == 'no-prebuild': options_test += ' --no-prebuild' - elif prebuild == 'no-dex2oat': - options_test += ' --no-prebuild --no-dex2oat' if cdex_level: # Add option and remove the cdex- prefix. |