Transfer ClassLoaderContext to the caller of OatFileAssistant::Create.
mast@ pointed out that the owned object adds complexity to
OatFileAssistant. Full discussion here: ag/19066608.
Bug: 229268202
Test: m test-art-host-gtest-art_runtime_tests
Change-Id: Iadcd5f5f090808d8dbbb6449ba9fc32832d99756
Merged-In: Ia8f320d1375985bbb6239822a90e6f95a9774bb5
diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc
index f7c9e03..b69d2af 100644
--- a/runtime/oat_file_assistant.cc
+++ b/runtime/oat_file_assistant.cc
@@ -242,22 +242,23 @@
bool load_executable,
bool only_load_trusted_executable,
std::unique_ptr<RuntimeOptions> runtime_options,
- std::string* error_msg) {
+ /*out*/ std::unique_ptr<ClassLoaderContext>* context,
+ /*out*/ std::string* error_msg) {
InstructionSet isa = GetInstructionSetFromString(isa_str.c_str());
if (isa == InstructionSet::kNone) {
*error_msg = StringPrintf("Instruction set '%s' is invalid", isa_str.c_str());
return nullptr;
}
- std::unique_ptr<ClassLoaderContext> context = ClassLoaderContext::Create(context_str.c_str());
- if (context == nullptr) {
+ std::unique_ptr<ClassLoaderContext> tmp_context = ClassLoaderContext::Create(context_str.c_str());
+ if (tmp_context == nullptr) {
*error_msg = StringPrintf("Class loader context '%s' is invalid", context_str.c_str());
return nullptr;
}
- if (!context->OpenDexFiles(android::base::Dirname(filename.c_str()),
- /*context_fds=*/{},
- /*only_read_checksums=*/true)) {
+ if (!tmp_context->OpenDexFiles(android::base::Dirname(filename.c_str()),
+ /*context_fds=*/{},
+ /*only_read_checksums=*/true)) {
*error_msg =
StringPrintf("Failed to load class loader context files for '%s' with context '%s'",
filename.c_str(),
@@ -267,12 +268,12 @@
auto assistant = std::make_unique<OatFileAssistant>(filename.c_str(),
isa,
- context.get(),
+ tmp_context.get(),
load_executable,
only_load_trusted_executable,
std::move(runtime_options));
- assistant->owned_context_ = std::move(context);
+ *context = std::move(tmp_context);
return assistant;
}
diff --git a/runtime/oat_file_assistant.h b/runtime/oat_file_assistant.h
index 1198832..abbd896 100644
--- a/runtime/oat_file_assistant.h
+++ b/runtime/oat_file_assistant.h
@@ -157,15 +157,18 @@
int zip_fd);
// A convenient factory function that accepts ISA, class loader context, and compiler filter in
- // strings. Returns the created instance on success, or returns nullptr and outputs an error
- // message if it fails to parse the input strings.
- static std::unique_ptr<OatFileAssistant> Create(const std::string& filename,
- const std::string& isa_str,
- const std::string& context_str,
- bool load_executable,
- bool only_load_trusted_executable,
- std::unique_ptr<RuntimeOptions> runtime_options,
- std::string* error_msg);
+ // strings. Returns the created instance and ClassLoaderContext on success, or returns nullptr and
+ // outputs an error message if it fails to parse the input strings.
+ // The returned ClassLoaderContext must live at least as long as the OatFileAssistant.
+ static std::unique_ptr<OatFileAssistant> Create(
+ const std::string& filename,
+ const std::string& isa_str,
+ const std::string& context_str,
+ bool load_executable,
+ bool only_load_trusted_executable,
+ std::unique_ptr<RuntimeOptions> runtime_options,
+ /*out*/ std::unique_ptr<ClassLoaderContext>* context,
+ /*out*/ std::string* error_msg);
// Returns true if the dex location refers to an element of the boot class
// path.
@@ -471,7 +474,6 @@
std::string dex_location_;
ClassLoaderContext* context_;
- std::unique_ptr<ClassLoaderContext> owned_context_;
// Whether or not the parent directory of the dex file is writable.
bool dex_parent_writable_ = false;
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index e414e4e..87fe2cb 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -1785,6 +1785,7 @@
auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+ std::unique_ptr<ClassLoaderContext> context;
std::string error_msg;
std::unique_ptr<OatFileAssistant> oat_file_assistant =
OatFileAssistant::Create(dex_location,
@@ -1793,6 +1794,7 @@
/*load_executable=*/false,
/*only_load_trusted_executable=*/true,
MaybeCreateRuntimeOptions(),
+ &context,
&error_msg);
ASSERT_NE(oat_file_assistant, nullptr);
@@ -1808,6 +1810,7 @@
auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+ std::unique_ptr<ClassLoaderContext> context;
std::string error_msg;
EXPECT_EQ(OatFileAssistant::Create(dex_location,
/*isa_str=*/"foo",
@@ -1815,6 +1818,7 @@
/*load_executable=*/false,
/*only_load_trusted_executable=*/true,
MaybeCreateRuntimeOptions(),
+ &context,
&error_msg),
nullptr);
EXPECT_EQ(error_msg, "Instruction set 'foo' is invalid");
@@ -1828,6 +1832,7 @@
auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+ std::unique_ptr<ClassLoaderContext> context;
std::string error_msg;
EXPECT_EQ(OatFileAssistant::Create(dex_location,
GetInstructionSetString(kRuntimeISA),
@@ -1835,6 +1840,7 @@
/*load_executable=*/false,
/*only_load_trusted_executable=*/true,
MaybeCreateRuntimeOptions(),
+ &context,
&error_msg),
nullptr);
EXPECT_EQ(error_msg, "Class loader context 'foo' is invalid");
@@ -1853,6 +1859,7 @@
auto scoped_maybe_without_runtime = ScopedMaybeWithoutRuntime();
+ std::unique_ptr<ClassLoaderContext> context;
std::string error_msg;
EXPECT_EQ(OatFileAssistant::Create(dex_location,
GetInstructionSetString(kRuntimeISA),
@@ -1860,6 +1867,7 @@
/*load_executable=*/false,
/*only_load_trusted_executable=*/true,
MaybeCreateRuntimeOptions(),
+ &context,
&error_msg),
nullptr);
EXPECT_EQ(error_msg,