From 70bef0d8f6aa30b0da5c6ca56e1bc5729f74654b Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Wed, 15 Apr 2015 02:37:28 -0700 Subject: ART: Add compiled-methods Add a dex2oat option for compiled-methods, a more granular filter than compiled-classes. Add compiler-driver support for it. Refactor dex2oat to reuse file reading. Add a test to oat_test. Change-Id: I78d0d040bce7738b4bb7aabe7768b5788d2587ac --- dex2oat/dex2oat.cc | 133 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 95 insertions(+), 38 deletions(-) (limited to 'dex2oat') diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 70b4213..9c01a0f 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -445,6 +445,8 @@ class Dex2Oat FINAL { image_classes_filename_(nullptr), compiled_classes_zip_filename_(nullptr), compiled_classes_filename_(nullptr), + compiled_methods_zip_filename_(nullptr), + compiled_methods_filename_(nullptr), image_(false), is_host_(false), dump_stats_(false), @@ -564,6 +566,10 @@ class Dex2Oat FINAL { compiled_classes_filename_ = option.substr(strlen("--compiled-classes=")).data(); } else if (option.starts_with("--compiled-classes-zip=")) { compiled_classes_zip_filename_ = option.substr(strlen("--compiled-classes-zip=")).data(); + } else if (option.starts_with("--compiled-methods=")) { + compiled_methods_filename_ = option.substr(strlen("--compiled-methods=")).data(); + } else if (option.starts_with("--compiled-methods-zip=")) { + compiled_methods_zip_filename_ = option.substr(strlen("--compiled-methods-zip=")).data(); } else if (option.starts_with("--base=")) { const char* image_base_str = option.substr(strlen("--base=")).data(); char* end; @@ -1092,8 +1098,8 @@ class Dex2Oat FINAL { std::string error_msg; if (image_classes_zip_filename_ != nullptr) { image_classes_.reset(ReadImageClassesFromZip(image_classes_zip_filename_, - image_classes_filename_, - &error_msg)); + image_classes_filename_, + &error_msg)); } else { image_classes_.reset(ReadImageClassesFromFile(image_classes_filename_)); } @@ -1121,9 +1127,29 @@ class Dex2Oat FINAL { << compiled_classes_filename_ << "': " << error_msg; return false; } - } else if (image_) { + } else { compiled_classes_.reset(nullptr); // By default compile everything. } + // If --compiled-methods was specified, read the methods to compile from the given file(s). + if (compiled_methods_filename_ != nullptr) { + std::string error_msg; + if (compiled_methods_zip_filename_ != nullptr) { + compiled_methods_.reset(ReadCommentedInputFromZip(compiled_methods_zip_filename_, + compiled_methods_filename_, + nullptr, // No post-processing. + &error_msg)); + } else { + compiled_methods_.reset(ReadCommentedInputFromFile(compiled_methods_filename_, + nullptr)); // No post-processing. + } + if (compiled_methods_.get() == nullptr) { + LOG(ERROR) << "Failed to create list of compiled methods from '" + << compiled_methods_filename_ << "': " << error_msg; + return false; + } + } else { + compiled_methods_.reset(nullptr); // By default compile everything. + } if (boot_image_option_.empty()) { dex_files_ = Runtime::Current()->GetClassLinker()->GetBootClassPath(); @@ -1258,6 +1284,7 @@ class Dex2Oat FINAL { image_, image_classes_.release(), compiled_classes_.release(), + nullptr, thread_count_, dump_stats_, dump_passes_, @@ -1618,59 +1645,86 @@ class Dex2Oat FINAL { // Reads the class names (java.lang.Object) and returns a set of descriptors (Ljava/lang/Object;) static std::unordered_set* ReadImageClassesFromFile( const char* image_classes_filename) { - std::unique_ptr image_classes_file(new std::ifstream(image_classes_filename, - std::ifstream::in)); - if (image_classes_file.get() == nullptr) { - LOG(ERROR) << "Failed to open image classes file " << image_classes_filename; - return nullptr; - } - std::unique_ptr> result(ReadImageClasses(*image_classes_file)); - image_classes_file->close(); - return result.release(); + std::function process = DotToDescriptor; + return ReadCommentedInputFromFile(image_classes_filename, &process); } - static std::unordered_set* ReadImageClasses(std::istream& image_classes_stream) { - std::unique_ptr> image_classes( - new std::unordered_set); - while (image_classes_stream.good()) { - std::string dot; - std::getline(image_classes_stream, dot); - if (StartsWith(dot, "#") || dot.empty()) { - continue; - } - std::string descriptor(DotToDescriptor(dot.c_str())); - image_classes->insert(descriptor); + // Reads the class names (java.lang.Object) and returns a set of descriptors (Ljava/lang/Object;) + static std::unordered_set* ReadImageClassesFromZip( + const char* zip_filename, + const char* image_classes_filename, + std::string* error_msg) { + std::function process = DotToDescriptor; + return ReadCommentedInputFromZip(zip_filename, image_classes_filename, &process, error_msg); + } + + // Read lines from the given file, dropping comments and empty lines. Post-process each line with + // the given function. + static std::unordered_set* ReadCommentedInputFromFile( + const char* input_filename, std::function* process) { + std::unique_ptr input_file(new std::ifstream(input_filename, std::ifstream::in)); + if (input_file.get() == nullptr) { + LOG(ERROR) << "Failed to open input file " << input_filename; + return nullptr; } - return image_classes.release(); + std::unique_ptr> result( + ReadCommentedInputStream(*input_file, process)); + input_file->close(); + return result.release(); } - // Reads the class names (java.lang.Object) and returns a set of descriptors (Ljava/lang/Object;) - static std::unordered_set* ReadImageClassesFromZip( + // Read lines from the given file from the given zip file, dropping comments and empty lines. + // Post-process each line with the given function. + static std::unordered_set* ReadCommentedInputFromZip( const char* zip_filename, - const char* image_classes_filename, + const char* input_filename, + std::function* process, std::string* error_msg) { std::unique_ptr zip_archive(ZipArchive::Open(zip_filename, error_msg)); if (zip_archive.get() == nullptr) { return nullptr; } - std::unique_ptr zip_entry(zip_archive->Find(image_classes_filename, error_msg)); + std::unique_ptr zip_entry(zip_archive->Find(input_filename, error_msg)); if (zip_entry.get() == nullptr) { - *error_msg = StringPrintf("Failed to find '%s' within '%s': %s", image_classes_filename, + *error_msg = StringPrintf("Failed to find '%s' within '%s': %s", input_filename, zip_filename, error_msg->c_str()); return nullptr; } - std::unique_ptr image_classes_file(zip_entry->ExtractToMemMap(zip_filename, - image_classes_filename, - error_msg)); - if (image_classes_file.get() == nullptr) { - *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", image_classes_filename, + std::unique_ptr input_file(zip_entry->ExtractToMemMap(zip_filename, + input_filename, + error_msg)); + if (input_file.get() == nullptr) { + *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", input_filename, zip_filename, error_msg->c_str()); return nullptr; } - const std::string image_classes_string(reinterpret_cast(image_classes_file->Begin()), - image_classes_file->Size()); - std::istringstream image_classes_stream(image_classes_string); - return ReadImageClasses(image_classes_stream); + const std::string input_string(reinterpret_cast(input_file->Begin()), + input_file->Size()); + std::istringstream input_stream(input_string); + return ReadCommentedInputStream(input_stream, process); + } + + // Read lines from the given stream, dropping comments and empty lines. Post-process each line + // with the given function. + static std::unordered_set* ReadCommentedInputStream( + std::istream& in_stream, + std::function* process) { + std::unique_ptr> image_classes( + new std::unordered_set); + while (in_stream.good()) { + std::string dot; + std::getline(in_stream, dot); + if (StartsWith(dot, "#") || dot.empty()) { + continue; + } + if (process != nullptr) { + std::string descriptor((*process)(dot.c_str())); + image_classes->insert(descriptor); + } else { + image_classes->insert(dot); + } + } + return image_classes.release(); } void LogCompletionTime() { @@ -1724,8 +1778,11 @@ class Dex2Oat FINAL { const char* image_classes_filename_; const char* compiled_classes_zip_filename_; const char* compiled_classes_filename_; + const char* compiled_methods_zip_filename_; + const char* compiled_methods_filename_; std::unique_ptr> image_classes_; std::unique_ptr> compiled_classes_; + std::unique_ptr> compiled_methods_; bool image_; std::unique_ptr image_writer_; bool is_host_; -- cgit v1.1