Merge "Create the class loader context within a Runtime scope."
diff --git a/dexoptanalyzer/dexoptanalyzer.cc b/dexoptanalyzer/dexoptanalyzer.cc
index acf0f94..92850f7 100644
--- a/dexoptanalyzer/dexoptanalyzer.cc
+++ b/dexoptanalyzer/dexoptanalyzer.cc
@@ -202,11 +202,7 @@
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 @@
}
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 @@
}
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 @@
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 f6fd1fb..7b6b36c 100644
--- a/dexoptanalyzer/dexoptanalyzer_test.cc
+++ b/dexoptanalyzer/dexoptanalyzer_test.cc
@@ -36,7 +36,8 @@
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 @@
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 @@
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 @@
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 7f697d1..9c0ac8f 100644
--- a/runtime/dexopt_test.cc
+++ b/runtime/dexopt_test.cc
@@ -72,7 +72,8 @@
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 @@
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::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 efbdcba..026fe55 100644
--- a/runtime/dexopt_test.h
+++ b/runtime/dexopt_test.h
@@ -42,13 +42,15 @@
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).