summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2019-01-10 13:10:36 +0000
committer Nicolas Geoffray <ngeoffray@google.com> 2019-01-10 13:10:36 +0000
commit35de14bff67555a41ffcc0998a6c177cdaf25439 (patch)
tree5a45ec746dc7e00be9382a8367dd8d471e5e113f
parentddcc8c4860f0c513d5e7733d1805ff8830ed057d (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.cc21
-rw-r--r--dexoptanalyzer/dexoptanalyzer_test.cc30
-rw-r--r--runtime/dexopt_test.cc11
-rw-r--r--runtime/dexopt_test.h6
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).