dex2oat.cc revision f0cb1eb5b2020c3c527aca3ff458801b90b5e06c
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
28f94b781745e715463482695e22addfa95198b548Vladimir Marko#if defined(__linux__) && defined(__arm__)
29f94b781745e715463482695e22addfa95198b548Vladimir Marko#include <sys/personality.h>
30f94b781745e715463482695e22addfa95198b548Vladimir Marko#include <sys/utsname.h>
31f94b781745e715463482695e22addfa95198b548Vladimir Marko#endif
32f94b781745e715463482695e22addfa95198b548Vladimir Marko
331aa246dec5abe212f699de1413a0c4a191ca364aElliott Hughes#include "base/stl_util.h"
34e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "base/stringpiece.h"
35a84395489098e4531619b1cffd1afc282b14510eSameer Abu Asal#include "base/timing_logger.h"
36761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/unix_file/fd_file.h"
3769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "class_linker.h"
38b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray#include "compiler.h"
392b5eaa2b49f7489bafdadc4b4463ae27e4261817Vladimir Marko#include "compiler_callbacks.h"
404f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h"
412469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler#include "dex/pass_driver_me_opts.h"
42c7f832061fea59fd6abd125f26c8ca1faec695a5Vladimir Marko#include "dex/verification_results.h"
43e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "dex/quick_compiler_callbacks.h"
44e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers#include "dex/quick/dex_file_to_method_inliner_map.h"
457940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "driver/compiler_driver.h"
466449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#include "driver/compiler_options.h"
477940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "elf_fixup.h"
48a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light#include "elf_patcher.h"
497940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "elf_stripper.h"
501d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/space/image_space.h"
511d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/space/space-inl.h"
527940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "image_writer.h"
536f1dfe415019de95f0305de66b3afb40005fe382Ian Rogers#include "leb128.h"
54ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_method-inl.h"
552dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h"
562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class_loader.h"
572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h"
582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object_array-inl.h"
597940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "oat_writer.h"
605e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers#include "os.h"
6169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom#include "runtime.h"
6200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "ScopedLocalRef.h"
6300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h"
6453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light#include "utils.h"
65700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom#include "vector_output_stream.h"
6600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "well_known_classes.h"
67a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom#include "zip_archive.h"
6869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
6969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromnamespace art {
7069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
716449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstromstatic int original_argc;
726449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstromstatic char** original_argv;
736449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
746449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstromstatic std::string CommandLine() {
756449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  std::vector<std::string> command;
766449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  for (int i = 0; i < original_argc; ++i) {
776449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    command.push_back(original_argv[i]);
786449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  }
796449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  return Join(command, ' ');
806449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom}
816449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
82cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstromstatic void UsageErrorV(const char* fmt, va_list ap) {
83cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  std::string error;
84cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  StringAppendV(&error, fmt, ap);
85cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  LOG(ERROR) << error;
86cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom}
87cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom
88cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstromstatic void UsageError(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}
94cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom
95cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstromstatic void Usage(const char* fmt, ...) {
96cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  va_list ap;
97cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  va_start(ap, fmt);
98cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageErrorV(fmt, ap);
99cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  va_end(ap);
100cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom
1016449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("Command: %s", CommandLine().c_str());
1026449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
103cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("Usage: dex2oat [options]...");
104cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
105cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --dex-file=<dex-file>: specifies a .dex file to compile.");
106cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --dex-file=/system/framework/core.jar");
107cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
108cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --zip-fd=<file-descriptor>: specifies a file descriptor of a zip file");
109cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      containing a classes.dex file to compile.");
110cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --zip-fd=5");
111cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
1124560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  UsageError("  --zip-location=<zip-location>: specifies a symbolic name for the file");
1134560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  UsageError("      corresponding to the file descriptor specified by --zip-fd.");
114cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --zip-location=/system/app/Calculator.apk");
115cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
116265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("  --oat-file=<file.oat>: specifies the oat output destination via a filename.");
117265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("      Example: --oat-file=/system/framework/boot.oat");
118265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("");
119265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("  --oat-fd=<number>: specifies the oat output destination via a file descriptor.");
1209cb554a7784307d97c20991d90c76d9cf8a12e01Wonil Kim  UsageError("      Example: --oat-fd=6");
121cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
122cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --oat-location=<oat-name>: specifies a symbolic name for the file corresponding");
123cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      to the file descriptor specified by --oat-fd.");
1247675e16bcae06c0fe258aad89b3d511037dec399Brian Carlstrom  UsageError("      Example: --oat-location=/data/dalvik-cache/system@app@Calculator.apk.oat");
125cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
126265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("  --oat-symbols=<file.oat>: specifies the oat output destination with full symbols.");
127265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("      Example: --oat-symbols=/symbols/system/framework/boot.oat");
128265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("");
1298b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien  UsageError("  --bitcode=<file.bc>: specifies the optional bitcode filename.");
1308b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien  UsageError("      Example: --bitcode=/system/framework/boot.bc");
1318b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien  UsageError("");
132cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --image=<file.art>: specifies the output image filename.");
133cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --image=/system/framework/boot.art");
134cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
135cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --image-classes=<classname-file>: specifies classes to include in an image.");
136cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --image=frameworks/base/preloaded-classes");
137cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
138cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --base=<hex-address>: specifies the base address when creating a boot image.");
139cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --base=0x50000000");
140cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
141cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --boot-image=<file.art>: provide the image file for the boot class path.");
142cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --boot-image=/system/framework/boot.art");
1439583fbcf597eff6d0b3c5359b8e8d5f70ed82c40Nicolas Geoffray  UsageError("      Default: $ANDROID_ROOT/system/framework/boot.art");
144cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
1453f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  UsageError("  --android-root=<path>: used to locate libraries for portable linking.");
1463f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  UsageError("      Example: --android-root=out/host/linux-x86");
1473f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  UsageError("      Default: $ANDROID_ROOT");
1483f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  UsageError("");
14953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --instruction-set=(arm|arm64|mips|x86|x86_64): compile for a particular");
15053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      instruction set.");
1511f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao  UsageError("      Example: --instruction-set=x86");
1521f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao  UsageError("      Default: arm");
15349c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers  UsageError("");
1547020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  UsageError("  --instruction-set-features=...,: Specify instruction set features");
1557020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  UsageError("      Example: --instruction-set-features=div");
1567020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  UsageError("      Default: default");
1577020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  UsageError("");
158b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray  UsageError("  --compiler-backend=(Quick|Optimizing|Portable): select compiler backend");
159c531cefbfb5394413122e9f57d211ba436cff012buzbee  UsageError("      set.");
160635733da0f67df1c979cc9764409d2a9dcbb20aaBrian Carlstrom  UsageError("      Example: --compiler-backend=Portable");
161c531cefbfb5394413122e9f57d211ba436cff012buzbee  UsageError("      Default: Quick");
162265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("");
1634a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  UsageError("  --compiler-filter=(verify-none|interpret-only|space|balanced|speed|everything):");
1644a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  UsageError("      select compiler filter.");
1656449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --compiler-filter=everything");
1666449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#if ART_SMALL_MODE
1676449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: interpret-only");
1686449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#else
1696449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: speed");
1706449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#endif
1716449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
1726449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --huge-method-max=<method-instruction-count>: the threshold size for a huge");
1736449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      method for compiler filter tuning.");
1746449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --huge-method-max=%d", CompilerOptions::kDefaultHugeMethodThreshold);
1756449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultHugeMethodThreshold);
1766449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
1776449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --huge-method-max=<method-instruction-count>: threshold size for a huge");
1786449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      method for compiler filter tuning.");
1796449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --huge-method-max=%d", CompilerOptions::kDefaultHugeMethodThreshold);
1806449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultHugeMethodThreshold);
1816449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
1826449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --large-method-max=<method-instruction-count>: threshold size for a large");
1836449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      method for compiler filter tuning.");
1846449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --large-method-max=%d", CompilerOptions::kDefaultLargeMethodThreshold);
1856449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultLargeMethodThreshold);
1866449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
1876449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --small-method-max=<method-instruction-count>: threshold size for a small");
1886449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      method for compiler filter tuning.");
1896449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --small-method-max=%d", CompilerOptions::kDefaultSmallMethodThreshold);
1906449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultSmallMethodThreshold);
1916449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
1926449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --tiny-method-max=<method-instruction-count>: threshold size for a tiny");
1936449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      method for compiler filter tuning.");
1946449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --tiny-method-max=%d", CompilerOptions::kDefaultTinyMethodThreshold);
1956449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultTinyMethodThreshold);
1966449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
1976449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --num-dex-methods=<method-count>: threshold size for a small dex file for");
1986449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      compiler filter tuning. If the input has fewer than this many methods");
1994a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  UsageError("      and the filter is not interpret-only or verify-none, overrides the");
2004a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  UsageError("      filter to use speed");
2016449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --num-dex-method=%d", CompilerOptions::kDefaultNumDexMethodsThreshold);
2026449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultNumDexMethodsThreshold);
2036449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
204265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("  --host: used with Portable backend to link against host runtime libraries");
205265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("");
20646398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers  UsageError("  --dump-timing: display a breakdown of where time was spent");
20746398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers  UsageError("");
20853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --include-patch-information: Include patching information so the generated code");
20953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      can have its base address moved without full recompilation.");
21053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
21153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --no-include-patch-information: Do not include patching information.");
21253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
21378382fa44ee505cf16835e4d22515e7252a90864Alex Light  UsageError("  --include-debug-symbols: Include ELF symbols in this oat file");
21478382fa44ee505cf16835e4d22515e7252a90864Alex Light  UsageError("");
21578382fa44ee505cf16835e4d22515e7252a90864Alex Light  UsageError("  --no-include-debug-symbols: Do not include ELF symbols in this oat file");
21678382fa44ee505cf16835e4d22515e7252a90864Alex Light  UsageError("");
217cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --runtime-arg <argument>: used to specify various arguments for the runtime,");
218cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      such as initial heap size, maximum heap size, and verbose output.");
219cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Use a separate --runtime-arg switch for each argument.");
220cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --runtime-arg -Xms256m");
2214a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  UsageError("");
222d6ed642458c8820e1beca72f3d7b5f0be4a4b64bDave Allison  UsageError("  --profile-file=<filename>: specify profiler output file to use for compilation.");
223cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
224cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu  UsageError("  --print-pass-names: print a list of pass names");
225cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu  UsageError("");
226cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu  UsageError("  --disable-passes=<pass-names>:  disable one or more passes separated by comma.");
227cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu  UsageError("      Example: --disable-passes=UseCount,BBOptimizations");
228cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu  UsageError("");
229cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  std::cerr << "See log for usage error information\n";
23069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  exit(EXIT_FAILURE);
23169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom}
23269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
233ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromclass Dex2Oat {
234ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom public:
2354560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  static bool Create(Dex2Oat** p_dex2oat,
236e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers                     const RuntimeOptions& runtime_options,
2376449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                     const CompilerOptions& compiler_options,
238b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray                     Compiler::Kind compiler_kind,
2394560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                     InstructionSet instruction_set,
2407020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison                     InstructionSetFeatures instruction_set_features,
2416449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                     VerificationResults* verification_results,
2426449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                     DexFileToMethodInlinerMap* method_inliner_map,
2434560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                     size_t thread_count)
244b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_) {
2456449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    CHECK(verification_results != nullptr);
2466449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    CHECK(method_inliner_map != nullptr);
247700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers    std::unique_ptr<Dex2Oat> dex2oat(new Dex2Oat(&compiler_options,
248b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray                                           compiler_kind,
2496449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                           instruction_set,
2506449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                           instruction_set_features,
2516449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                           verification_results,
2526449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                           method_inliner_map,
2536449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                           thread_count));
2546449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    if (!dex2oat->CreateRuntime(runtime_options, instruction_set)) {
2555131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      *p_dex2oat = nullptr;
25600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      return false;
257254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson    }
2582b5eaa2b49f7489bafdadc4b4463ae27e4261817Vladimir Marko    *p_dex2oat = dex2oat.release();
25900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return true;
260ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
261ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
262ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  ~Dex2Oat() {
263ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    delete runtime_;
26465c23bbb25f069b3b49761468b848c4e5d1aa879Brian Carlstrom    LogCompletionTime();
26565c23bbb25f069b3b49761468b848c4e5d1aa879Brian Carlstrom  }
26665c23bbb25f069b3b49761468b848c4e5d1aa879Brian Carlstrom
26765c23bbb25f069b3b49761468b848c4e5d1aa879Brian Carlstrom  void LogCompletionTime() {
26865c23bbb25f069b3b49761468b848c4e5d1aa879Brian Carlstrom    LOG(INFO) << "dex2oat took " << PrettyDuration(NanoTime() - start_ns_)
2694560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom              << " (threads: " << thread_count_ << ")";
270ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
271ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
272c4f105d75cd0cbc5145620068bbb8a819148e535Anwar Ghuloum
2734560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  // Reads the class names (java.lang.Object) and returns a set of descriptors (Ljava/lang/Object;)
274cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers  std::set<std::string>* ReadImageClassesFromFile(const char* image_classes_filename) {
275700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers    std::unique_ptr<std::ifstream> image_classes_file(new std::ifstream(image_classes_filename,
2764560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                                                                  std::ifstream::in));
2775131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (image_classes_file.get() == nullptr) {
278ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      LOG(ERROR) << "Failed to open image classes file " << image_classes_filename;
2795131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      return nullptr;
280ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
281cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers    std::unique_ptr<std::set<std::string>> result(ReadImageClasses(*image_classes_file));
2824922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    image_classes_file->close();
2834922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    return result.release();
2844922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom  }
285ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
286cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers  std::set<std::string>* ReadImageClasses(std::istream& image_classes_stream) {
287cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers    std::unique_ptr<std::set<std::string>> image_classes(new std::set<std::string>);
2884922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    while (image_classes_stream.good()) {
289ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      std::string dot;
2904922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      std::getline(image_classes_stream, dot);
291f1a5adc87760f938b01df26d906295063546b259Elliott Hughes      if (StartsWith(dot, "#") || dot.empty()) {
292ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        continue;
293ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
294955724179c6c739524f610023287f56b24dc31deElliott Hughes      std::string descriptor(DotToDescriptor(dot.c_str()));
29596391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom      image_classes->insert(descriptor);
296ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
297ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    return image_classes.release();
298254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson  }
299254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson
3004560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  // Reads the class names (java.lang.Object) and returns a set of descriptors (Ljava/lang/Object;)
301cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers  std::set<std::string>* ReadImageClassesFromZip(const char* zip_filename,
3028d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                         const char* image_classes_filename,
3038d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                         std::string* error_msg) {
304700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers    std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(zip_filename, error_msg));
3055131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (zip_archive.get() == nullptr) {
3065131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      return nullptr;
3074922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    }
308700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers    std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(image_classes_filename, error_msg));
3095131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (zip_entry.get() == nullptr) {
3108d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      *error_msg = StringPrintf("Failed to find '%s' within '%s': %s", image_classes_filename,
3118d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                zip_filename, error_msg->c_str());
3125131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      return nullptr;
3134922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    }
3140aa504b5bb19f0944d50941b20c8eeaca4165328Brian Carlstrom    std::unique_ptr<MemMap> image_classes_file(zip_entry->ExtractToMemMap(zip_filename,
3150aa504b5bb19f0944d50941b20c8eeaca4165328Brian Carlstrom                                                                          image_classes_filename,
3160aa504b5bb19f0944d50941b20c8eeaca4165328Brian Carlstrom                                                                          error_msg));
3175131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (image_classes_file.get() == nullptr) {
3188d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", image_classes_filename,
3198d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                zip_filename, error_msg->c_str());
3205131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      return nullptr;
3214922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    }
3224922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    const std::string image_classes_string(reinterpret_cast<char*>(image_classes_file->Begin()),
3234922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom                                           image_classes_file->Size());
3244922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    std::istringstream image_classes_stream(image_classes_string);
3254922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    return ReadImageClasses(image_classes_stream);
3264922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom  }
3274922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom
328a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  bool PatchOatCode(const CompilerDriver* compiler_driver, File* oat_file,
329a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                    const std::string& oat_location, std::string* error_msg) {
330a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    // We asked to include patch information but we are not making an image. We need to fix
331a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    // everything up manually.
332a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    std::unique_ptr<ElfFile> elf_file(ElfFile::Open(oat_file, PROT_READ|PROT_WRITE,
333a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                                                    MAP_SHARED, error_msg));
334a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    if (elf_file.get() == NULL) {
335a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      LOG(ERROR) << error_msg;
336a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      return false;
337a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    }
338a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    {
339a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      ReaderMutexLock mu(Thread::Current(), *Locks::mutator_lock_);
340a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      return ElfPatcher::Patch(compiler_driver, elf_file.get(), oat_location, error_msg);
341a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    }
342a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  }
343a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
3441212a022fa5f8ef9585d765b1809521812af882cIan Rogers  const CompilerDriver* CreateOatFile(const std::string& boot_image_option,
3453f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      const std::string& android_root,
3463f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      bool is_host,
3473f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      const std::vector<const DexFile*>& dex_files,
3483f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      File* oat_file,
349a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                                      const std::string& oat_location,
3503f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      const std::string& bitcode_filename,
3513f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      bool image,
352cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers                                      std::unique_ptr<std::set<std::string>>& image_classes,
3533f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      bool dump_stats,
354ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray                                      bool dump_passes,
355ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray                                      TimingLogger& timings,
35639c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison                                      CumulativeLogger& compiler_phases_timings,
35722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                      std::string profile_file,
35822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                      SafeMap<std::string, std::string>* key_value_store) {
35922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe    CHECK(key_value_store != nullptr);
36022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
361eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    // Handle and ClassLoader creation needs to come after Runtime::Create
3625131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    jobject class_loader = nullptr;
3633f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers    Thread* self = Thread::Current();
364ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    if (!boot_image_option.empty()) {
365ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
366ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      std::vector<const DexFile*> class_path_files(dex_files);
367a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      OpenClassPathFiles(runtime_->GetClassPathString(), class_path_files);
3683f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers      ScopedObjectAccess soa(self);
369ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      for (size_t i = 0; i < class_path_files.size(); i++) {
370ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        class_linker->RegisterDexFile(*class_path_files[i]);
371ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
37200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader);
37300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      ScopedLocalRef<jobject> class_loader_local(soa.Env(),
37400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers          soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
37500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
37600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path_files);
377254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson    }
378ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
379700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers    std::unique_ptr<CompilerDriver> driver(new CompilerDriver(compiler_options_,
38022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              verification_results_,
38122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              method_inliner_map_,
38222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              compiler_kind_,
38322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              instruction_set_,
38422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              instruction_set_features_,
38522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              image,
38622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              image_classes.release(),
38722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              thread_count_,
38822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              dump_stats,
38922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              dump_passes,
39022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              &compiler_phases_timings,
39122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              profile_file));
3928b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien
393b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray    driver->GetCompiler()->SetBitcodeFileName(*driver.get(), bitcode_filename);
3948b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien
3953d504075f7c1204d581923460754bf6d3714b13fIan Rogers    driver->CompileAll(class_loader, dex_files, &timings);
39600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
397f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier    TimingLogger::ScopedTiming t2("dex2oat OatWriter", &timings);
39881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom    std::string image_file_location;
39928db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom    uint32_t image_file_location_oat_checksum = 0;
400ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    uintptr_t image_file_location_oat_data_begin = 0;
401a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    int32_t image_patch_delta = 0;
4020aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao    if (!driver->IsImage()) {
403f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier      TimingLogger::ScopedTiming t3("Loading image checksum", &timings);
4041d54e73444e017d3a65234e0f193846f3e27472bIan Rogers      gc::space::ImageSpace* image_space = Runtime::Current()->GetHeap()->GetImageSpace();
40528db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom      image_file_location_oat_checksum = image_space->GetImageHeader().GetOatChecksum();
40639ebcb800aabedd0ffa6aa4aeac8aa4194c66e61Ian Rogers      image_file_location_oat_data_begin =
407ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers          reinterpret_cast<uintptr_t>(image_space->GetImageHeader().GetOatDataBegin());
40881f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom      image_file_location = image_space->GetImageFilename();
409a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      image_patch_delta = image_space->GetImageHeader().GetPatchDelta();
41081f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom    }
41181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom
41222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe    if (!image_file_location.empty()) {
41322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe      key_value_store->Put(OatHeader::kImageLocationKey, image_file_location);
41422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe    }
41522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
416f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier    OatWriter oat_writer(dex_files, image_file_location_oat_checksum,
417c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom                         image_file_location_oat_data_begin,
418a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                         image_patch_delta,
419ca368cb576cf6a436a32c357fca51fbb3082d7a9Ian Rogers                         driver.get(),
42022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                         &timings,
42122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                         key_value_store);
422700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
423f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier    t2.NewTiming("Writing ELF");
4243d504075f7c1204d581923460754bf6d3714b13fIan Rogers    if (!driver->WriteElf(android_root, is_host, dex_files, &oat_writer, oat_file)) {
425700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      LOG(ERROR) << "Failed to write ELF file " << oat_file->GetPath();
4265131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      return nullptr;
427700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    }
428700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
429035592c51fee2995a3d90a9043f91a7a3128df2bAndreas Gampe    // Flush result to disk. Patching code will re-open the file (mmap), so ensure that our view
430035592c51fee2995a3d90a9043f91a7a3128df2bAndreas Gampe    // of the file already made it there and won't be re-ordered with writes from PatchOat or
431035592c51fee2995a3d90a9043f91a7a3128df2bAndreas Gampe    // image patching.
432035592c51fee2995a3d90a9043f91a7a3128df2bAndreas Gampe    oat_file->Flush();
433035592c51fee2995a3d90a9043f91a7a3128df2bAndreas Gampe
434a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    if (!driver->IsImage() && driver->GetCompilerOptions().GetIncludePatchInformation()) {
435a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      t2.NewTiming("Patching ELF");
436a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      std::string error_msg;
437a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      if (!PatchOatCode(driver.get(), oat_file, oat_location, &error_msg)) {
438a62a588a9202f69e53fbeb3045ea8ea5ec2587f8Jim_Guo        LOG(ERROR) << "Failed to fixup ELF file " << oat_file->GetPath() << ": " << error_msg;
439a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light        return nullptr;
440a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      }
441a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    }
442a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
4431212a022fa5f8ef9585d765b1809521812af882cIan Rogers    return driver.release();
444254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson  }
445ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
446a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  bool CreateImageFile(const std::string& image_filename,
447ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                       uintptr_t image_base,
448ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                       const std::string& oat_filename,
449f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                       const std::string& oat_location,
4501212a022fa5f8ef9585d765b1809521812af882cIan Rogers                       const CompilerDriver& compiler)
451b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::mutator_lock_) {
452700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    uintptr_t oat_data_begin;
453700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    {
454700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      // ImageWriter is scoped so it can free memory before doing FixupElf
45596391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom      ImageWriter image_writer(compiler);
45696391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom      if (!image_writer.Write(image_filename, image_base, oat_filename, oat_location)) {
457700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom        LOG(ERROR) << "Failed to create image file " << image_filename;
458700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom        return false;
459700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      }
460700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      oat_data_begin = image_writer.GetOatDataBegin();
461700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    }
462700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
463700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers    std::unique_ptr<File> oat_file(OS::OpenFileReadWrite(oat_filename.c_str()));
4645131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (oat_file.get() == nullptr) {
465700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      PLOG(ERROR) << "Failed to open ELF file: " << oat_filename;
466700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      return false;
467700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    }
46851c2467e8771b56e25ae4f17f66522f979f57a7eBrian Carlstrom    if (!ElfFixup::Fixup(oat_file.get(), oat_data_begin)) {
469700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      LOG(ERROR) << "Failed to fixup ELF file " << oat_file->GetPath();
470ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      return false;
471ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
472ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    return true;
473ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
474ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
475ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom private:
4766449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  explicit Dex2Oat(const CompilerOptions* compiler_options,
477b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray                   Compiler::Kind compiler_kind,
4784560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                   InstructionSet instruction_set,
4797020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison                   InstructionSetFeatures instruction_set_features,
4806449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                   VerificationResults* verification_results,
4816449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                   DexFileToMethodInlinerMap* method_inliner_map,
4820177fe200efc1bf4d433955ee7920c683fdf5901Brian Carlstrom                   size_t thread_count)
4836449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      : compiler_options_(compiler_options),
484b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray        compiler_kind_(compiler_kind),
485c531cefbfb5394413122e9f57d211ba436cff012buzbee        instruction_set_(instruction_set),
4867020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison        instruction_set_features_(instruction_set_features),
4876449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        verification_results_(verification_results),
4886449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        method_inliner_map_(method_inliner_map),
4892b5eaa2b49f7489bafdadc4b4463ae27e4261817Vladimir Marko        runtime_(nullptr),
490de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes        thread_count_(thread_count),
491de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes        start_ns_(NanoTime()) {
4926449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    CHECK(compiler_options != nullptr);
4936449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    CHECK(verification_results != nullptr);
4946449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    CHECK(method_inliner_map != nullptr);
495bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  }
496ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
497e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers  bool CreateRuntime(const RuntimeOptions& runtime_options, InstructionSet instruction_set)
498b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_) {
4996449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    if (!Runtime::Create(runtime_options, false)) {
500ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      LOG(ERROR) << "Failed to create runtime";
50100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      return false;
502ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
50300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    Runtime* runtime = Runtime::Current();
5047624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko    runtime->SetInstructionSet(instruction_set);
505ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
506ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
507ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (!runtime->HasCalleeSaveMethod(type)) {
5087624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko        runtime->SetCalleeSaveMethod(runtime->CreateCalleeSaveMethod(type), type);
509ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
510ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
5111984651929744dd603fd082e23eacd877b9bc177Ian Rogers    runtime->GetClassLinker()->FixupDexCaches(runtime->GetResolutionMethod());
5124e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz    runtime->GetClassLinker()->RunRootClinits();
5132b5eaa2b49f7489bafdadc4b4463ae27e4261817Vladimir Marko    runtime_ = runtime;
51400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return true;
515ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
516ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
517ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // Appends to dex_files any elements of class_path that it doesn't already
518ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // contain. This will open those dex files as necessary.
5194560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  static void OpenClassPathFiles(const std::string& class_path,
5204560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                                 std::vector<const DexFile*>& dex_files) {
521ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    std::vector<std::string> parsed;
522ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    Split(class_path, ':', parsed);
52333e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers    // Take Locks::mutator_lock_ so that lock ordering on the ClassLinker::dex_lock_ is maintained.
52433e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers    ScopedObjectAccess soa(Thread::Current());
525ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    for (size_t i = 0; i < parsed.size(); ++i) {
526ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (DexFilesContains(dex_files, parsed[i])) {
527ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        continue;
528ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
5298d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      std::string error_msg;
530833a48501d560c9fa7fc78ef619888138c2d374fAndreas Gampe      if (!DexFile::Open(parsed[i].c_str(), parsed[i].c_str(), &error_msg, &dex_files)) {
5318d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers        LOG(WARNING) << "Failed to open dex file '" << parsed[i] << "': " << error_msg;
532ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
533ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
534ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
535ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
536ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // Returns true if dex_files has a dex with the named location.
5374560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  static bool DexFilesContains(const std::vector<const DexFile*>& dex_files,
5384560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                               const std::string& location) {
539ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    for (size_t i = 0; i < dex_files.size(); ++i) {
540ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (dex_files[i]->GetLocation() == location) {
541ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        return true;
542ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
543ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
544ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    return false;
545ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
546ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
547ae7083dac2db59dcdef869e35ac44a039d888ee9Brian Carlstrom  const CompilerOptions* const compiler_options_;
548b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray  const Compiler::Kind compiler_kind_;
549c531cefbfb5394413122e9f57d211ba436cff012buzbee
55049c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers  const InstructionSet instruction_set_;
5517020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  const InstructionSetFeatures instruction_set_features_;
552ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
553ae7083dac2db59dcdef869e35ac44a039d888ee9Brian Carlstrom  VerificationResults* const verification_results_;
554ae7083dac2db59dcdef869e35ac44a039d888ee9Brian Carlstrom  DexFileToMethodInlinerMap* const method_inliner_map_;
555bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  Runtime* runtime_;
5565523ee070b005576c6f889415205d49ea77cf243Elliott Hughes  size_t thread_count_;
557bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  uint64_t start_ns_;
558bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes
559ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  DISALLOW_IMPLICIT_CONSTRUCTORS(Dex2Oat);
560ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom};
561254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson
5623cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstromstatic size_t OpenDexFiles(const std::vector<const char*>& dex_filenames,
5633cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom                           const std::vector<const char*>& dex_locations,
5643cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom                           std::vector<const DexFile*>& dex_files) {
5653cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom  size_t failure_count = 0;
5665b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  for (size_t i = 0; i < dex_filenames.size(); i++) {
5675b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom    const char* dex_filename = dex_filenames[i];
568a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    const char* dex_location = dex_locations[i];
569740a11d0bfeaef36d910669844d01f3957dbe696Ian Rogers    ATRACE_BEGIN(StringPrintf("Opening dex file '%s'", dex_filenames[i]).c_str());
5708d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers    std::string error_msg;
571d5aba599561d8d14bb8c19fd633bfcd05af3c264Brian Carlstrom    if (!OS::FileExists(dex_filename)) {
572d5aba599561d8d14bb8c19fd633bfcd05af3c264Brian Carlstrom      LOG(WARNING) << "Skipping non-existent dex file '" << dex_filename << "'";
573d5aba599561d8d14bb8c19fd633bfcd05af3c264Brian Carlstrom      continue;
574d5aba599561d8d14bb8c19fd633bfcd05af3c264Brian Carlstrom    }
575833a48501d560c9fa7fc78ef619888138c2d374fAndreas Gampe    if (!DexFile::Open(dex_filename, dex_location, &error_msg, &dex_files)) {
5768d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      LOG(WARNING) << "Failed to open .dex from file '" << dex_filename << "': " << error_msg;
5773cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      ++failure_count;
5785b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom    }
579740a11d0bfeaef36d910669844d01f3957dbe696Ian Rogers    ATRACE_END();
5805b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  }
5813cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom  return failure_count;
5825b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom}
5835b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom
584bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// The primary goal of the watchdog is to prevent stuck build servers
585bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// during development when fatal aborts lead to a cascade of failures
586bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// that result in a deadlock.
587bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstromclass WatchDog {
588bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// WatchDog defines its own CHECK_PTHREAD_CALL to avoid using Log which uses locks
589bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#undef CHECK_PTHREAD_CALL
590bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#define CHECK_WATCH_DOG_PTHREAD_CALL(call, args, what) \
591bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  do { \
592bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    int rc = call args; \
593bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    if (rc != 0) { \
594bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      errno = rc; \
595bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      std::string message(# call); \
596bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      message += " failed for "; \
597bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      message += reason; \
598ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom      Fatal(message); \
599bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    } \
600bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  } while (false)
601bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
602bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom public:
60393ba893c20532990a430741e0a97212900094e8cBrian Carlstrom  explicit WatchDog(bool is_watch_dog_enabled) {
604994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    is_watch_dog_enabled_ = is_watch_dog_enabled;
605994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    if (!is_watch_dog_enabled_) {
606bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      return;
607bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    }
608bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    shutting_down_ = false;
609bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    const char* reason = "dex2oat watch dog thread startup";
6105131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_init, (&mutex_, nullptr), reason);
6115131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_init, (&cond_, nullptr), reason);
612bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_init, (&attr_), reason);
613bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_create, (&pthread_, &attr_, &CallBack, this), reason);
614bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_destroy, (&attr_), reason);
615bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
616bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  ~WatchDog() {
617994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    if (!is_watch_dog_enabled_) {
618bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      return;
619bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    }
620bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    const char* reason = "dex2oat watch dog thread shutdown";
621bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason);
622bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    shutting_down_ = true;
623bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_signal, (&cond_), reason);
624bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason);
625bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
6265131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_join, (pthread_, nullptr), reason);
627bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
628bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_destroy, (&cond_), reason);
629bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_destroy, (&mutex_), reason);
630bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
631bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
632bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom private:
633bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  static void* CallBack(void* arg) {
634bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    WatchDog* self = reinterpret_cast<WatchDog*>(arg);
6351d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    ::art::SetThreadName("dex2oat watch dog");
636bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    self->Wait();
6375131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    return nullptr;
638bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
639bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
640ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  static void Message(char severity, const std::string& message) {
6411d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    // TODO: Remove when we switch to LOG when we can guarantee it won't prevent shutdown in error
6421d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    //       cases.
643ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    fprintf(stderr, "dex2oat%s %c %d %d %s\n",
644ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            kIsDebugBuild ? "d" : "",
645ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            severity,
646ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            getpid(),
647ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            GetTid(),
648ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            message.c_str());
649ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  }
650ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom
651eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers  static void Warn(const std::string& message) {
652ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    Message('W', message);
653eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers  }
654eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers
655ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  static void Fatal(const std::string& message) {
656ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    Message('F', message);
657bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    exit(1);
658bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
659bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
660bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  void Wait() {
661eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers    bool warning = true;
662eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers    CHECK_GT(kWatchDogTimeoutSeconds, kWatchDogWarningSeconds);
6631d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    // TODO: tune the multiplier for GC verification, the following is just to make the timeout
6641d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    //       large.
6654e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    int64_t multiplier = kVerifyObjectSupport > kVerifyObjectModeFast ? 100 : 1;
666ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    timespec warning_ts;
6671d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    InitTimeSpec(true, CLOCK_REALTIME, multiplier * kWatchDogWarningSeconds * 1000, 0, &warning_ts);
668ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    timespec timeout_ts;
6691d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    InitTimeSpec(true, CLOCK_REALTIME, multiplier * kWatchDogTimeoutSeconds * 1000, 0, &timeout_ts);
670bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    const char* reason = "dex2oat watch dog thread waiting";
671bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason);
672bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    while (!shutting_down_) {
673eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers      int rc = TEMP_FAILURE_RETRY(pthread_cond_timedwait(&cond_, &mutex_,
674eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers                                                         warning ? &warning_ts
675eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers                                                                 : &timeout_ts));
676bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      if (rc == ETIMEDOUT) {
677bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom        std::string message(StringPrintf("dex2oat did not finish after %d seconds",
678eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers                                         warning ? kWatchDogWarningSeconds
679eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers                                                 : kWatchDogTimeoutSeconds));
680eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers        if (warning) {
681eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers          Warn(message.c_str());
682eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers          warning = false;
683eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers        } else {
684ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom          Fatal(message.c_str());
685eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers        }
686eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers      } else if (rc != 0) {
687bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom        std::string message(StringPrintf("pthread_cond_timedwait failed: %s",
688bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom                                         strerror(errno)));
689ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom        Fatal(message.c_str());
690bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      }
691bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    }
692bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason);
693bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
694bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
695ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  // When setting timeouts, keep in mind that the build server may not be as fast as your desktop.
6960bff4f375d8013a4a59cf70b3427fb461a17e6deMathieu Chartier  // Debug builds are slower so they have larger timeouts.
6970bff4f375d8013a4a59cf70b3427fb461a17e6deMathieu Chartier  static const unsigned int kSlowdownFactor = kIsDebugBuild ? 5U : 1U;
698ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom#if ART_USE_PORTABLE_COMPILER
6990bff4f375d8013a4a59cf70b3427fb461a17e6deMathieu Chartier  // 2 minutes scaled by kSlowdownFactor.
7000bff4f375d8013a4a59cf70b3427fb461a17e6deMathieu Chartier  static const unsigned int kWatchDogWarningSeconds = kSlowdownFactor * 2 * 60;
7010bff4f375d8013a4a59cf70b3427fb461a17e6deMathieu Chartier  // 30 minutes scaled by kSlowdownFactor.
7020bff4f375d8013a4a59cf70b3427fb461a17e6deMathieu Chartier  static const unsigned int kWatchDogTimeoutSeconds = kSlowdownFactor * 30 * 60;
703bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#else
7040bff4f375d8013a4a59cf70b3427fb461a17e6deMathieu Chartier  // 1 minutes scaled by kSlowdownFactor.
7050bff4f375d8013a4a59cf70b3427fb461a17e6deMathieu Chartier  static const unsigned int kWatchDogWarningSeconds = kSlowdownFactor * 1 * 60;
7060bff4f375d8013a4a59cf70b3427fb461a17e6deMathieu Chartier  // 6 minutes scaled by kSlowdownFactor.
7070bff4f375d8013a4a59cf70b3427fb461a17e6deMathieu Chartier  static const unsigned int kWatchDogTimeoutSeconds = kSlowdownFactor * 6 * 60;
708bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#endif
709bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
710994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  bool is_watch_dog_enabled_;
711bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  bool shutting_down_;
7121d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // TODO: Switch to Mutex when we can guarantee it won't prevent shutdown in error cases.
713bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_mutex_t mutex_;
714bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_cond_t cond_;
715bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_attr_t attr_;
716bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_t pthread_;
717bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom};
7181c653d545058a1a850fb6d07d74e607fa1ddf48eIan Rogersconst unsigned int WatchDog::kWatchDogWarningSeconds;
7191c653d545058a1a850fb6d07d74e607fa1ddf48eIan Rogersconst unsigned int WatchDog::kWatchDogTimeoutSeconds;
720bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
7217020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison// Given a set of instruction features from the build, parse it.  The
7227020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison// input 'str' is a comma separated list of feature names.  Parse it and
7237020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison// return the InstructionSetFeatures object.
7247020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allisonstatic InstructionSetFeatures ParseFeatureList(std::string str) {
7257020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  InstructionSetFeatures result;
7267020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  typedef std::vector<std::string> FeatureList;
7277020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  FeatureList features;
7287020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  Split(str, ',', features);
7297020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  for (FeatureList::iterator i = features.begin(); i != features.end(); i++) {
7307020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    std::string feature = Trim(*i);
7317020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    if (feature == "default") {
7327020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      // Nothing to do.
7337020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    } else if (feature == "div") {
7347020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      // Supports divide instruction.
7357020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison       result.SetHasDivideInstruction(true);
7367020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    } else if (feature == "nodiv") {
7377020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      // Turn off support for divide instruction.
7387020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      result.SetHasDivideInstruction(false);
739674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko    } else if (feature == "lpae") {
740674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko      // Supports Large Physical Address Extension.
741674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko      result.SetHasLpae(true);
742674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko    } else if (feature == "nolpae") {
743674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko      // Turn off support for Large Physical Address Extension.
744674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko      result.SetHasLpae(false);
7457020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    } else {
7467020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      Usage("Unknown instruction set feature: '%s'", feature.c_str());
7477020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    }
7487020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  }
7497020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  // others...
7507020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  return result;
7517020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison}
7527020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
753c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravlevoid ParseStringAfterChar(const std::string& s, char c, std::string* parsed_value) {
754c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  std::string::size_type colon = s.find(c);
755c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  if (colon == std::string::npos) {
756c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    Usage("Missing char %c in option %s\n", c, s.c_str());
757c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  }
758c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  // Add one to remove the char we were trimming until.
759c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  *parsed_value = s.substr(colon + 1);
760c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle}
761c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle
762c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravlevoid ParseDouble(const std::string& option, char after_char,
763c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle                 double min, double max, double* parsed_value) {
764c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  std::string substring;
765c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  ParseStringAfterChar(option, after_char, &substring);
766c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  bool sane_val = true;
767c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  double value;
768c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  if (false) {
769c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    // TODO: this doesn't seem to work on the emulator.  b/15114595
770c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    std::stringstream iss(substring);
771c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    iss >> value;
772c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    // Ensure that we have a value, there was no cruft after it and it satisfies a sensible range.
773c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    sane_val = iss.eof() && (value >= min) && (value <= max);
774c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  } else {
775c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    char* end = nullptr;
776c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    value = strtod(substring.c_str(), &end);
777c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    sane_val = *end == '\0' && value >= min && value <= max;
778c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  }
779c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  if (!sane_val) {
780c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    Usage("Invalid double value %s for option %s\n", substring.c_str(), option.c_str());
781c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  }
782c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  *parsed_value = value;
783c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle}
784c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle
78572395bf298b7707ad9d93c3e51b57e1b8e010311Elliott Hughesstatic int dex2oat(int argc, char** argv) {
786f94b781745e715463482695e22addfa95198b548Vladimir Marko#if defined(__linux__) && defined(__arm__)
787f94b781745e715463482695e22addfa95198b548Vladimir Marko  int major, minor;
788f94b781745e715463482695e22addfa95198b548Vladimir Marko  struct utsname uts;
789f94b781745e715463482695e22addfa95198b548Vladimir Marko  if (uname(&uts) != -1 &&
790f94b781745e715463482695e22addfa95198b548Vladimir Marko      sscanf(uts.release, "%d.%d", &major, &minor) == 2 &&
791f94b781745e715463482695e22addfa95198b548Vladimir Marko      ((major < 3) || ((major == 3) && (minor < 4)))) {
792f94b781745e715463482695e22addfa95198b548Vladimir Marko    // Kernels before 3.4 don't handle the ASLR well and we can run out of address
793f94b781745e715463482695e22addfa95198b548Vladimir Marko    // space (http://b/13564922). Work around the issue by inhibiting further mmap() randomization.
794f94b781745e715463482695e22addfa95198b548Vladimir Marko    int old_personality = personality(0xffffffff);
795f94b781745e715463482695e22addfa95198b548Vladimir Marko    if ((old_personality & ADDR_NO_RANDOMIZE) == 0) {
796f94b781745e715463482695e22addfa95198b548Vladimir Marko      int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE);
797f94b781745e715463482695e22addfa95198b548Vladimir Marko      if (new_personality == -1) {
798f94b781745e715463482695e22addfa95198b548Vladimir Marko        LOG(WARNING) << "personality(. | ADDR_NO_RANDOMIZE) failed.";
799f94b781745e715463482695e22addfa95198b548Vladimir Marko      }
800f94b781745e715463482695e22addfa95198b548Vladimir Marko    }
801f94b781745e715463482695e22addfa95198b548Vladimir Marko  }
802f94b781745e715463482695e22addfa95198b548Vladimir Marko#endif
803f94b781745e715463482695e22addfa95198b548Vladimir Marko
8046449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  original_argc = argc;
8056449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  original_argv = argv;
8066449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
8075fe9af720048673e62ee29597a30bb9e54c903c5Ian Rogers  TimingLogger timings("compiler", false, false);
808ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray  CumulativeLogger compiler_phases_timings("compilation times");
8094560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom
8100d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes  InitLogging(argv);
81172395bf298b7707ad9d93c3e51b57e1b8e010311Elliott Hughes
81269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  // Skip over argv[0].
81369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  argv++;
81469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  argc--;
81569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
81669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  if (argc == 0) {
817e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom    Usage("No arguments specified");
81869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
81969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
82069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  std::vector<const char*> dex_filenames;
821a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::vector<const char*> dex_locations;
822a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  int zip_fd = -1;
823a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::string zip_location;
824e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  std::string oat_filename;
825265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  std::string oat_symbols;
826a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::string oat_location;
827a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  int oat_fd = -1;
8288b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien  std::string bitcode_filename;
8295131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  const char* image_classes_zip_filename = nullptr;
8305131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  const char* image_classes_filename = nullptr;
831a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::string image_filename;
832b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  std::string boot_image_filename;
83369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  uintptr_t image_base = 0;
8343f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  std::string android_root;
8355d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao  std::vector<const char*> runtime_args;
8365c599943f8c347acd84c4d9fda56a9df70649b78Elliott Hughes  int thread_count = sysconf(_SC_NPROCESSORS_CONF);
837b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray  Compiler::Kind compiler_kind = kUsePortableCompiler
838b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray      ? Compiler::kPortable
839b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray      : Compiler::kQuick;
8405131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  const char* compiler_filter_string = nullptr;
8416449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int huge_method_threshold = CompilerOptions::kDefaultHugeMethodThreshold;
8426449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int large_method_threshold = CompilerOptions::kDefaultLargeMethodThreshold;
8436449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int small_method_threshold = CompilerOptions::kDefaultSmallMethodThreshold;
8446449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int tiny_method_threshold = CompilerOptions::kDefaultTinyMethodThreshold;
8456449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int num_dex_methods_threshold = CompilerOptions::kDefaultNumDexMethodsThreshold;
8467020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
8471bd2ceb3a8c68ae6ea1f9627b588a7bc7a74487fBrian Carlstrom  // Take the default set of instruction features from the build.
8487020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  InstructionSetFeatures instruction_set_features =
8498afeb85d3def12b559b7565fb6d3956f81b55132Ian Rogers      ParseFeatureList(Runtime::GetDefaultInstructionSetFeatures());
8507020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
85191268c1afd6c0d4fad55b7c86d907233d4660205Andreas Gampe  InstructionSet instruction_set = kRuntimeISA;
8527020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
85339c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison  // Profile file to use
85439c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison  std::string profile_file;
855c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  double top_k_profile_threshold = CompilerOptions::kDefaultTopKProfileThreshold;
8567020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
857265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  bool is_host = false;
858e732ef1c0192acd71925bd0ff1ab09640d45531dIan Rogers  bool dump_stats = false;
85946398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers  bool dump_timing = false;
860ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray  bool dump_passes = false;
86153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool include_patch_information = CompilerOptions::kDefaultIncludePatchInformation;
86278382fa44ee505cf16835e4d22515e7252a90864Alex Light  bool include_debug_symbols = kIsDebugBuild;
86346398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers  bool dump_slow_timing = kIsDebugBuild;
864b28a16147f5b3503d9ca9e95ff56bdeb449e17d6Andreas Gampe  bool watch_dog_enabled = true;
865ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  bool generate_gdb_information = kIsDebugBuild;
866161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom
86769dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison  // Checks are all explicit until we know the architecture.
86869dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison  bool implicit_null_checks = false;
86969dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison  bool implicit_so_checks = false;
87069dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison  bool implicit_suspend_checks = false;
8715655e84e8d71697d8ef3ea901a0b853af42c559eAndreas Gampe
87269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  for (int i = 0; i < argc; i++) {
87369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    const StringPiece option(argv[i]);
874b9beb2e2efb6a204a69ca660d478b45f851e8f09Ian Rogers    const bool log_options = false;
875a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    if (log_options) {
876b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom      LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i];
877b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom    }
87869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    if (option.starts_with("--dex-file=")) {
87969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      dex_filenames.push_back(option.substr(strlen("--dex-file=")).data());
880a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    } else if (option.starts_with("--dex-location=")) {
881a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      dex_locations.push_back(option.substr(strlen("--dex-location=")).data());
882a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else if (option.starts_with("--zip-fd=")) {
883a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      const char* zip_fd_str = option.substr(strlen("--zip-fd=")).data();
884bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes      if (!ParseInt(zip_fd_str, &zip_fd)) {
885e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom        Usage("Failed to parse --zip-fd argument '%s' as an integer", zip_fd_str);
886a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
8876449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (zip_fd < 0) {
8886449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--zip-fd passed a negative value %d", zip_fd);
8896449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
890a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    } else if (option.starts_with("--zip-location=")) {
891a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      zip_location = option.substr(strlen("--zip-location=")).data();
892a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else if (option.starts_with("--oat-file=")) {
893a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      oat_filename = option.substr(strlen("--oat-file=")).data();
894265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    } else if (option.starts_with("--oat-symbols=")) {
895265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      oat_symbols = option.substr(strlen("--oat-symbols=")).data();
896a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else if (option.starts_with("--oat-fd=")) {
897a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      const char* oat_fd_str = option.substr(strlen("--oat-fd=")).data();
898bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes      if (!ParseInt(oat_fd_str, &oat_fd)) {
899e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom        Usage("Failed to parse --oat-fd argument '%s' as an integer", oat_fd_str);
900a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
9016449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (oat_fd < 0) {
9026449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--oat-fd passed a negative value %d", oat_fd);
9036449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
904994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    } else if (option == "--watch-dog") {
905994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom      watch_dog_enabled = true;
906994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    } else if (option == "--no-watch-dog") {
907994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom      watch_dog_enabled = false;
908ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell    } else if (option == "--gen-gdb-info") {
909ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell      generate_gdb_information = true;
9103470ab4011b5e18d590d5375e2f13a1e3bd69222Alex Light      // Debug symbols are needed for gdb information.
9113470ab4011b5e18d590d5375e2f13a1e3bd69222Alex Light      include_debug_symbols = true;
912ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell    } else if (option == "--no-gen-gdb-info") {
913ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell      generate_gdb_information = false;
9145523ee070b005576c6f889415205d49ea77cf243Elliott Hughes    } else if (option.starts_with("-j")) {
915b12552a95d68b9e4a567103190074ae47b6a61dcBrian Carlstrom      const char* thread_count_str = option.substr(strlen("-j")).data();
9165523ee070b005576c6f889415205d49ea77cf243Elliott Hughes      if (!ParseInt(thread_count_str, &thread_count)) {
917e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom        Usage("Failed to parse -j argument '%s' as an integer", thread_count_str);
9185523ee070b005576c6f889415205d49ea77cf243Elliott Hughes      }
919a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    } else if (option.starts_with("--oat-location=")) {
920a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      oat_location = option.substr(strlen("--oat-location=")).data();
9218b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien    } else if (option.starts_with("--bitcode=")) {
9228b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien      bitcode_filename = option.substr(strlen("--bitcode=")).data();
92369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    } else if (option.starts_with("--image=")) {
92469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      image_filename = option.substr(strlen("--image=")).data();
925ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    } else if (option.starts_with("--image-classes=")) {
926ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      image_classes_filename = option.substr(strlen("--image-classes=")).data();
9274922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    } else if (option.starts_with("--image-classes-zip=")) {
9284922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      image_classes_zip_filename = option.substr(strlen("--image-classes-zip=")).data();
92969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    } else if (option.starts_with("--base=")) {
93069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      const char* image_base_str = option.substr(strlen("--base=")).data();
93169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      char* end;
93269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      image_base = strtoul(image_base_str, &end, 16);
93369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      if (end == image_base_str || *end != '\0') {
934cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom        Usage("Failed to parse hexadecimal value for option %s", option.data());
93569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      }
936e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom    } else if (option.starts_with("--boot-image=")) {
937b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom      boot_image_filename = option.substr(strlen("--boot-image=")).data();
9383f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    } else if (option.starts_with("--android-root=")) {
9393f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom      android_root = option.substr(strlen("--android-root=")).data();
94049c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers    } else if (option.starts_with("--instruction-set=")) {
94149c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers      StringPiece instruction_set_str = option.substr(strlen("--instruction-set=")).data();
9421f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao      if (instruction_set_str == "arm") {
94349c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        instruction_set = kThumb2;
944b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith      } else if (instruction_set_str == "arm64") {
945b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith        instruction_set = kArm64;
9461f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao      } else if (instruction_set_str == "mips") {
94749c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        instruction_set = kMips;
9481f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao      } else if (instruction_set_str == "x86") {
94949c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        instruction_set = kX86;
950ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      } else if (instruction_set_str == "x86_64") {
951ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers        instruction_set = kX86_64;
95249c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers      }
9537020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    } else if (option.starts_with("--instruction-set-features=")) {
9547020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      StringPiece str = option.substr(strlen("--instruction-set-features=")).data();
9557020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      instruction_set_features = ParseFeatureList(str.as_string());
956c531cefbfb5394413122e9f57d211ba436cff012buzbee    } else if (option.starts_with("--compiler-backend=")) {
957c531cefbfb5394413122e9f57d211ba436cff012buzbee      StringPiece backend_str = option.substr(strlen("--compiler-backend=")).data();
958c531cefbfb5394413122e9f57d211ba436cff012buzbee      if (backend_str == "Quick") {
959b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray        compiler_kind = Compiler::kQuick;
960b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray      } else if (backend_str == "Optimizing") {
961b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray        compiler_kind = Compiler::kOptimizing;
962c531cefbfb5394413122e9f57d211ba436cff012buzbee      } else if (backend_str == "Portable") {
963b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray        compiler_kind = Compiler::kPortable;
964c531cefbfb5394413122e9f57d211ba436cff012buzbee      }
9656449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--compiler-filter=")) {
9666449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      compiler_filter_string = option.substr(strlen("--compiler-filter=")).data();
9676449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--huge-method-max=")) {
9686449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--huge-method-max=")).data();
9696449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &huge_method_threshold)) {
9706449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --huge-method-max '%s' as an integer", threshold);
9716449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
9726449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (huge_method_threshold < 0) {
9736449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--huge-method-max passed a negative value %s", huge_method_threshold);
9746449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
9756449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--large-method-max=")) {
9766449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--large-method-max=")).data();
9776449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &large_method_threshold)) {
9786449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --large-method-max '%s' as an integer", threshold);
9796449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
9806449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (large_method_threshold < 0) {
9816449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--large-method-max passed a negative value %s", large_method_threshold);
9826449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
9836449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--small-method-max=")) {
9846449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--small-method-max=")).data();
9856449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &small_method_threshold)) {
9866449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --small-method-max '%s' as an integer", threshold);
9876449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
9886449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (small_method_threshold < 0) {
9896449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--small-method-max passed a negative value %s", small_method_threshold);
9906449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
9916449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--tiny-method-max=")) {
9926449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--tiny-method-max=")).data();
9936449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &tiny_method_threshold)) {
9946449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --tiny-method-max '%s' as an integer", threshold);
9956449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
9966449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (tiny_method_threshold < 0) {
9976449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--tiny-method-max passed a negative value %s", tiny_method_threshold);
9986449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
9996449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--num-dex-methods=")) {
10006449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--num-dex-methods=")).data();
10016449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &num_dex_methods_threshold)) {
10026449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --num-dex-methods '%s' as an integer", threshold);
10036449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
10046449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (num_dex_methods_threshold < 0) {
10056449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--num-dex-methods passed a negative value %s", num_dex_methods_threshold);
10066449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
1007265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    } else if (option == "--host") {
1008265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      is_host = true;
10095d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao    } else if (option == "--runtime-arg") {
10105d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao      if (++i >= argc) {
1011cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom        Usage("Missing required argument for --runtime-arg");
10125d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao      }
1013a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      if (log_options) {
1014a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom        LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i];
1015a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
10165d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao      runtime_args.push_back(argv[i]);
101746398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers    } else if (option == "--dump-timing") {
101846398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers      dump_timing = true;
1019ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray    } else if (option == "--dump-passes") {
1020ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray      dump_passes = true;
1021e732ef1c0192acd71925bd0ff1ab09640d45531dIan Rogers    } else if (option == "--dump-stats") {
1022e732ef1c0192acd71925bd0ff1ab09640d45531dIan Rogers      dump_stats = true;
102378382fa44ee505cf16835e4d22515e7252a90864Alex Light    } else if (option == "--include-debug-symbols" || option == "--no-strip-symbols") {
102478382fa44ee505cf16835e4d22515e7252a90864Alex Light      include_debug_symbols = true;
102578382fa44ee505cf16835e4d22515e7252a90864Alex Light    } else if (option == "--no-include-debug-symbols" || option == "--strip-symbols") {
102678382fa44ee505cf16835e4d22515e7252a90864Alex Light      include_debug_symbols = false;
1027afa6b8e93a0dc0de33c9d404945c7c5621e20b1aAndreas Gampe      generate_gdb_information = false;  // Depends on debug symbols, see above.
102839c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison    } else if (option.starts_with("--profile-file=")) {
102939c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison      profile_file = option.substr(strlen("--profile-file=")).data();
103039c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison      VLOG(compiler) << "dex2oat: profile file is " << profile_file;
103139c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison    } else if (option == "--no-profile-file") {
103239c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison      // No profile
1033c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    } else if (option.starts_with("--top-k-profile-threshold=")) {
103444c5ee7a14bde25207032ac7c2427e8629b8ff42Calin Juravle      ParseDouble(option.data(), '=', 0.0, 100.0, &top_k_profile_threshold);
1035cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu    } else if (option == "--print-pass-names") {
10362469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler      PassDriverMEOpts::PrintPassNames();
1037cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu    } else if (option.starts_with("--disable-passes=")) {
1038cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu      std::string disable_passes = option.substr(strlen("--disable-passes=")).data();
10392469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler      PassDriverMEOpts::CreateDefaultPassList(disable_passes);
10408bceccec7eddff8cd872aa20505b4a3a6be60a16Jean Christophe Beyler    } else if (option.starts_with("--print-passes=")) {
10418bceccec7eddff8cd872aa20505b4a3a6be60a16Jean Christophe Beyler      std::string print_passes = option.substr(strlen("--print-passes=")).data();
10422469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler      PassDriverMEOpts::SetPrintPassList(print_passes);
10438bceccec7eddff8cd872aa20505b4a3a6be60a16Jean Christophe Beyler    } else if (option == "--print-all-passes") {
10442469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler      PassDriverMEOpts::SetPrintAllPasses();
10458bceccec7eddff8cd872aa20505b4a3a6be60a16Jean Christophe Beyler    } else if (option.starts_with("--dump-cfg-passes=")) {
10468bceccec7eddff8cd872aa20505b4a3a6be60a16Jean Christophe Beyler      std::string dump_passes = option.substr(strlen("--dump-cfg-passes=")).data();
10472469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler      PassDriverMEOpts::SetDumpPassList(dump_passes);
104853cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option == "--include-patch-information") {
104953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      include_patch_information = true;
105053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option == "--no-include-patch-information") {
105153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      include_patch_information = false;
105269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    } else {
1053e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom      Usage("Unknown argument %s", option.data());
105469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    }
105569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
105669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
1057a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (oat_filename.empty() && oat_fd == -1) {
1058cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("Output must be supplied with either --oat-file or --oat-fd");
1059a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1060a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1061a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (!oat_filename.empty() && oat_fd != -1) {
1062cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--oat-file should not be used with --oat-fd");
1063a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1064a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1065265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (!oat_symbols.empty() && oat_fd != -1) {
1066265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    Usage("--oat-symbols should not be used with --oat-fd");
1067265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  }
1068265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
1069265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (!oat_symbols.empty() && is_host) {
1070265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    Usage("--oat-symbols should not be used with --host");
1071a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1072a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1073a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (oat_fd != -1 && !image_filename.empty()) {
1074cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--oat-fd should not be used with --image");
1075e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  }
1076e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
10773f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  if (android_root.empty()) {
10783f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    const char* android_root_env_var = getenv("ANDROID_ROOT");
10795131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (android_root_env_var == nullptr) {
108054d22c2bb47da44ef586b9de94749d5648178a26Brian Carlstrom      Usage("--android-root unspecified and ANDROID_ROOT not set");
10813f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    }
10823f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    android_root += android_root_env_var;
10833f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  }
10843f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom
1085a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  bool image = (!image_filename.empty());
1086b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  if (!image && boot_image_filename.empty()) {
1087887235845e203fce046c17120e86d4cac4c56035Ian Rogers    boot_image_filename += android_root;
10883ac05bba3eadccb33d26b41d9797f63e8378125fBrian Carlstrom    boot_image_filename += "/framework/boot.art";
1089b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  }
1090b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  std::string boot_image_option;
1091a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (!boot_image_filename.empty()) {
1092b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom    boot_image_option += "-Ximage:";
1093b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom    boot_image_option += boot_image_filename;
109469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
109569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
10965131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (image_classes_filename != nullptr && !image) {
1097cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--image-classes should only be used with --image");
1098ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
1099ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
11005131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (image_classes_filename != nullptr && !boot_image_option.empty()) {
1101cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--image-classes should not be used with --boot-image");
110278128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom  }
110378128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom
11045131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (image_classes_zip_filename != nullptr && image_classes_filename == nullptr) {
11054922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    Usage("--image-classes-zip should be used with --image-classes");
11064922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom  }
11074922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom
1108a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (dex_filenames.empty() && zip_fd == -1) {
1109cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("Input must be supplied with either --dex-file or --zip-fd");
1110a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1111a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1112a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (!dex_filenames.empty() && zip_fd != -1) {
1113cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--dex-file should not be used with --zip-fd");
1114a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1115a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1116a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (!dex_filenames.empty() && !zip_location.empty()) {
1117cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--dex-file should not be used with --zip-location");
1118a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1119a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1120a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (dex_locations.empty()) {
1121a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    for (size_t i = 0; i < dex_filenames.size(); i++) {
1122a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      dex_locations.push_back(dex_filenames[i]);
1123a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    }
1124a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  } else if (dex_locations.size() != dex_filenames.size()) {
1125cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--dex-location arguments do not match --dex-file arguments");
1126a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  }
1127a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom
1128a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (zip_fd != -1 && zip_location.empty()) {
1129cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--zip-location should be supplied with --zip-fd");
1130a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1131a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
113269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  if (boot_image_option.empty()) {
113369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    if (image_base == 0) {
1134e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom      Usage("Non-zero --base not specified");
113569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    }
113669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
113769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
1138265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  std::string oat_stripped(oat_filename);
1139265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  std::string oat_unstripped;
1140265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (!oat_symbols.empty()) {
1141265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    oat_unstripped += oat_symbols;
1142265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  } else {
1143265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    oat_unstripped += oat_filename;
1144265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  }
1145265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
11465131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (compiler_filter_string == nullptr) {
11472db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung    if (instruction_set == kMips64) {
11482db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung      // TODO: fix compiler for Mips64.
1149befbd5731ecca08f08780ee28a913d08ffb14656Ian Rogers      compiler_filter_string = "interpret-only";
1150befbd5731ecca08f08780ee28a913d08ffb14656Ian Rogers    } else if (image) {
11515e754d88c73f1f1fafbbf87d564df000d5a0a12cBrian Carlstrom      compiler_filter_string = "speed";
11526449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else {
11536449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#if ART_SMALL_MODE
11546449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      compiler_filter_string = "interpret-only";
11556449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#else
11566449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      compiler_filter_string = "speed";
11576449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#endif
11586449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    }
11596449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  }
11606449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  CHECK(compiler_filter_string != nullptr);
11616449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  CompilerOptions::CompilerFilter compiler_filter = CompilerOptions::kDefaultCompilerFilter;
11624a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  if (strcmp(compiler_filter_string, "verify-none") == 0) {
11634a200f56b7075309316b04d550c9cc50f8314eddJeff Hao    compiler_filter = CompilerOptions::kVerifyNone;
11644a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  } else if (strcmp(compiler_filter_string, "interpret-only") == 0) {
11656449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kInterpretOnly;
11666449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else if (strcmp(compiler_filter_string, "space") == 0) {
11676449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kSpace;
11686449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else if (strcmp(compiler_filter_string, "balanced") == 0) {
11696449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kBalanced;
11706449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else if (strcmp(compiler_filter_string, "speed") == 0) {
11716449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kSpeed;
11726449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else if (strcmp(compiler_filter_string, "everything") == 0) {
11736449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kEverything;
11746449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else {
11756449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    Usage("Unknown --compiler-filter value %s", compiler_filter_string);
11766449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  }
11776449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
117869dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison  // Set the compilation target's implicit checks options.
117969dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison  switch (instruction_set) {
118069dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison    case kArm:
118169dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison    case kThumb2:
11827204c04dd86ae8ce05690e38737b2abf017a0a69Stuart Monteith    case kArm64:
118369dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison    case kX86:
1184b0f05b9654eb005bc8c8e15f615a7f5a312f640cDave Allison    case kX86_64:
118569dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison      implicit_null_checks = true;
118669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison      implicit_so_checks = true;
118769dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison      break;
118869dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison
118969dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison    default:
119069dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison      // Defaults are correct.
119169dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison      break;
119269dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison  }
119369dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison
119422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  std::unique_ptr<CompilerOptions> compiler_options(new CompilerOptions(compiler_filter,
119522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        huge_method_threshold,
119622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        large_method_threshold,
119722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        small_method_threshold,
119822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        tiny_method_threshold,
119922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        num_dex_methods_threshold,
120022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        generate_gdb_information,
120122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        include_patch_information,
120222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        top_k_profile_threshold,
120322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        include_debug_symbols,
120469dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison                                                                        implicit_null_checks,
120569dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison                                                                        implicit_so_checks,
120669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison                                                                        implicit_suspend_checks
12076449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#ifdef ART_SEA_IR_MODE
120822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        , compiler_options.sea_ir_ =
120922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                              true;
12106449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#endif
121122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  ));  // NOLINT(whitespace/parens)
12126449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
1213994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  // Done with usage checks, enable watchdog if requested
1214994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  WatchDog watch_dog(watch_dog_enabled);
1215994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom
12166ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom  // Check early that the result of compilation can be written
1217700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<File> oat_file;
1218265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  bool create_file = !oat_unstripped.empty();  // as opposed to using open file descriptor
12196cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom  if (create_file) {
12207571e8b761ebc2c923525e12ea9fcf07e62cb33eBrian Carlstrom    oat_file.reset(OS::CreateEmptyFile(oat_unstripped.c_str()));
1221a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    if (oat_location.empty()) {
1222a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      oat_location = oat_filename;
1223a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    }
1224a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  } else {
1225761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    oat_file.reset(new File(oat_fd, oat_location));
1226761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    oat_file->DisableAutoClose();
1227aa93129ca54cc897fdc2c8ddd0a7136f7b5632edBrian Carlstrom    oat_file->SetLength(0);
1228a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
12295131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (oat_file.get() == nullptr) {
12306cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom    PLOG(ERROR) << "Failed to create oat file: " << oat_location;
12316cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom    return EXIT_FAILURE;
12326cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom  }
12336cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom  if (create_file && fchmod(oat_file->Fd(), 0644) != 0) {
12346cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom    PLOG(ERROR) << "Failed to make oat file world readable: " << oat_location;
12356ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom    return EXIT_FAILURE;
1236234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  }
1237a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1238f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier  timings.StartTiming("dex2oat Setup");
123909881a85579cab1779ddf6ba9a91eed861a13cb2Brian Carlstrom  LOG(INFO) << CommandLine();
12405e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers
1241e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers  RuntimeOptions runtime_options;
1242a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::vector<const DexFile*> boot_class_path;
1243c54e12a413e16f90526318f1f466a900a717fbb0Mathieu Chartier  art::MemMap::Init();  // For ZipEntry::ExtractToMemMap.
124469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  if (boot_image_option.empty()) {
12453cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom    size_t failure_count = OpenDexFiles(dex_filenames, dex_locations, boot_class_path);
12463cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom    if (failure_count > 0) {
12473cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      LOG(ERROR) << "Failed to open some dex files: " << failure_count;
12483cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      return EXIT_FAILURE;
12493cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom    }
12506449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    runtime_options.push_back(std::make_pair("bootclasspath", &boot_class_path));
125169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  } else {
12525131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    runtime_options.push_back(std::make_pair(boot_image_option.c_str(), nullptr));
125369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
12545d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao  for (size_t i = 0; i < runtime_args.size(); i++) {
12555131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    runtime_options.push_back(std::make_pair(runtime_args[i], nullptr));
12565d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao  }
125769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
125822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  std::unique_ptr<VerificationResults> verification_results(new VerificationResults(
125969dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison                                                            compiler_options.get()));
12606449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  DexFileToMethodInlinerMap method_inliner_map;
1261e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers  QuickCompilerCallbacks callbacks(verification_results.get(), &method_inliner_map);
12626449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  runtime_options.push_back(std::make_pair("compilercallbacks", &callbacks));
126311d9f06a96a6909905c248ed684366190140095cNarayan Kamath  runtime_options.push_back(
126411d9f06a96a6909905c248ed684366190140095cNarayan Kamath      std::make_pair("imageinstructionset",
126511d9f06a96a6909905c248ed684366190140095cNarayan Kamath                     reinterpret_cast<const void*>(GetInstructionSetString(instruction_set))));
12667467ee05012e1fd9834df74663c1ebda46f5636bDragos Sbirlea
126700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Dex2Oat* p_dex2oat;
12686449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  if (!Dex2Oat::Create(&p_dex2oat,
12696449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       runtime_options,
127022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                       *compiler_options,
1271b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray                       compiler_kind,
12726449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       instruction_set,
12736449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       instruction_set_features,
127422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                       verification_results.get(),
12756449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       &method_inliner_map,
12766449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       thread_count)) {
127700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    LOG(ERROR) << "Failed to create dex2oat";
1278f0cb1eb5b2020c3c527aca3ff458801b90b5e06cAndreas Gampe    timings.EndTiming();
127900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return EXIT_FAILURE;
128000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
1281700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<Dex2Oat> dex2oat(p_dex2oat);
12825655e84e8d71697d8ef3ea901a0b853af42c559eAndreas Gampe
128300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
12843f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers  // give it away now so that we don't starve GC.
12853f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers  Thread* self = Thread::Current();
12863f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers  self->TransitionFromRunnableToSuspended(kNative);
12870f40ac31134d9ae0f059d4c448165599dc8459c1Ian Rogers  // If we're doing the image, override the compiler filter to force full compilation. Must be
1288fe9ca4028f379688ecba6132ac3738171176b3e4buzbee  // done ahead of WellKnownClasses::Init that causes verification.  Note: doesn't force
1289fe9ca4028f379688ecba6132ac3738171176b3e4buzbee  // compilation of class initializers.
129000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Whilst we're in native take the opportunity to initialize well known classes.
12913f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers  WellKnownClasses::Init(self->GetJniEnv());
129269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
1293bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  // If --image-classes was specified, calculate the full list of classes to include in the image
1294cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers  std::unique_ptr<std::set<std::string>> image_classes(nullptr);
1295d5185344e19d9feb7ac268369e0af6a467d1cb48Kenny Root  if (image_classes_filename != nullptr) {
12968d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers    std::string error_msg;
1297d5185344e19d9feb7ac268369e0af6a467d1cb48Kenny Root    if (image_classes_zip_filename != nullptr) {
12984922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      image_classes.reset(dex2oat->ReadImageClassesFromZip(image_classes_zip_filename,
12998d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                           image_classes_filename,
13008d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                           &error_msg));
13014922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    } else {
13024922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      image_classes.reset(dex2oat->ReadImageClassesFromFile(image_classes_filename));
13034922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    }
1304d5185344e19d9feb7ac268369e0af6a467d1cb48Kenny Root    if (image_classes.get() == nullptr) {
13058d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      LOG(ERROR) << "Failed to create list of image classes from '" << image_classes_filename <<
13068d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers          "': " << error_msg;
1307f0cb1eb5b2020c3c527aca3ff458801b90b5e06cAndreas Gampe      timings.EndTiming();
1308ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      return EXIT_FAILURE;
130969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    }
1310d5185344e19d9feb7ac268369e0af6a467d1cb48Kenny Root  } else if (image) {
1311cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers    image_classes.reset(new std::set<std::string>);
131269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
131369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
1314a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  std::vector<const DexFile*> dex_files;
1315a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (boot_image_option.empty()) {
1316a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    dex_files = Runtime::Current()->GetClassLinker()->GetBootClassPath();
1317a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  } else {
1318a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    if (dex_filenames.empty()) {
1319740a11d0bfeaef36d910669844d01f3957dbe696Ian Rogers      ATRACE_BEGIN("Opening zip archive from file descriptor");
13208d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      std::string error_msg;
1321700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers      std::unique_ptr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(zip_fd, zip_location.c_str(),
13228d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                               &error_msg));
13235131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      if (zip_archive.get() == nullptr) {
13248d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers        LOG(ERROR) << "Failed to open zip from file descriptor for '" << zip_location << "': "
13258d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers            << error_msg;
1326f0cb1eb5b2020c3c527aca3ff458801b90b5e06cAndreas Gampe        timings.EndTiming();
13272e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom        return EXIT_FAILURE;
1328a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
1329833a48501d560c9fa7fc78ef619888138c2d374fAndreas Gampe      if (!DexFile::OpenFromZip(*zip_archive.get(), zip_location, &error_msg, &dex_files)) {
13308d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers        LOG(ERROR) << "Failed to open dex from file descriptor for zip file '" << zip_location
13318d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers            << "': " << error_msg;
1332f0cb1eb5b2020c3c527aca3ff458801b90b5e06cAndreas Gampe        timings.EndTiming();
1333a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom        return EXIT_FAILURE;
1334a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
1335740a11d0bfeaef36d910669844d01f3957dbe696Ian Rogers      ATRACE_END();
1336a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else {
13373cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      size_t failure_count = OpenDexFiles(dex_filenames, dex_locations, dex_files);
13383cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      if (failure_count > 0) {
13393cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom        LOG(ERROR) << "Failed to open some dex files: " << failure_count;
1340f0cb1eb5b2020c3c527aca3ff458801b90b5e06cAndreas Gampe        timings.EndTiming();
13413cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom        return EXIT_FAILURE;
13423cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      }
1343a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    }
1344d76e08323893c60df77eccca6e882279e7246d8cBrian Carlstrom
1345f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom    const bool kSaveDexInput = false;
1346f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom    if (kSaveDexInput) {
1347f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom      for (size_t i = 0; i < dex_files.size(); ++i) {
1348f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom        const DexFile* dex_file = dex_files[i];
13495180cc1cddc5112ea544bf9d8323f1d27db56f75Ian Rogers        std::string tmp_file_name(StringPrintf("/data/local/tmp/dex2oat.%d.%zd.dex", getpid(), i));
1350700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers        std::unique_ptr<File> tmp_file(OS::CreateEmptyFile(tmp_file_name.c_str()));
1351f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom        if (tmp_file.get() == nullptr) {
13526449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom            PLOG(ERROR) << "Failed to open file " << tmp_file_name
13536449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                        << ". Try: adb shell chmod 777 /data/local/tmp";
1354f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom            continue;
1355f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom        }
1356f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom        tmp_file->WriteFully(dex_file->Begin(), dex_file->Size());
1357f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom        LOG(INFO) << "Wrote input to " << tmp_file_name;
1358f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom      }
1359f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom    }
13602ec6520d57479d393bffa05defa1479b25ca8382Brian Carlstrom  }
13612ec6520d57479d393bffa05defa1479b25ca8382Brian Carlstrom  // Ensure opened dex files are writable for dex-to-dex transformations.
13622ec6520d57479d393bffa05defa1479b25ca8382Brian Carlstrom  for (const auto& dex_file : dex_files) {
13632ec6520d57479d393bffa05defa1479b25ca8382Brian Carlstrom    if (!dex_file->EnableWrite()) {
13642ec6520d57479d393bffa05defa1479b25ca8382Brian Carlstrom      PLOG(ERROR) << "Failed to make .dex file writeable '" << dex_file->GetLocation() << "'\n";
1365d76e08323893c60df77eccca6e882279e7246d8cBrian Carlstrom    }
1366a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1367a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1368a024a0686c3b0fea13f362bff70d65981e5febc5buzbee  /*
13694a200f56b7075309316b04d550c9cc50f8314eddJeff Hao   * If we're not in interpret-only or verify-none mode, go ahead and compile small applications.
13704a200f56b7075309316b04d550c9cc50f8314eddJeff Hao   * Don't bother to check if we're doing the image.
1371a024a0686c3b0fea13f362bff70d65981e5febc5buzbee   */
137222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  if (!image && compiler_options->IsCompilationEnabled()) {
13738447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum    size_t num_methods = 0;
13748447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum    for (size_t i = 0; i != dex_files.size(); ++i) {
13758447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum      const DexFile* dex_file = dex_files[i];
13765131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      CHECK(dex_file != nullptr);
13778447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum      num_methods += dex_file->NumMethodIds();
13788447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum    }
137922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe    if (num_methods <= compiler_options->GetNumDexMethodsThreshold()) {
138022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe      compiler_options->SetCompilerFilter(CompilerOptions::kSpeed);
138175a43f10f55e2aa550de51e969cc1e60d583b632Anwar Ghuloum      VLOG(compiler) << "Below method threshold, compiling anyways";
13828447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum    }
13838447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum  }
1384c4f105d75cd0cbc5145620068bbb8a819148e535Anwar Ghuloum
138522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  // Fill some values into the key-value store for the oat header.
138622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  std::unique_ptr<SafeMap<std::string, std::string> > key_value_store(
138722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe      new SafeMap<std::string, std::string>());
138822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
138922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  // Insert some compiler things.
139022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  std::ostringstream oss;
139122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  for (int i = 0; i < argc; ++i) {
139222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe    if (i > 0) {
139322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe      oss << ' ';
139422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe    }
139522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe    oss << argv[i];
139622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  }
139722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  key_value_store->Put(OatHeader::kDex2OatCmdLineKey, oss.str());
139822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  oss.str("");  // Reset.
139922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  oss << kRuntimeISA;
140022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  key_value_store->Put(OatHeader::kDex2OatHostKey, oss.str());
140122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
1402700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<const CompilerDriver> compiler(dex2oat->CreateOatFile(boot_image_option,
140322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        android_root,
140422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        is_host,
140522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        dex_files,
140622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        oat_file.get(),
1407a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                                                                        oat_location,
140822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        bitcode_filename,
140922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        image,
141022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        image_classes,
141122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        dump_stats,
141222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        dump_passes,
141322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        timings,
141422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        compiler_phases_timings,
141522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        profile_file,
141622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        key_value_store.get()));
14175131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (compiler.get() == nullptr) {
1418a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    LOG(ERROR) << "Failed to create oat file: " << oat_location;
1419f0cb1eb5b2020c3c527aca3ff458801b90b5e06cAndreas Gampe    timings.EndTiming();
1420e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom    return EXIT_FAILURE;
1421e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  }
1422e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
142375a43f10f55e2aa550de51e969cc1e60d583b632Anwar Ghuloum  VLOG(compiler) << "Oat file written successfully (unstripped): " << oat_location;
1424aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
1425700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // Notes on the interleaving of creating the image and oat file to
1426700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // ensure the references between the two are correct.
1427700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1428700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // Currently we have a memory layout that looks something like this:
1429700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1430700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // +--------------+
1431700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // | image        |
1432700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // +--------------+
1433700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // | boot oat     |
1434700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // +--------------+
1435700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // | alloc spaces |
1436700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // +--------------+
1437700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
14384560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  // There are several constraints on the loading of the image and boot.oat.
1439700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1440700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 1. The image is expected to be loaded at an absolute address and
1441700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // contains Objects with absolute pointers within the image.
1442700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1443700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 2. There are absolute pointers from Methods in the image to their
1444700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // code in the oat.
1445700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1446700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 3. There are absolute pointers from the code in the oat to Methods
1447700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // in the image.
1448700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1449700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 4. There are absolute pointers from code in the oat to other code
1450700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // in the oat.
1451700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1452700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // To get this all correct, we go through several steps.
1453700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1454700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 1. We have already created that oat file above with
1455700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // CreateOatFile. Originally this was just our own proprietary file
14564560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  // but now it is contained within an ELF dynamic object (aka an .so
1457700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // file). The Compiler returned by CreateOatFile provides
1458700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // PatchInformation for references to oat code and Methods that need
1459700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // to be update once we know where the oat file will be located
1460700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // after the image.
1461700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1462700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 2. We create the image file. It needs to know where the oat file
1463700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // will be loaded after itself. Originally when oat file was simply
1464700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // memory mapped so we could predict where its contents were based
1465700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // on the file size. Now that it is an ELF file, we need to inspect
1466700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // the ELF file to understand the in memory segment layout including
1467a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  // where the oat header is located within. ElfPatcher's Patch method
1468a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  // uses the PatchInformation from the Compiler to touch up absolute
1469a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  // references in the oat file.
1470700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1471700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 3. We fixup the ELF program headers so that dlopen will try to
1472700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // load the .so at the desired location at runtime by offsetting the
1473700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // Elf32_Phdr.p_vaddr values by the desired base address.
1474700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1475265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (image) {
1476f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier    TimingLogger::ScopedTiming t("dex2oat ImageWriter", &timings);
1477265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    bool image_creation_success = dex2oat->CreateImageFile(image_filename,
1478265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                                                           image_base,
1479265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                                                           oat_unstripped,
1480265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                                                           oat_location,
1481265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                                                           *compiler.get());
1482265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    if (!image_creation_success) {
1483f0cb1eb5b2020c3c527aca3ff458801b90b5e06cAndreas Gampe      timings.EndTiming();
1484265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      return EXIT_FAILURE;
1485265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    }
148675a43f10f55e2aa550de51e969cc1e60d583b632Anwar Ghuloum    VLOG(compiler) << "Image written successfully: " << image_filename;
1487265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  }
1488265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
1489265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (is_host) {
1490f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier    timings.EndTiming();
149146398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers    if (dump_timing || (dump_slow_timing && timings.GetTotalNs() > MsToNs(1000))) {
14925fe9af720048673e62ee29597a30bb9e54c903c5Ian Rogers      LOG(INFO) << Dumpable<TimingLogger>(timings);
14934560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom    }
1494ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray    if (dump_passes) {
14953d504075f7c1204d581923460754bf6d3714b13fIan Rogers      LOG(INFO) << Dumpable<CumulativeLogger>(*compiler.get()->GetTimingsLogger());
1496ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray    }
1497265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    return EXIT_SUCCESS;
149869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
149969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
1500265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // If we don't want to strip in place, copy from unstripped location to stripped location.
1501265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // We need to strip after image creation because FixupElf needs to use .strtab.
1502265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (oat_unstripped != oat_stripped) {
1503f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier    TimingLogger::ScopedTiming t("dex2oat OatFile copy", &timings);
1504265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    oat_file.reset();
1505700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers     std::unique_ptr<File> in(OS::OpenFileForReading(oat_unstripped.c_str()));
1506700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers    std::unique_ptr<File> out(OS::CreateEmptyFile(oat_stripped.c_str()));
1507265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    size_t buffer_size = 8192;
1508700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers    std::unique_ptr<uint8_t> buffer(new uint8_t[buffer_size]);
1509265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    while (true) {
1510265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      int bytes_read = TEMP_FAILURE_RETRY(read(in->Fd(), buffer.get(), buffer_size));
1511265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      if (bytes_read <= 0) {
1512265091e581c9f643b37e7966890911f09e223269Brian Carlstrom        break;
1513265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      }
1514265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      bool write_ok = out->WriteFully(buffer.get(), bytes_read);
1515265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      CHECK(write_ok);
1516265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    }
1517265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    oat_file.reset(out.release());
151875a43f10f55e2aa550de51e969cc1e60d583b632Anwar Ghuloum    VLOG(compiler) << "Oat file copied successfully (stripped): " << oat_stripped;
1519265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  }
1520265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
15217fcba11846d3320911aefdba6a20c1192e36fc2eBrian Carlstrom#if ART_USE_PORTABLE_COMPILER  // We currently only generate symbols on Portable
152278382fa44ee505cf16835e4d22515e7252a90864Alex Light  if (!compiler_options.GetIncludeDebugSymbols()) {
152378382fa44ee505cf16835e4d22515e7252a90864Alex Light    timings.NewSplit("dex2oat ElfStripper");
152478382fa44ee505cf16835e4d22515e7252a90864Alex Light    // Strip unneeded sections for target
152578382fa44ee505cf16835e4d22515e7252a90864Alex Light    off_t seek_actual = lseek(oat_file->Fd(), 0, SEEK_SET);
152678382fa44ee505cf16835e4d22515e7252a90864Alex Light    CHECK_EQ(0, seek_actual);
152778382fa44ee505cf16835e4d22515e7252a90864Alex Light    std::string error_msg;
152878382fa44ee505cf16835e4d22515e7252a90864Alex Light    CHECK(ElfStripper::Strip(oat_file.get(), &error_msg)) << error_msg;
15296f28d91aab952e3244fbb4e707fa38f85538f374Anwar Ghuloum
1530265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
153178382fa44ee505cf16835e4d22515e7252a90864Alex Light    // We wrote the oat file successfully, and want to keep it.
153278382fa44ee505cf16835e4d22515e7252a90864Alex Light    VLOG(compiler) << "Oat file written successfully (stripped): " << oat_location;
153378382fa44ee505cf16835e4d22515e7252a90864Alex Light  } else {
153478382fa44ee505cf16835e4d22515e7252a90864Alex Light    VLOG(compiler) << "Oat file written successfully without stripping: " << oat_location;
153578382fa44ee505cf16835e4d22515e7252a90864Alex Light  }
15367934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom#endif  // ART_USE_PORTABLE_COMPILER
15374560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom
1538f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier  timings.EndTiming();
15396f28d91aab952e3244fbb4e707fa38f85538f374Anwar Ghuloum
1540c6dfdacea2fd9e268f70328805b0366cdd6b7b9eBrian Carlstrom  if (dump_timing || (dump_slow_timing && timings.GetTotalNs() > MsToNs(1000))) {
15415fe9af720048673e62ee29597a30bb9e54c903c5Ian Rogers    LOG(INFO) << Dumpable<TimingLogger>(timings);
15424560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  }
1543ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray  if (dump_passes) {
1544ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray    LOG(INFO) << Dumpable<CumulativeLogger>(compiler_phases_timings);
1545ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray  }
15462672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers
15472672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers  // Everything was successfully written, do an explicit exit here to avoid running Runtime
15482672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers  // destructors that take time (bug 10645725) unless we're a debug build or running on valgrind.
15496449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  if (!kIsDebugBuild && (RUNNING_ON_VALGRIND == 0)) {
155065c23bbb25f069b3b49761468b848c4e5d1aa879Brian Carlstrom    dex2oat->LogCompletionTime();
15512672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers    exit(EXIT_SUCCESS);
15522672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers  }
15532672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers
155469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  return EXIT_SUCCESS;
15556449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom}  // NOLINT(readability/fn_size)
15567934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom}  // namespace art
155769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
155869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromint main(int argc, char** argv) {
155969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  return art::dex2oat(argc, argv);
156069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom}
1561