dex2oat.cc revision 2dd0e2cea360bc9206eb88ecc40d259e796c239d
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>
196cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom#include <sys/stat.h>
2069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
21ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom#include <iostream>
22ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom#include <fstream>
2369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include <string>
2469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include <vector>
2569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
261aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "base/stl_util.h"
27e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "base/stringpiece.h"
28761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/unix_file/fd_file.h"
2969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "class_linker.h"
3069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "compiler.h"
3169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "image_writer.h"
326f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers#include "leb128.h"
332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/abstract_method-inl.h"
342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h"
352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h"
362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h"
372dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h"
38e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom#include "oat_writer.h"
396d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h"
405e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers#include "os.h"
4169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "runtime.h"
4200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "ScopedLocalRef.h"
4300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h"
441f5393447b9f45be7918042d9ee7b521376de866Ian Rogers#include "sirt_ref.h"
45bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes#include "timing_logger.h"
46700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom#include "vector_output_stream.h"
4700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "well_known_classes.h"
48a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom#include "zip_archive.h"
4969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
5069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromnamespace art {
5169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
52cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstromstatic void UsageErrorV(const char* fmt, va_list ap) {
53cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  std::string error;
54cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  StringAppendV(&error, fmt, ap);
55cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  LOG(ERROR) << error;
56cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom}
57cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom
58cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstromstatic void UsageError(const char* fmt, ...) {
59cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  va_list ap;
60cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  va_start(ap, fmt);
61cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageErrorV(fmt, ap);
62cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  va_end(ap);
63cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom}
64cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom
65cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstromstatic void Usage(const char* fmt, ...) {
66cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  va_list ap;
67cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  va_start(ap, fmt);
68cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageErrorV(fmt, ap);
69cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  va_end(ap);
70cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom
71cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("Usage: dex2oat [options]...");
72cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
73cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --dex-file=<dex-file>: specifies a .dex file to compile.");
74cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --dex-file=/system/framework/core.jar");
75cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
76cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --zip-fd=<file-descriptor>: specifies a file descriptor of a zip file");
77cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      containing a classes.dex file to compile.");
78cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --zip-fd=5");
79cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
80cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --zip-location=<zip-location>: specifies a symbolic name for the file corresponding");
81cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      to the file descriptor specified by --zip-fd.");
82cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --zip-location=/system/app/Calculator.apk");
83cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
84cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --oat-file=<file.oat>: specifies the required oat filename.");
85cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --oat-file=/system/framework/boot.oat");
86cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
87cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --oat-location=<oat-name>: specifies a symbolic name for the file corresponding");
88cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      to the file descriptor specified by --oat-fd.");
89cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --oat-location=/data/art-cache/system@app@Calculator.apk.oat");
90cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
918b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien  UsageError("  --bitcode=<file.bc>: specifies the optional bitcode filename.");
928b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien  UsageError("      Example: --bitcode=/system/framework/boot.bc");
938b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien  UsageError("");
94cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --image=<file.art>: specifies the output image filename.");
95cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --image=/system/framework/boot.art");
96cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
97cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --image-classes=<classname-file>: specifies classes to include in an image.");
98cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --image=frameworks/base/preloaded-classes");
99cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
100cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --base=<hex-address>: specifies the base address when creating a boot image.");
101cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --base=0x50000000");
102cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
103cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --boot-image=<file.art>: provide the image file for the boot class path.");
104cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --boot-image=/system/framework/boot.art");
105cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Default: <host-prefix>/system/framework/boot.art");
106cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
107cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --host-prefix may be used to translate host paths to target paths during");
108cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      cross compilation.");
109cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --host-prefix=out/target/product/crespo");
110cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Default: $ANDROID_PRODUCT_OUT");
111cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
1121f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao  UsageError("  --instruction-set=(arm|mips|x86): compile for a particular instruction");
11349c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers  UsageError("      set.");
1141f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao  UsageError("      Example: --instruction-set=x86");
1151f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao  UsageError("      Default: arm");
11649c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers  UsageError("");
117c531cefbfb5394413122e9f57d211ba436cff012buzbee  UsageError("  --compiler-backend=(Quick|QuickGBC|Portable): select compiler backend");
118c531cefbfb5394413122e9f57d211ba436cff012buzbee  UsageError("      set.");
119c531cefbfb5394413122e9f57d211ba436cff012buzbee  UsageError("      Example: --instruction-set=Portable");
120c531cefbfb5394413122e9f57d211ba436cff012buzbee  UsageError("      Default: Quick");
121cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --runtime-arg <argument>: used to specify various arguments for the runtime,");
122cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      such as initial heap size, maximum heap size, and verbose output.");
123cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Use a separate --runtime-arg switch for each argument.");
124cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --runtime-arg -Xms256m");
125cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
126cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  std::cerr << "See log for usage error information\n";
12769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  exit(EXIT_FAILURE);
12869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom}
12969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
130ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromclass Dex2Oat {
131ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom public:
132c531cefbfb5394413122e9f57d211ba436cff012buzbee  static bool Create(Dex2Oat** p_dex2oat, Runtime::Options& options, CompilerBackend compiler_backend,
133c531cefbfb5394413122e9f57d211ba436cff012buzbee                     InstructionSet instruction_set, size_t thread_count, bool support_debugging)
134b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_) {
13500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if (!CreateRuntime(options, instruction_set)) {
13600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      *p_dex2oat = NULL;
13700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      return false;
138254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson    }
139c531cefbfb5394413122e9f57d211ba436cff012buzbee    *p_dex2oat = new Dex2Oat(Runtime::Current(), compiler_backend, instruction_set, thread_count,
140c531cefbfb5394413122e9f57d211ba436cff012buzbee                             support_debugging);
14100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return true;
142ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
143ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
144ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  ~Dex2Oat() {
145ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    delete runtime_;
1465523ee070b005576c6f889415205d49ea77cf243Elliott Hughes    LOG(INFO) << "dex2oat took " << PrettyDuration(NanoTime() - start_ns_) << " (threads: " << thread_count_ << ")";
147ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
148ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
149ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // Make a list of descriptors for classes to include in the image
15000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  const std::set<std::string>* GetImageClassDescriptors(const char* image_classes_filename)
151b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
152ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    UniquePtr<std::ifstream> image_classes_file(new std::ifstream(image_classes_filename, std::ifstream::in));
153ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    if (image_classes_file.get() == NULL) {
154ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      LOG(ERROR) << "Failed to open image classes file " << image_classes_filename;
155ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      return NULL;
156ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
157ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
1586f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    // Load all the classes specified in the file
159ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    ClassLinker* class_linker = runtime_->GetClassLinker();
1601f5393447b9f45be7918042d9ee7b521376de866Ian Rogers    Thread* self = Thread::Current();
161ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    while (image_classes_file->good()) {
162ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      std::string dot;
163ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      std::getline(*image_classes_file.get(), dot);
164f1a5adc87760f938b01df26d906295063546b259Elliott Hughes      if (StartsWith(dot, "#") || dot.empty()) {
165ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        continue;
166ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
167955724179c6c739524f610023287f56b24dc31deElliott Hughes      std::string descriptor(DotToDescriptor(dot.c_str()));
1682dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      SirtRef<mirror::Class> klass(self, class_linker->FindSystemClass(descriptor.c_str()));
169ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (klass.get() == NULL) {
170ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        LOG(WARNING) << "Failed to find class " << descriptor;
171ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        Thread::Current()->ClearException();
172ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
173ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
174ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    image_classes_file->close();
175ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
1766f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    // Resolve exception classes referenced by the loaded classes. The catch logic assumes
1776f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    // exceptions are resolved by the verifier when there is a catch block in an interested method.
1786f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    // Do this here so that exception classes appear to have been specified image classes.
1796f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    std::set<std::pair<uint16_t, const DexFile*> > unresolved_exception_types;
1802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    SirtRef<mirror::Class> java_lang_Throwable(self,
1811f5393447b9f45be7918042d9ee7b521376de866Ian Rogers                                       class_linker->FindSystemClass("Ljava/lang/Throwable;"));
1826f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    do {
1836f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      unresolved_exception_types.clear();
1846f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      class_linker->VisitClasses(ResolveCatchBlockExceptionsClassVisitor,
1856f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers                                 &unresolved_exception_types);
1866f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      typedef std::set<std::pair<uint16_t, const DexFile*> >::const_iterator It;  // TODO: C++0x auto
1876f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      for (It it = unresolved_exception_types.begin(),
1886f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers           end = unresolved_exception_types.end();
1896f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers           it != end; ++it) {
1906f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers        uint16_t exception_type_idx = it->first;
1916f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers        const DexFile* dex_file = it->second;
1922dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        mirror::DexCache* dex_cache = class_linker->FindDexCache(*dex_file);
1932dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        mirror:: ClassLoader* class_loader = NULL;
1942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        SirtRef<mirror::Class> klass(self, class_linker->ResolveType(*dex_file, exception_type_idx,
1952dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                                                     dex_cache, class_loader));
1966f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers        if (klass.get() == NULL) {
1976f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers          const DexFile::TypeId& type_id = dex_file->GetTypeId(exception_type_idx);
1986f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers          const char* descriptor = dex_file->GetTypeDescriptor(type_id);
1996f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers          LOG(FATAL) << "Failed to resolve class " << descriptor;
2006f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers        }
20135be9b1f7d5b51652adda85d79e368597df68d64Elliott Hughes        DCHECK(java_lang_Throwable->IsAssignableFrom(klass.get()));
2026f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      }
2036f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      // Resolving exceptions may load classes that reference more exceptions, iterate until no
2046f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      // more are found
2056f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    } while (!unresolved_exception_types.empty());
2066f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers
207ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    // We walk the roots looking for classes so that we'll pick up the
208ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    // above classes plus any classes them depend on such super
209ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    // classes, interfaces, and the required ClassLinker roots.
210ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    UniquePtr<std::set<std::string> > image_classes(new std::set<std::string>());
2116f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    class_linker->VisitClasses(RecordImageClassesVisitor, image_classes.get());
212ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    CHECK_NE(image_classes->size(), 0U);
213ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    return image_classes.release();
214254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson  }
215254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson
216f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  const Compiler* CreateOatFile(const std::string& boot_image_option,
21734f1fa453357af94377f83b21485a60429d1cd7fBrian Carlstrom                                const std::string* host_prefix,
218f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                const std::vector<const DexFile*>& dex_files,
219f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                File* oat_file,
220de08e84143f7339d5bad24f252681207abbe0951Logan Chien                                const std::string& bitcode_filename,
221f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                bool image,
222ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom                                const std::set<std::string>* image_classes,
223ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom                                bool dump_stats,
22400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                bool dump_timings)
225b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
226ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    // SirtRef and ClassLoader creation needs to come after Runtime::Create
22700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    jobject class_loader = NULL;
228ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    if (!boot_image_option.empty()) {
229ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
230ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      std::vector<const DexFile*> class_path_files(dex_files);
231a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      OpenClassPathFiles(runtime_->GetClassPathString(), class_path_files);
232ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      for (size_t i = 0; i < class_path_files.size(); i++) {
233ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        class_linker->RegisterDexFile(*class_path_files[i]);
234ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
23500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      ScopedObjectAccessUnchecked soa(Thread::Current());
23600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader);
23700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      ScopedLocalRef<jobject> class_loader_local(soa.Env(),
23800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers          soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
23900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
24000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path_files);
241254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson    }
242ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
243c531cefbfb5394413122e9f57d211ba436cff012buzbee    UniquePtr<Compiler> compiler(new Compiler(compiler_backend_,
244c531cefbfb5394413122e9f57d211ba436cff012buzbee                                              instruction_set_,
245f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                              image,
246f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                              thread_count_,
247f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                              support_debugging_,
248ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom                                              image_classes,
249ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom                                              dump_stats,
250ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom                                              dump_timings));
2518b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien
252c531cefbfb5394413122e9f57d211ba436cff012buzbee    if ((compiler_backend_ == kPortable) || (compiler_backend_ == kIceland)) {
253c531cefbfb5394413122e9f57d211ba436cff012buzbee      compiler->SetBitcodeFileName(bitcode_filename);
254c531cefbfb5394413122e9f57d211ba436cff012buzbee    }
2558b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien
25600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    Thread::Current()->TransitionFromRunnableToSuspended(kNative);
25700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
25800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    compiler->CompileAll(class_loader, dex_files);
25900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
26000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    Thread::Current()->TransitionFromSuspendedToRunnable();
261ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
26281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom    std::string image_file_location;
26328db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom    uint32_t image_file_location_oat_checksum = 0;
264700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    uint32_t image_file_location_oat_data_begin = 0;
26581f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom    Heap* heap = Runtime::Current()->GetHeap();
26681f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom    if (heap->GetSpaces().size() > 1) {
26781f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom      ImageSpace* image_space = heap->GetImageSpace();
26828db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom      image_file_location_oat_checksum = image_space->GetImageHeader().GetOatChecksum();
269700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      image_file_location_oat_data_begin = reinterpret_cast<uint32_t>(image_space->GetImageHeader().GetOatDataBegin());
27081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom      image_file_location = image_space->GetImageFilename();
27134f1fa453357af94377f83b21485a60429d1cd7fBrian Carlstrom      if (host_prefix != NULL && StartsWith(image_file_location, host_prefix->c_str())) {
27234f1fa453357af94377f83b21485a60429d1cd7fBrian Carlstrom        image_file_location = image_file_location.substr(host_prefix->size());
27381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom      }
27481f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom    }
27581f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom
276700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    std::vector<uint8_t> oat_contents;
277700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    VectorOutputStream vector_output_stream(oat_file->GetPath(), oat_contents);
278700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    if (!OatWriter::Create(vector_output_stream,
27981f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom                           dex_files,
28028db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom                           image_file_location_oat_checksum,
281700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom                           image_file_location_oat_data_begin,
28281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom                           image_file_location,
283f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                           *compiler.get())) {
284761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes      LOG(ERROR) << "Failed to create oat file " << oat_file->GetPath();
285f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom      return NULL;
286ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
287700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
288700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    if (!compiler->WriteElf(oat_contents, oat_file)) {
289700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      LOG(ERROR) << "Failed to write ELF file " << oat_file->GetPath();
290700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      return NULL;
291700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    }
292700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
293f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom    return compiler.release();
294254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson  }
295ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
296a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  bool CreateImageFile(const std::string& image_filename,
297ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                       uintptr_t image_base,
298ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                       const std::set<std::string>* image_classes,
299ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                       const std::string& oat_filename,
300f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                       const std::string& oat_location,
30100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                       const Compiler& compiler)
302b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::mutator_lock_) {
303700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    uintptr_t oat_data_begin;
304700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    {
305700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      // ImageWriter is scoped so it can free memory before doing FixupElf
306700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      ImageWriter image_writer(image_classes);
307700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      if (!image_writer.Write(image_filename, image_base, oat_filename, oat_location, compiler)) {
308700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom        LOG(ERROR) << "Failed to create image file " << image_filename;
309700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom        return false;
310700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      }
311700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      oat_data_begin = image_writer.GetOatDataBegin();
312700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    }
313700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
314700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    LG << "dex2oat CreateImageFile opening : " << oat_filename;
315700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    UniquePtr<File> oat_file(OS::OpenFile(oat_filename.c_str(), true, false));
316700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    LG << "dex2oat CreateImageFile opened : " << oat_filename;
317700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    if (oat_file.get() == NULL) {
318700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      PLOG(ERROR) << "Failed to open ELF file: " << oat_filename;
319700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      return false;
320700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    }
321700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    if (!compiler.FixupElf(oat_file.get(), oat_data_begin)) {
322700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      LOG(ERROR) << "Failed to fixup ELF file " << oat_file->GetPath();
323ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      return false;
324ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
325700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    LOG(ERROR) << "ELF file fixed up successfully: " << oat_file->GetPath();
326ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    return true;
327ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
328ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
329ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom private:
330c531cefbfb5394413122e9f57d211ba436cff012buzbee  explicit Dex2Oat(Runtime* runtime, CompilerBackend compiler_backend, InstructionSet instruction_set,
331c531cefbfb5394413122e9f57d211ba436cff012buzbee                   size_t thread_count, bool support_debugging)
332c531cefbfb5394413122e9f57d211ba436cff012buzbee      : compiler_backend_(compiler_backend),
333c531cefbfb5394413122e9f57d211ba436cff012buzbee        instruction_set_(instruction_set),
33449c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        runtime_(runtime),
335de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes        thread_count_(thread_count),
336de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes        support_debugging_(support_debugging),
337de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes        start_ns_(NanoTime()) {
338bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  }
339ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
34000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  static bool CreateRuntime(Runtime::Options& options, InstructionSet instruction_set)
341b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_) {
34200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    if (!Runtime::Create(options, false)) {
343ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      LOG(ERROR) << "Failed to create runtime";
34400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      return false;
345ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
34600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    Runtime* runtime = Runtime::Current();
347ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    // if we loaded an existing image, we will reuse values from the image roots.
348ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    if (!runtime->HasJniDlsymLookupStub()) {
34949c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers      runtime->SetJniDlsymLookupStub(Compiler::CreateJniDlsymLookupStub(instruction_set));
350ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
351ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    if (!runtime->HasAbstractMethodErrorStubArray()) {
35249c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers      runtime->SetAbstractMethodErrorStubArray(Compiler::CreateAbstractMethodErrorStub(instruction_set));
353ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
354ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    for (int i = 0; i < Runtime::kLastTrampolineMethodType; i++) {
355ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      Runtime::TrampolineType type = Runtime::TrampolineType(i);
356ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (!runtime->HasResolutionStubArray(type)) {
35749c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        runtime->SetResolutionStubArray(Compiler::CreateResolutionStub(instruction_set, type), type);
358ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
359ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
3601984651929744dd603fd082e23eacd877b9bc177Ian Rogers    if (!runtime->HasResolutionMethod()) {
3611984651929744dd603fd082e23eacd877b9bc177Ian Rogers      runtime->SetResolutionMethod(runtime->CreateResolutionMethod());
3621984651929744dd603fd082e23eacd877b9bc177Ian Rogers    }
363ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
364ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
365ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (!runtime->HasCalleeSaveMethod(type)) {
36649c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        runtime->SetCalleeSaveMethod(runtime->CreateCalleeSaveMethod(instruction_set, type), type);
367ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
368ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
3691984651929744dd603fd082e23eacd877b9bc177Ian Rogers    runtime->GetClassLinker()->FixupDexCaches(runtime->GetResolutionMethod());
37000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return true;
371ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
372ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
3736f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers  static void ResolveExceptionsForMethod(MethodHelper* mh,
37400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                           std::set<std::pair<uint16_t, const DexFile*> >& exceptions_to_resolve)
375b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
3766f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    const DexFile::CodeItem* code_item = mh->GetCodeItem();
3776f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    if (code_item == NULL) {
3786f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      return;  // native or abstract method
3796f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    }
3806f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    if (code_item->tries_size_ == 0) {
3816f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      return;  // nothing to process
3826f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    }
3836f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    const byte* encoded_catch_handler_list = DexFile::GetCatchHandlerData(*code_item, 0);
3846f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    size_t num_encoded_catch_handlers = DecodeUnsignedLeb128(&encoded_catch_handler_list);
3856f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    for (size_t i = 0; i < num_encoded_catch_handlers; i++) {
3866f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      int32_t encoded_catch_handler_size = DecodeSignedLeb128(&encoded_catch_handler_list);
3876f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      bool has_catch_all = false;
3886f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      if (encoded_catch_handler_size <= 0) {
3896f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers        encoded_catch_handler_size = -encoded_catch_handler_size;
3906f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers        has_catch_all = true;
3916f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      }
3926f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      for (int32_t j = 0; j < encoded_catch_handler_size; j++) {
3936f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers        uint16_t encoded_catch_handler_handlers_type_idx =
3946f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers            DecodeUnsignedLeb128(&encoded_catch_handler_list);
3956f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers        // Add to set of types to resolve if not already in the dex cache resolved types
3966f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers        if (!mh->IsResolvedTypeIdx(encoded_catch_handler_handlers_type_idx)) {
3976f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers          exceptions_to_resolve.insert(
3986f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers              std::pair<uint16_t, const DexFile*>(encoded_catch_handler_handlers_type_idx,
3996f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers                                                  &mh->GetDexFile()));
4006f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers        }
4016f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers        // ignore address associated with catch handler
4026f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers        DecodeUnsignedLeb128(&encoded_catch_handler_list);
4036f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      }
4046f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      if (has_catch_all) {
4056f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers        // ignore catch all address
4066f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers        DecodeUnsignedLeb128(&encoded_catch_handler_list);
4076f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      }
4086f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    }
4096f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers  }
41000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
4112dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  static bool ResolveCatchBlockExceptionsClassVisitor(mirror::Class* c, void* arg)
412b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
4136f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    std::set<std::pair<uint16_t, const DexFile*> >* exceptions_to_resolve =
4146f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers        reinterpret_cast<std::set<std::pair<uint16_t, const DexFile*> >*>(arg);
4156f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    MethodHelper mh;
4166f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
4172dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      mirror::AbstractMethod* m = c->GetVirtualMethod(i);
4186f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      mh.ChangeMethod(m);
4196f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      ResolveExceptionsForMethod(&mh, *exceptions_to_resolve);
4206f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    }
4216f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
4222dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      mirror::AbstractMethod* m = c->GetDirectMethod(i);
4236f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      mh.ChangeMethod(m);
4246f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers      ResolveExceptionsForMethod(&mh, *exceptions_to_resolve);
4256f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    }
4266f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers    return true;
4276f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers  }
42800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
4292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  static bool RecordImageClassesVisitor(mirror::Class* klass, void* arg)
430b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
431ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    std::set<std::string>* image_classes = reinterpret_cast<std::set<std::string>*>(arg);
432ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    if (klass->IsArrayClass() || klass->IsPrimitive()) {
433ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      return true;
434ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
4356d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers    image_classes->insert(ClassHelper(klass).GetDescriptor());
436ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    return true;
437ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
438ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
439ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // Appends to dex_files any elements of class_path that it doesn't already
440ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // contain. This will open those dex files as necessary.
441ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  static void OpenClassPathFiles(const std::string& class_path, std::vector<const DexFile*>& dex_files) {
442ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    std::vector<std::string> parsed;
443ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    Split(class_path, ':', parsed);
444ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    for (size_t i = 0; i < parsed.size(); ++i) {
445ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (DexFilesContains(dex_files, parsed[i])) {
446ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        continue;
447ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
448a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      const DexFile* dex_file = DexFile::Open(parsed[i], parsed[i]);
449ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (dex_file == NULL) {
450ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        LOG(WARNING) << "Failed to open dex file " << parsed[i];
451ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      } else {
452ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        dex_files.push_back(dex_file);
453ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
454ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
455ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
456ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
457ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // Returns true if dex_files has a dex with the named location.
458ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  static bool DexFilesContains(const std::vector<const DexFile*>& dex_files, const std::string& location) {
459ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    for (size_t i = 0; i < dex_files.size(); ++i) {
460ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (dex_files[i]->GetLocation() == location) {
461ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        return true;
462ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
463ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
464ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    return false;
465ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
466ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
467c531cefbfb5394413122e9f57d211ba436cff012buzbee  const CompilerBackend compiler_backend_;
468c531cefbfb5394413122e9f57d211ba436cff012buzbee
46949c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers  const InstructionSet instruction_set_;
470ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
471bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  Runtime* runtime_;
4725523ee070b005576c6f889415205d49ea77cf243Elliott Hughes  size_t thread_count_;
473de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes  bool support_debugging_;
474bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  uint64_t start_ns_;
475bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes
476ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  DISALLOW_IMPLICIT_CONSTRUCTORS(Dex2Oat);
477ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom};
478254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson
47972395bf298b7707ad9d93c3e51b57e1b8e010311Elliott Hughesstatic bool ParseInt(const char* in, int* out) {
480a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  char* end;
481a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  int result = strtol(in, &end, 10);
482a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (in == end || *end != '\0') {
483a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    return false;
484a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
485a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  *out = result;
486a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  return true;
487a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom}
488a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
489bf1b4574dc681d49696571c59033e8c63583a029Elliott Hughesstatic size_t OpenDexFiles(const std::vector<const char*>& dex_filenames,
490bf1b4574dc681d49696571c59033e8c63583a029Elliott Hughes                           const std::vector<const char*>& dex_locations,
491bf1b4574dc681d49696571c59033e8c63583a029Elliott Hughes                           std::vector<const DexFile*>& dex_files) {
492bf1b4574dc681d49696571c59033e8c63583a029Elliott Hughes  size_t failure_count = 0;
4935b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  for (size_t i = 0; i < dex_filenames.size(); i++) {
4945b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom    const char* dex_filename = dex_filenames[i];
495a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    const char* dex_location = dex_locations[i];
496a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    const DexFile* dex_file = DexFile::Open(dex_filename, dex_location);
4975b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom    if (dex_file == NULL) {
49860f83e3274739317d8c3a1b069cebc6bf1e40f29jeffhao      LOG(WARNING) << "could not open .dex from file " << dex_filename;
499bf1b4574dc681d49696571c59033e8c63583a029Elliott Hughes      ++failure_count;
50060f83e3274739317d8c3a1b069cebc6bf1e40f29jeffhao    } else {
50160f83e3274739317d8c3a1b069cebc6bf1e40f29jeffhao      dex_files.push_back(dex_file);
5025b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom    }
5035b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  }
504bf1b4574dc681d49696571c59033e8c63583a029Elliott Hughes  return failure_count;
5055b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom}
5065b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom
507bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// The primary goal of the watchdog is to prevent stuck build servers
508bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// during development when fatal aborts lead to a cascade of failures
509bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// that result in a deadlock.
510bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstromclass WatchDog {
511bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
512bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// WatchDog defines its own CHECK_PTHREAD_CALL to avoid using Log which uses locks
513bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#undef CHECK_PTHREAD_CALL
514bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#define CHECK_WATCH_DOG_PTHREAD_CALL(call, args, what) \
515bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  do { \
516bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    int rc = call args; \
517bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    if (rc != 0) { \
518bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      errno = rc; \
519bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      std::string message(# call); \
520bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      message += " failed for "; \
521bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      message += reason; \
522bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      Die(message); \
523bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    } \
524bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  } while (false)
525bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
526bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom public:
527994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  WatchDog(bool is_watch_dog_enabled) {
528994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    is_watch_dog_enabled_ = is_watch_dog_enabled;
529994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    if (!is_watch_dog_enabled_) {
530bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      return;
531bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    }
532bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    shutting_down_ = false;
533bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    const char* reason = "dex2oat watch dog thread startup";
534bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_init, (&mutex_, NULL), reason);
535bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_init, (&cond_, NULL), reason);
536bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_init, (&attr_), reason);
537bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_create, (&pthread_, &attr_, &CallBack, this), reason);
538bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_destroy, (&attr_), reason);
539bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
540bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  ~WatchDog() {
541994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    if (!is_watch_dog_enabled_) {
542bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      return;
543bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    }
544bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    const char* reason = "dex2oat watch dog thread shutdown";
545bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason);
546bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    shutting_down_ = true;
547bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_signal, (&cond_), reason);
548bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason);
549bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
550bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_join, (pthread_, NULL), reason);
551bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
552bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_destroy, (&cond_), reason);
553bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_destroy, (&mutex_), reason);
554bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
555bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
556bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom private:
557bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  static void* CallBack(void* arg) {
558bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    WatchDog* self = reinterpret_cast<WatchDog*>(arg);
559bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    self->Wait();
560bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    return NULL;
561bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
562bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
563bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  static void Die(const std::string& message) {
564bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    // TODO: Switch to LOG(FATAL) when we can guarantee it won't prevent shutdown in error cases
565bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    fprintf(stderr, "%s\n", message.c_str());
566bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    exit(1);
567bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
568bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
569bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  void Wait() {
570bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    int64_t ms = kWatchDogTimeoutSeconds * 1000;
571bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    int32_t ns = 0;
572bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    timespec ts;
573bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    InitTimeSpec(true, CLOCK_REALTIME, ms, ns, &ts);
574bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    const char* reason = "dex2oat watch dog thread waiting";
575bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason);
576bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    while (!shutting_down_) {
577bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      int rc = TEMP_FAILURE_RETRY(pthread_cond_timedwait(&cond_, &mutex_, &ts));
578bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      if (rc == ETIMEDOUT) {
579bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom        std::string message(StringPrintf("dex2oat did not finish after %d seconds",
580bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom                                         kWatchDogTimeoutSeconds));
581bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom        Die(message.c_str());
582bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      }
583bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      if (rc != 0) {
584bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom        std::string message(StringPrintf("pthread_cond_timedwait failed: %s",
585bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom                                         strerror(errno)));
586bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom        Die(message.c_str());
587bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      }
588bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    }
589bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason);
590bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
591bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
592bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#ifdef ART_USE_LLVM_COMPILER
593bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  static const unsigned int kWatchDogTimeoutSeconds = 20 * 60; // 15 minutes + buffer
594bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#else
595bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  static const unsigned int kWatchDogTimeoutSeconds = 2 * 60;  // 1 minute + buffer
596bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#endif
597bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
598994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  bool is_watch_dog_enabled_;
599bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  bool shutting_down_;
600bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  // TODO: Switch to Mutex when we can guarantee it won't prevent shutdown in error cases
601bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_mutex_t mutex_;
602bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_cond_t cond_;
603bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_attr_t attr_;
604bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_t pthread_;
605bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom};
606bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
60772395bf298b7707ad9d93c3e51b57e1b8e010311Elliott Hughesstatic int dex2oat(int argc, char** argv) {
6080d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes  InitLogging(argv);
60972395bf298b7707ad9d93c3e51b57e1b8e010311Elliott Hughes
61069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  // Skip over argv[0].
61169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  argv++;
61269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  argc--;
61369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
61469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  if (argc == 0) {
615cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("no arguments specified");
61669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
61769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
61869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  std::vector<const char*> dex_filenames;
619a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::vector<const char*> dex_locations;
620a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  int zip_fd = -1;
621a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::string zip_location;
622e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  std::string oat_filename;
623a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::string oat_location;
624a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  int oat_fd = -1;
6258b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien  std::string bitcode_filename;
626ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  const char* image_classes_filename = NULL;
627a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::string image_filename;
628b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  std::string boot_image_filename;
62969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  uintptr_t image_base = 0;
63034f1fa453357af94377f83b21485a60429d1cd7fBrian Carlstrom  UniquePtr<std::string> host_prefix;
6315d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao  std::vector<const char*> runtime_args;
6325c599943f8c347acd84c4d9fda56a9df70649b78Elliott Hughes  int thread_count = sysconf(_SC_NPROCESSORS_CONF);
633de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes  bool support_debugging = false;
634c531cefbfb5394413122e9f57d211ba436cff012buzbee#if defined(ART_USE_PORTABLE_COMPILER)
635c531cefbfb5394413122e9f57d211ba436cff012buzbee  CompilerBackend compiler_backend = kPortable;
636c531cefbfb5394413122e9f57d211ba436cff012buzbee#elif defined(ART_USE_LLVM_COMPILER)
637c531cefbfb5394413122e9f57d211ba436cff012buzbee  CompilerBackend compiler_backend = kIceland;
638c531cefbfb5394413122e9f57d211ba436cff012buzbee#else
639c531cefbfb5394413122e9f57d211ba436cff012buzbee  CompilerBackend compiler_backend = kQuick;
640c531cefbfb5394413122e9f57d211ba436cff012buzbee#endif
6419ad4f22cd9a94a3bd3439e1bc9d67fdc3e9bc67fjeffhao#if defined(__arm__)
64249c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers  InstructionSet instruction_set = kThumb2;
6439ad4f22cd9a94a3bd3439e1bc9d67fdc3e9bc67fjeffhao#elif defined(__i386__)
6449ad4f22cd9a94a3bd3439e1bc9d67fdc3e9bc67fjeffhao  InstructionSet instruction_set = kX86;
6459ad4f22cd9a94a3bd3439e1bc9d67fdc3e9bc67fjeffhao#elif defined(__mips__)
6469ad4f22cd9a94a3bd3439e1bc9d67fdc3e9bc67fjeffhao  InstructionSet instruction_set = kMips;
6479ad4f22cd9a94a3bd3439e1bc9d67fdc3e9bc67fjeffhao#else
6489ad4f22cd9a94a3bd3439e1bc9d67fdc3e9bc67fjeffhao#error "Unsupported architecture"
6499ad4f22cd9a94a3bd3439e1bc9d67fdc3e9bc67fjeffhao#endif
65067d920071fe4a0aa8b8bc339e93b18276238c320Elliott Hughes  bool dump_stats = kIsDebugBuild;
65167d920071fe4a0aa8b8bc339e93b18276238c320Elliott Hughes  bool dump_timings = kIsDebugBuild;
652994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  bool watch_dog_enabled = !kIsTargetBuild;
653161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom
65469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  for (int i = 0; i < argc; i++) {
65569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    const StringPiece option(argv[i]);
656a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    bool log_options = false;
657a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    if (log_options) {
658b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom      LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i];
659b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom    }
66069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    if (option.starts_with("--dex-file=")) {
66169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      dex_filenames.push_back(option.substr(strlen("--dex-file=")).data());
662a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    } else if (option.starts_with("--dex-location=")) {
663a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      dex_locations.push_back(option.substr(strlen("--dex-location=")).data());
664a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else if (option.starts_with("--zip-fd=")) {
665a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      const char* zip_fd_str = option.substr(strlen("--zip-fd=")).data();
666bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes      if (!ParseInt(zip_fd_str, &zip_fd)) {
667cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom        Usage("could not parse --zip-fd argument '%s' as an integer", zip_fd_str);
668a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
669a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    } else if (option.starts_with("--zip-location=")) {
670a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      zip_location = option.substr(strlen("--zip-location=")).data();
671a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else if (option.starts_with("--oat-file=")) {
672a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      oat_filename = option.substr(strlen("--oat-file=")).data();
673a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else if (option.starts_with("--oat-fd=")) {
674a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      const char* oat_fd_str = option.substr(strlen("--oat-fd=")).data();
675bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes      if (!ParseInt(oat_fd_str, &oat_fd)) {
676cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom        Usage("could not parse --oat-fd argument '%s' as an integer", oat_fd_str);
677a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
678994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    } else if (option == "-g") {
679de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes      support_debugging = true;
680994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    } else if (option == "--watch-dog") {
681994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom      watch_dog_enabled = true;
682994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    } else if (option == "--no-watch-dog") {
683994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom      watch_dog_enabled = false;
6845523ee070b005576c6f889415205d49ea77cf243Elliott Hughes    } else if (option.starts_with("-j")) {
685b12552a95d68b9e4a567103190074ae47b6a61dcBrian Carlstrom      const char* thread_count_str = option.substr(strlen("-j")).data();
6865523ee070b005576c6f889415205d49ea77cf243Elliott Hughes      if (!ParseInt(thread_count_str, &thread_count)) {
687cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom        Usage("could not parse -j argument '%s' as an integer", thread_count_str);
6885523ee070b005576c6f889415205d49ea77cf243Elliott Hughes      }
689a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    } else if (option.starts_with("--oat-location=")) {
690a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      oat_location = option.substr(strlen("--oat-location=")).data();
6918b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien    } else if (option.starts_with("--bitcode=")) {
6928b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien      bitcode_filename = option.substr(strlen("--bitcode=")).data();
69369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    } else if (option.starts_with("--image=")) {
69469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      image_filename = option.substr(strlen("--image=")).data();
695ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    } else if (option.starts_with("--image-classes=")) {
696ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      image_classes_filename = option.substr(strlen("--image-classes=")).data();
69769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    } else if (option.starts_with("--base=")) {
69869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      const char* image_base_str = option.substr(strlen("--base=")).data();
69969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      char* end;
70069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      image_base = strtoul(image_base_str, &end, 16);
70169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      if (end == image_base_str || *end != '\0') {
702cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom        Usage("Failed to parse hexadecimal value for option %s", option.data());
70369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      }
704e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom    } else if (option.starts_with("--boot-image=")) {
705b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom      boot_image_filename = option.substr(strlen("--boot-image=")).data();
70658ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom    } else if (option.starts_with("--host-prefix=")) {
70734f1fa453357af94377f83b21485a60429d1cd7fBrian Carlstrom      host_prefix.reset(new std::string(option.substr(strlen("--host-prefix=")).data()));
70849c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers    } else if (option.starts_with("--instruction-set=")) {
70949c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers      StringPiece instruction_set_str = option.substr(strlen("--instruction-set=")).data();
7101f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao      if (instruction_set_str == "arm") {
71149c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        instruction_set = kThumb2;
7121f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao      } else if (instruction_set_str == "mips") {
71349c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        instruction_set = kMips;
7141f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao      } else if (instruction_set_str == "x86") {
71549c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        instruction_set = kX86;
71649c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers      }
717c531cefbfb5394413122e9f57d211ba436cff012buzbee    } else if (option.starts_with("--compiler-backend=")) {
718c531cefbfb5394413122e9f57d211ba436cff012buzbee      StringPiece backend_str = option.substr(strlen("--compiler-backend=")).data();
719c531cefbfb5394413122e9f57d211ba436cff012buzbee      if (backend_str == "Quick") {
720c531cefbfb5394413122e9f57d211ba436cff012buzbee        compiler_backend = kQuick;
721c531cefbfb5394413122e9f57d211ba436cff012buzbee      } else if (backend_str == "QuickGBC") {
722c531cefbfb5394413122e9f57d211ba436cff012buzbee        compiler_backend = kQuickGBC;
723c531cefbfb5394413122e9f57d211ba436cff012buzbee      } else if (backend_str == "Iceland") {
724c531cefbfb5394413122e9f57d211ba436cff012buzbee        // TODO: remove this when Portable/Iceland merge complete
725c531cefbfb5394413122e9f57d211ba436cff012buzbee        compiler_backend = kIceland;
726c531cefbfb5394413122e9f57d211ba436cff012buzbee      } else if (backend_str == "Portable") {
727c531cefbfb5394413122e9f57d211ba436cff012buzbee        compiler_backend = kPortable;
728c531cefbfb5394413122e9f57d211ba436cff012buzbee      }
7295d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao    } else if (option == "--runtime-arg") {
7305d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao      if (++i >= argc) {
731cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom        Usage("Missing required argument for --runtime-arg");
7325d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao      }
733a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      if (log_options) {
734a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom        LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i];
735a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
7365d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao      runtime_args.push_back(argv[i]);
73769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    } else {
738cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom      Usage("unknown argument %s", option.data());
73969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    }
74069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
74169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
742a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (oat_filename.empty() && oat_fd == -1) {
743cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("Output must be supplied with either --oat-file or --oat-fd");
744a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
745a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
746a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (!oat_filename.empty() && oat_fd != -1) {
747cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--oat-file should not be used with --oat-fd");
748a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
749a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
750a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (!oat_filename.empty() && oat_fd != -1) {
751cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--oat-file should not be used with --oat-fd");
752a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
753a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
754a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (oat_fd != -1 && !image_filename.empty()) {
755cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--oat-fd should not be used with --image");
756e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  }
757e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
75834f1fa453357af94377f83b21485a60429d1cd7fBrian Carlstrom  if (host_prefix.get() == NULL) {
759b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom    const char* android_product_out = getenv("ANDROID_PRODUCT_OUT");
760b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom    if (android_product_out != NULL) {
76134f1fa453357af94377f83b21485a60429d1cd7fBrian Carlstrom        host_prefix.reset(new std::string(android_product_out));
762b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom    }
763b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  }
764b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom
765a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  bool image = (!image_filename.empty());
766b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  if (!image && boot_image_filename.empty()) {
76734f1fa453357af94377f83b21485a60429d1cd7fBrian Carlstrom    if (host_prefix.get() == NULL) {
768a56fcd60596ae8694da21fccde5c56832e437c56Brian Carlstrom      boot_image_filename += GetAndroidRoot();
769a56fcd60596ae8694da21fccde5c56832e437c56Brian Carlstrom    } else {
77034f1fa453357af94377f83b21485a60429d1cd7fBrian Carlstrom      boot_image_filename += *host_prefix.get();
771a56fcd60596ae8694da21fccde5c56832e437c56Brian Carlstrom      boot_image_filename += "/system";
772a56fcd60596ae8694da21fccde5c56832e437c56Brian Carlstrom    }
773a56fcd60596ae8694da21fccde5c56832e437c56Brian Carlstrom    boot_image_filename += "/framework/boot.art";
774b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  }
775b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  std::string boot_image_option;
776a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (!boot_image_filename.empty()) {
777b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom    boot_image_option += "-Ximage:";
778b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom    boot_image_option += boot_image_filename;
77969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
78069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
781ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  if (image_classes_filename != NULL && !image) {
782cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--image-classes should only be used with --image");
783ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
784ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
785ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  if (image_classes_filename != NULL && !boot_image_option.empty()) {
786cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--image-classes should not be used with --boot-image");
78778128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom  }
78878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom
789a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (dex_filenames.empty() && zip_fd == -1) {
790cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("Input must be supplied with either --dex-file or --zip-fd");
791a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
792a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
793a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (!dex_filenames.empty() && zip_fd != -1) {
794cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--dex-file should not be used with --zip-fd");
795a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
796a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
797a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (!dex_filenames.empty() && !zip_location.empty()) {
798cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--dex-file should not be used with --zip-location");
799a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
800a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
801a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (dex_locations.empty()) {
802a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    for (size_t i = 0; i < dex_filenames.size(); i++) {
803a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      dex_locations.push_back(dex_filenames[i]);
804a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    }
805a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  } else if (dex_locations.size() != dex_filenames.size()) {
806cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--dex-location arguments do not match --dex-file arguments");
807a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  }
808a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom
809a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (zip_fd != -1 && zip_location.empty()) {
810cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--zip-location should be supplied with --zip-fd");
811a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
812a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
81369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  if (boot_image_option.empty()) {
81469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    if (image_base == 0) {
815cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom      Usage("non-zero --base not specified");
81669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    }
81769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
81869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
819994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  // Done with usage checks, enable watchdog if requested
820994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  WatchDog watch_dog(watch_dog_enabled);
821994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom
8226ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom  // Check early that the result of compilation can be written
823a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  UniquePtr<File> oat_file;
8246cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom  bool create_file = !oat_filename.empty();  // as opposed to using open file descriptor
8256cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom  if (create_file) {
826a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    oat_file.reset(OS::OpenFile(oat_filename.c_str(), true));
827a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    if (oat_location.empty()) {
828a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      oat_location = oat_filename;
829a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    }
830a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  } else {
831761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    oat_file.reset(new File(oat_fd, oat_location));
832761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    oat_file->DisableAutoClose();
833a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
8346ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom  if (oat_file.get() == NULL) {
8356cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom    PLOG(ERROR) << "Failed to create oat file: " << oat_location;
8366cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom    return EXIT_FAILURE;
8376cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom  }
8386cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom  if (create_file && fchmod(oat_file->Fd(), 0644) != 0) {
8396cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom    PLOG(ERROR) << "Failed to make oat file world readable: " << oat_location;
8406ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom    return EXIT_FAILURE;
841234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  }
842a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
843a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  LOG(INFO) << "dex2oat: " << oat_location;
8445e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers
84569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  Runtime::Options options;
8465de8fe5253ca8bd285cba0eb2e56930573ea4c7fBrian Carlstrom  options.push_back(std::make_pair("compiler", reinterpret_cast<void*>(NULL)));
847a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::vector<const DexFile*> boot_class_path;
84869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  if (boot_image_option.empty()) {
849bf1b4574dc681d49696571c59033e8c63583a029Elliott Hughes    size_t failure_count = OpenDexFiles(dex_filenames, dex_locations, boot_class_path);
850bf1b4574dc681d49696571c59033e8c63583a029Elliott Hughes    if (failure_count > 0) {
851bf1b4574dc681d49696571c59033e8c63583a029Elliott Hughes      LOG(ERROR) << "Failed to open some dex files: " << failure_count;
852bf1b4574dc681d49696571c59033e8c63583a029Elliott Hughes      return EXIT_FAILURE;
853bf1b4574dc681d49696571c59033e8c63583a029Elliott Hughes    }
854a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    options.push_back(std::make_pair("bootclasspath", &boot_class_path));
85569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  } else {
85669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    options.push_back(std::make_pair(boot_image_option.c_str(), reinterpret_cast<void*>(NULL)));
85769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
85834f1fa453357af94377f83b21485a60429d1cd7fBrian Carlstrom  if (host_prefix.get() != NULL) {
85934f1fa453357af94377f83b21485a60429d1cd7fBrian Carlstrom    options.push_back(std::make_pair("host-prefix", host_prefix->c_str()));
86058ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom  }
8615d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao  for (size_t i = 0; i < runtime_args.size(); i++) {
8625d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao    options.push_back(std::make_pair(runtime_args[i], reinterpret_cast<void*>(NULL)));
8635d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao  }
86469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
86500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Dex2Oat* p_dex2oat;
866c531cefbfb5394413122e9f57d211ba436cff012buzbee  if (!Dex2Oat::Create(&p_dex2oat, options, compiler_backend, instruction_set, thread_count, support_debugging)) {
86700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    LOG(ERROR) << "Failed to create dex2oat";
86800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return EXIT_FAILURE;
86900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
87000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  UniquePtr<Dex2Oat> dex2oat(p_dex2oat);
87100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
87200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // give it away now and then switch to a more managable ScopedObjectAccess.
87300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread::Current()->TransitionFromRunnableToSuspended(kNative);
87400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Whilst we're in native take the opportunity to initialize well known classes.
87500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  WellKnownClasses::InitClasses(Thread::Current()->GetJniEnv());
87600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
87769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
878bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  // If --image-classes was specified, calculate the full list of classes to include in the image
879ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  UniquePtr<const std::set<std::string> > image_classes(NULL);
880ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  if (image_classes_filename != NULL) {
881ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    image_classes.reset(dex2oat->GetImageClassDescriptors(image_classes_filename));
882ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    if (image_classes.get() == NULL) {
883ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      LOG(ERROR) << "Failed to create list of image classes from " << image_classes_filename;
884ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      return EXIT_FAILURE;
88569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    }
88669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
88769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
888a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  std::vector<const DexFile*> dex_files;
889a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (boot_image_option.empty()) {
890a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    dex_files = Runtime::Current()->GetClassLinker()->GetBootClassPath();
891a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  } else {
892a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    if (dex_filenames.empty()) {
893a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      UniquePtr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(zip_fd));
894a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      if (zip_archive.get() == NULL) {
895a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom        LOG(ERROR) << "Failed to zip from file descriptor for " << zip_location;
8962e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom        return EXIT_FAILURE;
897a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
898a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      const DexFile* dex_file = DexFile::Open(*zip_archive.get(), zip_location);
899a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      if (dex_file == NULL) {
900a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom        LOG(ERROR) << "Failed to open dex from file descriptor for zip file: " << zip_location;
901a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom        return EXIT_FAILURE;
902a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
903a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      dex_files.push_back(dex_file);
904a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else {
905bf1b4574dc681d49696571c59033e8c63583a029Elliott Hughes      size_t failure_count = OpenDexFiles(dex_filenames, dex_locations, dex_files);
906bf1b4574dc681d49696571c59033e8c63583a029Elliott Hughes      if (failure_count > 0) {
907bf1b4574dc681d49696571c59033e8c63583a029Elliott Hughes        LOG(ERROR) << "Failed to open some dex files: " << failure_count;
908bf1b4574dc681d49696571c59033e8c63583a029Elliott Hughes        return EXIT_FAILURE;
909bf1b4574dc681d49696571c59033e8c63583a029Elliott Hughes      }
910a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    }
911a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
912a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
913f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  UniquePtr<const Compiler> compiler(dex2oat->CreateOatFile(boot_image_option,
91434f1fa453357af94377f83b21485a60429d1cd7fBrian Carlstrom                                                            host_prefix.get(),
915f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                            dex_files,
916f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                            oat_file.get(),
917f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                            bitcode_filename,
918f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                                                            image,
919ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom                                                            image_classes.get(),
920ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom                                                            dump_stats,
921ba0668ecd2a6459ed7c77012995ad08d27f88725Brian Carlstrom                                                            dump_timings));
922f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom
923f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  if (compiler.get() == NULL) {
924a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    LOG(ERROR) << "Failed to create oat file: " << oat_location;
925e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom    return EXIT_FAILURE;
926e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  }
927e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
928ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  if (!image) {
929a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    LOG(INFO) << "Oat file written successfully: " << oat_location;
930aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom    return EXIT_SUCCESS;
931aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom  }
932aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
933700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // Notes on the interleaving of creating the image and oat file to
934700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // ensure the references between the two are correct.
935700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
936700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // Currently we have a memory layout that looks something like this:
937700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
938700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // +--------------+
939700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // | image        |
940700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // +--------------+
941700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // | boot oat     |
942700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // +--------------+
943700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // | alloc spaces |
944700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // +--------------+
945700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
946700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // There are several constraints on the loading of the imag and boot.oat.
947700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
948700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 1. The image is expected to be loaded at an absolute address and
949700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // contains Objects with absolute pointers within the image.
950700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
951700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 2. There are absolute pointers from Methods in the image to their
952700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // code in the oat.
953700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
954700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 3. There are absolute pointers from the code in the oat to Methods
955700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // in the image.
956700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
957700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 4. There are absolute pointers from code in the oat to other code
958700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // in the oat.
959700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
960700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // To get this all correct, we go through several steps.
961700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
962700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 1. We have already created that oat file above with
963700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // CreateOatFile. Originally this was just our own proprietary file
964700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // but now it is contained within an ELF dynamic object (aka .so
965700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // file). The Compiler returned by CreateOatFile provides
966700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // PatchInformation for references to oat code and Methods that need
967700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // to be update once we know where the oat file will be located
968700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // after the image.
969700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
970700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 2. We create the image file. It needs to know where the oat file
971700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // will be loaded after itself. Originally when oat file was simply
972700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // memory mapped so we could predict where its contents were based
973700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // on the file size. Now that it is an ELF file, we need to inspect
974700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // the ELF file to understand the in memory segment layout including
975700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // where the oat header is located within. ImageWriter's
976700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // PatchOatCodeAndMethods uses the PatchInformation from the
977700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // Compiler to touch up absolute references in the oat file.
978700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
979700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 3. We fixup the ELF program headers so that dlopen will try to
980700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // load the .so at the desired location at runtime by offsetting the
981700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // Elf32_Phdr.p_vaddr values by the desired base address.
982700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
98300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread::Current()->TransitionFromRunnableToSuspended(kNative);
98400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  bool image_creation_success = dex2oat->CreateImageFile(image_filename,
98500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                                         image_base,
98600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                                         image_classes.get(),
98700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                                         oat_filename,
98800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                                         oat_location,
98900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers                                                         *compiler.get());
99000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Thread::Current()->TransitionFromSuspendedToRunnable();
99100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (!image_creation_success) {
99269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    return EXIT_FAILURE;
99369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
99469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
995ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // We wrote the oat file successfully, and want to keep it.
996bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  LOG(INFO) << "Oat file written successfully: " << oat_filename;
997bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  LOG(INFO) << "Image written successfully: " << image_filename;
99869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  return EXIT_SUCCESS;
99969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom}
100069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
100169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom} // namespace art
100269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
100369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromint main(int argc, char** argv) {
100469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  return art::dex2oat(argc, argv);
100569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom}
1006