dex2oat.cc revision 5e863ddd72a70d33525f7403a695f7bc1c218938
169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom// Copyright 2011 Google Inc. All Rights Reserved. 269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include <stdio.h> 469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include <stdlib.h> 569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include <string> 769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include <vector> 869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "class_linker.h" 1069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "class_loader.h" 1169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "compiler.h" 125e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers#include "file.h" 1369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "image_writer.h" 14e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "oat_writer.h" 155e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers#include "os.h" 1669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "runtime.h" 1769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "stringpiece.h" 1869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 1969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromnamespace art { 2069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 2169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromstatic void usage() { 2269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 2369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom "Usage: dex2oat [options]...\n" 2469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom "\n"); 2569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 2678128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom " --dex-file=<dex-file>: specifies a .dex file to compile. At least one .dex\n" 2778128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom " file must be specified. \n" 2869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom " Example: --dex-file=/system/framework/core.jar\n" 2969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom "\n"); 3069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 31e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom " --image=<file.art>: specifies the required output image filename.\n" 3247a0d5a6f221066c3daf7f67f2122ed9c9cd217cBrian Carlstrom " Example: --image=/data/art-cache/boot.art\n" 33e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom "\n"); 34e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // TODO: remove this by inferring from --image 35e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom fprintf(stderr, 36e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom " --oat=<file.oat>: specifies the required oat filename.\n" 3747a0d5a6f221066c3daf7f67f2122ed9c9cd217cBrian Carlstrom " Example: --image=/data/art-cache/boot.oat\n" 3869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom "\n"); 3969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 4069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom " --base=<hex-address>: specifies the base address when creating a boot image.\n" 4169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom " Example: --base=0x50000000\n" 4269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom "\n"); 4369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 44e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom " --boot-image=<file.art>: provide the image file for the boot class path.\n" 4547a0d5a6f221066c3daf7f67f2122ed9c9cd217cBrian Carlstrom " Example: --boot-image=/data/art-cache/boot.art\n" 46e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom "\n"); 4769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, 4869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom " --method may be used to limit compilation to a subset of methods.\n" 4969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom " Example: --method=Ljava/lang/Object;<init>()V\n" 5069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom "\n"); 51161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom fprintf(stderr, 5258ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom " --host-prefix may be used to translate host paths to target paths during\n" 5358ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom " cross compilation.\n" 5458ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom " Example: --host-prefix=out/target/product/crespo\n" 55161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom "\n"); 5627ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom fprintf(stderr, 575d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao " --runtime-arg <argument>: used to specify various arguments for the runtime,\n" 585d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao " such as initial heap size, maximum heap size, and verbose output.\n" 595d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao " Use a separate --runtime-arg switch for each argument.\n" 605d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao " Example: --runtime-arg -Xms256m\n" 6127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom "\n"); 6269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom exit(EXIT_FAILURE); 6369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom} 6469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 6569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromint dex2oat(int argc, char** argv) { 6669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom // Skip over argv[0]. 6769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom argv++; 6869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom argc--; 6969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 7069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (argc == 0) { 7169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, "no arguments specified\n"); 7269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom usage(); 7369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 7469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 7569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom std::vector<const char*> dex_filenames; 7669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom std::vector<const char*> method_names; 77e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom std::string oat_filename; 7869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom const char* image_filename = NULL; 7969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom std::string boot_image_option; 8069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom uintptr_t image_base = 0; 8158ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom std::string host_prefix; 825d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao std::vector<const char*> runtime_args; 83161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom 8469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom for (int i = 0; i < argc; i++) { 8569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom const StringPiece option(argv[i]); 86b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom if (false) { 87b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i]; 88b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom } 8969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (option.starts_with("--dex-file=")) { 9069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom dex_filenames.push_back(option.substr(strlen("--dex-file=")).data()); 9169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } else if (option.starts_with("--method=")) { 9269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom method_names.push_back(option.substr(strlen("--method=")).data()); 93e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } else if (option.starts_with("--oat=")) { 94e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom oat_filename = option.substr(strlen("--oat=")).data(); 9569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } else if (option.starts_with("--image=")) { 9669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom image_filename = option.substr(strlen("--image=")).data(); 9769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } else if (option.starts_with("--base=")) { 9869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom const char* image_base_str = option.substr(strlen("--base=")).data(); 9969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom char* end; 10069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom image_base = strtoul(image_base_str, &end, 16); 10169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (end == image_base_str || *end != '\0') { 10227ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom fprintf(stderr, "Failed to parse hexadecimal value for option %s\n", option.data()); 10369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom usage(); 10469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 105e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } else if (option.starts_with("--boot-image=")) { 106e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom const char* boot_image_filename = option.substr(strlen("--boot-image=")).data(); 10769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom boot_image_option.clear(); 10858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom boot_image_option += "-Ximage:"; 10969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom boot_image_option += boot_image_filename; 11058ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom } else if (option.starts_with("--host-prefix=")) { 11158ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom host_prefix = option.substr(strlen("--host-prefix=")).data(); 1125d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao } else if (option == "--runtime-arg") { 1135d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao if (++i >= argc) { 1145d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao fprintf(stderr, "Missing required argument for --runtime-arg\n"); 1155d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao usage(); 1165d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao } 1175d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao runtime_args.push_back(argv[i]); 11869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } else { 11969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, "unknown argument %s\n", option.data()); 12069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom usage(); 12169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 12269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 12369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 124e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (oat_filename == NULL) { 125362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes fprintf(stderr, "--oat file name not specified\n"); 126362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes return EXIT_FAILURE; 127e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 128e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 129aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom if (image_filename == NULL && boot_image_option.empty()) { 130362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes fprintf(stderr, "Either --image or --boot-image must be specified\n"); 131362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes return EXIT_FAILURE; 13269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 13369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 13478128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom if (dex_filenames.empty()) { 135362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes fprintf(stderr, "no --dex-file values specified\n"); 136362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes return EXIT_FAILURE; 13778128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 13878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 13969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (boot_image_option.empty()) { 14069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (image_base == 0) { 14169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom fprintf(stderr, "non-zero --base not specified\n"); 14269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return EXIT_FAILURE; 14369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 14469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 14569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 1465e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers // Check early that the result of compilation can be written 1475e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers if (OS::FileExists(oat_filename.c_str())) { 1485e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers // File exists, check we can write to it 1495e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers UniquePtr<File> file(OS::OpenFile(oat_filename.c_str(), true)); 1505e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers if (file.get() == NULL) { 1515e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers PLOG(ERROR) << "Unable to create oat file " << oat_filename; 1525e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers return EXIT_FAILURE; 1535e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers } 1545e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers } 1555e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers LOG(INFO) << "dex2oat: " << oat_filename; 1565e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers 15769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom Runtime::Options options; 1585de8fe5253ca8bd285cba0eb2e56930573ea4c7fBrian Carlstrom options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL))); 159b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom std::string boot_class_path_string; 16069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (boot_image_option.empty()) { 16158ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom boot_class_path_string += "-Xbootclasspath:"; 16258ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom for (size_t i = 0; i < dex_filenames.size()-1; i++) { 16358ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom boot_class_path_string += dex_filenames[i]; 16458ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom boot_class_path_string += ":"; 16558ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom } 16658ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom boot_class_path_string += dex_filenames[dex_filenames.size()-1]; 16758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom options.push_back(std::make_pair(boot_class_path_string.c_str(), reinterpret_cast<void*>(NULL))); 16869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } else { 16969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom options.push_back(std::make_pair(boot_image_option.c_str(), reinterpret_cast<void*>(NULL))); 17069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 17158ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom if (!host_prefix.empty()) { 17258ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom options.push_back(std::make_pair("host-prefix", host_prefix.c_str())); 17358ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom } 1745d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao for (size_t i = 0; i < runtime_args.size(); i++) { 1755d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao options.push_back(std::make_pair(runtime_args[i], reinterpret_cast<void*>(NULL))); 1765d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao } 17769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom UniquePtr<Runtime> runtime(Runtime::Create(options, false)); 17869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (runtime.get() == NULL) { 1793fe79571ff3507d478a9d447f0d3fb99abadc7a8Ian Rogers LOG(ERROR) << "Could not create runtime"; 18069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return EXIT_FAILURE; 18169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 18269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom ClassLinker* class_linker = runtime->GetClassLinker(); 18369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 184e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // If we have an existing boot image, position new space after its oat file 18558ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom if (Heap::GetSpaces().size() > 1) { 18658ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom Space* last_image_space = Heap::GetSpaces()[Heap::GetSpaces().size()-2]; 18758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom CHECK(last_image_space != NULL); 18858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom CHECK(last_image_space->IsImageSpace()); 18958ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom CHECK(!Heap::GetSpaces()[Heap::GetSpaces().size()-1]->IsImageSpace()); 19058ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom byte* oat_limit_addr = last_image_space->GetImageHeader().GetOatLimitAddr(); 191e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom image_base = RoundUp(reinterpret_cast<uintptr_t>(oat_limit_addr), kPageSize); 19269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 19369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 19469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom // ClassLoader creation needs to come after Runtime::Create 19540381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom SirtRef<ClassLoader> class_loader(NULL); 19640381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom if (!boot_image_option.empty()) { 19758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom std::vector<const DexFile*> dex_files; 19858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom DexFile::OpenDexFiles(dex_filenames, dex_files, host_prefix); 19969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom for (size_t i = 0; i < dex_files.size(); i++) { 20069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom class_linker->RegisterDexFile(*dex_files[i]); 20169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 20240381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom class_loader.reset(PathClassLoader::AllocCompileTime(dex_files)); 20369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 20469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 205e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom // if we loaded an existing image, we will reuse values from the image roots. 206161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom if (!runtime->HasJniStubArray()) { 207161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom runtime->SetJniStubArray(JniCompiler::CreateJniStub(kThumb2)); 208161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom } 209e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom if (!runtime->HasAbstractMethodErrorStubArray()) { 210e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom runtime->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(kThumb2)); 211e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 2124f0d07c783afef89703dce32c94440fc8621a29bIan Rogers for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) { 2131cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers Runtime::TrampolineType type = Runtime::TrampolineType(i); 2141cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers if (!runtime->HasResolutionStubArray(type)) { 2151cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers runtime->SetResolutionStubArray(Compiler::CreateResolutionStub(kThumb2, type), type); 2161cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers } 217ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers } 2184f0d07c783afef89703dce32c94440fc8621a29bIan Rogers for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { 2194f0d07c783afef89703dce32c94440fc8621a29bIan Rogers Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i); 2204f0d07c783afef89703dce32c94440fc8621a29bIan Rogers if (!runtime->HasCalleeSaveMethod(type)) { 2214f0d07c783afef89703dce32c94440fc8621a29bIan Rogers runtime->SetCalleeSaveMethod(runtime->CreateCalleeSaveMethod(kThumb2, type), type); 2224f0d07c783afef89703dce32c94440fc8621a29bIan Rogers } 223ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogers } 224aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom Compiler compiler(kThumb2, image_filename != NULL); 22569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (method_names.empty()) { 22640381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom compiler.CompileAll(class_loader.get()); 22769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } else { 22869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom for (size_t i = 0; i < method_names.size(); i++) { 22969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom // names are actually class_descriptor + name + signature. 23069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom // example: Ljava/lang/Object;<init>()V 23169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom StringPiece method_name = method_names[i]; 23269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom size_t end_of_class_descriptor = method_name.find(';'); 23369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (end_of_class_descriptor == method_name.npos) { 2343fe79571ff3507d478a9d447f0d3fb99abadc7a8Ian Rogers LOG(ERROR) << "Could not find class descriptor in method " << method_name << "'"; 23569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return EXIT_FAILURE; 23669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 23769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom end_of_class_descriptor++; // want to include ; 23869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom std::string class_descriptor = method_name.substr(0, end_of_class_descriptor).ToString(); 23969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom size_t end_of_name = method_name.find('(', end_of_class_descriptor); 24069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (end_of_name == method_name.npos) { 2413fe79571ff3507d478a9d447f0d3fb99abadc7a8Ian Rogers LOG(ERROR) << "Could not find start of method signature in method '" << method_name << "'"; 24269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return EXIT_FAILURE; 24369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 24469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom std::string name = method_name.substr(end_of_class_descriptor, 24569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom end_of_name - end_of_class_descriptor).ToString(); 24669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom std::string signature = method_name.substr(end_of_name).ToString(); 24769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 24840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom Class* klass = class_linker->FindClass(class_descriptor, class_loader.get()); 24969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (klass == NULL) { 2503fe79571ff3507d478a9d447f0d3fb99abadc7a8Ian Rogers LOG(ERROR) << "Could not find class for descriptor '" << class_descriptor 2513fe79571ff3507d478a9d447f0d3fb99abadc7a8Ian Rogers << "' in method '" << method_name << "'"; 25269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return EXIT_FAILURE; 25369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 25469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom Method* method = klass->FindDirectMethod(name, signature); 25569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (method == NULL) { 25669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom method = klass->FindVirtualMethod(name, signature); 25769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 25869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom if (method == NULL) { 2593fe79571ff3507d478a9d447f0d3fb99abadc7a8Ian Rogers LOG(ERROR) << "Could not find method '" << method_name << "' with signature '" 2603fe79571ff3507d478a9d447f0d3fb99abadc7a8Ian Rogers << signature << "' in class '" << class_descriptor << "' for method argument '" 2613fe79571ff3507d478a9d447f0d3fb99abadc7a8Ian Rogers << method_name << "'"; 26269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return EXIT_FAILURE; 26369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 26469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom compiler.CompileOne(method); 26569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 26669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 26769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 26840381fb9dc4b4cf274f1e58b2cdf4396202c6189Brian Carlstrom if (!OatWriter::Create(oat_filename, class_loader.get(), compiler)) { 2693fe79571ff3507d478a9d447f0d3fb99abadc7a8Ian Rogers LOG(ERROR) << "Failed to create oat file " << oat_filename; 270e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom return EXIT_FAILURE; 271e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } 272e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 273aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom if (image_filename == NULL) { 274aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom return EXIT_SUCCESS; 275aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 276aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom CHECK(compiler.IsImage()); 277aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 278e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom ImageWriter image_writer; 27958ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom if (!image_writer.Write(image_filename, image_base, oat_filename, host_prefix)) { 2803fe79571ff3507d478a9d447f0d3fb99abadc7a8Ian Rogers LOG(ERROR) << "Failed to create image file " << image_filename; 28169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return EXIT_FAILURE; 28269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom } 28369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 28469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return EXIT_SUCCESS; 28569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom} 28669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 28769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom} // namespace art 28869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom 28969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromint main(int argc, char** argv) { 29069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom return art::dex2oat(argc, argv); 29169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom} 292