dex2oat.cc revision b12552a95d68b9e4a567103190074ae47b6a61dc
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 1669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 1769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include <stdio.h> 1869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include <stdlib.h> 1969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 20ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom#include <iostream> 21ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom#include <fstream> 2269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include <string> 2369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include <vector> 2469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 2569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "class_linker.h" 2669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "class_loader.h" 2769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "compiler.h" 285e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers#include "file.h" 2969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "image_writer.h" 306f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers#include "leb128.h" 31e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "oat_writer.h" 326d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 335e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers#include "os.h" 3469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "runtime.h" 3569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "stringpiece.h" 36bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes#include "timing_logger.h" 37a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom#include "zip_archive.h" 3869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 3969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromnamespace art { 4069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 4169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromstatic void usage() { 4269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 4369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom "Usage: dex2oat [options]...\n" 4469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom "\n"); 4569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 46a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom " --dex-file=<dex-file>: specifies a .dex file to compile.\n" 4769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom " Example: --dex-file=/system/framework/core.jar\n" 4869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom "\n"); 4969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 50a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom " --zip-fd=<file-descriptor>: specifies a file descriptor of a zip file\n" 51a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom " containing a classes.dex file to compile.\n" 52a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom " Example: --zip-fd=5\n" 53a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom "\n"); 54a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom fprintf(stderr, 55a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom " --zip-name=<zip-name>: specifies a symbolic name for the file corresponding\n" 56a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom " to the file descriptor specified by --zip-fd.\n" 57a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom " Example: --zip-name=/system/app/Calculator.apk\n" 58a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom "\n"); 59a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom fprintf(stderr, 60a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom " --oat-file=<file.oat>: specifies the required oat filename.\n" 61a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom " Example: --oat-file=/system/framework/boot.oat\n" 62a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom "\n"); 63a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom fprintf(stderr, 64a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom " --oat-name=<oat-name>: specifies a symbolic name for the file corresponding\n" 65a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom " to the file descriptor specified by --oat-fd.\n" 66a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom " Example: --oat-name=/data/art-cache/system@app@Calculator.apk.oat\n" 67ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom "\n"); 68ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom fprintf(stderr, 69ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom " --image=<file.art>: specifies the output image filename.\n" 7029e7ac74a3f9aec192099fec381baadaa55730adBrian Carlstrom " Example: --image=/system/framework/boot.art\n" 71e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom "\n"); 72e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom fprintf(stderr, 73ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom " --image-classes=<classname-file>: specifies classes to include in an image.\n" 74ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom " Example: --image=frameworks/base/preloaded-classes\n" 7569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom "\n"); 7669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 7769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom " --base=<hex-address>: specifies the base address when creating a boot image.\n" 7869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom " Example: --base=0x50000000\n" 7969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom "\n"); 8069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 81e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom " --boot-image=<file.art>: provide the image file for the boot class path.\n" 8229e7ac74a3f9aec192099fec381baadaa55730adBrian Carlstrom " Example: --boot-image=/system/framework/boot.art\n" 8329e7ac74a3f9aec192099fec381baadaa55730adBrian Carlstrom " Default: <host-prefix>/system/framework/boot.art\n" 84e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom "\n"); 8569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 8658ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom " --host-prefix may be used to translate host paths to target paths during\n" 8758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom " cross compilation.\n" 8858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom " Example: --host-prefix=out/target/product/crespo\n" 89b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom " Default: $ANDROID_PRODUCT_OUT\n" 90161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom "\n"); 9127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom fprintf(stderr, 925d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao " --runtime-arg <argument>: used to specify various arguments for the runtime,\n" 935d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao " such as initial heap size, maximum heap size, and verbose output.\n" 945d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao " Use a separate --runtime-arg switch for each argument.\n" 955d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao " Example: --runtime-arg -Xms256m\n" 9627ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom "\n"); 9769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom exit(EXIT_FAILURE); 9869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom} 9969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 100ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromclass Dex2Oat { 101ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom public: 102ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 1035523ee070b005576c6f889415205d49ea77cf243Elliott Hughes static Dex2Oat* Create(Runtime::Options& options, size_t thread_count) { 104ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom UniquePtr<Runtime> runtime(CreateRuntime(options)); 105ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (runtime.get() == NULL) { 106ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return NULL; 107254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson } 1085523ee070b005576c6f889415205d49ea77cf243Elliott Hughes return new Dex2Oat(runtime.release(), thread_count); 109ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 110ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 111ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom ~Dex2Oat() { 112ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom delete runtime_; 1135523ee070b005576c6f889415205d49ea77cf243Elliott Hughes LOG(INFO) << "dex2oat took " << PrettyDuration(NanoTime() - start_ns_) << " (threads: " << thread_count_ << ")"; 114ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 115ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 116ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // Make a list of descriptors for classes to include in the image 117ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::set<std::string>* GetImageClassDescriptors(const char* image_classes_filename) { 118ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom UniquePtr<std::ifstream> image_classes_file(new std::ifstream(image_classes_filename, std::ifstream::in)); 119ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes_file.get() == NULL) { 120ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(ERROR) << "Failed to open image classes file " << image_classes_filename; 121ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return NULL; 122ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 123ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 1246f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // Load all the classes specified in the file 125ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom ClassLinker* class_linker = runtime_->GetClassLinker(); 126ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom while (image_classes_file->good()) { 127ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::string dot; 128ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::getline(*image_classes_file.get(), dot); 129ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (StringPiece(dot).starts_with("#") || dot.empty()) { 130ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom continue; 131ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 132955724179c6c739524f610023287f56b24dc31deElliott Hughes std::string descriptor(DotToDescriptor(dot.c_str())); 133c3b77c7c2971124cbf3b2d9da64e7a8a9a649f2eElliott Hughes SirtRef<Class> klass(class_linker->FindSystemClass(descriptor.c_str())); 134ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (klass.get() == NULL) { 135ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(WARNING) << "Failed to find class " << descriptor; 136ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Thread::Current()->ClearException(); 137ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 138ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 139ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom image_classes_file->close(); 140ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 1416f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // Resolve exception classes referenced by the loaded classes. The catch logic assumes 1426f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // exceptions are resolved by the verifier when there is a catch block in an interested method. 1436f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // Do this here so that exception classes appear to have been specified image classes. 1446f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers std::set<std::pair<uint16_t, const DexFile*> > unresolved_exception_types; 1456f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers do { 1466f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers unresolved_exception_types.clear(); 1476f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers class_linker->VisitClasses(ResolveCatchBlockExceptionsClassVisitor, 1486f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers &unresolved_exception_types); 1496f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers typedef std::set<std::pair<uint16_t, const DexFile*> >::const_iterator It; // TODO: C++0x auto 1506f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers for (It it = unresolved_exception_types.begin(), 1516f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers end = unresolved_exception_types.end(); 1526f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers it != end; ++it) { 1536f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers uint16_t exception_type_idx = it->first; 1546f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers const DexFile* dex_file = it->second; 1556f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers DexCache* dex_cache = class_linker->FindDexCache(*dex_file); 1566f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers ClassLoader* class_loader = NULL; 1576f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers SirtRef<Class> klass(class_linker->ResolveType(*dex_file, exception_type_idx, dex_cache, 1586f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers class_loader)); 1596f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers if (klass.get() == NULL) { 1606f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers const DexFile::TypeId& type_id = dex_file->GetTypeId(exception_type_idx); 1616f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers const char* descriptor = dex_file->GetTypeDescriptor(type_id); 1626f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers LOG(FATAL) << "Failed to resolve class " << descriptor; 1636f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 1646f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers DCHECK(klass->IsThrowableClass()); 1656f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 1666f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // Resolving exceptions may load classes that reference more exceptions, iterate until no 1676f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // more are found 1686f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } while (!unresolved_exception_types.empty()); 1696f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers 170ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // We walk the roots looking for classes so that we'll pick up the 171ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // above classes plus any classes them depend on such super 172ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // classes, interfaces, and the required ClassLinker roots. 173ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom UniquePtr<std::set<std::string> > image_classes(new std::set<std::string>()); 1746f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers class_linker->VisitClasses(RecordImageClassesVisitor, image_classes.get()); 175ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom CHECK_NE(image_classes->size(), 0U); 176ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return image_classes.release(); 177254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson } 178254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson 179ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom bool CreateOatFile(const std::string& boot_image_option, 180a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom const std::vector<const DexFile*>& dex_files, 181ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom File* oat_file, 182ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom bool image, 183ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::set<std::string>* image_classes) { 184ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // SirtRef and ClassLoader creation needs to come after Runtime::Create 185ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom UniquePtr<SirtRef<ClassLoader> > class_loader(new SirtRef<ClassLoader>(NULL)); 186ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (class_loader.get() == NULL) { 187ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(ERROR) << "Failed to create SirtRef for class loader"; 188ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return false; 189254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson } 190ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 191ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!boot_image_option.empty()) { 192ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 193ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::vector<const DexFile*> class_path_files(dex_files); 194ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom OpenClassPathFiles(runtime_->GetClassPath(), class_path_files); 195ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i < class_path_files.size(); i++) { 196ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom class_linker->RegisterDexFile(*class_path_files[i]); 197ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 198ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom class_loader.get()->reset(PathClassLoader::AllocCompileTime(class_path_files)); 199254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson } 200ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 2015523ee070b005576c6f889415205d49ea77cf243Elliott Hughes Compiler compiler(instruction_set_, image, thread_count_, image_classes); 202ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom compiler.CompileAll(class_loader->get(), dex_files); 203ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 20410037c866b04550fc5461058c398c2e3e509381ajeffhao if (!OatWriter::Create(oat_file, class_loader->get(), dex_files, compiler)) { 205ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(ERROR) << "Failed to create oat file " << oat_file->name(); 206ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return false; 207ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 208ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return true; 209254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson } 210ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 211ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom bool CreateImageFile(const char* image_filename, 212ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom uintptr_t image_base, 213ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::set<std::string>* image_classes, 214ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::string& oat_filename, 215ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const std::string& host_prefix) { 216ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // If we have an existing boot image, position new space after its oat file 217ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (Heap::GetSpaces().size() > 1) { 21830fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers ImageSpace* last_image_space = NULL; 21930fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers const std::vector<Space*>& spaces = Heap::GetSpaces(); 22030fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers for (size_t i=0; i < spaces.size(); i++) { 22130fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers if (spaces[i]->IsImageSpace()) { 22230fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers last_image_space = spaces[i]->AsImageSpace(); 22330fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers } 22430fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers } 225ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom CHECK(last_image_space != NULL); 226ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom CHECK(last_image_space->IsImageSpace()); 227ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom CHECK(!Heap::GetSpaces()[Heap::GetSpaces().size()-1]->IsImageSpace()); 22830fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers byte* oat_limit_addr = last_image_space->GetImageHeader().GetOatEnd(); 229ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom image_base = RoundUp(reinterpret_cast<uintptr_t>(oat_limit_addr), kPageSize); 230ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 231ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 232ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom ImageWriter image_writer(image_classes); 233ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!image_writer.Write(image_filename, image_base, oat_filename, host_prefix)) { 234ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(ERROR) << "Failed to create image file " << image_filename; 235ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return false; 236ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 237ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return true; 238ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 239ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 240ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom private: 241ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 2425523ee070b005576c6f889415205d49ea77cf243Elliott Hughes explicit Dex2Oat(Runtime* runtime, size_t thread_count) 2435523ee070b005576c6f889415205d49ea77cf243Elliott Hughes : runtime_(runtime), thread_count_(thread_count), start_ns_(NanoTime()) { 244bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes } 245ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 246ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom static Runtime* CreateRuntime(Runtime::Options& options) { 247ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Runtime* runtime = Runtime::Create(options, false); 248ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (runtime == NULL) { 249ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(ERROR) << "Failed to create runtime"; 250ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return NULL; 251ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 252ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 253ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // if we loaded an existing image, we will reuse values from the image roots. 254ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!runtime->HasJniDlsymLookupStub()) { 2558add92dcf59568c72c17e9a979948b1a7a0b1264Elliott Hughes runtime->SetJniDlsymLookupStub(Compiler::CreateJniDlsymLookupStub(instruction_set_)); 256ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 257ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!runtime->HasAbstractMethodErrorStubArray()) { 258ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom runtime->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(instruction_set_)); 259ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 260ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) { 261ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Runtime::TrampolineType type = Runtime::TrampolineType(i); 262ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!runtime->HasResolutionStubArray(type)) { 263ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom runtime->SetResolutionStubArray(Compiler::CreateResolutionStub(instruction_set_, type), type); 264ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 265ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 266ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { 267ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i); 268ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!runtime->HasCalleeSaveMethod(type)) { 269ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom runtime->SetCalleeSaveMethod(runtime->CreateCalleeSaveMethod(instruction_set_, type), type); 270ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 271ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 272ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return runtime; 273ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 274ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 2756f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers static void ResolveExceptionsForMethod(MethodHelper* mh, 2766f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers std::set<std::pair<uint16_t, const DexFile*> >& exceptions_to_resolve) { 2776f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers const DexFile::CodeItem* code_item = mh->GetCodeItem(); 2786f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers if (code_item == NULL) { 2796f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers return; // native or abstract method 2806f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 2816f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers if (code_item->tries_size_ == 0) { 2826f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers return; // nothing to process 2836f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 2846f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers const byte* encoded_catch_handler_list = DexFile::GetCatchHandlerData(*code_item, 0); 2856f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers size_t num_encoded_catch_handlers = DecodeUnsignedLeb128(&encoded_catch_handler_list); 2866f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers for (size_t i = 0; i < num_encoded_catch_handlers; i++) { 2876f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers int32_t encoded_catch_handler_size = DecodeSignedLeb128(&encoded_catch_handler_list); 2886f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers bool has_catch_all = false; 2896f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers if (encoded_catch_handler_size <= 0) { 2906f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers encoded_catch_handler_size = -encoded_catch_handler_size; 2916f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers has_catch_all = true; 2926f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 2936f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers for (int32_t j = 0; j < encoded_catch_handler_size; j++) { 2946f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers uint16_t encoded_catch_handler_handlers_type_idx = 2956f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers DecodeUnsignedLeb128(&encoded_catch_handler_list); 2966f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // Add to set of types to resolve if not already in the dex cache resolved types 2976f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers if (!mh->IsResolvedTypeIdx(encoded_catch_handler_handlers_type_idx)) { 2986f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers exceptions_to_resolve.insert( 2996f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers std::pair<uint16_t, const DexFile*>(encoded_catch_handler_handlers_type_idx, 3006f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers &mh->GetDexFile())); 3016f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 3026f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // ignore address associated with catch handler 3036f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers DecodeUnsignedLeb128(&encoded_catch_handler_list); 3046f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 3056f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers if (has_catch_all) { 3066f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers // ignore catch all address 3076f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers DecodeUnsignedLeb128(&encoded_catch_handler_list); 3086f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 3096f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 3106f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 3116f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers static bool ResolveCatchBlockExceptionsClassVisitor(Class* c, void* arg) { 3126f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers std::set<std::pair<uint16_t, const DexFile*> >* exceptions_to_resolve = 3136f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers reinterpret_cast<std::set<std::pair<uint16_t, const DexFile*> >*>(arg); 3146f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers MethodHelper mh; 3156f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers for (size_t i = 0; i < c->NumVirtualMethods(); ++i) { 3166f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers Method* m = c->GetVirtualMethod(i); 3176f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers mh.ChangeMethod(m); 3186f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers ResolveExceptionsForMethod(&mh, *exceptions_to_resolve); 3196f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 3206f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers for (size_t i = 0; i < c->NumDirectMethods(); ++i) { 3216f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers Method* m = c->GetDirectMethod(i); 3226f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers mh.ChangeMethod(m); 3236f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers ResolveExceptionsForMethod(&mh, *exceptions_to_resolve); 3246f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 3256f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers return true; 3266f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers } 3276f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers static bool RecordImageClassesVisitor(Class* klass, void* arg) { 328ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::set<std::string>* image_classes = reinterpret_cast<std::set<std::string>*>(arg); 329ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (klass->IsArrayClass() || klass->IsPrimitive()) { 330ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return true; 331ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 3326d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers image_classes->insert(ClassHelper(klass).GetDescriptor()); 333ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return true; 334ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 335ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 336ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // Appends to dex_files any elements of class_path that it doesn't already 337ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // contain. This will open those dex files as necessary. 338ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom static void OpenClassPathFiles(const std::string& class_path, std::vector<const DexFile*>& dex_files) { 339ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom std::vector<std::string> parsed; 340ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom Split(class_path, ':', parsed); 341ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i < parsed.size(); ++i) { 342ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (DexFilesContains(dex_files, parsed[i])) { 343ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom continue; 344ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 345ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const DexFile* dex_file = DexFile::Open(parsed[i], Runtime::Current()->GetHostPrefix()); 346ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (dex_file == NULL) { 347ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(WARNING) << "Failed to open dex file " << parsed[i]; 348ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } else { 349ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom dex_files.push_back(dex_file); 350ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 351ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 352ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 353ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 354ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // Returns true if dex_files has a dex with the named location. 355ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom static bool DexFilesContains(const std::vector<const DexFile*>& dex_files, const std::string& location) { 356ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom for (size_t i = 0; i < dex_files.size(); ++i) { 357ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (dex_files[i]->GetLocation() == location) { 358ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return true; 359ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 360ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 361ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return false; 362ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 363ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 364ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom static const InstructionSet instruction_set_ = kThumb2; 365ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 366bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes Runtime* runtime_; 3675523ee070b005576c6f889415205d49ea77cf243Elliott Hughes size_t thread_count_; 368bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes uint64_t start_ns_; 369bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes 370ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom DISALLOW_IMPLICIT_CONSTRUCTORS(Dex2Oat); 371ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom}; 372254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson 373bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughesbool ParseInt(const char* in, int* out) { 374a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom char* end; 375a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom int result = strtol(in, &end, 10); 376a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (in == end || *end != '\0') { 377a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom return false; 378a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 379a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom *out = result; 380a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom return true; 381a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom} 382a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom 3835b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstromvoid OpenDexFiles(const std::vector<const char*>& dex_filenames, 3845b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom std::vector<const DexFile*>& dex_files, 3855b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom const std::string& strip_location_prefix) { 3865b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom for (size_t i = 0; i < dex_filenames.size(); i++) { 3875b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom const char* dex_filename = dex_filenames[i]; 3885b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom const DexFile* dex_file = DexFile::Open(dex_filename, strip_location_prefix); 3895b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom if (dex_file == NULL) { 3905b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom fprintf(stderr, "could not open .dex from file %s\n", dex_filename); 3915b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom exit(EXIT_FAILURE); 3925b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom } 3935b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom dex_files.push_back(dex_file); 3945b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom } 3955b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom} 3965b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom 3975b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom 39869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromint dex2oat(int argc, char** argv) { 39969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom // Skip over argv[0]. 40069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom argv++; 40169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom argc--; 40269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 40369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (argc == 0) { 40469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, "no arguments specified\n"); 40569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom usage(); 40669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 40769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 40869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom std::vector<const char*> dex_filenames; 409a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom int zip_fd = -1; 410a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom std::string zip_name; 411e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom std::string oat_filename; 412a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom int oat_fd = -1; 413a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom std::string oat_name; 41469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom const char* image_filename = NULL; 415ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const char* image_classes_filename = NULL; 416b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom std::string boot_image_filename; 41769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom uintptr_t image_base = 0; 41858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom std::string host_prefix; 4195d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao std::vector<const char*> runtime_args; 42097574f4589041ecb652ff30a0fb5e55eeffb5ea0Brian Carlstrom#if defined(__APPLE__) 42197574f4589041ecb652ff30a0fb5e55eeffb5ea0Brian Carlstrom // Apple lacks GetOwner and therefore working Mutexes, so only use one thread on that platform 42297574f4589041ecb652ff30a0fb5e55eeffb5ea0Brian Carlstrom int thread_count = 1; 42397574f4589041ecb652ff30a0fb5e55eeffb5ea0Brian Carlstrom#else 4245523ee070b005576c6f889415205d49ea77cf243Elliott Hughes int thread_count = 2; 42597574f4589041ecb652ff30a0fb5e55eeffb5ea0Brian Carlstrom#endif 426161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom 42769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom for (int i = 0; i < argc; i++) { 42869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom const StringPiece option(argv[i]); 429a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom bool log_options = false; 430a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (log_options) { 431b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i]; 432b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom } 43369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (option.starts_with("--dex-file=")) { 43469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom dex_filenames.push_back(option.substr(strlen("--dex-file=")).data()); 435a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } else if (option.starts_with("--zip-fd=")) { 436a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom const char* zip_fd_str = option.substr(strlen("--zip-fd=")).data(); 437bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes if (!ParseInt(zip_fd_str, &zip_fd)) { 438866c8627626b7c47fb69b498b341772d7dfa7f60Brian Carlstrom fprintf(stderr, "could not parse --zip-fd argument '%s' as an integer\n", zip_fd_str); 439a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom usage(); 440a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 441a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } else if (option.starts_with("--zip-name=")) { 442a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom zip_name = option.substr(strlen("--zip-name=")).data(); 443a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } else if (option.starts_with("--oat-file=")) { 444a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom oat_filename = option.substr(strlen("--oat-file=")).data(); 445a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } else if (option.starts_with("--oat-fd=")) { 446a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom const char* oat_fd_str = option.substr(strlen("--oat-fd=")).data(); 447bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes if (!ParseInt(oat_fd_str, &oat_fd)) { 448866c8627626b7c47fb69b498b341772d7dfa7f60Brian Carlstrom fprintf(stderr, "could not parse --oat-fd argument '%s' as an integer\n", oat_fd_str); 449a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom usage(); 450a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 4515523ee070b005576c6f889415205d49ea77cf243Elliott Hughes } else if (option.starts_with("-j")) { 45297574f4589041ecb652ff30a0fb5e55eeffb5ea0Brian Carlstrom#if! defined(__APPLE__) 453b12552a95d68b9e4a567103190074ae47b6a61dcBrian Carlstrom const char* thread_count_str = option.substr(strlen("-j")).data(); 45497574f4589041ecb652ff30a0fb5e55eeffb5ea0Brian Carlstrom // Apple lacks GetOwner and therefore working Mutexes, so we ignore -j on that platform 4555523ee070b005576c6f889415205d49ea77cf243Elliott Hughes if (!ParseInt(thread_count_str, &thread_count)) { 4565523ee070b005576c6f889415205d49ea77cf243Elliott Hughes fprintf(stderr, "could not parse -j argument '%s' as an integer\n", thread_count_str); 4575523ee070b005576c6f889415205d49ea77cf243Elliott Hughes usage(); 4585523ee070b005576c6f889415205d49ea77cf243Elliott Hughes } 45997574f4589041ecb652ff30a0fb5e55eeffb5ea0Brian Carlstrom#endif 460a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } else if (option.starts_with("--oat-name=")) { 461a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom oat_name = option.substr(strlen("--oat-name=")).data(); 46269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } else if (option.starts_with("--image=")) { 46369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom image_filename = option.substr(strlen("--image=")).data(); 464ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } else if (option.starts_with("--image-classes=")) { 465ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom image_classes_filename = option.substr(strlen("--image-classes=")).data(); 46669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } else if (option.starts_with("--base=")) { 46769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom const char* image_base_str = option.substr(strlen("--base=")).data(); 46869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom char* end; 46969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom image_base = strtoul(image_base_str, &end, 16); 47069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (end == image_base_str || *end != '\0') { 47127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom fprintf(stderr, "Failed to parse hexadecimal value for option %s\n", option.data()); 47269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom usage(); 47369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 474e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } else if (option.starts_with("--boot-image=")) { 475b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom boot_image_filename = option.substr(strlen("--boot-image=")).data(); 47658ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom } else if (option.starts_with("--host-prefix=")) { 47758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom host_prefix = option.substr(strlen("--host-prefix=")).data(); 4785d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao } else if (option == "--runtime-arg") { 4795d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao if (++i >= argc) { 4805d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao fprintf(stderr, "Missing required argument for --runtime-arg\n"); 4815d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao usage(); 4825d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao } 483a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (log_options) { 484a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i]; 485a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 4865d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao runtime_args.push_back(argv[i]); 48769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } else { 48869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, "unknown argument %s\n", option.data()); 48969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom usage(); 49069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 49169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 49269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 493a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (oat_filename.empty() && oat_fd == -1) { 494a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom fprintf(stderr, "Output must be supplied with either --oat-file or --oat-fd\n"); 495a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom return EXIT_FAILURE; 496a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 497a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom 498a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (!oat_filename.empty() && oat_fd != -1) { 499a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom fprintf(stderr, "--oat-file should not be used with --oat-fd\n"); 500a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom return EXIT_FAILURE; 501a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 502a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom 503a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (!oat_filename.empty() && oat_fd != -1) { 504a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom fprintf(stderr, "--oat-file should not be used with --oat-fd\n"); 505a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom return EXIT_FAILURE; 506a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 507a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom 508a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (!oat_filename.empty() && !oat_name.empty()) { 509a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom fprintf(stderr, "--oat-file should not be used with --oat-name\n"); 510a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom return EXIT_FAILURE; 511a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 512a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom 513a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (oat_fd != -1 && oat_name.empty()) { 514a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom fprintf(stderr, "--oat-name should be supplied with --oat-fd\n"); 515a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom return EXIT_FAILURE; 516a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 517a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom 518a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (oat_fd != -1 && image_filename != NULL) { 519a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom fprintf(stderr, "--oat-fd should not be used with --image\n"); 520362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes return EXIT_FAILURE; 521e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 522e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 523b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom if (host_prefix.empty()) { 524b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom const char* android_product_out = getenv("ANDROID_PRODUCT_OUT"); 525b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom if (android_product_out != NULL) { 526b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom host_prefix = android_product_out; 527b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom } 528b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom } 529b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom 530ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom bool image = (image_filename != NULL); 531b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom if (!image && boot_image_filename.empty()) { 532b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom boot_image_filename += host_prefix; 533a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom boot_image_filename += "/system/framework/boot.art"; 534b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom } 535b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom std::string boot_image_option; 536b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom if (boot_image_filename != NULL) { 537b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom boot_image_option += "-Ximage:"; 538b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom boot_image_option += boot_image_filename; 53969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 54069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 541ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes_filename != NULL && !image) { 542ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom fprintf(stderr, "--image-classes should only be used with --image\n"); 543ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return EXIT_FAILURE; 544ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom } 545ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom 546ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes_filename != NULL && !boot_image_option.empty()) { 547ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom fprintf(stderr, "--image-classes should not be used with --boot-image\n"); 548362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes return EXIT_FAILURE; 54978128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 55078128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 551a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (dex_filenames.empty() && zip_fd == -1) { 552a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom fprintf(stderr, "Input must be supplied with either --dex-file or --zip-fd\n"); 553a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom return EXIT_FAILURE; 554a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 555a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom 556a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (!dex_filenames.empty() && zip_fd != -1) { 557a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom fprintf(stderr, "--dex-file should not be used with --zip-fd\n"); 558a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom return EXIT_FAILURE; 559a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 560a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom 561a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (!dex_filenames.empty() && !zip_name.empty()) { 562a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom fprintf(stderr, "--dex-file should not be used with --zip-name\n"); 563a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom return EXIT_FAILURE; 564a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 565a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom 566a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (zip_fd != -1 && zip_name.empty()) { 567a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom fprintf(stderr, "--zip-name should be supplied with --zip-fd\n"); 568a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom return EXIT_FAILURE; 569a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 570a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom 57169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (boot_image_option.empty()) { 57269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (image_base == 0) { 57369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, "non-zero --base not specified\n"); 57469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return EXIT_FAILURE; 57569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 57669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 57769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 5786ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom // Check early that the result of compilation can be written 579a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom UniquePtr<File> oat_file; 580a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (!oat_filename.empty()) { 581a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom oat_file.reset(OS::OpenFile(oat_filename.c_str(), true)); 582a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom oat_name = oat_filename; 583a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } else { 584a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom oat_file.reset(OS::FileFromFd(oat_name.c_str(), oat_fd)); 585a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 5866ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom if (oat_file.get() == NULL) { 587fd8cba4ad6d4d0586dc783c031383a9ca953372dElliott Hughes PLOG(ERROR) << "Unable to create oat file: " << oat_name; 5886ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom return EXIT_FAILURE; 589234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes } 590a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom 591a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom LOG(INFO) << "dex2oat: " << oat_name; 5925e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers 59369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom Runtime::Options options; 5945de8fe5253ca8bd285cba0eb2e56930573ea4c7fBrian Carlstrom options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL))); 595b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom std::string boot_class_path_string; 59669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (boot_image_option.empty()) { 59758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom boot_class_path_string += "-Xbootclasspath:"; 59858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom for (size_t i = 0; i < dex_filenames.size()-1; i++) { 59958ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom boot_class_path_string += dex_filenames[i]; 60058ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom boot_class_path_string += ":"; 60158ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom } 60258ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom boot_class_path_string += dex_filenames[dex_filenames.size()-1]; 60358ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom options.push_back(std::make_pair(boot_class_path_string.c_str(), reinterpret_cast<void*>(NULL))); 60469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } else { 60569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom options.push_back(std::make_pair(boot_image_option.c_str(), reinterpret_cast<void*>(NULL))); 60669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 60758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom if (!host_prefix.empty()) { 60858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom options.push_back(std::make_pair("host-prefix", host_prefix.c_str())); 60958ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom } 6105d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao for (size_t i = 0; i < runtime_args.size(); i++) { 6115d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao options.push_back(std::make_pair(runtime_args[i], reinterpret_cast<void*>(NULL))); 6125d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao } 61369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 6145523ee070b005576c6f889415205d49ea77cf243Elliott Hughes UniquePtr<Dex2Oat> dex2oat(Dex2Oat::Create(options, thread_count)); 61569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 616bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes // If --image-classes was specified, calculate the full list of classes to include in the image 617ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom UniquePtr<const std::set<std::string> > image_classes(NULL); 618ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes_filename != NULL) { 619ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom image_classes.reset(dex2oat->GetImageClassDescriptors(image_classes_filename)); 620ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (image_classes.get() == NULL) { 621ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom LOG(ERROR) << "Failed to create list of image classes from " << image_classes_filename; 622ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom return EXIT_FAILURE; 62369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 62469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 62569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 626a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom std::vector<const DexFile*> dex_files; 627a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (boot_image_option.empty()) { 628a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom dex_files = Runtime::Current()->GetClassLinker()->GetBootClassPath(); 629a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } else { 630a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (dex_filenames.empty()) { 631a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom UniquePtr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(zip_fd)); 632a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (zip_archive.get() == NULL) { 633a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom LOG(ERROR) << "Failed to zip from file descriptor for " << zip_name; 6342e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom return EXIT_FAILURE; 635a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 636a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom const DexFile* dex_file = DexFile::Open(*zip_archive.get(), zip_name); 637a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (dex_file == NULL) { 638fd8cba4ad6d4d0586dc783c031383a9ca953372dElliott Hughes LOG(ERROR) << "Failed to open dex from file descriptor for zip file: " << zip_name; 639a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom return EXIT_FAILURE; 640a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 641a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom dex_files.push_back(dex_file); 642a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } else { 6435b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom OpenDexFiles(dex_filenames, dex_files, host_prefix); 644a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 645a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom } 646a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom 647ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!dex2oat->CreateOatFile(boot_image_option, 648a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom dex_files, 649ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom oat_file.get(), 650ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom image, 651ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom image_classes.get())) { 652fd8cba4ad6d4d0586dc783c031383a9ca953372dElliott Hughes LOG(ERROR) << "Failed to create oat file: " << oat_name; 653e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return EXIT_FAILURE; 654e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 655e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 656ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!image) { 657fd8cba4ad6d4d0586dc783c031383a9ca953372dElliott Hughes LOG(INFO) << "Oat file written successfully: " << oat_name; 658aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom return EXIT_SUCCESS; 659aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 660aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 661ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom if (!dex2oat->CreateImageFile(image_filename, 662ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom image_base, 663ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom image_classes.get(), 664ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom oat_filename, 665ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom host_prefix)) { 66669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return EXIT_FAILURE; 66769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 66869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 669ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom // We wrote the oat file successfully, and want to keep it. 670bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes LOG(INFO) << "Oat file written successfully: " << oat_filename; 671bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes LOG(INFO) << "Image written successfully: " << image_filename; 67269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return EXIT_SUCCESS; 67369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom} 67469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 67569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom} // namespace art 67669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 67769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromint main(int argc, char** argv) { 67869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return art::dex2oat(argc, argv); 67969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom} 680