diff options
author | Brian Carlstrom <bdc@google.com> | 2013-07-09 17:18:47 -0700 |
---|---|---|
committer | Brian Carlstrom <bdc@google.com> | 2013-07-10 09:16:07 -0700 |
commit | 4922e9d4e5f86e40ca89fb097cec40e191dae0a1 (patch) | |
tree | dc480f255588c59f221654566a05a61aee7a9795 /src | |
parent | c64440528822281a7889aba9cebf96baa4235b87 (diff) | |
download | android_art-4922e9d4e5f86e40ca89fb097cec40e191dae0a1.tar.gz android_art-4922e9d4e5f86e40ca89fb097cec40e191dae0a1.tar.bz2 android_art-4922e9d4e5f86e40ca89fb097cec40e191dae0a1.zip |
Use /system/framework/framework.jar:preloaded-classes for on device dex2oat
Change-Id: I30ccbd5295a2979b9c89f00c93ad316d9b6475e9
Diffstat (limited to 'src')
-rw-r--r-- | src/dex2oat.cc | 54 | ||||
-rw-r--r-- | src/dex_file.cc | 17 | ||||
-rw-r--r-- | src/gc/heap.cc | 5 | ||||
-rw-r--r-- | src/zip_archive.cc | 44 | ||||
-rw-r--r-- | src/zip_archive.h | 3 |
5 files changed, 90 insertions, 33 deletions
diff --git a/src/dex2oat.cc b/src/dex2oat.cc index 7cf54b4eee..6397f40b44 100644 --- a/src/dex2oat.cc +++ b/src/dex2oat.cc @@ -18,8 +18,9 @@ #include <stdlib.h> #include <sys/stat.h> -#include <iostream> #include <fstream> +#include <iostream> +#include <sstream> #include <string> #include <vector> @@ -164,27 +165,54 @@ class Dex2Oat { // Reads the class names (java.lang.Object) and returns as set of class descriptors (Ljava/lang/Object;) - CompilerDriver::DescriptorSet* ReadImageClasses(const char* image_classes_filename) { + CompilerDriver::DescriptorSet* ReadImageClassesFromFile(const char* image_classes_filename) { UniquePtr<std::ifstream> image_classes_file(new std::ifstream(image_classes_filename, std::ifstream::in)); if (image_classes_file.get() == NULL) { LOG(ERROR) << "Failed to open image classes file " << image_classes_filename; return NULL; } + UniquePtr<CompilerDriver::DescriptorSet> result(ReadImageClasses(*image_classes_file.get())); + image_classes_file->close(); + return result.release(); + } + CompilerDriver::DescriptorSet* ReadImageClasses(std::istream& image_classes_stream) { UniquePtr<CompilerDriver::DescriptorSet> image_classes(new CompilerDriver::DescriptorSet); - while (image_classes_file->good()) { + while (image_classes_stream.good()) { std::string dot; - std::getline(*image_classes_file.get(), dot); + std::getline(image_classes_stream, dot); if (StartsWith(dot, "#") || dot.empty()) { continue; } std::string descriptor(DotToDescriptor(dot.c_str())); image_classes->insert(descriptor); } - image_classes_file->close(); return image_classes.release(); } + // Reads the class names (java.lang.Object) and returns as set of class descriptors (Ljava/lang/Object;) + CompilerDriver::DescriptorSet* ReadImageClassesFromZip(const std::string& zip_filename, const char* image_classes_filename) { + UniquePtr<ZipArchive> zip_archive(ZipArchive::Open(zip_filename)); + if (zip_archive.get() == NULL) { + LOG(ERROR) << "Failed to open zip file " << zip_filename; + return NULL; + } + UniquePtr<ZipEntry> zip_entry(zip_archive->Find(image_classes_filename)); + if (zip_entry.get() == NULL) { + LOG(ERROR) << "Failed to find " << image_classes_filename << " within " << zip_filename; + return NULL; + } + UniquePtr<MemMap> image_classes_file(zip_entry->ExtractToMemMap(image_classes_filename)); + if (image_classes_file.get() == NULL) { + LOG(ERROR) << "Failed to extract " << image_classes_filename << " from " << zip_filename; + return NULL; + } + 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 CompilerDriver* CreateOatFile(const std::string& boot_image_option, const std::string* host_prefix, const std::string& android_root, @@ -558,6 +586,7 @@ static int dex2oat(int argc, char** argv) { std::string oat_location; int oat_fd = -1; std::string bitcode_filename; + const char* image_classes_zip_filename = NULL; const char* image_classes_filename = NULL; std::string image_filename; std::string boot_image_filename; @@ -632,6 +661,8 @@ static int dex2oat(int argc, char** argv) { image_filename = option.substr(strlen("--image=")).data(); } else if (option.starts_with("--image-classes=")) { image_classes_filename = option.substr(strlen("--image-classes=")).data(); + } else if (option.starts_with("--image-classes-zip=")) { + image_classes_zip_filename = option.substr(strlen("--image-classes-zip=")).data(); } else if (option.starts_with("--base=")) { const char* image_base_str = option.substr(strlen("--base=")).data(); char* end; @@ -735,6 +766,10 @@ static int dex2oat(int argc, char** argv) { Usage("--image-classes should not be used with --boot-image"); } + if (image_classes_zip_filename != NULL && image_classes_filename == NULL) { + Usage("--image-classes-zip should be used with --image-classes"); + } + if (dex_filenames.empty() && zip_fd == -1) { Usage("Input must be supplied with either --dex-file or --zip-fd"); } @@ -846,7 +881,12 @@ static int dex2oat(int argc, char** argv) { // If --image-classes was specified, calculate the full list of classes to include in the image UniquePtr<CompilerDriver::DescriptorSet> image_classes(NULL); if (image_classes_filename != NULL) { - image_classes.reset(dex2oat->ReadImageClasses(image_classes_filename)); + if (image_classes_zip_filename != NULL) { + image_classes.reset(dex2oat->ReadImageClassesFromZip(image_classes_zip_filename, + image_classes_filename)); + } else { + image_classes.reset(dex2oat->ReadImageClassesFromFile(image_classes_filename)); + } if (image_classes.get() == NULL) { LOG(ERROR) << "Failed to create list of image classes from " << image_classes_filename; return EXIT_FAILURE; @@ -860,7 +900,7 @@ static int dex2oat(int argc, char** argv) { if (dex_filenames.empty()) { UniquePtr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(zip_fd)); if (zip_archive.get() == NULL) { - LOG(ERROR) << "Failed to zip from file descriptor for " << zip_location; + LOG(ERROR) << "Failed to open zip from file descriptor for " << zip_location; return EXIT_FAILURE; } const DexFile* dex_file = DexFile::Open(*zip_archive.get(), zip_location); diff --git a/src/dex_file.cc b/src/dex_file.cc index 80465f2fed..1e37dcde07 100644 --- a/src/dex_file.cc +++ b/src/dex_file.cc @@ -206,26 +206,15 @@ const DexFile* DexFile::Open(const ZipArchive& zip_archive, const std::string& l CHECK(!location.empty()); UniquePtr<ZipEntry> zip_entry(zip_archive.Find(kClassesDex)); if (zip_entry.get() == NULL) { - LOG(ERROR) << "Failed to find classes.dex within " << location; + LOG(ERROR) << "Failed to find classes.dex within '" << location << "'"; return NULL; } - uint32_t length = zip_entry->GetUncompressedLength(); - std::string name("classes.dex extracted in memory from "); - name += location; - UniquePtr<MemMap> map(MemMap::MapAnonymous(name.c_str(), NULL, length, PROT_READ | PROT_WRITE)); + UniquePtr<MemMap> map(zip_entry->ExtractToMemMap(kClassesDex)); if (map.get() == NULL) { - LOG(ERROR) << "mmap classes.dex for \"" << location << "\" failed"; + LOG(ERROR) << "Failed to extract '" << kClassesDex << "' from '" << location << "'"; return NULL; } - - // Extract classes.dex - bool success = zip_entry->ExtractToMemory(*map.get()); - if (!success) { - LOG(ERROR) << "Failed to extract classes.dex from '" << location << "' to memory"; - return NULL; - } - const DexFile* dex_file = OpenMemory(location, zip_entry->GetCrc32(), map.release()); if (dex_file == NULL) { LOG(ERROR) << "Failed to open dex file '" << location << "' from memory"; diff --git a/src/gc/heap.cc b/src/gc/heap.cc index 9ec1f21243..7bd86872ee 100644 --- a/src/gc/heap.cc +++ b/src/gc/heap.cc @@ -109,7 +109,10 @@ static bool GenerateImage(const std::string& image_file_name) { std::string base_option_string(StringPrintf("--base=0x%x", ART_BASE_ADDRESS)); arg_vector.push_back(strdup(base_option_string.c_str())); - if (!kIsTargetBuild) { + if (kIsTargetBuild) { + arg_vector.push_back(strdup("--image-classes-zip=/system/framework/framework.jar")); + arg_vector.push_back(strdup("--image-classes=preloaded-classes")); + } else { arg_vector.push_back(strdup("--host")); } diff --git a/src/zip_archive.cc b/src/zip_archive.cc index c9e9c0a64a..9cf7a09155 100644 --- a/src/zip_archive.cc +++ b/src/zip_archive.cc @@ -121,8 +121,8 @@ off_t ZipEntry::GetDataOffset() { return data_offset; } -static bool CopyFdToMemory(MemMap& mem_map, int in, size_t count) { - uint8_t* dst = mem_map.Begin(); +static bool CopyFdToMemory(uint8_t* begin, size_t size, int in, size_t count) { + uint8_t* dst = begin; std::vector<uint8_t> buf(kBufSize); while (count != 0) { size_t bytes_to_read = (count > kBufSize) ? kBufSize : count; @@ -135,7 +135,7 @@ static bool CopyFdToMemory(MemMap& mem_map, int in, size_t count) { dst += bytes_to_read; count -= bytes_to_read; } - DCHECK_EQ(dst, mem_map.End()); + DCHECK_EQ(dst, begin + size); return true; } @@ -165,8 +165,9 @@ class ZStream { z_stream zstream_; }; -static bool InflateToMemory(MemMap& mem_map, int in, size_t uncompressed_length, size_t compressed_length) { - uint8_t* dst = mem_map.Begin(); +static bool InflateToMemory(uint8_t* begin, size_t size, + int in, size_t uncompressed_length, size_t compressed_length) { + uint8_t* dst = begin; UniquePtr<uint8_t[]> read_buf(new uint8_t[kBufSize]); UniquePtr<uint8_t[]> write_buf(new uint8_t[kBufSize]); if (read_buf.get() == NULL || write_buf.get() == NULL) { @@ -236,7 +237,7 @@ static bool InflateToMemory(MemMap& mem_map, int in, size_t uncompressed_length, return false; } - DCHECK_EQ(dst, mem_map.End()); + DCHECK_EQ(dst, begin + size); return true; } @@ -254,10 +255,10 @@ bool ZipEntry::ExtractToFile(File& file) { return false; } - return ExtractToMemory(*map.get()); + return ExtractToMemory(map->Begin(), map->Size()); } -bool ZipEntry::ExtractToMemory(MemMap& mem_map) { +bool ZipEntry::ExtractToMemory(uint8_t* begin, size_t size) { off_t data_offset = GetDataOffset(); if (data_offset == -1) { LOG(WARNING) << "Zip: data_offset=" << data_offset; @@ -272,15 +273,38 @@ bool ZipEntry::ExtractToMemory(MemMap& mem_map) { // for uncompressed data). switch (GetCompressionMethod()) { case kCompressStored: - return CopyFdToMemory(mem_map, zip_archive_->fd_, GetUncompressedLength()); + return CopyFdToMemory(begin, size, zip_archive_->fd_, GetUncompressedLength()); case kCompressDeflated: - return InflateToMemory(mem_map, zip_archive_->fd_, GetUncompressedLength(), GetCompressedLength()); + return InflateToMemory(begin, size, zip_archive_->fd_, + GetUncompressedLength(), GetCompressedLength()); default: LOG(WARNING) << "Zip: unknown compression method " << std::hex << GetCompressionMethod(); return false; } } +MemMap* ZipEntry::ExtractToMemMap(const char* entry_filename) { + std::string name(entry_filename); + name += " extracted in memory from "; + name += entry_filename; + UniquePtr<MemMap> map(MemMap::MapAnonymous(name.c_str(), + NULL, + GetUncompressedLength(), + PROT_READ | PROT_WRITE)); + if (map.get() == NULL) { + LOG(ERROR) << "Zip: mmap for '" << entry_filename << "' failed"; + return NULL; + } + + bool success = ExtractToMemory(map->Begin(), map->Size()); + if (!success) { + LOG(ERROR) << "Zip: Failed to extract '" << entry_filename << "' to memory"; + return NULL; + } + + return map.release(); +} + static void SetCloseOnExec(int fd) { // This dance is more portable than Linux's O_CLOEXEC open(2) flag. int flags = fcntl(fd, F_GETFD); diff --git a/src/zip_archive.h b/src/zip_archive.h index 54835cfc9a..ef3148696e 100644 --- a/src/zip_archive.h +++ b/src/zip_archive.h @@ -37,7 +37,8 @@ class MemMap; class ZipEntry { public: bool ExtractToFile(File& file); - bool ExtractToMemory(MemMap& mem_map); + bool ExtractToMemory(uint8_t* begin, size_t size); + MemMap* ExtractToMemMap(const char* entry_filename); uint32_t GetUncompressedLength(); uint32_t GetCrc32(); |