Add a preloaded-classes-fds argument to dex2oat.
odrefresh passes files as fds.
Test: m
Bug: 162110941
Change-Id: I84cac774e66442268159e732e6313f8c77a061d2
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 57b81b6..f5c6bc9 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -823,6 +823,10 @@
Usage("--dirty-image-objects and --dirty-image-objects-fd should not be both specified");
}
+ if (!preloaded_classes_files_.empty() && !preloaded_classes_fds_.empty()) {
+ Usage("--preloaded-classes and --preloaded-classes-fds should not be both specified");
+ }
+
if (!cpu_set_.empty()) {
SetCpuAffinity(cpu_set_);
}
@@ -1071,6 +1075,7 @@
AssignIfExists(args, M::Profile, &profile_files_);
AssignIfExists(args, M::ProfileFd, &profile_file_fds_);
AssignIfExists(args, M::PreloadedClasses, &preloaded_classes_files_);
+ AssignIfExists(args, M::PreloadedClassesFds, &preloaded_classes_fds_);
AssignIfExists(args, M::RuntimeOptions, &runtime_args_);
AssignIfExists(args, M::SwapFile, &swap_file_name_);
AssignIfExists(args, M::SwapFileFd, &swap_fd_);
@@ -2526,11 +2531,15 @@
}
bool PreparePreloadedClasses() {
- preloaded_classes_.reset(new HashSet<std::string>());
- for (const std::string& file : preloaded_classes_files_) {
- ReadCommentedInputFromFile<HashSet<std::string>>(file.c_str(),
- nullptr,
- preloaded_classes_.get());
+ preloaded_classes_ = std::make_unique<HashSet<std::string>>();
+ if (!preloaded_classes_fds_.empty()) {
+ for (int fd : preloaded_classes_fds_) {
+ ReadCommentedInputFromFd(fd, nullptr, preloaded_classes_.get());
+ }
+ } else {
+ for (const std::string& file : preloaded_classes_files_) {
+ ReadCommentedInputFromFile(file.c_str(), nullptr, preloaded_classes_.get());
+ }
}
return true;
}
@@ -2774,18 +2783,24 @@
ReadCommentedInputStream<T>(input_file.get(), process, output);
}
+ template <typename T>
+ static void ReadCommentedInputFromFd(
+ int input_fd, std::function<std::string(const char*)>* process, T* output) {
+ auto input_file = std::unique_ptr<FILE, decltype(&fclose)>{fdopen(input_fd, "r"), fclose};
+ if (!input_file) {
+ LOG(ERROR) << "Failed to re-open input fd from /prof/self/fd/" << input_fd;
+ return;
+ }
+ ReadCommentedInputStream<T>(input_file.get(), process, output);
+ }
+
// Read lines from the given file, dropping comments and empty lines. Post-process each line with
// the given function.
template <typename T>
static std::unique_ptr<T> ReadCommentedInputFromFile(
const char* input_filename, std::function<std::string(const char*)>* process) {
- auto input_file = std::unique_ptr<FILE, decltype(&fclose)>{fopen(input_filename, "r"), fclose};
- if (!input_file) {
- LOG(ERROR) << "Failed to open input file " << input_filename;
- return nullptr;
- }
std::unique_ptr<T> output(new T());
- ReadCommentedInputStream<T>(input_file.get(), process, output.get());
+ ReadCommentedInputFromFile(input_filename, process, output.get());
return output;
}
@@ -2794,13 +2809,8 @@
template <typename T>
static std::unique_ptr<T> ReadCommentedInputFromFd(
int input_fd, std::function<std::string(const char*)>* process) {
- auto input_file = std::unique_ptr<FILE, decltype(&fclose)>{fdopen(input_fd, "r"), fclose};
- if (!input_file) {
- LOG(ERROR) << "Failed to re-open input fd from /prof/self/fd/" << input_fd;
- return nullptr;
- }
std::unique_ptr<T> output(new T());
- ReadCommentedInputStream<T>(input_file.get(), process, output.get());
+ ReadCommentedInputFromFd(input_fd, process, output.get());
return output;
}
@@ -2950,6 +2960,7 @@
std::vector<std::string> profile_files_;
std::vector<int> profile_file_fds_;
std::vector<std::string> preloaded_classes_files_;
+ std::vector<int> preloaded_classes_fds_;
std::unique_ptr<ProfileCompilationInfo> profile_compilation_info_;
TimingLogger* timings_;
std::vector<std::vector<const DexFile*>> dex_files_per_oat_file_;
diff --git a/dex2oat/dex2oat_options.cc b/dex2oat/dex2oat_options.cc
index e8439cc..1f9138e 100644
--- a/dex2oat/dex2oat_options.cc
+++ b/dex2oat/dex2oat_options.cc
@@ -259,7 +259,11 @@
.Define("--preloaded-classes=_")
.WithType<std::vector<std::string>>().AppendValues()
.WithHelp("Specify files containing list of classes preloaded in the zygote.")
- .IntoKey(M::PreloadedClasses);
+ .IntoKey(M::PreloadedClasses)
+ .Define("--preloaded-classes-fds=_")
+ .WithType<std::vector<int>>().AppendValues()
+ .WithHelp("Specify files containing list of classes preloaded in the zygote.")
+ .IntoKey(M::PreloadedClassesFds);
}
static void AddTargetMappings(Builder& builder) {
diff --git a/dex2oat/dex2oat_options.def b/dex2oat/dex2oat_options.def
index 2b47735..7c071dc 100644
--- a/dex2oat/dex2oat_options.def
+++ b/dex2oat/dex2oat_options.def
@@ -104,5 +104,6 @@
DEX2OAT_OPTIONS_KEY (std::string, ApexVersions)
DEX2OAT_OPTIONS_KEY (Unit, ForcePaletteCompilationHooks)
DEX2OAT_OPTIONS_KEY (std::vector<std::string>, PreloadedClasses)
+DEX2OAT_OPTIONS_KEY (std::vector<int>, PreloadedClassesFds)
#undef DEX2OAT_OPTIONS_KEY
diff --git a/odrefresh/odrefresh.cc b/odrefresh/odrefresh.cc
index 2455772..1d12b94 100644
--- a/odrefresh/odrefresh.cc
+++ b/odrefresh/odrefresh.cc
@@ -1348,6 +1348,15 @@
LOG(WARNING) << "Missing dirty objects file : " << QuotePath(dirty_image_objects_file);
}
+ const std::string preloaded_classes_file(GetAndroidRoot() + "/etc/preloaded-classes");
+ if (OS::FileExists(preloaded_classes_file.c_str())) {
+ std::unique_ptr<File> file(OS::OpenFileForReading(preloaded_classes_file.c_str()));
+ args.emplace_back(android::base::StringPrintf("--preloaded-classes-fds=%d", file->Fd()));
+ readonly_files_raii.push_back(std::move(file));
+ } else {
+ LOG(WARNING) << "Missing preloaded classes file : " << QuotePath(preloaded_classes_file);
+ }
+
// Add boot classpath jars to compile.
std::vector<std::string> jars_to_compile = boot_classpath_compilable_jars_;
if (minimal) {