dex2oat.cc revision 3ac05bba3eadccb33d26b41d9797f63e8378125f
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)) {
2395131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      *p_dex2oat = nullptr;
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));
2615131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (image_classes_file.get() == nullptr) {
262ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      LOG(ERROR) << "Failed to open image classes file " << image_classes_filename;
2635131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      return nullptr;
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));
2895131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (zip_archive.get() == nullptr) {
2905131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      return nullptr;
2914922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    }
29292572be7f754c213e615a62955cc5f65ca8c0c0eNarayan Kamath    UniquePtr<ZipEntry> zip_entry(zip_archive->Find(image_classes_filename, error_msg));
2935131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (zip_entry.get() == nullptr) {
2948d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      *error_msg = StringPrintf("Failed to find '%s' within '%s': %s", image_classes_filename,
2958d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                zip_filename, error_msg->c_str());
2965131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      return nullptr;
2974922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    }
2988d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers    UniquePtr<MemMap> image_classes_file(zip_entry->ExtractToMemMap(image_classes_filename,
2998d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                                    error_msg));
3005131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (image_classes_file.get() == nullptr) {
3018d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", image_classes_filename,
3028d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                zip_filename, error_msg->c_str());
3035131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      return nullptr;
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) {
324eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    // Handle and ClassLoader creation needs to come after Runtime::Create
3255131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    jobject class_loader = nullptr;
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();
3835131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      return nullptr;
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()));
4075131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (oat_file.get() == nullptr) {
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();
4477624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko    runtime->SetInstructionSet(instruction_set);
448ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
449ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
450ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (!runtime->HasCalleeSaveMethod(type)) {
4517624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko        runtime->SetCalleeSaveMethod(runtime->CreateCalleeSaveMethod(type), type);
452ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
453ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
4541984651929744dd603fd082e23eacd877b9bc177Ian Rogers    runtime->GetClassLinker()->FixupDexCaches(runtime->GetResolutionMethod());
4552b5eaa2b49f7489bafdadc4b4463ae27e4261817Vladimir Marko    runtime_ = runtime;
45600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return true;
457ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
458ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
459ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // Appends to dex_files any elements of class_path that it doesn't already
460ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // contain. This will open those dex files as necessary.
4614560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  static void OpenClassPathFiles(const std::string& class_path,
4624560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                                 std::vector<const DexFile*>& dex_files) {
463ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    std::vector<std::string> parsed;
464ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    Split(class_path, ':', parsed);
46533e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers    // Take Locks::mutator_lock_ so that lock ordering on the ClassLinker::dex_lock_ is maintained.
46633e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers    ScopedObjectAccess soa(Thread::Current());
467ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    for (size_t i = 0; i < parsed.size(); ++i) {
468ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (DexFilesContains(dex_files, parsed[i])) {
469ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        continue;
470ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
4718d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      std::string error_msg;
4728d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      const DexFile* dex_file = DexFile::Open(parsed[i].c_str(), parsed[i].c_str(), &error_msg);
4735131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      if (dex_file == nullptr) {
4748d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers        LOG(WARNING) << "Failed to open dex file '" << parsed[i] << "': " << error_msg;
475ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      } else {
476ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        dex_files.push_back(dex_file);
477ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
478ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
479ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
480ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
481ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // Returns true if dex_files has a dex with the named location.
4824560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  static bool DexFilesContains(const std::vector<const DexFile*>& dex_files,
4834560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                               const std::string& location) {
484ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    for (size_t i = 0; i < dex_files.size(); ++i) {
485ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (dex_files[i]->GetLocation() == location) {
486ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        return true;
487ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
488ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
489ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    return false;
490ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
491ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
492ae7083dac2db59dcdef869e35ac44a039d888ee9Brian Carlstrom  const CompilerOptions* const compiler_options_;
493b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray  const Compiler::Kind compiler_kind_;
494c531cefbfb5394413122e9f57d211ba436cff012buzbee
49549c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers  const InstructionSet instruction_set_;
4967020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  const InstructionSetFeatures instruction_set_features_;
497ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
498ae7083dac2db59dcdef869e35ac44a039d888ee9Brian Carlstrom  VerificationResults* const verification_results_;
499ae7083dac2db59dcdef869e35ac44a039d888ee9Brian Carlstrom  DexFileToMethodInlinerMap* const method_inliner_map_;
500bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  Runtime* runtime_;
5015523ee070b005576c6f889415205d49ea77cf243Elliott Hughes  size_t thread_count_;
502bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  uint64_t start_ns_;
503bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes
504ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  DISALLOW_IMPLICIT_CONSTRUCTORS(Dex2Oat);
505ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom};
506254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson
50772395bf298b7707ad9d93c3e51b57e1b8e010311Elliott Hughesstatic bool ParseInt(const char* in, int* out) {
508a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  char* end;
509a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  int result = strtol(in, &end, 10);
510a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (in == end || *end != '\0') {
511a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    return false;
512a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
513a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  *out = result;
514a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  return true;
515a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom}
516a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
5173cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstromstatic size_t OpenDexFiles(const std::vector<const char*>& dex_filenames,
5183cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom                           const std::vector<const char*>& dex_locations,
5193cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom                           std::vector<const DexFile*>& dex_files) {
5203cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom  size_t failure_count = 0;
5215b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  for (size_t i = 0; i < dex_filenames.size(); i++) {
5225b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom    const char* dex_filename = dex_filenames[i];
523a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    const char* dex_location = dex_locations[i];
524740a11d0bfeaef36d910669844d01f3957dbe696Ian Rogers    ATRACE_BEGIN(StringPrintf("Opening dex file '%s'", dex_filenames[i]).c_str());
5258d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers    std::string error_msg;
526d5aba599561d8d14bb8c19fd633bfcd05af3c264Brian Carlstrom    if (!OS::FileExists(dex_filename)) {
527d5aba599561d8d14bb8c19fd633bfcd05af3c264Brian Carlstrom      LOG(WARNING) << "Skipping non-existent dex file '" << dex_filename << "'";
528d5aba599561d8d14bb8c19fd633bfcd05af3c264Brian Carlstrom      continue;
529d5aba599561d8d14bb8c19fd633bfcd05af3c264Brian Carlstrom    }
5308d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers    const DexFile* dex_file = DexFile::Open(dex_filename, dex_location, &error_msg);
5315131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (dex_file == nullptr) {
5328d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      LOG(WARNING) << "Failed to open .dex from file '" << dex_filename << "': " << error_msg;
5333cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      ++failure_count;
53460f83e3274739317d8c3a1b069cebc6bf1e40f29jeffhao    } else {
53560f83e3274739317d8c3a1b069cebc6bf1e40f29jeffhao      dex_files.push_back(dex_file);
5365b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom    }
537740a11d0bfeaef36d910669844d01f3957dbe696Ian Rogers    ATRACE_END();
5385b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  }
5393cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom  return failure_count;
5405b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom}
5415b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom
542bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// The primary goal of the watchdog is to prevent stuck build servers
543bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// during development when fatal aborts lead to a cascade of failures
544bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// that result in a deadlock.
545bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstromclass WatchDog {
546bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// WatchDog defines its own CHECK_PTHREAD_CALL to avoid using Log which uses locks
547bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#undef CHECK_PTHREAD_CALL
548bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#define CHECK_WATCH_DOG_PTHREAD_CALL(call, args, what) \
549bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  do { \
550bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    int rc = call args; \
551bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    if (rc != 0) { \
552bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      errno = rc; \
553bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      std::string message(# call); \
554bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      message += " failed for "; \
555bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      message += reason; \
556ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom      Fatal(message); \
557bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    } \
558bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  } while (false)
559bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
560bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom public:
56193ba893c20532990a430741e0a97212900094e8cBrian Carlstrom  explicit WatchDog(bool is_watch_dog_enabled) {
562994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    is_watch_dog_enabled_ = is_watch_dog_enabled;
563994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    if (!is_watch_dog_enabled_) {
564bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      return;
565bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    }
566bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    shutting_down_ = false;
567bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    const char* reason = "dex2oat watch dog thread startup";
5685131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_init, (&mutex_, nullptr), reason);
5695131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_init, (&cond_, nullptr), reason);
570bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_init, (&attr_), reason);
571bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_create, (&pthread_, &attr_, &CallBack, this), reason);
572bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_destroy, (&attr_), reason);
573bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
574bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  ~WatchDog() {
575994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    if (!is_watch_dog_enabled_) {
576bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      return;
577bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    }
578bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    const char* reason = "dex2oat watch dog thread shutdown";
579bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason);
580bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    shutting_down_ = true;
581bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_signal, (&cond_), reason);
582bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason);
583bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
5845131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_join, (pthread_, nullptr), reason);
585bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
586bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_destroy, (&cond_), reason);
587bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_destroy, (&mutex_), reason);
588bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
589bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
590bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom private:
591bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  static void* CallBack(void* arg) {
592bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    WatchDog* self = reinterpret_cast<WatchDog*>(arg);
5931d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    ::art::SetThreadName("dex2oat watch dog");
594bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    self->Wait();
5955131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    return nullptr;
596bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
597bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
598ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  static void Message(char severity, const std::string& message) {
5991d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    // TODO: Remove when we switch to LOG when we can guarantee it won't prevent shutdown in error
6001d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    //       cases.
601ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    fprintf(stderr, "dex2oat%s %c %d %d %s\n",
602ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            kIsDebugBuild ? "d" : "",
603ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            severity,
604ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            getpid(),
605ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            GetTid(),
606ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            message.c_str());
607ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  }
608ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom
609eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers  static void Warn(const std::string& message) {
610ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    Message('W', message);
611eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers  }
612eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers
613ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  static void Fatal(const std::string& message) {
614ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    Message('F', message);
615bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    exit(1);
616bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
617bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
618bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  void Wait() {
619eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers    bool warning = true;
620eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers    CHECK_GT(kWatchDogTimeoutSeconds, kWatchDogWarningSeconds);
6211d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    // TODO: tune the multiplier for GC verification, the following is just to make the timeout
6221d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    //       large.
6234e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    int64_t multiplier = kVerifyObjectSupport > kVerifyObjectModeFast ? 100 : 1;
624ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    timespec warning_ts;
6251d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    InitTimeSpec(true, CLOCK_REALTIME, multiplier * kWatchDogWarningSeconds * 1000, 0, &warning_ts);
626ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    timespec timeout_ts;
6271d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    InitTimeSpec(true, CLOCK_REALTIME, multiplier * kWatchDogTimeoutSeconds * 1000, 0, &timeout_ts);
628bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    const char* reason = "dex2oat watch dog thread waiting";
629bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason);
630bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    while (!shutting_down_) {
631eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers      int rc = TEMP_FAILURE_RETRY(pthread_cond_timedwait(&cond_, &mutex_,
632eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers                                                         warning ? &warning_ts
633eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers                                                                 : &timeout_ts));
634bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      if (rc == ETIMEDOUT) {
635bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom        std::string message(StringPrintf("dex2oat did not finish after %d seconds",
636eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers                                         warning ? kWatchDogWarningSeconds
637eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers                                                 : kWatchDogTimeoutSeconds));
638eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers        if (warning) {
639eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers          Warn(message.c_str());
640eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers          warning = false;
641eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers        } else {
642ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom          Fatal(message.c_str());
643eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers        }
644eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers      } else if (rc != 0) {
645bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom        std::string message(StringPrintf("pthread_cond_timedwait failed: %s",
646bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom                                         strerror(errno)));
647ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom        Fatal(message.c_str());
648bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      }
649bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    }
650bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason);
651bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
652bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
653ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  // When setting timeouts, keep in mind that the build server may not be as fast as your desktop.
654ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom#if ART_USE_PORTABLE_COMPILER
655ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  static const unsigned int kWatchDogWarningSeconds =  2 * 60;  // 2 minutes.
656eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers  static const unsigned int kWatchDogTimeoutSeconds = 30 * 60;  // 25 minutes + buffer.
657bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#else
658ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  static const unsigned int kWatchDogWarningSeconds =  1 * 60;  // 1 minute.
659ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  static const unsigned int kWatchDogTimeoutSeconds =  6 * 60;  // 5 minutes + buffer.
660bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#endif
661bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
662994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  bool is_watch_dog_enabled_;
663bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  bool shutting_down_;
6641d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // TODO: Switch to Mutex when we can guarantee it won't prevent shutdown in error cases.
665bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_mutex_t mutex_;
666bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_cond_t cond_;
667bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_attr_t attr_;
668bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_t pthread_;
669bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom};
6701c653d545058a1a850fb6d07d74e607fa1ddf48eIan Rogersconst unsigned int WatchDog::kWatchDogWarningSeconds;
6711c653d545058a1a850fb6d07d74e607fa1ddf48eIan Rogersconst unsigned int WatchDog::kWatchDogTimeoutSeconds;
672bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
6737020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison// Given a set of instruction features from the build, parse it.  The
6747020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison// input 'str' is a comma separated list of feature names.  Parse it and
6757020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison// return the InstructionSetFeatures object.
6767020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allisonstatic InstructionSetFeatures ParseFeatureList(std::string str) {
6777020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  InstructionSetFeatures result;
6787020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  typedef std::vector<std::string> FeatureList;
6797020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  FeatureList features;
6807020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  Split(str, ',', features);
6817020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  for (FeatureList::iterator i = features.begin(); i != features.end(); i++) {
6827020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    std::string feature = Trim(*i);
6837020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    if (feature == "default") {
6847020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      // Nothing to do.
6857020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    } else if (feature == "div") {
6867020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      // Supports divide instruction.
6877020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison       result.SetHasDivideInstruction(true);
6887020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    } else if (feature == "nodiv") {
6897020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      // Turn off support for divide instruction.
6907020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      result.SetHasDivideInstruction(false);
691674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko    } else if (feature == "lpae") {
692674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko      // Supports Large Physical Address Extension.
693674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko      result.SetHasLpae(true);
694674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko    } else if (feature == "nolpae") {
695674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko      // Turn off support for Large Physical Address Extension.
696674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko      result.SetHasLpae(false);
6977020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    } else {
6987020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      Usage("Unknown instruction set feature: '%s'", feature.c_str());
6997020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    }
7007020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  }
7017020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  // others...
7027020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  return result;
7037020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison}
7047020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
70572395bf298b7707ad9d93c3e51b57e1b8e010311Elliott Hughesstatic int dex2oat(int argc, char** argv) {
7066449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  original_argc = argc;
7076449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  original_argv = argv;
7086449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
7095fe9af720048673e62ee29597a30bb9e54c903c5Ian Rogers  TimingLogger timings("compiler", false, false);
710ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray  CumulativeLogger compiler_phases_timings("compilation times");
7114560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom
7120d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes  InitLogging(argv);
71372395bf298b7707ad9d93c3e51b57e1b8e010311Elliott Hughes
71469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  // Skip over argv[0].
71569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  argv++;
71669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  argc--;
71769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
71869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  if (argc == 0) {
719e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom    Usage("No arguments specified");
72069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
72169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
72269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  std::vector<const char*> dex_filenames;
723a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::vector<const char*> dex_locations;
724a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  int zip_fd = -1;
725a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::string zip_location;
726e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  std::string oat_filename;
727265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  std::string oat_symbols;
728a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::string oat_location;
729a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  int oat_fd = -1;
7308b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien  std::string bitcode_filename;
7315131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  const char* image_classes_zip_filename = nullptr;
7325131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  const char* image_classes_filename = nullptr;
733a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::string image_filename;
734b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  std::string boot_image_filename;
73569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  uintptr_t image_base = 0;
7363f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  std::string android_root;
7375d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao  std::vector<const char*> runtime_args;
7385c599943f8c347acd84c4d9fda56a9df70649b78Elliott Hughes  int thread_count = sysconf(_SC_NPROCESSORS_CONF);
739b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray  Compiler::Kind compiler_kind = kUsePortableCompiler
740b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray      ? Compiler::kPortable
741b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray      : Compiler::kQuick;
7425131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  const char* compiler_filter_string = nullptr;
7436449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int huge_method_threshold = CompilerOptions::kDefaultHugeMethodThreshold;
7446449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int large_method_threshold = CompilerOptions::kDefaultLargeMethodThreshold;
7456449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int small_method_threshold = CompilerOptions::kDefaultSmallMethodThreshold;
7466449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int tiny_method_threshold = CompilerOptions::kDefaultTinyMethodThreshold;
7476449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int num_dex_methods_threshold = CompilerOptions::kDefaultNumDexMethodsThreshold;
7487020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
7491bd2ceb3a8c68ae6ea1f9627b588a7bc7a74487fBrian Carlstrom  // Take the default set of instruction features from the build.
7507020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  InstructionSetFeatures instruction_set_features =
7518afeb85d3def12b559b7565fb6d3956f81b55132Ian Rogers      ParseFeatureList(Runtime::GetDefaultInstructionSetFeatures());
7527020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
75391268c1afd6c0d4fad55b7c86d907233d4660205Andreas Gampe  InstructionSet instruction_set = kRuntimeISA;
7547020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
75539c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison  // Profile file to use
75639c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison  std::string profile_file;
7577020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
758265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  bool is_host = false;
759e732ef1c0192acd71925bd0ff1ab09640d45531dIan Rogers  bool dump_stats = false;
76046398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers  bool dump_timing = false;
761ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray  bool dump_passes = false;
76246398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers  bool dump_slow_timing = kIsDebugBuild;
763994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  bool watch_dog_enabled = !kIsTargetBuild;
764ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  bool generate_gdb_information = kIsDebugBuild;
765161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom
76669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  for (int i = 0; i < argc; i++) {
76769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    const StringPiece option(argv[i]);
768b9beb2e2efb6a204a69ca660d478b45f851e8f09Ian Rogers    const bool log_options = false;
769a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    if (log_options) {
770b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom      LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i];
771b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom    }
77269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    if (option.starts_with("--dex-file=")) {
77369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      dex_filenames.push_back(option.substr(strlen("--dex-file=")).data());
774a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    } else if (option.starts_with("--dex-location=")) {
775a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      dex_locations.push_back(option.substr(strlen("--dex-location=")).data());
776a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else if (option.starts_with("--zip-fd=")) {
777a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      const char* zip_fd_str = option.substr(strlen("--zip-fd=")).data();
778bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes      if (!ParseInt(zip_fd_str, &zip_fd)) {
779e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom        Usage("Failed to parse --zip-fd argument '%s' as an integer", zip_fd_str);
780a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
7816449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (zip_fd < 0) {
7826449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--zip-fd passed a negative value %d", zip_fd);
7836449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
784a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    } else if (option.starts_with("--zip-location=")) {
785a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      zip_location = option.substr(strlen("--zip-location=")).data();
786a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else if (option.starts_with("--oat-file=")) {
787a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      oat_filename = option.substr(strlen("--oat-file=")).data();
788265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    } else if (option.starts_with("--oat-symbols=")) {
789265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      oat_symbols = option.substr(strlen("--oat-symbols=")).data();
790a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else if (option.starts_with("--oat-fd=")) {
791a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      const char* oat_fd_str = option.substr(strlen("--oat-fd=")).data();
792bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes      if (!ParseInt(oat_fd_str, &oat_fd)) {
793e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom        Usage("Failed to parse --oat-fd argument '%s' as an integer", oat_fd_str);
794a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
7956449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (oat_fd < 0) {
7966449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--oat-fd passed a negative value %d", oat_fd);
7976449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
798994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    } else if (option == "--watch-dog") {
799994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom      watch_dog_enabled = true;
800994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    } else if (option == "--no-watch-dog") {
801994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom      watch_dog_enabled = false;
802ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell    } else if (option == "--gen-gdb-info") {
803ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell      generate_gdb_information = true;
804ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell    } else if (option == "--no-gen-gdb-info") {
805ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell      generate_gdb_information = false;
8065523ee070b005576c6f889415205d49ea77cf243Elliott Hughes    } else if (option.starts_with("-j")) {
807b12552a95d68b9e4a567103190074ae47b6a61dcBrian Carlstrom      const char* thread_count_str = option.substr(strlen("-j")).data();
8085523ee070b005576c6f889415205d49ea77cf243Elliott Hughes      if (!ParseInt(thread_count_str, &thread_count)) {
809e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom        Usage("Failed to parse -j argument '%s' as an integer", thread_count_str);
8105523ee070b005576c6f889415205d49ea77cf243Elliott Hughes      }
811a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    } else if (option.starts_with("--oat-location=")) {
812a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      oat_location = option.substr(strlen("--oat-location=")).data();
8138b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien    } else if (option.starts_with("--bitcode=")) {
8148b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien      bitcode_filename = option.substr(strlen("--bitcode=")).data();
81569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    } else if (option.starts_with("--image=")) {
81669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      image_filename = option.substr(strlen("--image=")).data();
817ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    } else if (option.starts_with("--image-classes=")) {
818ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      image_classes_filename = option.substr(strlen("--image-classes=")).data();
8194922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    } else if (option.starts_with("--image-classes-zip=")) {
8204922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      image_classes_zip_filename = option.substr(strlen("--image-classes-zip=")).data();
82169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    } else if (option.starts_with("--base=")) {
82269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      const char* image_base_str = option.substr(strlen("--base=")).data();
82369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      char* end;
82469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      image_base = strtoul(image_base_str, &end, 16);
82569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      if (end == image_base_str || *end != '\0') {
826cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom        Usage("Failed to parse hexadecimal value for option %s", option.data());
82769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      }
828e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom    } else if (option.starts_with("--boot-image=")) {
829b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom      boot_image_filename = option.substr(strlen("--boot-image=")).data();
8303f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    } else if (option.starts_with("--android-root=")) {
8313f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom      android_root = option.substr(strlen("--android-root=")).data();
83249c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers    } else if (option.starts_with("--instruction-set=")) {
83349c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers      StringPiece instruction_set_str = option.substr(strlen("--instruction-set=")).data();
8341f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao      if (instruction_set_str == "arm") {
83549c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        instruction_set = kThumb2;
836b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith      } else if (instruction_set_str == "arm64") {
837b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith        instruction_set = kArm64;
8381f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao      } else if (instruction_set_str == "mips") {
83949c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        instruction_set = kMips;
8401f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao      } else if (instruction_set_str == "x86") {
84149c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        instruction_set = kX86;
842ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      } else if (instruction_set_str == "x86_64") {
843ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers        instruction_set = kX86_64;
84449c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers      }
8457020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    } else if (option.starts_with("--instruction-set-features=")) {
8467020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      StringPiece str = option.substr(strlen("--instruction-set-features=")).data();
8477020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      instruction_set_features = ParseFeatureList(str.as_string());
848c531cefbfb5394413122e9f57d211ba436cff012buzbee    } else if (option.starts_with("--compiler-backend=")) {
849c531cefbfb5394413122e9f57d211ba436cff012buzbee      StringPiece backend_str = option.substr(strlen("--compiler-backend=")).data();
850c531cefbfb5394413122e9f57d211ba436cff012buzbee      if (backend_str == "Quick") {
851b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray        compiler_kind = Compiler::kQuick;
852b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray      } else if (backend_str == "Optimizing") {
853b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray        compiler_kind = Compiler::kOptimizing;
854c531cefbfb5394413122e9f57d211ba436cff012buzbee      } else if (backend_str == "Portable") {
855b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray        compiler_kind = Compiler::kPortable;
856c531cefbfb5394413122e9f57d211ba436cff012buzbee      }
8576449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--compiler-filter=")) {
8586449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      compiler_filter_string = option.substr(strlen("--compiler-filter=")).data();
8596449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--huge-method-max=")) {
8606449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--huge-method-max=")).data();
8616449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &huge_method_threshold)) {
8626449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --huge-method-max '%s' as an integer", threshold);
8636449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8646449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (huge_method_threshold < 0) {
8656449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--huge-method-max passed a negative value %s", huge_method_threshold);
8666449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8676449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--large-method-max=")) {
8686449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--large-method-max=")).data();
8696449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &large_method_threshold)) {
8706449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --large-method-max '%s' as an integer", threshold);
8716449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8726449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (large_method_threshold < 0) {
8736449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--large-method-max passed a negative value %s", large_method_threshold);
8746449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8756449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--small-method-max=")) {
8766449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--small-method-max=")).data();
8776449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &small_method_threshold)) {
8786449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --small-method-max '%s' as an integer", threshold);
8796449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8806449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (small_method_threshold < 0) {
8816449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--small-method-max passed a negative value %s", small_method_threshold);
8826449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8836449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--tiny-method-max=")) {
8846449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--tiny-method-max=")).data();
8856449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &tiny_method_threshold)) {
8866449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --tiny-method-max '%s' as an integer", threshold);
8876449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8886449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (tiny_method_threshold < 0) {
8896449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--tiny-method-max passed a negative value %s", tiny_method_threshold);
8906449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8916449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--num-dex-methods=")) {
8926449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--num-dex-methods=")).data();
8936449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &num_dex_methods_threshold)) {
8946449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --num-dex-methods '%s' as an integer", threshold);
8956449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
8966449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (num_dex_methods_threshold < 0) {
8976449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--num-dex-methods passed a negative value %s", num_dex_methods_threshold);
8986449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
899265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    } else if (option == "--host") {
900265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      is_host = true;
9015d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao    } else if (option == "--runtime-arg") {
9025d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao      if (++i >= argc) {
903cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom        Usage("Missing required argument for --runtime-arg");
9045d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao      }
905a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      if (log_options) {
906a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom        LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i];
907a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
9085d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao      runtime_args.push_back(argv[i]);
90946398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers    } else if (option == "--dump-timing") {
91046398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers      dump_timing = true;
911ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray    } else if (option == "--dump-passes") {
912ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray      dump_passes = true;
913e732ef1c0192acd71925bd0ff1ab09640d45531dIan Rogers    } else if (option == "--dump-stats") {
914e732ef1c0192acd71925bd0ff1ab09640d45531dIan Rogers      dump_stats = true;
91539c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison    } else if (option.starts_with("--profile-file=")) {
91639c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison      profile_file = option.substr(strlen("--profile-file=")).data();
91739c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison      VLOG(compiler) << "dex2oat: profile file is " << profile_file;
91839c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison    } else if (option == "--no-profile-file") {
91939c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison      // No profile
920cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu    } else if (option == "--print-pass-names") {
921cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu      PassDriver::PrintPassNames();
922cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu    } else if (option.starts_with("--disable-passes=")) {
923cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu      std::string disable_passes = option.substr(strlen("--disable-passes=")).data();
924cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu      PassDriver::CreateDefaultPassList(disable_passes);
92569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    } else {
926e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom      Usage("Unknown argument %s", option.data());
92769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    }
92869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
92969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
930a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (oat_filename.empty() && oat_fd == -1) {
931cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("Output must be supplied with either --oat-file or --oat-fd");
932a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
933a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
934a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (!oat_filename.empty() && oat_fd != -1) {
935cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--oat-file should not be used with --oat-fd");
936a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
937a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
938265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (!oat_symbols.empty() && oat_fd != -1) {
939265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    Usage("--oat-symbols should not be used with --oat-fd");
940265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  }
941265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
942265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (!oat_symbols.empty() && is_host) {
943265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    Usage("--oat-symbols should not be used with --host");
944a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
945a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
946a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (oat_fd != -1 && !image_filename.empty()) {
947cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--oat-fd should not be used with --image");
948e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  }
949e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
9503f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  if (android_root.empty()) {
9513f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    const char* android_root_env_var = getenv("ANDROID_ROOT");
9525131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (android_root_env_var == nullptr) {
95354d22c2bb47da44ef586b9de94749d5648178a26Brian Carlstrom      Usage("--android-root unspecified and ANDROID_ROOT not set");
9543f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    }
9553f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    android_root += android_root_env_var;
9563f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  }
9573f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom
958a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  bool image = (!image_filename.empty());
959b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  if (!image && boot_image_filename.empty()) {
9609583fbcf597eff6d0b3c5359b8e8d5f70ed82c40Nicolas Geoffray    boot_image_filename += GetAndroidRoot();
9613ac05bba3eadccb33d26b41d9797f63e8378125fBrian Carlstrom    boot_image_filename += "/framework/boot.art";
962b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  }
963b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  std::string boot_image_option;
964a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (!boot_image_filename.empty()) {
965b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom    boot_image_option += "-Ximage:";
966b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom    boot_image_option += boot_image_filename;
96769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
96869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
9695131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (image_classes_filename != nullptr && !image) {
970cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--image-classes should only be used with --image");
971ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
972ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
9735131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (image_classes_filename != nullptr && !boot_image_option.empty()) {
974cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--image-classes should not be used with --boot-image");
97578128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom  }
97678128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom
9775131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (image_classes_zip_filename != nullptr && image_classes_filename == nullptr) {
9784922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    Usage("--image-classes-zip should be used with --image-classes");
9794922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom  }
9804922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom
981a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (dex_filenames.empty() && zip_fd == -1) {
982cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("Input must be supplied with either --dex-file or --zip-fd");
983a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
984a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
985a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (!dex_filenames.empty() && zip_fd != -1) {
986cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--dex-file should not be used with --zip-fd");
987a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
988a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
989a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (!dex_filenames.empty() && !zip_location.empty()) {
990cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--dex-file should not be used with --zip-location");
991a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
992a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
993a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (dex_locations.empty()) {
994a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    for (size_t i = 0; i < dex_filenames.size(); i++) {
995a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      dex_locations.push_back(dex_filenames[i]);
996a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    }
997a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  } else if (dex_locations.size() != dex_filenames.size()) {
998cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--dex-location arguments do not match --dex-file arguments");
999a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  }
1000a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom
1001a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (zip_fd != -1 && zip_location.empty()) {
1002cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--zip-location should be supplied with --zip-fd");
1003a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1004a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
100569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  if (boot_image_option.empty()) {
100669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    if (image_base == 0) {
1007e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom      Usage("Non-zero --base not specified");
100869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    }
100969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
101069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
1011265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  std::string oat_stripped(oat_filename);
1012265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  std::string oat_unstripped;
1013265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (!oat_symbols.empty()) {
1014265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    oat_unstripped += oat_symbols;
1015265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  } else {
1016265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    oat_unstripped += oat_filename;
1017265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  }
1018265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
10195131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (compiler_filter_string == nullptr) {
10209e06c8cd4a2e1471754470e09aaab63c0795b4afZheng Xu    if (instruction_set == kX86_64 || instruction_set == kMips) {
10217ca278be5f6f15681350e9f05af434df4aab59caIan Rogers      // TODO: implement/fix compilers for these architectures.
1022befbd5731ecca08f08780ee28a913d08ffb14656Ian Rogers      compiler_filter_string = "interpret-only";
1023befbd5731ecca08f08780ee28a913d08ffb14656Ian Rogers    } else if (image) {
10245e754d88c73f1f1fafbbf87d564df000d5a0a12cBrian Carlstrom      compiler_filter_string = "speed";
10256449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else {
10266449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#if ART_SMALL_MODE
10276449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      compiler_filter_string = "interpret-only";
10286449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#else
10296449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      compiler_filter_string = "speed";
10306449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#endif
10316449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    }
10326449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  }
10336449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  CHECK(compiler_filter_string != nullptr);
10346449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  CompilerOptions::CompilerFilter compiler_filter = CompilerOptions::kDefaultCompilerFilter;
10354a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  if (strcmp(compiler_filter_string, "verify-none") == 0) {
10364a200f56b7075309316b04d550c9cc50f8314eddJeff Hao    compiler_filter = CompilerOptions::kVerifyNone;
10374a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  } else if (strcmp(compiler_filter_string, "interpret-only") == 0) {
10386449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kInterpretOnly;
10396449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else if (strcmp(compiler_filter_string, "space") == 0) {
10406449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kSpace;
10416449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else if (strcmp(compiler_filter_string, "balanced") == 0) {
10426449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kBalanced;
10436449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else if (strcmp(compiler_filter_string, "speed") == 0) {
10446449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kSpeed;
10456449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else if (strcmp(compiler_filter_string, "everything") == 0) {
10466449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kEverything;
10476449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else {
10486449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    Usage("Unknown --compiler-filter value %s", compiler_filter_string);
10496449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  }
10506449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
10516449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  CompilerOptions compiler_options(compiler_filter,
10526449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                   huge_method_threshold,
10536449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                   large_method_threshold,
10546449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                   small_method_threshold,
10556449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                   tiny_method_threshold,
1056ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell                                   num_dex_methods_threshold,
1057d6ed642458c8820e1beca72f3d7b5f0be4a4b64bDave Allison                                   generate_gdb_information
10586449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#ifdef ART_SEA_IR_MODE
10596449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                   , compiler_options.sea_ir_ = true;
10606449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#endif
10616449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                   );  // NOLINT(whitespace/parens)
10626449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
1063994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  // Done with usage checks, enable watchdog if requested
1064994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  WatchDog watch_dog(watch_dog_enabled);
1065994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom
10666ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom  // Check early that the result of compilation can be written
1067a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  UniquePtr<File> oat_file;
1068265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  bool create_file = !oat_unstripped.empty();  // as opposed to using open file descriptor
10696cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom  if (create_file) {
10707571e8b761ebc2c923525e12ea9fcf07e62cb33eBrian Carlstrom    oat_file.reset(OS::CreateEmptyFile(oat_unstripped.c_str()));
1071a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    if (oat_location.empty()) {
1072a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      oat_location = oat_filename;
1073a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    }
1074a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  } else {
1075761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    oat_file.reset(new File(oat_fd, oat_location));
1076761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    oat_file->DisableAutoClose();
1077a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
10785131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (oat_file.get() == nullptr) {
10796cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom    PLOG(ERROR) << "Failed to create oat file: " << oat_location;
10806cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom    return EXIT_FAILURE;
10816cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom  }
10826cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom  if (create_file && fchmod(oat_file->Fd(), 0644) != 0) {
10836cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom    PLOG(ERROR) << "Failed to make oat file world readable: " << oat_location;
10846ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom    return EXIT_FAILURE;
1085234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  }
1086a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1087e6bb3b2ce5a69c31c2adfc7eb2705633b7f966ebIan Rogers  timings.StartSplit("dex2oat Setup");
108809881a85579cab1779ddf6ba9a91eed861a13cb2Brian Carlstrom  LOG(INFO) << CommandLine();
10895e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers
10906449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  Runtime::Options runtime_options;
1091a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::vector<const DexFile*> boot_class_path;
109269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  if (boot_image_option.empty()) {
10933cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom    size_t failure_count = OpenDexFiles(dex_filenames, dex_locations, boot_class_path);
10943cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom    if (failure_count > 0) {
10953cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      LOG(ERROR) << "Failed to open some dex files: " << failure_count;
10963cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      return EXIT_FAILURE;
10973cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom    }
10986449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    runtime_options.push_back(std::make_pair("bootclasspath", &boot_class_path));
109969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  } else {
11005131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    runtime_options.push_back(std::make_pair(boot_image_option.c_str(), nullptr));
110169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
11025d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao  for (size_t i = 0; i < runtime_args.size(); i++) {
11035131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    runtime_options.push_back(std::make_pair(runtime_args[i], nullptr));
11045d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao  }
110569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
11066449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  VerificationResults verification_results(&compiler_options);
11076449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  DexFileToMethodInlinerMap method_inliner_map;
11086449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  CompilerCallbacksImpl callbacks(&verification_results, &method_inliner_map);
11096449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  runtime_options.push_back(std::make_pair("compilercallbacks", &callbacks));
111011d9f06a96a6909905c248ed684366190140095cNarayan Kamath  runtime_options.push_back(
111111d9f06a96a6909905c248ed684366190140095cNarayan Kamath      std::make_pair("imageinstructionset",
111211d9f06a96a6909905c248ed684366190140095cNarayan Kamath                     reinterpret_cast<const void*>(GetInstructionSetString(instruction_set))));
11137467ee05012e1fd9834df74663c1ebda46f5636bDragos Sbirlea
111400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Dex2Oat* p_dex2oat;
11156449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  if (!Dex2Oat::Create(&p_dex2oat,
11166449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       runtime_options,
11176449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       compiler_options,
1118b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray                       compiler_kind,
11196449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       instruction_set,
11206449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       instruction_set_features,
11216449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       &verification_results,
11226449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       &method_inliner_map,
11236449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       thread_count)) {
112400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    LOG(ERROR) << "Failed to create dex2oat";
112500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return EXIT_FAILURE;
112600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
112700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  UniquePtr<Dex2Oat> dex2oat(p_dex2oat);
112800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
11293f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers  // give it away now so that we don't starve GC.
11303f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers  Thread* self = Thread::Current();
11313f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers  self->TransitionFromRunnableToSuspended(kNative);
11320f40ac31134d9ae0f059d4c448165599dc8459c1Ian Rogers  // If we're doing the image, override the compiler filter to force full compilation. Must be
1133fe9ca4028f379688ecba6132ac3738171176b3e4buzbee  // done ahead of WellKnownClasses::Init that causes verification.  Note: doesn't force
1134fe9ca4028f379688ecba6132ac3738171176b3e4buzbee  // compilation of class initializers.
113500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Whilst we're in native take the opportunity to initialize well known classes.
11363f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers  WellKnownClasses::Init(self->GetJniEnv());
113769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
1138bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  // If --image-classes was specified, calculate the full list of classes to include in the image
1139d5185344e19d9feb7ac268369e0af6a467d1cb48Kenny Root  UniquePtr<CompilerDriver::DescriptorSet> image_classes(nullptr);
1140d5185344e19d9feb7ac268369e0af6a467d1cb48Kenny Root  if (image_classes_filename != nullptr) {
11418d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers    std::string error_msg;
1142d5185344e19d9feb7ac268369e0af6a467d1cb48Kenny Root    if (image_classes_zip_filename != nullptr) {
11434922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      image_classes.reset(dex2oat->ReadImageClassesFromZip(image_classes_zip_filename,
11448d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                           image_classes_filename,
11458d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                           &error_msg));
11464922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    } else {
11474922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      image_classes.reset(dex2oat->ReadImageClassesFromFile(image_classes_filename));
11484922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    }
1149d5185344e19d9feb7ac268369e0af6a467d1cb48Kenny Root    if (image_classes.get() == nullptr) {
11508d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      LOG(ERROR) << "Failed to create list of image classes from '" << image_classes_filename <<
11518d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers          "': " << error_msg;
1152ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      return EXIT_FAILURE;
115369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    }
1154d5185344e19d9feb7ac268369e0af6a467d1cb48Kenny Root  } else if (image) {
1155d5185344e19d9feb7ac268369e0af6a467d1cb48Kenny Root    image_classes.reset(new CompilerDriver::DescriptorSet);
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));
11675131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      if (zip_archive.get() == nullptr) {
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);
11735131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      if (dex_file == nullptr) {
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];
12195131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      CHECK(dex_file != nullptr);
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
12425131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (compiler.get() == nullptr) {
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