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