diff options
author | Andreas Gampe <agampe@google.com> | 2015-04-15 02:37:28 -0700 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2015-04-21 15:03:15 -0700 |
commit | 70bef0d8f6aa30b0da5c6ca56e1bc5729f74654b (patch) | |
tree | aea4a31294c5a6a30c52ee886d5884a0b5b84fde /dex2oat | |
parent | bbf02afc641a393d33342976e269218668c07386 (diff) | |
download | art-70bef0d8f6aa30b0da5c6ca56e1bc5729f74654b.zip art-70bef0d8f6aa30b0da5c6ca56e1bc5729f74654b.tar.gz art-70bef0d8f6aa30b0da5c6ca56e1bc5729f74654b.tar.bz2 |
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
Diffstat (limited to 'dex2oat')
-rw-r--r-- | dex2oat/dex2oat.cc | 133 |
1 files changed, 95 insertions, 38 deletions
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<std::string>* ReadImageClassesFromFile( const char* image_classes_filename) { - std::unique_ptr<std::ifstream> 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<std::unordered_set<std::string>> result(ReadImageClasses(*image_classes_file)); - image_classes_file->close(); - return result.release(); + std::function<std::string(const char*)> process = DotToDescriptor; + return ReadCommentedInputFromFile(image_classes_filename, &process); } - static std::unordered_set<std::string>* ReadImageClasses(std::istream& image_classes_stream) { - std::unique_ptr<std::unordered_set<std::string>> image_classes( - new std::unordered_set<std::string>); - 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<std::string>* ReadImageClassesFromZip( + const char* zip_filename, + const char* image_classes_filename, + std::string* error_msg) { + std::function<std::string(const char*)> 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<std::string>* ReadCommentedInputFromFile( + const char* input_filename, std::function<std::string(const char*)>* process) { + std::unique_ptr<std::ifstream> 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<std::unordered_set<std::string>> 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<std::string>* 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<std::string>* ReadCommentedInputFromZip( const char* zip_filename, - const char* image_classes_filename, + const char* input_filename, + std::function<std::string(const char*)>* process, std::string* error_msg) { std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(zip_filename, error_msg)); if (zip_archive.get() == nullptr) { return nullptr; } - std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(image_classes_filename, error_msg)); + std::unique_ptr<ZipEntry> 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<MemMap> 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<MemMap> 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<char*>(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<char*>(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<std::string>* ReadCommentedInputStream( + std::istream& in_stream, + std::function<std::string(const char*)>* process) { + std::unique_ptr<std::unordered_set<std::string>> image_classes( + new std::unordered_set<std::string>); + 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<std::unordered_set<std::string>> image_classes_; std::unique_ptr<std::unordered_set<std::string>> compiled_classes_; + std::unique_ptr<std::unordered_set<std::string>> compiled_methods_; bool image_; std::unique_ptr<ImageWriter> image_writer_; bool is_host_; |