diff options
author | 2019-01-10 13:10:36 +0000 | |
---|---|---|
committer | 2019-01-10 13:10:36 +0000 | |
commit | 35de14bff67555a41ffcc0998a6c177cdaf25439 (patch) | |
tree | 5a45ec746dc7e00be9382a8367dd8d471e5e113f | |
parent | ddcc8c4860f0c513d5e7733d1805ff8830ed057d (diff) |
Create the class loader context within a Runtime scope.
Otherwise, we would delete the maps owned by the class loader context
*after* deleting the runtime, which is a destruction order violation
as the runtime owns the map lock.
bug: 122475825
Test: dexoptanalyzer_test
Change-Id: Ia81b0720e3178a71f143a524b61e3e63e5973e16
-rw-r--r-- | dexoptanalyzer/dexoptanalyzer.cc | 21 | ||||
-rw-r--r-- | dexoptanalyzer/dexoptanalyzer_test.cc | 30 | ||||
-rw-r--r-- | runtime/dexopt_test.cc | 11 | ||||
-rw-r--r-- | runtime/dexopt_test.h | 6 |
4 files changed, 53 insertions, 15 deletions
diff --git a/dexoptanalyzer/dexoptanalyzer.cc b/dexoptanalyzer/dexoptanalyzer.cc index acf0f94572..92850f7590 100644 --- a/dexoptanalyzer/dexoptanalyzer.cc +++ b/dexoptanalyzer/dexoptanalyzer.cc @@ -202,11 +202,7 @@ class DexoptAnalyzer final { Usage("Invalid --zip-fd %d", zip_fd_); } } else if (option.starts_with("--class-loader-context=")) { - std::string context_str = option.substr(strlen("--class-loader-context=")).ToString(); - class_loader_context_ = ClassLoaderContext::Create(context_str); - if (class_loader_context_ == nullptr) { - Usage("Invalid --class-loader-context '%s'", context_str.c_str()); - } + context_str_ = option.substr(strlen("--class-loader-context=")).ToString(); } else { Usage("Unknown argument '%s'", option.data()); } @@ -264,6 +260,17 @@ class DexoptAnalyzer final { } std::unique_ptr<Runtime> runtime(Runtime::Current()); + // Only when the runtime is created can we create the class loader context: the + // class loader context will open dex file and use the MemMap global lock that the + // runtime owns. + std::unique_ptr<ClassLoaderContext> class_loader_context; + if (!context_str_.empty()) { + class_loader_context = ClassLoaderContext::Create(context_str_); + if (class_loader_context == nullptr) { + Usage("Invalid --class-loader-context '%s'", context_str_.c_str()); + } + } + std::unique_ptr<OatFileAssistant> oat_file_assistant; oat_file_assistant = std::make_unique<OatFileAssistant>(dex_file_.c_str(), isa_, @@ -279,7 +286,7 @@ class DexoptAnalyzer final { } int dexoptNeeded = oat_file_assistant->GetDexOptNeeded( - compiler_filter_, assume_profile_changed_, downgrade_, class_loader_context_.get()); + compiler_filter_, assume_profile_changed_, downgrade_, class_loader_context.get()); // Convert OatFileAssitant codes to dexoptanalyzer codes. switch (dexoptNeeded) { @@ -300,7 +307,7 @@ class DexoptAnalyzer final { std::string dex_file_; InstructionSet isa_; CompilerFilter::Filter compiler_filter_; - std::unique_ptr<ClassLoaderContext> class_loader_context_; + std::string context_str_; bool assume_profile_changed_; bool downgrade_; std::string image_; diff --git a/dexoptanalyzer/dexoptanalyzer_test.cc b/dexoptanalyzer/dexoptanalyzer_test.cc index f6fd1fb014..7b6b36c133 100644 --- a/dexoptanalyzer/dexoptanalyzer_test.cc +++ b/dexoptanalyzer/dexoptanalyzer_test.cc @@ -36,7 +36,8 @@ class DexoptAnalyzerTest : public DexoptTest { int Analyze(const std::string& dex_file, CompilerFilter::Filter compiler_filter, - bool assume_profile_changed) { + bool assume_profile_changed, + const std::string& class_loader_context) { std::string dexoptanalyzer_cmd = GetDexoptAnalyzerCmd(); std::vector<std::string> argv_str; argv_str.push_back(dexoptanalyzer_cmd); @@ -52,6 +53,9 @@ class DexoptAnalyzerTest : public DexoptTest { argv_str.push_back(GetClassPathOption("-Xbootclasspath-locations:", GetLibCoreDexLocations())); argv_str.push_back("--image=" + GetImageLocation()); argv_str.push_back("--android-data=" + android_data_); + if (!class_loader_context.empty()) { + argv_str.push_back("--class-loader-context=" + class_loader_context); + } std::string error; return ExecAndReturnCode(argv_str, &error); @@ -74,8 +78,10 @@ class DexoptAnalyzerTest : public DexoptTest { void Verify(const std::string& dex_file, CompilerFilter::Filter compiler_filter, bool assume_profile_changed = false, - bool downgrade = false) { - int dexoptanalyzerResult = Analyze(dex_file, compiler_filter, assume_profile_changed); + bool downgrade = false, + const std::string& class_loader_context = "") { + int dexoptanalyzerResult = Analyze( + dex_file, compiler_filter, assume_profile_changed, class_loader_context); dexoptanalyzerResult = DexoptanalyzerToOatFileAssistant(dexoptanalyzerResult); OatFileAssistant oat_file_assistant(dex_file.c_str(), kRuntimeISA, /*load_executable=*/ false); int assistantResult = oat_file_assistant.GetDexOptNeeded( @@ -305,4 +311,22 @@ TEST_F(DexoptAnalyzerTest, ShortDexLocation) { Verify(dex_location, CompilerFilter::kSpeed); } +// Case: We have a DEX file and up-to-date OAT file for it, and we check with +// a class loader context. +TEST_F(DexoptAnalyzerTest, ClassLoaderContext) { + std::string dex_location1 = GetScratchDir() + "/DexToAnalyze.jar"; + std::string odex_location1 = GetOdexDir() + "/DexToAnalyze.odex"; + std::string dex_location2 = GetScratchDir() + "/DexInContext.jar"; + Copy(GetDexSrc1(), dex_location1); + Copy(GetDexSrc2(), dex_location2); + + std::string class_loader_context = "PCL[" + dex_location2 + "]"; + std::string class_loader_context_option = "--class-loader-context=PCL[" + dex_location2 + "]"; + + // Generate the odex to get the class loader context also open the dex files. + GenerateOdexForTest(dex_location1, odex_location1, CompilerFilter::kSpeed, /* compilation_reason= */ nullptr, /* extra_args= */ { class_loader_context_option }); + + Verify(dex_location1, CompilerFilter::kSpeed, false, false, class_loader_context); +} + } // namespace art diff --git a/runtime/dexopt_test.cc b/runtime/dexopt_test.cc index 7f697d1eb8..9c0ac8fc54 100644 --- a/runtime/dexopt_test.cc +++ b/runtime/dexopt_test.cc @@ -72,7 +72,8 @@ void DexoptTest::GenerateOatForTest(const std::string& dex_location, const std::string& oat_location, CompilerFilter::Filter filter, bool with_alternate_image, - const char* compilation_reason) { + const char* compilation_reason, + const std::vector<std::string>& extra_args) { std::string dalvik_cache = GetDalvikCache(GetInstructionSetString(kRuntimeISA)); std::string dalvik_cache_tmp = dalvik_cache + ".redirected"; @@ -101,6 +102,8 @@ void DexoptTest::GenerateOatForTest(const std::string& dex_location, args.push_back("--compilation-reason=" + std::string(compilation_reason)); } + args.insert(args.end(), extra_args.begin(), extra_args.end()); + std::string error_msg; ASSERT_TRUE(Dex2Oat(args, &error_msg)) << error_msg; @@ -136,12 +139,14 @@ void DexoptTest::GenerateOatForTest(const std::string& dex_location, void DexoptTest::GenerateOdexForTest(const std::string& dex_location, const std::string& odex_location, CompilerFilter::Filter filter, - const char* compilation_reason) { + const char* compilation_reason, + const std::vector<std::string>& extra_args) { GenerateOatForTest(dex_location, odex_location, filter, /*with_alternate_image=*/ false, - compilation_reason); + compilation_reason, + extra_args); } void DexoptTest::GenerateOatForTest(const char* dex_location, diff --git a/runtime/dexopt_test.h b/runtime/dexopt_test.h index efbdcbaa07..026fe55131 100644 --- a/runtime/dexopt_test.h +++ b/runtime/dexopt_test.h @@ -42,13 +42,15 @@ class DexoptTest : public Dex2oatEnvironmentTest { const std::string& oat_location, CompilerFilter::Filter filter, bool with_alternate_image, - const char* compilation_reason = nullptr); + const char* compilation_reason = nullptr, + const std::vector<std::string>& extra_args = {}); // Generate an odex file for the purposes of test. void GenerateOdexForTest(const std::string& dex_location, const std::string& odex_location, CompilerFilter::Filter filter, - const char* compilation_reason = nullptr); + const char* compilation_reason = nullptr, + const std::vector<std::string>& extra_args = {}); // Generate an oat file for the given dex location in its oat location (under // the dalvik cache). |