diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 57b81b6609..f5c6bc9b51 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -823,6 +823,10 @@ class Dex2Oat final { 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 @@ class Dex2Oat final { 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 @@ class Dex2Oat final { } bool PreparePreloadedClasses() { - preloaded_classes_.reset(new HashSet()); - for (const std::string& file : preloaded_classes_files_) { - ReadCommentedInputFromFile>(file.c_str(), - nullptr, - preloaded_classes_.get()); + preloaded_classes_ = std::make_unique>(); + 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 @@ class Dex2Oat final { ReadCommentedInputStream(input_file.get(), process, output); } + template + static void ReadCommentedInputFromFd( + int input_fd, std::function* process, T* output) { + auto input_file = std::unique_ptr{fdopen(input_fd, "r"), fclose}; + if (!input_file) { + LOG(ERROR) << "Failed to re-open input fd from /prof/self/fd/" << input_fd; + return; + } + ReadCommentedInputStream(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 static std::unique_ptr ReadCommentedInputFromFile( const char* input_filename, std::function* process) { - auto input_file = std::unique_ptr{fopen(input_filename, "r"), fclose}; - if (!input_file) { - LOG(ERROR) << "Failed to open input file " << input_filename; - return nullptr; - } std::unique_ptr output(new T()); - ReadCommentedInputStream(input_file.get(), process, output.get()); + ReadCommentedInputFromFile(input_filename, process, output.get()); return output; } @@ -2794,13 +2809,8 @@ class Dex2Oat final { template static std::unique_ptr ReadCommentedInputFromFd( int input_fd, std::function* process) { - auto input_file = std::unique_ptr{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 output(new T()); - ReadCommentedInputStream(input_file.get(), process, output.get()); + ReadCommentedInputFromFd(input_fd, process, output.get()); return output; } @@ -2950,6 +2960,7 @@ class Dex2Oat final { std::vector profile_files_; std::vector profile_file_fds_; std::vector preloaded_classes_files_; + std::vector preloaded_classes_fds_; std::unique_ptr profile_compilation_info_; TimingLogger* timings_; std::vector> dex_files_per_oat_file_; diff --git a/dex2oat/dex2oat_options.cc b/dex2oat/dex2oat_options.cc index e8439cc5d9..1f9138e8ff 100644 --- a/dex2oat/dex2oat_options.cc +++ b/dex2oat/dex2oat_options.cc @@ -259,7 +259,11 @@ static void AddCompilerMappings(Builder& builder) { .Define("--preloaded-classes=_") .WithType>().AppendValues() .WithHelp("Specify files containing list of classes preloaded in the zygote.") - .IntoKey(M::PreloadedClasses); + .IntoKey(M::PreloadedClasses) + .Define("--preloaded-classes-fds=_") + .WithType>().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 2b47735062..7c071dc898 100644 --- a/dex2oat/dex2oat_options.def +++ b/dex2oat/dex2oat_options.def @@ -104,5 +104,6 @@ DEX2OAT_OPTIONS_KEY (Unit, ForceAllowOjInlines) DEX2OAT_OPTIONS_KEY (std::string, ApexVersions) DEX2OAT_OPTIONS_KEY (Unit, ForcePaletteCompilationHooks) DEX2OAT_OPTIONS_KEY (std::vector, PreloadedClasses) +DEX2OAT_OPTIONS_KEY (std::vector, PreloadedClassesFds) #undef DEX2OAT_OPTIONS_KEY diff --git a/odrefresh/odrefresh.cc b/odrefresh/odrefresh.cc index 24557723e3..1d12b94fce 100644 --- a/odrefresh/odrefresh.cc +++ b/odrefresh/odrefresh.cc @@ -1348,6 +1348,15 @@ WARN_UNUSED bool OnDeviceRefresh::CompileBootClasspathArtifacts( 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(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 jars_to_compile = boot_classpath_compilable_jars_; if (minimal) {