dex2oat.cc revision b9beb2e2efb6a204a69ca660d478b45f851e8f09
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>
202672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers#include <valgrind.h>
2169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
22ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom#include <fstream>
234922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom#include <iostream>
244922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom#include <sstream>
2569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include <string>
2669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include <vector>
2769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
281aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "base/stl_util.h"
29e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "base/stringpiece.h"
30a84395489098e4531619b1cffd1afc282b14510eSameer Abu Asal#include "base/timing_logger.h"
31761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/unix_file/fd_file.h"
3269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "class_linker.h"
33b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#include "compiler.h"
342b5eaa2b49f7489bafdadc4b4463ae27e4261817Vladimir Marko#include "compiler_callbacks.h"
354f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h"
36cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu#include "dex/pass_driver.h"
37c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "dex/verification_results.h"
386449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#include "driver/compiler_callbacks_impl.h"
397940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "driver/compiler_driver.h"
406449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#include "driver/compiler_options.h"
417940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "elf_fixup.h"
427940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "elf_stripper.h"
431d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/space/image_space.h"
441d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/space/space-inl.h"
457940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "image_writer.h"
466f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers#include "leb128.h"
47ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_method-inl.h"
482dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h"
492dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h"
502dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h"
512dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h"
527940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "oat_writer.h"
536d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h"
545e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers#include "os.h"
5569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "runtime.h"
5600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "ScopedLocalRef.h"
5700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h"
58700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom#include "vector_output_stream.h"
5900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "well_known_classes.h"
60a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom#include "zip_archive.h"
6169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
6269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromnamespace art {
6369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
646449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstromstatic int original_argc;
656449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstromstatic char** original_argv;
666449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
676449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstromstatic std::string CommandLine() {
686449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  std::vector<std::string> command;
696449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  for (int i = 0; i < original_argc; ++i) {
706449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    command.push_back(original_argv[i]);
716449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  }
726449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  return Join(command, ' ');
736449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom}
746449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
75cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstromstatic void UsageErrorV(const char* fmt, va_list ap) {
76cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  std::string error;
77cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  StringAppendV(&error, fmt, ap);
78cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  LOG(ERROR) << error;
79cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom}
80cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom
81cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstromstatic void UsageError(const char* fmt, ...) {
82cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  va_list ap;
83cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  va_start(ap, fmt);
84cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageErrorV(fmt, ap);
85cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  va_end(ap);
86cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom}
87cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom
88cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstromstatic void Usage(const char* fmt, ...) {
89cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  va_list ap;
90cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  va_start(ap, fmt);
91cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageErrorV(fmt, ap);
92cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  va_end(ap);
93cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom
946449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("Command: %s", CommandLine().c_str());
956449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
96cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("Usage: dex2oat [options]...");
97cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
98cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --dex-file=<dex-file>: specifies a .dex file to compile.");
99cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --dex-file=/system/framework/core.jar");
100cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
101cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --zip-fd=<file-descriptor>: specifies a file descriptor of a zip file");
102cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      containing a classes.dex file to compile.");
103cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --zip-fd=5");
104cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
1054560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  UsageError("  --zip-location=<zip-location>: specifies a symbolic name for the file");
1064560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  UsageError("      corresponding to the file descriptor specified by --zip-fd.");
107cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --zip-location=/system/app/Calculator.apk");
108cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
109265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("  --oat-file=<file.oat>: specifies the oat output destination via a filename.");
110265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("      Example: --oat-file=/system/framework/boot.oat");
111265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("");
112265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("  --oat-fd=<number>: specifies the oat output destination via a file descriptor.");
1139cb554a7784307d97c20991d90c76d9cf8a12e01Wonil Kim  UsageError("      Example: --oat-fd=6");
114cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
115cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --oat-location=<oat-name>: specifies a symbolic name for the file corresponding");
116cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      to the file descriptor specified by --oat-fd.");
1177675e16bcae06c0fe258aad89b3d511037dec399Brian Carlstrom  UsageError("      Example: --oat-location=/data/dalvik-cache/system@app@Calculator.apk.oat");
118cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
119265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("  --oat-symbols=<file.oat>: specifies the oat output destination with full symbols.");
120265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("      Example: --oat-symbols=/symbols/system/framework/boot.oat");
121265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("");
1228b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien  UsageError("  --bitcode=<file.bc>: specifies the optional bitcode filename.");
1238b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien  UsageError("      Example: --bitcode=/system/framework/boot.bc");
1248b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien  UsageError("");
125cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --image=<file.art>: specifies the output image filename.");
126cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --image=/system/framework/boot.art");
127cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
128cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --image-classes=<classname-file>: specifies classes to include in an image.");
129cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --image=frameworks/base/preloaded-classes");
130cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
131cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --base=<hex-address>: specifies the base address when creating a boot image.");
132cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --base=0x50000000");
133cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
134cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --boot-image=<file.art>: provide the image file for the boot class path.");
135cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --boot-image=/system/framework/boot.art");
1369583fbcf597eff6d0b3c5359b8e8d5f70ed82c40Nicolas Geoffray  UsageError("      Default: $ANDROID_ROOT/system/framework/boot.art");
137cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
1383f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  UsageError("  --android-root=<path>: used to locate libraries for portable linking.");
1393f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  UsageError("      Example: --android-root=out/host/linux-x86");
1403f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  UsageError("      Default: $ANDROID_ROOT");
1413f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  UsageError("");
14204ae1630adb4d4f10bfa7fded595052a9124de76Stuart Monteith  UsageError("  --instruction-set=(arm|arm64|mips|x86|x86_64): compile for a particular instruction");
14349c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers  UsageError("      set.");
1441f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao  UsageError("      Example: --instruction-set=x86");
1451f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao  UsageError("      Default: arm");
14649c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers  UsageError("");
1477020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  UsageError("  --instruction-set-features=...,: Specify instruction set features");
1487020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  UsageError("      Example: --instruction-set-features=div");
1497020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  UsageError("      Default: default");
1507020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  UsageError("");
151b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray  UsageError("  --compiler-backend=(Quick|Optimizing|Portable): select compiler backend");
152c531cefbfb5394413122e9f57d211ba436cff012buzbee  UsageError("      set.");
153635733da0f67df1c979cc9764409d2a9dcbb20aaBrian Carlstrom  UsageError("      Example: --compiler-backend=Portable");
154c531cefbfb5394413122e9f57d211ba436cff012buzbee  UsageError("      Default: Quick");
155265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("");
1564a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  UsageError("  --compiler-filter=(verify-none|interpret-only|space|balanced|speed|everything):");
1574a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  UsageError("      select compiler filter.");
1586449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --compiler-filter=everything");
1596449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#if ART_SMALL_MODE
1606449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: interpret-only");
1616449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#else
1626449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: speed");
1636449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#endif
1646449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
1656449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --huge-method-max=<method-instruction-count>: the threshold size for a huge");
1666449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      method for compiler filter tuning.");
1676449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --huge-method-max=%d", CompilerOptions::kDefaultHugeMethodThreshold);
1686449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultHugeMethodThreshold);
1696449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
1706449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --huge-method-max=<method-instruction-count>: threshold size for a huge");
1716449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      method for compiler filter tuning.");
1726449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --huge-method-max=%d", CompilerOptions::kDefaultHugeMethodThreshold);
1736449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultHugeMethodThreshold);
1746449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
1756449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --large-method-max=<method-instruction-count>: threshold size for a large");
1766449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      method for compiler filter tuning.");
1776449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --large-method-max=%d", CompilerOptions::kDefaultLargeMethodThreshold);
1786449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultLargeMethodThreshold);
1796449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
1806449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --small-method-max=<method-instruction-count>: threshold size for a small");
1816449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      method for compiler filter tuning.");
1826449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --small-method-max=%d", CompilerOptions::kDefaultSmallMethodThreshold);
1836449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultSmallMethodThreshold);
1846449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
1856449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --tiny-method-max=<method-instruction-count>: threshold size for a tiny");
1866449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      method for compiler filter tuning.");
1876449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --tiny-method-max=%d", CompilerOptions::kDefaultTinyMethodThreshold);
1886449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultTinyMethodThreshold);
1896449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
1906449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --num-dex-methods=<method-count>: threshold size for a small dex file for");
1916449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      compiler filter tuning. If the input has fewer than this many methods");
1924a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  UsageError("      and the filter is not interpret-only or verify-none, overrides the");
1934a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  UsageError("      filter to use speed");
1946449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --num-dex-method=%d", CompilerOptions::kDefaultNumDexMethodsThreshold);
1956449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultNumDexMethodsThreshold);
1966449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
197265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("  --host: used with Portable backend to link against host runtime libraries");
198265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("");
19946398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers  UsageError("  --dump-timing: display a breakdown of where time was spent");
20046398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers  UsageError("");
201cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --runtime-arg <argument>: used to specify various arguments for the runtime,");
202cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      such as initial heap size, maximum heap size, and verbose output.");
203cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Use a separate --runtime-arg switch for each argument.");
204cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --runtime-arg -Xms256m");
2054a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  UsageError("");
206d6ed642458c8820e1beca72f3d7b5f0be4a4b64bDave Allison  UsageError("  --profile-file=<filename>: specify profiler output file to use for compilation.");
207cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
208cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu  UsageError("  --print-pass-names: print a list of pass names");
209cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu  UsageError("");
210cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu  UsageError("  --disable-passes=<pass-names>:  disable one or more passes separated by comma.");
211cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu  UsageError("      Example: --disable-passes=UseCount,BBOptimizations");
212cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu  UsageError("");
213cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  std::cerr << "See log for usage error information\n";
21469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  exit(EXIT_FAILURE);
21569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom}
21669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
217ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromclass Dex2Oat {
218ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom public:
2194560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  static bool Create(Dex2Oat** p_dex2oat,
2206449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                     const Runtime::Options& runtime_options,
2216449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                     const CompilerOptions& compiler_options,
222b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray                     Compiler::Kind compiler_kind,
2234560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                     InstructionSet instruction_set,
2247020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison                     InstructionSetFeatures instruction_set_features,
2256449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                     VerificationResults* verification_results,
2266449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                     DexFileToMethodInlinerMap* method_inliner_map,
2274560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                     size_t thread_count)
228b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_) {
2296449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    CHECK(verification_results != nullptr);
2306449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    CHECK(method_inliner_map != nullptr);
2316449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    UniquePtr<Dex2Oat> dex2oat(new Dex2Oat(&compiler_options,
232b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray                                           compiler_kind,
2336449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                           instruction_set,
2346449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                           instruction_set_features,
2356449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                           verification_results,
2366449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                           method_inliner_map,
2376449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                           thread_count));
2386449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    if (!dex2oat->CreateRuntime(runtime_options, instruction_set)) {
23900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      *p_dex2oat = NULL;
24000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      return false;
241254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson    }
2422b5eaa2b49f7489bafdadc4b4463ae27e4261817Vladimir Marko    *p_dex2oat = dex2oat.release();
24300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return true;
244ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
245ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
246ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  ~Dex2Oat() {
247ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    delete runtime_;
24865c23bbb25f069b3b49761468b848c4e5d1aa879Brian Carlstrom    LogCompletionTime();
24965c23bbb25f069b3b49761468b848c4e5d1aa879Brian Carlstrom  }
25065c23bbb25f069b3b49761468b848c4e5d1aa879Brian Carlstrom
25165c23bbb25f069b3b49761468b848c4e5d1aa879Brian Carlstrom  void LogCompletionTime() {
25265c23bbb25f069b3b49761468b848c4e5d1aa879Brian Carlstrom    LOG(INFO) << "dex2oat took " << PrettyDuration(NanoTime() - start_ns_)
2534560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom              << " (threads: " << thread_count_ << ")";
254ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
255ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
256c4f105d75cd0cbc5145620068bbb8a819148e535Anwar Ghuloum
2574560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  // Reads the class names (java.lang.Object) and returns a set of descriptors (Ljava/lang/Object;)
2584922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom  CompilerDriver::DescriptorSet* ReadImageClassesFromFile(const char* image_classes_filename) {
2594560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom    UniquePtr<std::ifstream> image_classes_file(new std::ifstream(image_classes_filename,
2604560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                                                                  std::ifstream::in));
261ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    if (image_classes_file.get() == NULL) {
262ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      LOG(ERROR) << "Failed to open image classes file " << image_classes_filename;
263ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      return NULL;
264ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
2654922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    UniquePtr<CompilerDriver::DescriptorSet> result(ReadImageClasses(*image_classes_file.get()));
2664922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    image_classes_file->close();
2674922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    return result.release();
2684922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom  }
269ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
2704922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom  CompilerDriver::DescriptorSet* ReadImageClasses(std::istream& image_classes_stream) {
27196391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom    UniquePtr<CompilerDriver::DescriptorSet> image_classes(new CompilerDriver::DescriptorSet);
2724922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    while (image_classes_stream.good()) {
273ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      std::string dot;
2744922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      std::getline(image_classes_stream, dot);
275f1a5adc87760f938b01df26d906295063546b259Elliott Hughes      if (StartsWith(dot, "#") || dot.empty()) {
276ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        continue;
277ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
278955724179c6c739524f610023287f56b24dc31deElliott Hughes      std::string descriptor(DotToDescriptor(dot.c_str()));
27996391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom      image_classes->insert(descriptor);
280ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
281ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    return image_classes.release();
282254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson  }
283254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson
2844560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  // Reads the class names (java.lang.Object) and returns a set of descriptors (Ljava/lang/Object;)
2858d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers  CompilerDriver::DescriptorSet* ReadImageClassesFromZip(const char* zip_filename,
2868d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                         const char* image_classes_filename,
2878d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                         std::string* error_msg) {
2888d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers    UniquePtr<ZipArchive> zip_archive(ZipArchive::Open(zip_filename, error_msg));
2894922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    if (zip_archive.get() == NULL) {
2904922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      return NULL;
2914922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    }
29292572be7f754c213e615a62955cc5f65ca8c0c0eNarayan Kamath    UniquePtr<ZipEntry> zip_entry(zip_archive->Find(image_classes_filename, error_msg));
2934922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    if (zip_entry.get() == NULL) {
2948d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      *error_msg = StringPrintf("Failed to find '%s' within '%s': %s", image_classes_filename,
2958d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                zip_filename, error_msg->c_str());
2964922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      return NULL;
2974922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    }
2988d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers    UniquePtr<MemMap> image_classes_file(zip_entry->ExtractToMemMap(image_classes_filename,
2998d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                                    error_msg));
3004922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    if (image_classes_file.get() == NULL) {
3018d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", image_classes_filename,
3028d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                zip_filename, error_msg->c_str());
3034922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      return NULL;
3044922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    }
3054922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    const std::string image_classes_string(reinterpret_cast<char*>(image_classes_file->Begin()),
3064922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom                                           image_classes_file->Size());
3074922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    std::istringstream image_classes_stream(image_classes_string);
3084922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    return ReadImageClasses(image_classes_stream);
3094922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom  }
3104922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom
3111212a022fa5f8ef9585d765b1809521812af882cIan Rogers  const CompilerDriver* CreateOatFile(const std::string& boot_image_option,
3123f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      const std::string& android_root,
3133f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      bool is_host,
3143f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      const std::vector<const DexFile*>& dex_files,
3153f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      File* oat_file,
3163f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      const std::string& bitcode_filename,
3173f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      bool image,
31896391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom                                      UniquePtr<CompilerDriver::DescriptorSet>& image_classes,
3193f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      bool dump_stats,
320ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray                                      bool dump_passes,
321ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray                                      TimingLogger& timings,
32239c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison                                      CumulativeLogger& compiler_phases_timings,
32339c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison                                      std::string profile_file) {
324ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    // SirtRef and ClassLoader creation needs to come after Runtime::Create
32500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    jobject class_loader = NULL;
3263f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers    Thread* self = Thread::Current();
327ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    if (!boot_image_option.empty()) {
328ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
329ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      std::vector<const DexFile*> class_path_files(dex_files);
330a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      OpenClassPathFiles(runtime_->GetClassPathString(), class_path_files);
3313f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers      ScopedObjectAccess soa(self);
332ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      for (size_t i = 0; i < class_path_files.size(); i++) {
333ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        class_linker->RegisterDexFile(*class_path_files[i]);
334ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
33500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader);
33600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      ScopedLocalRef<jobject> class_loader_local(soa.Env(),
33700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers          soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
33800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
33900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path_files);
340254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson    }
341ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
3426449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    UniquePtr<CompilerDriver> driver(new CompilerDriver(compiler_options_,
3436449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                                        verification_results_,
3446449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                                        method_inliner_map_,
345b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray                                                        compiler_kind_,
3461212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                        instruction_set_,
3477020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison                                                        instruction_set_features_,
3481212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                        image,
34996391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom                                                        image_classes.release(),
3501212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                        thread_count_,
351ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray                                                        dump_stats,
352ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray                                                        dump_passes,
35339c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison                                                        &compiler_phases_timings,
35439c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison                                                        profile_file));
3558b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien
356b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray    driver->GetCompiler()->SetBitcodeFileName(*driver.get(), bitcode_filename);
3578b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien
3583d504075f7c1204d581923460754bf6d3714b13fIan Rogers    driver->CompileAll(class_loader, dex_files, &timings);
35900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
3606f28d91aab952e3244fbb4e707fa38f85538f374Anwar Ghuloum    timings.NewSplit("dex2oat OatWriter");
36181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom    std::string image_file_location;
36228db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom    uint32_t image_file_location_oat_checksum = 0;
363ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    uintptr_t image_file_location_oat_data_begin = 0;
3640aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao    if (!driver->IsImage()) {
365ca368cb576cf6a436a32c357fca51fbb3082d7a9Ian Rogers      TimingLogger::ScopedSplit split("Loading image checksum", &timings);
3661d54e73444e017d3a65234e0f193846f3e27472bIan Rogers      gc::space::ImageSpace* image_space = Runtime::Current()->GetHeap()->GetImageSpace();
36728db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom      image_file_location_oat_checksum = image_space->GetImageHeader().GetOatChecksum();
36839ebcb800aabedd0ffa6aa4aeac8aa4194c66e61Ian Rogers      image_file_location_oat_data_begin =
369ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers          reinterpret_cast<uintptr_t>(image_space->GetImageHeader().GetOatDataBegin());
37081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom      image_file_location = image_space->GetImageFilename();
37181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom    }
37281f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom
373c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom    OatWriter oat_writer(dex_files,
374c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom                         image_file_location_oat_checksum,
375c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom                         image_file_location_oat_data_begin,
376c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom                         image_file_location,
377ca368cb576cf6a436a32c357fca51fbb3082d7a9Ian Rogers                         driver.get(),
378ca368cb576cf6a436a32c357fca51fbb3082d7a9Ian Rogers                         &timings);
379700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
380ca368cb576cf6a436a32c357fca51fbb3082d7a9Ian Rogers    TimingLogger::ScopedSplit split("Writing ELF", &timings);
3813d504075f7c1204d581923460754bf6d3714b13fIan Rogers    if (!driver->WriteElf(android_root, is_host, dex_files, &oat_writer, oat_file)) {
382700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      LOG(ERROR) << "Failed to write ELF file " << oat_file->GetPath();
383700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      return NULL;
384700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    }
385700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
3861212a022fa5f8ef9585d765b1809521812af882cIan Rogers    return driver.release();
387254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson  }
388ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
389a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  bool CreateImageFile(const std::string& image_filename,
390ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                       uintptr_t image_base,
391ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                       const std::string& oat_filename,
392f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                       const std::string& oat_location,
3931212a022fa5f8ef9585d765b1809521812af882cIan Rogers                       const CompilerDriver& compiler)
394b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::mutator_lock_) {
395700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    uintptr_t oat_data_begin;
396700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    {
397700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      // ImageWriter is scoped so it can free memory before doing FixupElf
39896391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom      ImageWriter image_writer(compiler);
39996391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom      if (!image_writer.Write(image_filename, image_base, oat_filename, oat_location)) {
400700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom        LOG(ERROR) << "Failed to create image file " << image_filename;
401700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom        return false;
402700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      }
403700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      oat_data_begin = image_writer.GetOatDataBegin();
404700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    }
405700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
4067571e8b761ebc2c923525e12ea9fcf07e62cb33eBrian Carlstrom    UniquePtr<File> oat_file(OS::OpenFileReadWrite(oat_filename.c_str()));
407700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    if (oat_file.get() == NULL) {
408700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      PLOG(ERROR) << "Failed to open ELF file: " << oat_filename;
409700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      return false;
410700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    }
41151c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom    if (!ElfFixup::Fixup(oat_file.get(), oat_data_begin)) {
412700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      LOG(ERROR) << "Failed to fixup ELF file " << oat_file->GetPath();
413ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      return false;
414ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
415ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    return true;
416ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
417ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
418ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom private:
4196449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  explicit Dex2Oat(const CompilerOptions* compiler_options,
420b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray                   Compiler::Kind compiler_kind,
4214560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                   InstructionSet instruction_set,
4227020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison                   InstructionSetFeatures instruction_set_features,
4236449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                   VerificationResults* verification_results,
4246449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                   DexFileToMethodInlinerMap* method_inliner_map,
4250177fe200efc1bf4d433955ee7920c683fdf5901Brian Carlstrom                   size_t thread_count)
4266449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      : compiler_options_(compiler_options),
427b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray        compiler_kind_(compiler_kind),
428c531cefbfb5394413122e9f57d211ba436cff012buzbee        instruction_set_(instruction_set),
4297020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison        instruction_set_features_(instruction_set_features),
4306449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        verification_results_(verification_results),
4316449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        method_inliner_map_(method_inliner_map),
4322b5eaa2b49f7489bafdadc4b4463ae27e4261817Vladimir Marko        runtime_(nullptr),
433de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes        thread_count_(thread_count),
434de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes        start_ns_(NanoTime()) {
4356449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    CHECK(compiler_options != nullptr);
4366449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    CHECK(verification_results != nullptr);
4376449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    CHECK(method_inliner_map != nullptr);
438bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  }
439ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
4406449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  bool CreateRuntime(const Runtime::Options& runtime_options, InstructionSet instruction_set)
441b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_) {
4426449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    if (!Runtime::Create(runtime_options, false)) {
443ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      LOG(ERROR) << "Failed to create runtime";
44400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      return false;
445ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
44600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    Runtime* runtime = Runtime::Current();
447ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
448ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
449ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (!runtime->HasCalleeSaveMethod(type)) {
45049c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        runtime->SetCalleeSaveMethod(runtime->CreateCalleeSaveMethod(instruction_set, type), type);
451ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
452ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
4531984651929744dd603fd082e23eacd877b9bc177Ian Rogers    runtime->GetClassLinker()->FixupDexCaches(runtime->GetResolutionMethod());
4542b5eaa2b49f7489bafdadc4b4463ae27e4261817Vladimir Marko    runtime_ = runtime;
45500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return true;
456ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
457ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
458ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // Appends to dex_files any elements of class_path that it doesn't already
459ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // contain. This will open those dex files as necessary.
4604560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  static void OpenClassPathFiles(const std::string& class_path,
4614560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                                 std::vector<const DexFile*>& dex_files) {
462ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    std::vector<std::string> parsed;
463ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    Split(class_path, ':', parsed);
46433e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers    // Take Locks::mutator_lock_ so that lock ordering on the ClassLinker::dex_lock_ is maintained.
46533e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers    ScopedObjectAccess soa(Thread::Current());
466ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    for (size_t i = 0; i < parsed.size(); ++i) {
467ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (DexFilesContains(dex_files, parsed[i])) {
468ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        continue;
469ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
4708d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      std::string error_msg;
4718d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      const DexFile* dex_file = DexFile::Open(parsed[i].c_str(), parsed[i].c_str(), &error_msg);
472ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (dex_file == NULL) {
4738d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers        LOG(WARNING) << "Failed to open dex file '" << parsed[i] << "': " << error_msg;
474ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      } else {
475ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        dex_files.push_back(dex_file);
476ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
477ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
478ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
479ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
480ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // Returns true if dex_files has a dex with the named location.
4814560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  static bool DexFilesContains(const std::vector<const DexFile*>& dex_files,
4824560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                               const std::string& location) {
483ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    for (size_t i = 0; i < dex_files.size(); ++i) {
484ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (dex_files[i]->GetLocation() == location) {
485ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        return true;
486ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
487ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
488ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    return false;
489ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
490ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
491ae7083dac2db59dcdef869e35ac44a039d888ee9Brian Carlstrom  const CompilerOptions* const compiler_options_;
492b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray  const Compiler::Kind compiler_kind_;
493c531cefbfb5394413122e9f57d211ba436cff012buzbee
49449c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers  const InstructionSet instruction_set_;
4957020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  const InstructionSetFeatures instruction_set_features_;
496ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
497ae7083dac2db59dcdef869e35ac44a039d888ee9Brian Carlstrom  VerificationResults* const verification_results_;
498ae7083dac2db59dcdef869e35ac44a039d888ee9Brian Carlstrom  DexFileToMethodInlinerMap* const method_inliner_map_;
499bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  Runtime* runtime_;
5005523ee070b005576c6f889415205d49ea77cf243Elliott Hughes  size_t thread_count_;
501bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  uint64_t start_ns_;
502bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes
503ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  DISALLOW_IMPLICIT_CONSTRUCTORS(Dex2Oat);
504ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom};
505254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson
50672395bf298b7707ad9d93c3e51b57e1b8e010311Elliott Hughesstatic bool ParseInt(const char* in, int* out) {
507a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  char* end;
508a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  int result = strtol(in, &end, 10);
509a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (in == end || *end != '\0') {
510a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    return false;
511a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
512a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  *out = result;
513a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  return true;
514a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom}
515a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
5163cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstromstatic size_t OpenDexFiles(const std::vector<const char*>& dex_filenames,
5173cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom                           const std::vector<const char*>& dex_locations,
5183cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom                           std::vector<const DexFile*>& dex_files) {
5193cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom  size_t failure_count = 0;
5205b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  for (size_t i = 0; i < dex_filenames.size(); i++) {
5215b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom    const char* dex_filename = dex_filenames[i];
522a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    const char* dex_location = dex_locations[i];
523740a11d0bfeaef36d910669844d01f3957dbe696Ian Rogers    ATRACE_BEGIN(StringPrintf("Opening dex file '%s'", dex_filenames[i]).c_str());
5248d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers    std::string error_msg;
525d5aba599561d8d14bb8c19fd633bfcd05af3c264Brian Carlstrom    if (!OS::FileExists(dex_filename)) {
526d5aba599561d8d14bb8c19fd633bfcd05af3c264Brian Carlstrom      LOG(WARNING) << "Skipping non-existent dex file '" << dex_filename << "'";
527d5aba599561d8d14bb8c19fd633bfcd05af3c264Brian Carlstrom      continue;
528d5aba599561d8d14bb8c19fd633bfcd05af3c264Brian Carlstrom    }
5298d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers    const DexFile* dex_file = DexFile::Open(dex_filename, dex_location, &error_msg);
5305b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom    if (dex_file == NULL) {
5318d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      LOG(WARNING) << "Failed to open .dex from file '" << dex_filename << "': " << error_msg;
5323cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      ++failure_count;
53360f83e3274739317d8c3a1b069cebc6bf1e40f29jeffhao    } else {
53460f83e3274739317d8c3a1b069cebc6bf1e40f29jeffhao      dex_files.push_back(dex_file);
5355b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom    }
536740a11d0bfeaef36d910669844d01f3957dbe696Ian Rogers    ATRACE_END();
5375b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  }
5383cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom  return failure_count;
5395b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom}
5405b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom
541bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// The primary goal of the watchdog is to prevent stuck build servers
542bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// during development when fatal aborts lead to a cascade of failures
543bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// that result in a deadlock.
544bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstromclass WatchDog {
545bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// WatchDog defines its own CHECK_PTHREAD_CALL to avoid using Log which uses locks
546bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#undef CHECK_PTHREAD_CALL
547bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#define CHECK_WATCH_DOG_PTHREAD_CALL(call, args, what) \
548bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  do { \
549bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    int rc = call args; \
550bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    if (rc != 0) { \
551bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      errno = rc; \
552bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      std::string message(# call); \
553bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      message += " failed for "; \
554bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      message += reason; \
555ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom      Fatal(message); \
556bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    } \
557bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  } while (false)
558bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
559bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom public:
56093ba893c20532990a430741e0a97212900094e8cBrian Carlstrom  explicit WatchDog(bool is_watch_dog_enabled) {
561994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    is_watch_dog_enabled_ = is_watch_dog_enabled;
562994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    if (!is_watch_dog_enabled_) {
563bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      return;
564bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    }
565bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    shutting_down_ = false;
566bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    const char* reason = "dex2oat watch dog thread startup";
567bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_init, (&mutex_, NULL), reason);
568bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_init, (&cond_, NULL), reason);
569bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_init, (&attr_), reason);
570bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_create, (&pthread_, &attr_, &CallBack, this), reason);
571bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_destroy, (&attr_), reason);
572bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
573bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  ~WatchDog() {
574994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    if (!is_watch_dog_enabled_) {
575bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      return;
576bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    }
577bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    const char* reason = "dex2oat watch dog thread shutdown";
578bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason);
579bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    shutting_down_ = true;
580bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_signal, (&cond_), reason);
581bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason);
582bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
583bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_join, (pthread_, NULL), reason);
584bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
585bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_destroy, (&cond_), reason);
586bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_destroy, (&mutex_), reason);
587bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
588bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
589bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom private:
590bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  static void* CallBack(void* arg) {
591bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    WatchDog* self = reinterpret_cast<WatchDog*>(arg);
5921d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    ::art::SetThreadName("dex2oat watch dog");
593bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    self->Wait();
594bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    return NULL;
595bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
596bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
597ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  static void Message(char severity, const std::string& message) {
5981d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    // TODO: Remove when we switch to LOG when we can guarantee it won't prevent shutdown in error
5991d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    //       cases.
600ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    fprintf(stderr, "dex2oat%s %c %d %d %s\n",
601ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            kIsDebugBuild ? "d" : "",
602ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            severity,
603ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            getpid(),
604ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            GetTid(),
605ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            message.c_str());
606ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  }
607ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom
608eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers  static void Warn(const std::string& message) {
609ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    Message('W', message);
610eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers  }
611eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers
612ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  static void Fatal(const std::string& message) {
613ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    Message('F', message);
614bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    exit(1);
615bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
616bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
617bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  void Wait() {
618eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers    bool warning = true;
619eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers    CHECK_GT(kWatchDogTimeoutSeconds, kWatchDogWarningSeconds);
6201d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    // TODO: tune the multiplier for GC verification, the following is just to make the timeout
6211d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    //       large.
6224e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    int64_t multiplier = kVerifyObjectSupport > kVerifyObjectModeFast ? 100 : 1;
623ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    timespec warning_ts;
6241d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    InitTimeSpec(true, CLOCK_REALTIME, multiplier * kWatchDogWarningSeconds * 1000, 0, &warning_ts);
625ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    timespec timeout_ts;
6261d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    InitTimeSpec(true, CLOCK_REALTIME, multiplier * kWatchDogTimeoutSeconds * 1000, 0, &timeout_ts);
627bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    const char* reason = "dex2oat watch dog thread waiting";
628bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason);
629bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    while (!shutting_down_) {
630eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers      int rc = TEMP_FAILURE_RETRY(pthread_cond_timedwait(&cond_, &mutex_,
631eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers                                                         warning ? &warning_ts
632eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers                                                                 : &timeout_ts));
633bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      if (rc == ETIMEDOUT) {
634bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom        std::string message(StringPrintf("dex2oat did not finish after %d seconds",
635eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers                                         warning ? kWatchDogWarningSeconds
636eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers                                                 : kWatchDogTimeoutSeconds));
637eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers        if (warning) {
638eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers          Warn(message.c_str());
639eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers          warning = false;
640eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers        } else {
641ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom          Fatal(message.c_str());
642eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers        }
643eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers      } else if (rc != 0) {
644bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom        std::string message(StringPrintf("pthread_cond_timedwait failed: %s",
645bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom                                         strerror(errno)));
646ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom        Fatal(message.c_str());
647bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      }
648bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    }
649bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason);
650bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
651bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
652ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  // When setting timeouts, keep in mind that the build server may not be as fast as your desktop.
653ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom#if ART_USE_PORTABLE_COMPILER
654ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  static const unsigned int kWatchDogWarningSeconds =  2 * 60;  // 2 minutes.
655eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers  static const unsigned int kWatchDogTimeoutSeconds = 30 * 60;  // 25 minutes + buffer.
656bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#else
657ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  static const unsigned int kWatchDogWarningSeconds =  1 * 60;  // 1 minute.
658ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  static const unsigned int kWatchDogTimeoutSeconds =  6 * 60;  // 5 minutes + buffer.
659bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#endif
660bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
661994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  bool is_watch_dog_enabled_;
662bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  bool shutting_down_;
6631d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // TODO: Switch to Mutex when we can guarantee it won't prevent shutdown in error cases.
664bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_mutex_t mutex_;
665bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_cond_t cond_;
666bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_attr_t attr_;
667bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_t pthread_;
668bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom};
6691c653d545058a1a850fb6d07d74e607fa1ddf48eIan Rogersconst unsigned int WatchDog::kWatchDogWarningSeconds;
6701c653d545058a1a850fb6d07d74e607fa1ddf48eIan Rogersconst unsigned int WatchDog::kWatchDogTimeoutSeconds;
671bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
6727020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison// Given a set of instruction features from the build, parse it.  The
6737020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison// input 'str' is a comma separated list of feature names.  Parse it and
6747020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison// return the InstructionSetFeatures object.
6757020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allisonstatic InstructionSetFeatures ParseFeatureList(std::string str) {
6767020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  InstructionSetFeatures result;
6777020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  typedef std::vector<std::string> FeatureList;
6787020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  FeatureList features;
6797020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  Split(str, ',', features);
6807020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  for (FeatureList::iterator i = features.begin(); i != features.end(); i++) {
6817020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    std::string feature = Trim(*i);
6827020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    if (feature == "default") {
6837020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      // Nothing to do.
6847020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    } else if (feature == "div") {
6857020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      // Supports divide instruction.
6867020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison       result.SetHasDivideInstruction(true);
6877020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    } else if (feature == "nodiv") {
6887020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      // Turn off support for divide instruction.
6897020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      result.SetHasDivideInstruction(false);
690674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko    } else if (feature == "lpae") {
691674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko      // Supports Large Physical Address Extension.
692674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko      result.SetHasLpae(true);
693674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko    } else if (feature == "nolpae") {
694674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko      // Turn off support for Large Physical Address Extension.
695674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko      result.SetHasLpae(false);
6967020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    } else {
6977020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      Usage("Unknown instruction set feature: '%s'", feature.c_str());
6987020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    }
6997020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  }
7007020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  // others...
7017020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  return result;
7027020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison}
7037020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
70472395bf298b7707ad9d93c3e51b57e1b8e010311Elliott Hughesstatic int dex2oat(int argc, char** argv) {
7056449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  original_argc = argc;
7066449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  original_argv = argv;
7076449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
7085fe9af720048673e62ee29597a30bb9e54c903c5Ian Rogers  TimingLogger timings("compiler", false, false);
709ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray  CumulativeLogger compiler_phases_timings("compilation times");
7104560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom
7110d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes  InitLogging(argv);
71272395bf298b7707ad9d93c3e51b57e1b8e010311Elliott Hughes
71369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  // Skip over argv[0].
71469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  argv++;
71569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  argc--;
71669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
71769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  if (argc == 0) {
718e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom    Usage("No arguments specified");
71969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
72069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
72169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  std::vector<const char*> dex_filenames;
722a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::vector<const char*> dex_locations;
723a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  int zip_fd = -1;
724a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::string zip_location;
725e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  std::string oat_filename;
726265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  std::string oat_symbols;
727a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::string oat_location;
728a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  int oat_fd = -1;
7298b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien  std::string bitcode_filename;
7304922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom  const char* image_classes_zip_filename = NULL;
731ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  const char* image_classes_filename = NULL;
732a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::string image_filename;
733b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  std::string boot_image_filename;
73469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  uintptr_t image_base = 0;
7353f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  std::string android_root;
7365d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao  std::vector<const char*> runtime_args;
7375c599943f8c347acd84c4d9fda56a9df70649b78Elliott Hughes  int thread_count = sysconf(_SC_NPROCESSORS_CONF);
738b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray  Compiler::Kind compiler_kind = kUsePortableCompiler
739b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray      ? Compiler::kPortable
740b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray      : Compiler::kQuick;
7416449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  const char* compiler_filter_string = NULL;
7426449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int huge_method_threshold = CompilerOptions::kDefaultHugeMethodThreshold;
7436449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int large_method_threshold = CompilerOptions::kDefaultLargeMethodThreshold;
7446449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int small_method_threshold = CompilerOptions::kDefaultSmallMethodThreshold;
7456449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int tiny_method_threshold = CompilerOptions::kDefaultTinyMethodThreshold;
7466449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int num_dex_methods_threshold = CompilerOptions::kDefaultNumDexMethodsThreshold;
7477020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
7481bd2ceb3a8c68ae6ea1f9627b588a7bc7a74487fBrian Carlstrom  // Take the default set of instruction features from the build.
7497020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  InstructionSetFeatures instruction_set_features =
7508afeb85d3def12b559b7565fb6d3956f81b55132Ian Rogers      ParseFeatureList(Runtime::GetDefaultInstructionSetFeatures());
7517020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
75291268c1afd6c0d4fad55b7c86d907233d4660205Andreas Gampe  InstructionSet instruction_set = kRuntimeISA;
7537020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
75439c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison  // Profile file to use
75539c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison  std::string profile_file;
7567020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
757265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  bool is_host = false;
758e732ef1c0192acd71925bd0ff1ab09640d45531dIan Rogers  bool dump_stats = false;
75946398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers  bool dump_timing = false;
760ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray  bool dump_passes = false;
76146398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers  bool dump_slow_timing = kIsDebugBuild;
762994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  bool watch_dog_enabled = !kIsTargetBuild;
763ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  bool generate_gdb_information = kIsDebugBuild;
764161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom
76569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  for (int i = 0; i < argc; i++) {
76669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    const StringPiece option(argv[i]);
767b9beb2e2efb6a204a69ca660d478b45f851e8f09Ian Rogers    const bool log_options = false;
768a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    if (log_options) {
769b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom      LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i];
770b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom    }
77169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    if (option.starts_with("--dex-file=")) {
77269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      dex_filenames.push_back(option.substr(strlen("--dex-file=")).data());
773a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    } else if (option.starts_with("--dex-location=")) {
774a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      dex_locations.push_back(option.substr(strlen("--dex-location=")).data());
775a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else if (option.starts_with("--zip-fd=")) {
776a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      const char* zip_fd_str = option.substr(strlen("--zip-fd=")).data();
777bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes      if (!ParseInt(zip_fd_str, &zip_fd)) {
778e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom        Usage("Failed to parse --zip-fd argument '%s' as an integer", zip_fd_str);
779a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
7806449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (zip_fd < 0) {
7816449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--zip-fd passed a negative value %d", zip_fd);
7826449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
783a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    } else if (option.starts_with("--zip-location=")) {
784a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      zip_location = option.substr(strlen("--zip-location=")).data();
785a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else if (option.starts_with("--oat-file=")) {
786a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      oat_filename = option.substr(strlen("--oat-file=")).data();
787265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    } else if (option.starts_with("--oat-symbols=")) {
788265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      oat_symbols = option.substr(strlen("--oat-symbols=")).data();
789a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else if (option.starts_with("--oat-fd=")) {
790a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      const char* oat_fd_str = option.substr(strlen("--oat-fd=")).data();
791bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes      if (!ParseInt(oat_fd_str, &oat_fd)) {
792e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom        Usage("Failed to parse --oat-fd argument '%s' as an integer", oat_fd_str);
793a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
7946449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (oat_fd < 0) {
7956449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--oat-fd passed a negative value %d", oat_fd);
7966449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
797994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    } else if (option == "--watch-dog") {
798994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom      watch_dog_enabled = true;
799994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    } else if (option == "--no-watch-dog") {
800994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom      watch_dog_enabled = false;
801ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell    } else if (option == "--gen-gdb-info") {
802ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell      generate_gdb_information = true;
803ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell    } else if (option == "--no-gen-gdb-info") {
804ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell      generate_gdb_information = false;
8055523ee070b005576c6f889415205d49ea77cf243Elliott Hughes    } else if (option.starts_with("-j")) {
806b12552a95d68b9e4a567103190074ae47b6a61dcBrian Carlstrom      const char* thread_count_str = option.substr(strlen("-j")).data();
8075523ee070b005576c6f889415205d49ea77cf243Elliott Hughes      if (!ParseInt(thread_count_str, &thread_count)) {
808e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom        Usage("Failed to parse -j argument '%s' as an integer", thread_count_str);
8095523ee070b005576c6f889415205d49ea77cf243Elliott Hughes      }
810a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    } else if (option.starts_with("--oat-location=")) {
811a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      oat_location = option.substr(strlen("--oat-location=")).data();
8128b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien    } else if (option.starts_with("--bitcode=")) {
8138b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien      bitcode_filename = option.substr(strlen("--bitcode=")).data();
81469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    } else if (option.starts_with("--image=")) {
81569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      image_filename = option.substr(strlen("--image=")).data();
816ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    } else if (option.starts_with("--image-classes=")) {
817ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      image_classes_filename = option.substr(strlen("--image-classes=")).data();
8184922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    } else if (option.starts_with("--image-classes-zip=")) {
8194922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      image_classes_zip_filename = option.substr(strlen("--image-classes-zip=")).data();
82069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    } else if (option.starts_with("--base=")) {
82169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      const char* image_base_str = option.substr(strlen("--base=")).data();
82269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      char* end;
82369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      image_base = strtoul(image_base_str, &end, 16);
82469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      if (end == image_base_str || *end != '\0') {
825cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom        Usage("Failed to parse hexadecimal value for option %s", option.data());
82669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      }
827e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom    } else if (option.starts_with("--boot-image=")) {
828b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom      boot_image_filename = option.substr(strlen("--boot-image=")).data();
8293f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    } else if (option.starts_with("--android-root=")) {
8303f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom      android_root = option.substr(strlen("--android-root=")).data();
83149c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers    } else if (option.starts_with("--instruction-set=")) {
83249c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers      StringPiece instruction_set_str = option.substr(strlen("--instruction-set=")).data();
8331f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao      if (instruction_set_str == "arm") {
83449c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        instruction_set = kThumb2;
835b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith      } else if (instruction_set_str == "arm64") {
836b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith        instruction_set = kArm64;
8371f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao      } else if (instruction_set_str == "mips") {
83849c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        instruction_set = kMips;
8391f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao      } else if (instruction_set_str == "x86") {
84049c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        instruction_set = kX86;
841ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      } else if (instruction_set_str == "x86_64") {
842ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers        instruction_set = kX86_64;
84349c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers      }
8447020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    } else if (option.starts_with("--instruction-set-features=")) {
8457020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      StringPiece str = option.substr(strlen("--instruction-set-features=")).data();
8467020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      instruction_set_features = ParseFeatureList(str.as_string());
847c531cefbfb5394413122e9f57d211ba436cff012buzbee    } else if (option.starts_with("--compiler-backend=")) {
848c531cefbfb5394413122e9f57d211ba436cff012buzbee      StringPiece backend_str = option.substr(strlen("--compiler-backend=")).data();
849c531cefbfb5394413122e9f57d211ba436cff012buzbee      if (backend_str == "Quick") {
850b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray        compiler_kind = Compiler::kQuick;
851b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray      } else if (backend_str == "Optimizing") {
852b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray        compiler_kind = Compiler::kOptimizing;
853c531cefbfb5394413122e9f57d211ba436cff012buzbee      } else if (backend_str == "Portable") {
854b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray        compiler_kind = Compiler::kPortable;
855c531cefbfb5394413122e9f57d211ba436cff012buzbee      }
8566449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--compiler-filter=")) {
8576449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      compiler_filter_string = option.substr(strlen("--compiler-filter=")).data();
8586449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--huge-method-max=")) {
8596449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--huge-method-max=")).data();
8606449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &huge_method_threshold)) {
8616449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --huge-method-max '%s' as an integer", threshold);
8626449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8636449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (huge_method_threshold < 0) {
8646449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--huge-method-max passed a negative value %s", huge_method_threshold);
8656449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8666449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--large-method-max=")) {
8676449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--large-method-max=")).data();
8686449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &large_method_threshold)) {
8696449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --large-method-max '%s' as an integer", threshold);
8706449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8716449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (large_method_threshold < 0) {
8726449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--large-method-max passed a negative value %s", large_method_threshold);
8736449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8746449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--small-method-max=")) {
8756449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--small-method-max=")).data();
8766449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &small_method_threshold)) {
8776449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --small-method-max '%s' as an integer", threshold);
8786449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8796449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (small_method_threshold < 0) {
8806449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--small-method-max passed a negative value %s", small_method_threshold);
8816449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8826449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--tiny-method-max=")) {
8836449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--tiny-method-max=")).data();
8846449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &tiny_method_threshold)) {
8856449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --tiny-method-max '%s' as an integer", threshold);
8866449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8876449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (tiny_method_threshold < 0) {
8886449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--tiny-method-max passed a negative value %s", tiny_method_threshold);
8896449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8906449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--num-dex-methods=")) {
8916449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--num-dex-methods=")).data();
8926449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &num_dex_methods_threshold)) {
8936449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --num-dex-methods '%s' as an integer", threshold);
8946449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8956449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (num_dex_methods_threshold < 0) {
8966449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--num-dex-methods passed a negative value %s", num_dex_methods_threshold);
8976449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
898265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    } else if (option == "--host") {
899265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      is_host = true;
9005d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao    } else if (option == "--runtime-arg") {
9015d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao      if (++i >= argc) {
902cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom        Usage("Missing required argument for --runtime-arg");
9035d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao      }
904a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      if (log_options) {
905a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom        LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i];
906a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
9075d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao      runtime_args.push_back(argv[i]);
90846398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers    } else if (option == "--dump-timing") {
90946398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers      dump_timing = true;
910ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray    } else if (option == "--dump-passes") {
911ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray      dump_passes = true;
912e732ef1c0192acd71925bd0ff1ab09640d45531dIan Rogers    } else if (option == "--dump-stats") {
913e732ef1c0192acd71925bd0ff1ab09640d45531dIan Rogers      dump_stats = true;
91439c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison    } else if (option.starts_with("--profile-file=")) {
91539c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison      profile_file = option.substr(strlen("--profile-file=")).data();
91639c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison      VLOG(compiler) << "dex2oat: profile file is " << profile_file;
91739c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison    } else if (option == "--no-profile-file") {
91839c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison      // No profile
919cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu    } else if (option == "--print-pass-names") {
920cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu      PassDriver::PrintPassNames();
921cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu    } else if (option.starts_with("--disable-passes=")) {
922cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu      std::string disable_passes = option.substr(strlen("--disable-passes=")).data();
923cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu      PassDriver::CreateDefaultPassList(disable_passes);
92469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    } else {
925e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom      Usage("Unknown argument %s", option.data());
92669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    }
92769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
92869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
929a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (oat_filename.empty() && oat_fd == -1) {
930cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("Output must be supplied with either --oat-file or --oat-fd");
931a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
932a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
933a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (!oat_filename.empty() && oat_fd != -1) {
934cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--oat-file should not be used with --oat-fd");
935a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
936a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
937265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (!oat_symbols.empty() && oat_fd != -1) {
938265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    Usage("--oat-symbols should not be used with --oat-fd");
939265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  }
940265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
941265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (!oat_symbols.empty() && is_host) {
942265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    Usage("--oat-symbols should not be used with --host");
943a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
944a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
945a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (oat_fd != -1 && !image_filename.empty()) {
946cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--oat-fd should not be used with --image");
947e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  }
948e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
9493f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  if (android_root.empty()) {
9503f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    const char* android_root_env_var = getenv("ANDROID_ROOT");
9513f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    if (android_root_env_var == NULL) {
95254d22c2bb47da44ef586b9de94749d5648178a26Brian Carlstrom      Usage("--android-root unspecified and ANDROID_ROOT not set");
9533f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    }
9543f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    android_root += android_root_env_var;
9553f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  }
9563f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom
957a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  bool image = (!image_filename.empty());
958b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  if (!image && boot_image_filename.empty()) {
9599583fbcf597eff6d0b3c5359b8e8d5f70ed82c40Nicolas Geoffray    boot_image_filename += GetAndroidRoot();
960b9beb2e2efb6a204a69ca660d478b45f851e8f09Ian Rogers    boot_image_filename += "/framework/boot-";
961b9beb2e2efb6a204a69ca660d478b45f851e8f09Ian Rogers    boot_image_filename += GetInstructionSetString(instruction_set);
962b9beb2e2efb6a204a69ca660d478b45f851e8f09Ian Rogers    boot_image_filename += ".art";
963b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  }
964b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  std::string boot_image_option;
965a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (!boot_image_filename.empty()) {
966b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom    boot_image_option += "-Ximage:";
967b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom    boot_image_option += boot_image_filename;
96869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
96969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
970ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  if (image_classes_filename != NULL && !image) {
971cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--image-classes should only be used with --image");
972ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
973ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
974ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  if (image_classes_filename != NULL && !boot_image_option.empty()) {
975cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--image-classes should not be used with --boot-image");
97678128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom  }
97778128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom
9784922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom  if (image_classes_zip_filename != NULL && image_classes_filename == NULL) {
9794922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    Usage("--image-classes-zip should be used with --image-classes");
9804922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom  }
9814922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom
982a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (dex_filenames.empty() && zip_fd == -1) {
983cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("Input must be supplied with either --dex-file or --zip-fd");
984a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
985a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
986a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (!dex_filenames.empty() && zip_fd != -1) {
987cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--dex-file should not be used with --zip-fd");
988a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
989a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
990a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (!dex_filenames.empty() && !zip_location.empty()) {
991cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--dex-file should not be used with --zip-location");
992a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
993a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
994a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (dex_locations.empty()) {
995a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    for (size_t i = 0; i < dex_filenames.size(); i++) {
996a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      dex_locations.push_back(dex_filenames[i]);
997a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    }
998a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  } else if (dex_locations.size() != dex_filenames.size()) {
999cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--dex-location arguments do not match --dex-file arguments");
1000a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  }
1001a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom
1002a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (zip_fd != -1 && zip_location.empty()) {
1003cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--zip-location should be supplied with --zip-fd");
1004a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1005a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
100669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  if (boot_image_option.empty()) {
100769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    if (image_base == 0) {
1008e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom      Usage("Non-zero --base not specified");
100969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    }
101069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
101169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
1012265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  std::string oat_stripped(oat_filename);
1013265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  std::string oat_unstripped;
1014265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (!oat_symbols.empty()) {
1015265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    oat_unstripped += oat_symbols;
1016265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  } else {
1017265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    oat_unstripped += oat_filename;
1018265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  }
1019265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
10206449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  if (compiler_filter_string == NULL) {
10219e06c8cd4a2e1471754470e09aaab63c0795b4afZheng Xu    if (instruction_set == kX86_64 || instruction_set == kMips) {
10227ca278be5f6f15681350e9f05af434df4aab59caIan Rogers      // TODO: implement/fix compilers for these architectures.
1023befbd5731ecca08f08780ee28a913d08ffb14656Ian Rogers      compiler_filter_string = "interpret-only";
1024befbd5731ecca08f08780ee28a913d08ffb14656Ian Rogers    } else if (image) {
10255e754d88c73f1f1fafbbf87d564df000d5a0a12cBrian Carlstrom      compiler_filter_string = "speed";
10266449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else {
10276449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#if ART_SMALL_MODE
10286449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      compiler_filter_string = "interpret-only";
10296449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#else
10306449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      compiler_filter_string = "speed";
10316449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#endif
10326449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    }
10336449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  }
10346449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  CHECK(compiler_filter_string != nullptr);
10356449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  CompilerOptions::CompilerFilter compiler_filter = CompilerOptions::kDefaultCompilerFilter;
10364a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  if (strcmp(compiler_filter_string, "verify-none") == 0) {
10374a200f56b7075309316b04d550c9cc50f8314eddJeff Hao    compiler_filter = CompilerOptions::kVerifyNone;
10384a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  } else if (strcmp(compiler_filter_string, "interpret-only") == 0) {
10396449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kInterpretOnly;
10406449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else if (strcmp(compiler_filter_string, "space") == 0) {
10416449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kSpace;
10426449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else if (strcmp(compiler_filter_string, "balanced") == 0) {
10436449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kBalanced;
10446449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else if (strcmp(compiler_filter_string, "speed") == 0) {
10456449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kSpeed;
10466449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else if (strcmp(compiler_filter_string, "everything") == 0) {
10476449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kEverything;
10486449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else {
10496449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    Usage("Unknown --compiler-filter value %s", compiler_filter_string);
10506449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  }
10516449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
10526449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  CompilerOptions compiler_options(compiler_filter,
10536449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                   huge_method_threshold,
10546449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                   large_method_threshold,
10556449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                   small_method_threshold,
10566449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                   tiny_method_threshold,
1057ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell                                   num_dex_methods_threshold,
1058d6ed642458c8820e1beca72f3d7b5f0be4a4b64bDave Allison                                   generate_gdb_information
10596449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#ifdef ART_SEA_IR_MODE
10606449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                   , compiler_options.sea_ir_ = true;
10616449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#endif
10626449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                   );  // NOLINT(whitespace/parens)
10636449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
1064994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  // Done with usage checks, enable watchdog if requested
1065994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  WatchDog watch_dog(watch_dog_enabled);
1066994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom
10676ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom  // Check early that the result of compilation can be written
1068a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  UniquePtr<File> oat_file;
1069265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  bool create_file = !oat_unstripped.empty();  // as opposed to using open file descriptor
10706cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom  if (create_file) {
10717571e8b761ebc2c923525e12ea9fcf07e62cb33eBrian Carlstrom    oat_file.reset(OS::CreateEmptyFile(oat_unstripped.c_str()));
1072a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    if (oat_location.empty()) {
1073a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      oat_location = oat_filename;
1074a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    }
1075a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  } else {
1076761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    oat_file.reset(new File(oat_fd, oat_location));
1077761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    oat_file->DisableAutoClose();
1078a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
10796ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom  if (oat_file.get() == NULL) {
10806cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom    PLOG(ERROR) << "Failed to create oat file: " << oat_location;
10816cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom    return EXIT_FAILURE;
10826cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom  }
10836cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom  if (create_file && fchmod(oat_file->Fd(), 0644) != 0) {
10846cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom    PLOG(ERROR) << "Failed to make oat file world readable: " << oat_location;
10856ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom    return EXIT_FAILURE;
1086234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  }
1087a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1088e6bb3b2ce5a69c31c2adfc7eb2705633b7f966ebIan Rogers  timings.StartSplit("dex2oat Setup");
108909881a85579cab1779ddf6ba9a91eed861a13cb2Brian Carlstrom  LOG(INFO) << CommandLine();
10905e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers
10916449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  Runtime::Options runtime_options;
1092a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::vector<const DexFile*> boot_class_path;
109369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  if (boot_image_option.empty()) {
10943cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom    size_t failure_count = OpenDexFiles(dex_filenames, dex_locations, boot_class_path);
10953cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom    if (failure_count > 0) {
10963cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      LOG(ERROR) << "Failed to open some dex files: " << failure_count;
10973cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      return EXIT_FAILURE;
10983cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom    }
10996449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    runtime_options.push_back(std::make_pair("bootclasspath", &boot_class_path));
110069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  } else {
11016449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    runtime_options.push_back(std::make_pair(boot_image_option.c_str(),
11026449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                             reinterpret_cast<void*>(NULL)));
110369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
11045d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao  for (size_t i = 0; i < runtime_args.size(); i++) {
11056449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    runtime_options.push_back(std::make_pair(runtime_args[i], reinterpret_cast<void*>(NULL)));
11065d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao  }
110769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
11086449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  VerificationResults verification_results(&compiler_options);
11096449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  DexFileToMethodInlinerMap method_inliner_map;
11106449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  CompilerCallbacksImpl callbacks(&verification_results, &method_inliner_map);
11116449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  runtime_options.push_back(std::make_pair("compilercallbacks", &callbacks));
111211d9f06a96a6909905c248ed684366190140095cNarayan Kamath  runtime_options.push_back(
111311d9f06a96a6909905c248ed684366190140095cNarayan Kamath      std::make_pair("imageinstructionset",
111411d9f06a96a6909905c248ed684366190140095cNarayan Kamath                     reinterpret_cast<const void*>(GetInstructionSetString(instruction_set))));
11157467ee05012e1fd9834df74663c1ebda46f5636bDragos Sbirlea
111600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Dex2Oat* p_dex2oat;
11176449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  if (!Dex2Oat::Create(&p_dex2oat,
11186449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       runtime_options,
11196449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       compiler_options,
1120b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray                       compiler_kind,
11216449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       instruction_set,
11226449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       instruction_set_features,
11236449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       &verification_results,
11246449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       &method_inliner_map,
11256449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       thread_count)) {
112600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    LOG(ERROR) << "Failed to create dex2oat";
112700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return EXIT_FAILURE;
112800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
112900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  UniquePtr<Dex2Oat> dex2oat(p_dex2oat);
113000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
11313f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers  // give it away now so that we don't starve GC.
11323f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers  Thread* self = Thread::Current();
11333f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers  self->TransitionFromRunnableToSuspended(kNative);
11340f40ac31134d9ae0f059d4c448165599dc8459c1Ian Rogers  // If we're doing the image, override the compiler filter to force full compilation. Must be
1135fe9ca4028f379688ecba6132ac3738171176b3e4buzbee  // done ahead of WellKnownClasses::Init that causes verification.  Note: doesn't force
1136fe9ca4028f379688ecba6132ac3738171176b3e4buzbee  // compilation of class initializers.
113700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Whilst we're in native take the opportunity to initialize well known classes.
11383f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers  WellKnownClasses::Init(self->GetJniEnv());
113969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
1140bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  // If --image-classes was specified, calculate the full list of classes to include in the image
114196391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom  UniquePtr<CompilerDriver::DescriptorSet> image_classes(NULL);
1142ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  if (image_classes_filename != NULL) {
11438d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers    std::string error_msg;
11444922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    if (image_classes_zip_filename != NULL) {
11454922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      image_classes.reset(dex2oat->ReadImageClassesFromZip(image_classes_zip_filename,
11468d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                           image_classes_filename,
11478d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                           &error_msg));
11484922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    } else {
11494922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      image_classes.reset(dex2oat->ReadImageClassesFromFile(image_classes_filename));
11504922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    }
1151ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    if (image_classes.get() == NULL) {
11528d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      LOG(ERROR) << "Failed to create list of image classes from '" << image_classes_filename <<
11538d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers          "': " << error_msg;
1154ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      return EXIT_FAILURE;
115569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    }
115669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
115769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
1158a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  std::vector<const DexFile*> dex_files;
1159a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (boot_image_option.empty()) {
1160a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    dex_files = Runtime::Current()->GetClassLinker()->GetBootClassPath();
1161a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  } else {
1162a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    if (dex_filenames.empty()) {
1163740a11d0bfeaef36d910669844d01f3957dbe696Ian Rogers      ATRACE_BEGIN("Opening zip archive from file descriptor");
11648d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      std::string error_msg;
11658d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      UniquePtr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(zip_fd, zip_location.c_str(),
11668d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                               &error_msg));
1167a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      if (zip_archive.get() == NULL) {
11688d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers        LOG(ERROR) << "Failed to open zip from file descriptor for '" << zip_location << "': "
11698d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers            << error_msg;
11702e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom        return EXIT_FAILURE;
1171a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
11728d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      const DexFile* dex_file = DexFile::Open(*zip_archive.get(), zip_location, &error_msg);
1173a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      if (dex_file == NULL) {
11748d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers        LOG(ERROR) << "Failed to open dex from file descriptor for zip file '" << zip_location
11758d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers            << "': " << error_msg;
1176a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom        return EXIT_FAILURE;
1177a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
1178a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      dex_files.push_back(dex_file);
1179740a11d0bfeaef36d910669844d01f3957dbe696Ian Rogers      ATRACE_END();
1180a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else {
11813cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      size_t failure_count = OpenDexFiles(dex_filenames, dex_locations, dex_files);
11823cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      if (failure_count > 0) {
11833cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom        LOG(ERROR) << "Failed to open some dex files: " << failure_count;
11843cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom        return EXIT_FAILURE;
11853cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      }
1186a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    }
1187d76e08323893c60df77eccca6e882279e7246d8cBrian Carlstrom
1188f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom    const bool kSaveDexInput = false;
1189f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom    if (kSaveDexInput) {
1190f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom      for (size_t i = 0; i < dex_files.size(); ++i) {
1191f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom        const DexFile* dex_file = dex_files[i];
11925180cc1cddc5112ea544bf9d8323f1d27db56f75Ian Rogers        std::string tmp_file_name(StringPrintf("/data/local/tmp/dex2oat.%d.%zd.dex", getpid(), i));
1193f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom        UniquePtr<File> tmp_file(OS::CreateEmptyFile(tmp_file_name.c_str()));
1194f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom        if (tmp_file.get() == nullptr) {
11956449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom            PLOG(ERROR) << "Failed to open file " << tmp_file_name
11966449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                        << ". Try: adb shell chmod 777 /data/local/tmp";
1197f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom            continue;
1198f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom        }
1199f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom        tmp_file->WriteFully(dex_file->Begin(), dex_file->Size());
1200f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom        LOG(INFO) << "Wrote input to " << tmp_file_name;
1201f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom      }
1202f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom    }
12032ec6520d57479d393bffa05defa1479b25ca8382Brian Carlstrom  }
12042ec6520d57479d393bffa05defa1479b25ca8382Brian Carlstrom  // Ensure opened dex files are writable for dex-to-dex transformations.
12052ec6520d57479d393bffa05defa1479b25ca8382Brian Carlstrom  for (const auto& dex_file : dex_files) {
12062ec6520d57479d393bffa05defa1479b25ca8382Brian Carlstrom    if (!dex_file->EnableWrite()) {
12072ec6520d57479d393bffa05defa1479b25ca8382Brian Carlstrom      PLOG(ERROR) << "Failed to make .dex file writeable '" << dex_file->GetLocation() << "'\n";
1208d76e08323893c60df77eccca6e882279e7246d8cBrian Carlstrom    }
1209a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1210a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1211a024a0686c3b0fea13f362bff70d65981e5febc5buzbee  /*
12124a200f56b7075309316b04d550c9cc50f8314eddJeff Hao   * If we're not in interpret-only or verify-none mode, go ahead and compile small applications.
12134a200f56b7075309316b04d550c9cc50f8314eddJeff Hao   * Don't bother to check if we're doing the image.
1214a024a0686c3b0fea13f362bff70d65981e5febc5buzbee   */
12154a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  if (!image && compiler_options.IsCompilationEnabled()) {
12168447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum    size_t num_methods = 0;
12178447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum    for (size_t i = 0; i != dex_files.size(); ++i) {
12188447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum      const DexFile* dex_file = dex_files[i];
12198447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum      CHECK(dex_file != NULL);
12208447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum      num_methods += dex_file->NumMethodIds();
12218447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum    }
12226449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    if (num_methods <= compiler_options.GetNumDexMethodsThreshold()) {
12236449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      compiler_options.SetCompilerFilter(CompilerOptions::kSpeed);
122475a43f10f55e2aa550de51e969cc1e60d583b632Anwar Ghuloum      VLOG(compiler) << "Below method threshold, compiling anyways";
12258447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum    }
12268447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum  }
1227c4f105d75cd0cbc5145620068bbb8a819148e535Anwar Ghuloum
12281212a022fa5f8ef9585d765b1809521812af882cIan Rogers  UniquePtr<const CompilerDriver> compiler(dex2oat->CreateOatFile(boot_image_option,
12293f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                                                  android_root,
1230265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                                                                  is_host,
12311212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                                  dex_files,
12321212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                                  oat_file.get(),
12331212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                                  bitcode_filename,
12341212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                                  image,
123596391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom                                                                  image_classes,
12361212a022fa5f8ef9585d765b1809521812af882cIan Rogers                                                                  dump_stats,
1237ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray                                                                  dump_passes,
1238ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray                                                                  timings,
123939c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison                                                                  compiler_phases_timings,
124039c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison                                                                  profile_file));
1241f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom
1242f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom  if (compiler.get() == NULL) {
1243a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    LOG(ERROR) << "Failed to create oat file: " << oat_location;
1244e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom    return EXIT_FAILURE;
1245e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  }
1246e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
124775a43f10f55e2aa550de51e969cc1e60d583b632Anwar Ghuloum  VLOG(compiler) << "Oat file written successfully (unstripped): " << oat_location;
1248aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
1249700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // Notes on the interleaving of creating the image and oat file to
1250700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // ensure the references between the two are correct.
1251700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1252700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // Currently we have a memory layout that looks something like this:
1253700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1254700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // +--------------+
1255700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // | image        |
1256700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // +--------------+
1257700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // | boot oat     |
1258700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // +--------------+
1259700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // | alloc spaces |
1260700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // +--------------+
1261700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
12624560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  // There are several constraints on the loading of the image and boot.oat.
1263700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1264700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 1. The image is expected to be loaded at an absolute address and
1265700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // contains Objects with absolute pointers within the image.
1266700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1267700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 2. There are absolute pointers from Methods in the image to their
1268700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // code in the oat.
1269700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1270700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 3. There are absolute pointers from the code in the oat to Methods
1271700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // in the image.
1272700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1273700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 4. There are absolute pointers from code in the oat to other code
1274700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // in the oat.
1275700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1276700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // To get this all correct, we go through several steps.
1277700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1278700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 1. We have already created that oat file above with
1279700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // CreateOatFile. Originally this was just our own proprietary file
12804560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  // but now it is contained within an ELF dynamic object (aka an .so
1281700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // file). The Compiler returned by CreateOatFile provides
1282700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // PatchInformation for references to oat code and Methods that need
1283700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // to be update once we know where the oat file will be located
1284700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // after the image.
1285700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1286700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 2. We create the image file. It needs to know where the oat file
1287700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // will be loaded after itself. Originally when oat file was simply
1288700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // memory mapped so we could predict where its contents were based
1289700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // on the file size. Now that it is an ELF file, we need to inspect
1290700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // the ELF file to understand the in memory segment layout including
1291700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // where the oat header is located within. ImageWriter's
1292700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // PatchOatCodeAndMethods uses the PatchInformation from the
1293700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // Compiler to touch up absolute references in the oat file.
1294700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1295700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 3. We fixup the ELF program headers so that dlopen will try to
1296700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // load the .so at the desired location at runtime by offsetting the
1297700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // Elf32_Phdr.p_vaddr values by the desired base address.
1298700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1299265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (image) {
13006f28d91aab952e3244fbb4e707fa38f85538f374Anwar Ghuloum    timings.NewSplit("dex2oat ImageWriter");
1301265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    bool image_creation_success = dex2oat->CreateImageFile(image_filename,
1302265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                                                           image_base,
1303265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                                                           oat_unstripped,
1304265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                                                           oat_location,
1305265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                                                           *compiler.get());
1306265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    if (!image_creation_success) {
1307265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      return EXIT_FAILURE;
1308265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    }
130975a43f10f55e2aa550de51e969cc1e60d583b632Anwar Ghuloum    VLOG(compiler) << "Image written successfully: " << image_filename;
1310265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  }
1311265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
1312265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (is_host) {
131346398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers    if (dump_timing || (dump_slow_timing && timings.GetTotalNs() > MsToNs(1000))) {
13145fe9af720048673e62ee29597a30bb9e54c903c5Ian Rogers      LOG(INFO) << Dumpable<TimingLogger>(timings);
13154560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom    }
1316ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray    if (dump_passes) {
13173d504075f7c1204d581923460754bf6d3714b13fIan Rogers      LOG(INFO) << Dumpable<CumulativeLogger>(*compiler.get()->GetTimingsLogger());
1318ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray    }
1319265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    return EXIT_SUCCESS;
132069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
132169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
1322265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // If we don't want to strip in place, copy from unstripped location to stripped location.
1323265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // We need to strip after image creation because FixupElf needs to use .strtab.
1324265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (oat_unstripped != oat_stripped) {
13256f28d91aab952e3244fbb4e707fa38f85538f374Anwar Ghuloum    timings.NewSplit("dex2oat OatFile copy");
1326265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    oat_file.reset();
13277571e8b761ebc2c923525e12ea9fcf07e62cb33eBrian Carlstrom     UniquePtr<File> in(OS::OpenFileForReading(oat_unstripped.c_str()));
13287571e8b761ebc2c923525e12ea9fcf07e62cb33eBrian Carlstrom    UniquePtr<File> out(OS::CreateEmptyFile(oat_stripped.c_str()));
1329265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    size_t buffer_size = 8192;
1330265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    UniquePtr<uint8_t> buffer(new uint8_t[buffer_size]);
1331265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    while (true) {
1332265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      int bytes_read = TEMP_FAILURE_RETRY(read(in->Fd(), buffer.get(), buffer_size));
1333265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      if (bytes_read <= 0) {
1334265091e581c9f643b37e7966890911f09e223269Brian Carlstrom        break;
1335265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      }
1336265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      bool write_ok = out->WriteFully(buffer.get(), bytes_read);
1337265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      CHECK(write_ok);
1338265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    }
1339265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    oat_file.reset(out.release());
134075a43f10f55e2aa550de51e969cc1e60d583b632Anwar Ghuloum    VLOG(compiler) << "Oat file copied successfully (stripped): " << oat_stripped;
1341265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  }
1342265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
13437fcba11846d3320911aefdba6a20c1192e36fc2eBrian Carlstrom#if ART_USE_PORTABLE_COMPILER  // We currently only generate symbols on Portable
13446f28d91aab952e3244fbb4e707fa38f85538f374Anwar Ghuloum  timings.NewSplit("dex2oat ElfStripper");
1345265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // Strip unneeded sections for target
1346265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  off_t seek_actual = lseek(oat_file->Fd(), 0, SEEK_SET);
1347265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  CHECK_EQ(0, seek_actual);
13488d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers  std::string error_msg;
13498d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers  CHECK(ElfStripper::Strip(oat_file.get(), &error_msg)) << error_msg;
13506f28d91aab952e3244fbb4e707fa38f85538f374Anwar Ghuloum
1351265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
1352ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // We wrote the oat file successfully, and want to keep it.
135375a43f10f55e2aa550de51e969cc1e60d583b632Anwar Ghuloum  VLOG(compiler) << "Oat file written successfully (stripped): " << oat_location;
13547934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom#endif  // ART_USE_PORTABLE_COMPILER
13554560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom
13566f28d91aab952e3244fbb4e707fa38f85538f374Anwar Ghuloum  timings.EndSplit();
13576f28d91aab952e3244fbb4e707fa38f85538f374Anwar Ghuloum
1358c6dfdacea2fd9e268f70328805b0366cdd6b7b9eBrian Carlstrom  if (dump_timing || (dump_slow_timing && timings.GetTotalNs() > MsToNs(1000))) {
13595fe9af720048673e62ee29597a30bb9e54c903c5Ian Rogers    LOG(INFO) << Dumpable<TimingLogger>(timings);
13604560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  }
1361ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray  if (dump_passes) {
1362ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray    LOG(INFO) << Dumpable<CumulativeLogger>(compiler_phases_timings);
1363ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray  }
13642672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers
13652672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers  // Everything was successfully written, do an explicit exit here to avoid running Runtime
13662672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers  // destructors that take time (bug 10645725) unless we're a debug build or running on valgrind.
13676449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  if (!kIsDebugBuild && (RUNNING_ON_VALGRIND == 0)) {
136865c23bbb25f069b3b49761468b848c4e5d1aa879Brian Carlstrom    dex2oat->LogCompletionTime();
13692672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers    exit(EXIT_SUCCESS);
13702672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers  }
13712672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers
137269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  return EXIT_SUCCESS;
13736449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom}  // NOLINT(readability/fn_size)
13747934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom}  // namespace art
137569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
137669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromint main(int argc, char** argv) {
137769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  return art::dex2oat(argc, argv);
137869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom}
1379