dex2oat.cc revision 955724179c6c739524f610023287f56b24dc31de
169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom// Copyright 2011 Google Inc. All Rights Reserved. 269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include <stdio.h> 469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include <stdlib.h> 569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 6ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom#include <iostream> 7ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom#include <fstream> 869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include <string> 969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include <vector> 1069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 1169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "class_linker.h" 1269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "class_loader.h" 1369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "compiler.h" 145e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers#include "file.h" 1569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "image_writer.h" 166f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers#include "leb128.h" 17e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "oat_writer.h" 186d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 195e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers#include "os.h" 2069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "runtime.h" 2169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "stringpiece.h" 2269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 2369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromnamespace art { 2469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 2569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromstatic void usage() { 2669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 2769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom "Usage: dex2oat [options]...\n" 2869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom "\n"); 2969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 3078128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom " --dex-file=<dex-file>: specifies a .dex file to compile. At least one .dex\n" 3178128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom " file must be specified. \n" 3269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom " Example: --dex-file=/system/framework/core.jar\n" 3369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom "\n"); 3469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 35ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom " --oat=<file.oat>: specifies the required oat filename.\n" 36ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom " Example: --oat=/data/art-cache/boot.oat\n" 37ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom "\n"); 38ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom fprintf(stderr, 39ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom " --image=<file.art>: specifies the output image filename.\n" 4047a0d5a6f221066c3daf7f67f2122ed9c9cd217cBrian Carlstrom " Example: --image=/data/art-cache/boot.art\n" 41e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom "\n"); 42e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom fprintf(stderr, 43ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom " --image-classes=<classname-file>: specifies classes to include in an image.\n" 44ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom " Example: --image=frameworks/base/preloaded-classes\n" 4569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom "\n"); 4669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 4769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom " --base=<hex-address>: specifies the base address when creating a boot image.\n" 4869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom " Example: --base=0x50000000\n" 4969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom "\n"); 5069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 51e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom " --boot-image=<file.art>: provide the image file for the boot class path.\n" 5247a0d5a6f221066c3daf7f67f2122ed9c9cd217cBrian Carlstrom " Example: --boot-image=/data/art-cache/boot.art\n" 53b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom " Default: <host-prefix>/data/art-cache/boot.art\n" 54e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom "\n"); 5569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 5658ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom " --host-prefix may be used to translate host paths to target paths during\n" 5758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom " cross compilation.\n" 5858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom " Example: --host-prefix=out/target/product/crespo\n" 59b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom " Default: $ANDROID_PRODUCT_OUT\n" 60161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom "\n"); 6127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom fprintf(stderr, 625d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao " --runtime-arg <argument>: used to specify various arguments for the runtime,\n" 635d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao " such as initial heap size, maximum heap size, and verbose output.\n" 645d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao " Use a separate --runtime-arg switch for each argument.\n" 655d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao " Example: --runtime-arg -Xms256m\n" 6627ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom "\n"); 6769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom exit(EXIT_FAILURE); 6869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom} 6969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 70ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromclass Dex2Oat { 71ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom public: 72ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 73ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom static Dex2Oat* Create(Runtime::Options& options) { 74ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom UniquePtr<Runtime> runtime(CreateRuntime(options)); 75ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (runtime.get() == NULL) { 76ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return NULL; 77254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson } 78ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return new Dex2Oat(runtime.release()); 79ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 80ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 81ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom ~Dex2Oat() { 82ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom delete runtime_; 83ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 84ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 85ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // Make a list of descriptors for classes to include in the image 86ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::set<std::string>* GetImageClassDescriptors(const char* image_classes_filename) { 87ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom UniquePtr<std::ifstream> image_classes_file(new std::ifstream(image_classes_filename, std::ifstream::in)); 88ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes_file.get() == NULL) { 89ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(ERROR) << "Failed to open image classes file " << image_classes_filename; 90ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return NULL; 91ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 92ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 936f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // Load all the classes specified in the file 94ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom ClassLinker* class_linker = runtime_->GetClassLinker(); 95ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom while (image_classes_file->good()) { 96ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::string dot; 97ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::getline(*image_classes_file.get(), dot); 98ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (StringPiece(dot).starts_with("#") || dot.empty()) { 99ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom continue; 100ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 101955724179c6c739524f610023287f56b24dc31deElliott Hughes std::string descriptor(DotToDescriptor(dot.c_str())); 102ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom SirtRef<Class> klass(class_linker->FindSystemClass(descriptor)); 103ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (klass.get() == NULL) { 104ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(WARNING) << "Failed to find class " << descriptor; 105ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Thread::Current()->ClearException(); 106ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 107ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 108ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom image_classes_file->close(); 109ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 1106f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // Resolve exception classes referenced by the loaded classes. The catch logic assumes 1116f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // exceptions are resolved by the verifier when there is a catch block in an interested method. 1126f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // Do this here so that exception classes appear to have been specified image classes. 1136f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers std::set<std::pair<uint16_t, const DexFile*> > unresolved_exception_types; 1146f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers do { 1156f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers unresolved_exception_types.clear(); 1166f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers class_linker->VisitClasses(ResolveCatchBlockExceptionsClassVisitor, 1176f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers &unresolved_exception_types); 1186f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers typedef std::set<std::pair<uint16_t, const DexFile*> >::const_iterator It; // TODO: C++0x auto 1196f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers for (It it = unresolved_exception_types.begin(), 1206f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers end = unresolved_exception_types.end(); 1216f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers it != end; ++it) { 1226f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers uint16_t exception_type_idx = it->first; 1236f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers const DexFile* dex_file = it->second; 1246f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers DexCache* dex_cache = class_linker->FindDexCache(*dex_file); 1256f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers ClassLoader* class_loader = NULL; 1266f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers SirtRef<Class> klass(class_linker->ResolveType(*dex_file, exception_type_idx, dex_cache, 1276f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers class_loader)); 1286f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers if (klass.get() == NULL) { 1296f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers const DexFile::TypeId& type_id = dex_file->GetTypeId(exception_type_idx); 1306f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers const char* descriptor = dex_file->GetTypeDescriptor(type_id); 1316f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers LOG(FATAL) << "Failed to resolve class " << descriptor; 1326f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 1336f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers DCHECK(klass->IsThrowableClass()); 1346f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 1356f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // Resolving exceptions may load classes that reference more exceptions, iterate until no 1366f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // more are found 1376f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } while (!unresolved_exception_types.empty()); 1386f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers 139ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // We walk the roots looking for classes so that we'll pick up the 140ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // above classes plus any classes them depend on such super 141ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // classes, interfaces, and the required ClassLinker roots. 142ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom UniquePtr<std::set<std::string> > image_classes(new std::set<std::string>()); 1436f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers class_linker->VisitClasses(RecordImageClassesVisitor, image_classes.get()); 144ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom CHECK_NE(image_classes->size(), 0U); 145ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return image_classes.release(); 146254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson } 147254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson 148ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom bool CreateOatFile(const std::string& boot_image_option, 149ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::vector<const char*>& dex_filenames, 150ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::string& host_prefix, 151ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom File* oat_file, 152ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom bool image, 153ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::set<std::string>* image_classes) { 154ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // SirtRef and ClassLoader creation needs to come after Runtime::Create 155ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom UniquePtr<SirtRef<ClassLoader> > class_loader(new SirtRef<ClassLoader>(NULL)); 156ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (class_loader.get() == NULL) { 157ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(ERROR) << "Failed to create SirtRef for class loader"; 158ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return false; 159254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson } 160ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 161ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::vector<const DexFile*> dex_files; 162ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!boot_image_option.empty()) { 163ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 164ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom DexFile::OpenDexFiles(dex_filenames, dex_files, host_prefix); 165ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::vector<const DexFile*> class_path_files(dex_files); 166ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom OpenClassPathFiles(runtime_->GetClassPath(), class_path_files); 167ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i < class_path_files.size(); i++) { 168ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom class_linker->RegisterDexFile(*class_path_files[i]); 169ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 170ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom class_loader.get()->reset(PathClassLoader::AllocCompileTime(class_path_files)); 171254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson } else { 172ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom dex_files = runtime_->GetClassLinker()->GetBootClassPath(); 173254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson } 174ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 175ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Compiler compiler(instruction_set_, image, image_classes); 176ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom compiler.CompileAll(class_loader->get(), dex_files); 177ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 178ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!OatWriter::Create(oat_file, class_loader->get(), compiler)) { 179ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(ERROR) << "Failed to create oat file " << oat_file->name(); 180ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return false; 181ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 182ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return true; 183254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson } 184ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 185ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom bool CreateImageFile(const char* image_filename, 186ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom uintptr_t image_base, 187ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::set<std::string>* image_classes, 188ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::string& oat_filename, 189ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::string& host_prefix) { 190ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // If we have an existing boot image, position new space after its oat file 191ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (Heap::GetSpaces().size() > 1) { 192ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Space* last_image_space = Heap::GetSpaces()[Heap::GetSpaces().size()-2]; 193ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom CHECK(last_image_space != NULL); 194ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom CHECK(last_image_space->IsImageSpace()); 195ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom CHECK(!Heap::GetSpaces()[Heap::GetSpaces().size()-1]->IsImageSpace()); 196ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom byte* oat_limit_addr = last_image_space->GetImageHeader().GetOatLimitAddr(); 197ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom image_base = RoundUp(reinterpret_cast<uintptr_t>(oat_limit_addr), kPageSize); 198ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 199ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 200ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom ImageWriter image_writer(image_classes); 201ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!image_writer.Write(image_filename, image_base, oat_filename, host_prefix)) { 202ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(ERROR) << "Failed to create image file " << image_filename; 203ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return false; 204ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 205ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return true; 206ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 207ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 208ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom private: 209ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 210ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Dex2Oat(Runtime* runtime) : runtime_(runtime) {} 211ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 212ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom static Runtime* CreateRuntime(Runtime::Options& options) { 213ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Runtime* runtime = Runtime::Create(options, false); 214ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (runtime == NULL) { 215ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(ERROR) << "Failed to create runtime"; 216ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return NULL; 217ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 218ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 219ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // if we loaded an existing image, we will reuse values from the image roots. 220ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!runtime->HasJniDlsymLookupStub()) { 221ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom runtime->SetJniDlsymLookupStub(Compiler::CreateJniDlysmLookupStub(instruction_set_)); 222ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 223ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!runtime->HasAbstractMethodErrorStubArray()) { 224ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom runtime->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(instruction_set_)); 225ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 226ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) { 227ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Runtime::TrampolineType type = Runtime::TrampolineType(i); 228ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!runtime->HasResolutionStubArray(type)) { 229ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom runtime->SetResolutionStubArray(Compiler::CreateResolutionStub(instruction_set_, type), type); 230ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 231ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 232ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { 233ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i); 234ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!runtime->HasCalleeSaveMethod(type)) { 235ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom runtime->SetCalleeSaveMethod(runtime->CreateCalleeSaveMethod(instruction_set_, type), type); 236ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 237ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 238ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return runtime; 239ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 240ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 2416f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers static void ResolveExceptionsForMethod(MethodHelper* mh, 2426f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers std::set<std::pair<uint16_t, const DexFile*> >& exceptions_to_resolve) { 2436f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers const DexFile::CodeItem* code_item = mh->GetCodeItem(); 2446f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers if (code_item == NULL) { 2456f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers return; // native or abstract method 2466f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 2476f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers if (code_item->tries_size_ == 0) { 2486f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers return; // nothing to process 2496f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 2506f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers const byte* encoded_catch_handler_list = DexFile::GetCatchHandlerData(*code_item, 0); 2516f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers size_t num_encoded_catch_handlers = DecodeUnsignedLeb128(&encoded_catch_handler_list); 2526f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers for (size_t i = 0; i < num_encoded_catch_handlers; i++) { 2536f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers int32_t encoded_catch_handler_size = DecodeSignedLeb128(&encoded_catch_handler_list); 2546f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers bool has_catch_all = false; 2556f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers if (encoded_catch_handler_size <= 0) { 2566f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers encoded_catch_handler_size = -encoded_catch_handler_size; 2576f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers has_catch_all = true; 2586f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 2596f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers for (int32_t j = 0; j < encoded_catch_handler_size; j++) { 2606f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers uint16_t encoded_catch_handler_handlers_type_idx = 2616f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers DecodeUnsignedLeb128(&encoded_catch_handler_list); 2626f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // Add to set of types to resolve if not already in the dex cache resolved types 2636f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers if (!mh->IsResolvedTypeIdx(encoded_catch_handler_handlers_type_idx)) { 2646f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers exceptions_to_resolve.insert( 2656f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers std::pair<uint16_t, const DexFile*>(encoded_catch_handler_handlers_type_idx, 2666f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers &mh->GetDexFile())); 2676f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 2686f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // ignore address associated with catch handler 2696f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers DecodeUnsignedLeb128(&encoded_catch_handler_list); 2706f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 2716f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers if (has_catch_all) { 2726f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // ignore catch all address 2736f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers DecodeUnsignedLeb128(&encoded_catch_handler_list); 2746f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 2756f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 2766f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 2776f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers static bool ResolveCatchBlockExceptionsClassVisitor(Class* c, void* arg) { 2786f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers std::set<std::pair<uint16_t, const DexFile*> >* exceptions_to_resolve = 2796f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers reinterpret_cast<std::set<std::pair<uint16_t, const DexFile*> >*>(arg); 2806f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers MethodHelper mh; 2816f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers for (size_t i = 0; i < c->NumVirtualMethods(); ++i) { 2826f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers Method* m = c->GetVirtualMethod(i); 2836f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers mh.ChangeMethod(m); 2846f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers ResolveExceptionsForMethod(&mh, *exceptions_to_resolve); 2856f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 2866f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers for (size_t i = 0; i < c->NumDirectMethods(); ++i) { 2876f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers Method* m = c->GetDirectMethod(i); 2886f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers mh.ChangeMethod(m); 2896f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers ResolveExceptionsForMethod(&mh, *exceptions_to_resolve); 2906f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 2916f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers return true; 2926f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 2936f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers static bool RecordImageClassesVisitor(Class* klass, void* arg) { 294ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::set<std::string>* image_classes = reinterpret_cast<std::set<std::string>*>(arg); 295ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (klass->IsArrayClass() || klass->IsPrimitive()) { 296ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return true; 297ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 2986d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers image_classes->insert(ClassHelper(klass).GetDescriptor()); 299ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return true; 300ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 301ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 302ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // Appends to dex_files any elements of class_path that it doesn't already 303ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // contain. This will open those dex files as necessary. 304ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom static void OpenClassPathFiles(const std::string& class_path, std::vector<const DexFile*>& dex_files) { 305ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::vector<std::string> parsed; 306ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Split(class_path, ':', parsed); 307ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i < parsed.size(); ++i) { 308ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (DexFilesContains(dex_files, parsed[i])) { 309ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom continue; 310ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 311ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = DexFile::Open(parsed[i], Runtime::Current()->GetHostPrefix()); 312ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (dex_file == NULL) { 313ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(WARNING) << "Failed to open dex file " << parsed[i]; 314ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } else { 315ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom dex_files.push_back(dex_file); 316ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 317ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 318ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 319ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 320ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // Returns true if dex_files has a dex with the named location. 321ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom static bool DexFilesContains(const std::vector<const DexFile*>& dex_files, const std::string& location) { 322ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i < dex_files.size(); ++i) { 323ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (dex_files[i]->GetLocation() == location) { 324ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return true; 325ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 326ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 327ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return false; 328ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 329ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 330ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Runtime* runtime_; 331ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom static const InstructionSet instruction_set_ = kThumb2; 332ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 333ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom DISALLOW_IMPLICIT_CONSTRUCTORS(Dex2Oat); 334ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom}; 335254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson 33669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromint dex2oat(int argc, char** argv) { 33769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom // Skip over argv[0]. 33869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom argv++; 33969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom argc--; 34069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 34169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (argc == 0) { 34269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, "no arguments specified\n"); 34369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom usage(); 34469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 34569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 34669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom std::vector<const char*> dex_filenames; 347e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom std::string oat_filename; 34869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom const char* image_filename = NULL; 349ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const char* image_classes_filename = NULL; 350b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom std::string boot_image_filename; 35169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom uintptr_t image_base = 0; 35258ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom std::string host_prefix; 3535d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao std::vector<const char*> runtime_args; 354161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom 35569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom for (int i = 0; i < argc; i++) { 35669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom const StringPiece option(argv[i]); 357b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom if (false) { 358b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i]; 359b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom } 36069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (option.starts_with("--dex-file=")) { 36169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom dex_filenames.push_back(option.substr(strlen("--dex-file=")).data()); 362e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } else if (option.starts_with("--oat=")) { 363e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_filename = option.substr(strlen("--oat=")).data(); 36469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } else if (option.starts_with("--image=")) { 36569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom image_filename = option.substr(strlen("--image=")).data(); 366ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } else if (option.starts_with("--image-classes=")) { 367ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom image_classes_filename = option.substr(strlen("--image-classes=")).data(); 36869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } else if (option.starts_with("--base=")) { 36969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom const char* image_base_str = option.substr(strlen("--base=")).data(); 37069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom char* end; 37169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom image_base = strtoul(image_base_str, &end, 16); 37269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (end == image_base_str || *end != '\0') { 37327ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom fprintf(stderr, "Failed to parse hexadecimal value for option %s\n", option.data()); 37469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom usage(); 37569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 376e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } else if (option.starts_with("--boot-image=")) { 377b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom boot_image_filename = option.substr(strlen("--boot-image=")).data(); 37858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom } else if (option.starts_with("--host-prefix=")) { 37958ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom host_prefix = option.substr(strlen("--host-prefix=")).data(); 3805d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao } else if (option == "--runtime-arg") { 3815d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao if (++i >= argc) { 3825d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao fprintf(stderr, "Missing required argument for --runtime-arg\n"); 3835d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao usage(); 3845d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao } 3855d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao runtime_args.push_back(argv[i]); 38669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } else { 38769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, "unknown argument %s\n", option.data()); 38869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom usage(); 38969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 39069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 39169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 392ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (oat_filename.empty()) { 393362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes fprintf(stderr, "--oat file name not specified\n"); 394362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes return EXIT_FAILURE; 395e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 396e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 397b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom if (host_prefix.empty()) { 398b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom const char* android_product_out = getenv("ANDROID_PRODUCT_OUT"); 399b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom if (android_product_out != NULL) { 400b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom host_prefix = android_product_out; 401b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom } 402b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom } 403b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom 404ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom bool image = (image_filename != NULL); 405b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom if (!image && boot_image_filename.empty()) { 406b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom boot_image_filename += host_prefix; 407b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom boot_image_filename += "/data/art-cache/boot.art"; 408b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom } 409b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom std::string boot_image_option; 410b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom if (boot_image_filename != NULL) { 411b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom boot_image_option += "-Ximage:"; 412b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom boot_image_option += boot_image_filename; 41369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 41469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 415ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes_filename != NULL && !image) { 416ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom fprintf(stderr, "--image-classes should only be used with --image\n"); 417ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return EXIT_FAILURE; 418ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 419ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 420ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes_filename != NULL && !boot_image_option.empty()) { 421ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom fprintf(stderr, "--image-classes should not be used with --boot-image\n"); 422362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes return EXIT_FAILURE; 42378128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 42478128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 42569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (boot_image_option.empty()) { 42669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (image_base == 0) { 42769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, "non-zero --base not specified\n"); 42869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return EXIT_FAILURE; 42969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 43069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 43169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 4326ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom // Check early that the result of compilation can be written 4336ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom UniquePtr<File> oat_file(OS::OpenFile(oat_filename.c_str(), true)); 4346ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom if (oat_file.get() == NULL) { 4356ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom PLOG(ERROR) << "Unable to create oat file " << oat_filename; 4366ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom return EXIT_FAILURE; 437234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes } 4386ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom LOG(INFO) << "dex2oat: " << oat_filename; 4395e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers 44069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom Runtime::Options options; 4415de8fe5253ca8bd285cba0eb2e56930573ea4c7fBrian Carlstrom options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL))); 442b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom std::string boot_class_path_string; 44369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (boot_image_option.empty()) { 44458ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom boot_class_path_string += "-Xbootclasspath:"; 44558ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom for (size_t i = 0; i < dex_filenames.size()-1; i++) { 44658ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom boot_class_path_string += dex_filenames[i]; 44758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom boot_class_path_string += ":"; 44858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom } 44958ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom boot_class_path_string += dex_filenames[dex_filenames.size()-1]; 45058ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom options.push_back(std::make_pair(boot_class_path_string.c_str(), reinterpret_cast<void*>(NULL))); 45169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } else { 45269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom options.push_back(std::make_pair(boot_image_option.c_str(), reinterpret_cast<void*>(NULL))); 45369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 45458ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom if (!host_prefix.empty()) { 45558ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom options.push_back(std::make_pair("host-prefix", host_prefix.c_str())); 45658ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom } 4575d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao for (size_t i = 0; i < runtime_args.size(); i++) { 4585d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao options.push_back(std::make_pair(runtime_args[i], reinterpret_cast<void*>(NULL))); 4595d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao } 46069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 461ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom UniquePtr<Dex2Oat> dex2oat(Dex2Oat::Create(options)); 46269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 463ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // If --image-classes was specified, calculate the full list classes to include in the image 464ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom UniquePtr<const std::set<std::string> > image_classes(NULL); 465ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes_filename != NULL) { 466ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom image_classes.reset(dex2oat->GetImageClassDescriptors(image_classes_filename)); 467ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes.get() == NULL) { 468ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(ERROR) << "Failed to create list of image classes from " << image_classes_filename; 469ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return EXIT_FAILURE; 47069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 47169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 47269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 473ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!dex2oat->CreateOatFile(boot_image_option, 474ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom dex_filenames, 475ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom host_prefix, 476ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom oat_file.get(), 477ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom image, 478ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom image_classes.get())) { 479ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(ERROR) << "Failed to create oat file" << oat_filename; 480e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return EXIT_FAILURE; 481e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 482e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 483ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!image) { 484ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(INFO) << "Oat file written successfully " << oat_filename; 485aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom return EXIT_SUCCESS; 486aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 487aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 488ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!dex2oat->CreateImageFile(image_filename, 489ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom image_base, 490ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom image_classes.get(), 491ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom oat_filename, 492ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom host_prefix)) { 49369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return EXIT_FAILURE; 49469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 49569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 496ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // We wrote the oat file successfully, and want to keep it. 497ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(INFO) << "Oat file written successfully " << oat_filename; 498234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes LOG(INFO) << "Image written successfully " << image_filename; 49969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return EXIT_SUCCESS; 50069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom} 50169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 50269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom} // namespace art 50369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 50469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromint main(int argc, char** argv) { 50569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return art::dex2oat(argc, argv); 50669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom} 507