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("");
15890ca5c0301651101de0e363842e5d08ae65233f7Igor Murashkin  UsageError("  --compile-pic: Force indirect use of code, methods, and classes");
15990ca5c0301651101de0e363842e5d08ae65233f7Igor Murashkin  UsageError("      Default: disabled");
16090ca5c0301651101de0e363842e5d08ae65233f7Igor Murashkin  UsageError("");
161b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray  UsageError("  --compiler-backend=(Quick|Optimizing|Portable): select compiler backend");
162c531cefbfb5394413122e9f57d211ba436cff012buzbee  UsageError("      set.");
163635733da0f67df1c979cc9764409d2a9dcbb20aaBrian Carlstrom  UsageError("      Example: --compiler-backend=Portable");
164c531cefbfb5394413122e9f57d211ba436cff012buzbee  UsageError("      Default: Quick");
165265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("");
1664a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  UsageError("  --compiler-filter=(verify-none|interpret-only|space|balanced|speed|everything):");
1674a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  UsageError("      select compiler filter.");
1686449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --compiler-filter=everything");
1696449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#if ART_SMALL_MODE
1706449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: interpret-only");
1716449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#else
1726449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: speed");
1736449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#endif
1746449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
1756449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --huge-method-max=<method-instruction-count>: the threshold size for a huge");
1766449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      method for compiler filter tuning.");
1776449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --huge-method-max=%d", CompilerOptions::kDefaultHugeMethodThreshold);
1786449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultHugeMethodThreshold);
1796449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
1806449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --huge-method-max=<method-instruction-count>: threshold size for a huge");
1816449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      method for compiler filter tuning.");
1826449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --huge-method-max=%d", CompilerOptions::kDefaultHugeMethodThreshold);
1836449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultHugeMethodThreshold);
1846449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
1856449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --large-method-max=<method-instruction-count>: threshold size for a large");
1866449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      method for compiler filter tuning.");
1876449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --large-method-max=%d", CompilerOptions::kDefaultLargeMethodThreshold);
1886449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultLargeMethodThreshold);
1896449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
1906449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --small-method-max=<method-instruction-count>: threshold size for a small");
1916449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      method for compiler filter tuning.");
1926449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --small-method-max=%d", CompilerOptions::kDefaultSmallMethodThreshold);
1936449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultSmallMethodThreshold);
1946449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
1956449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --tiny-method-max=<method-instruction-count>: threshold size for a tiny");
1966449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      method for compiler filter tuning.");
1976449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --tiny-method-max=%d", CompilerOptions::kDefaultTinyMethodThreshold);
1986449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultTinyMethodThreshold);
1996449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
2006449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("  --num-dex-methods=<method-count>: threshold size for a small dex file for");
2016449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      compiler filter tuning. If the input has fewer than this many methods");
2024a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  UsageError("      and the filter is not interpret-only or verify-none, overrides the");
2034a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  UsageError("      filter to use speed");
2046449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Example: --num-dex-method=%d", CompilerOptions::kDefaultNumDexMethodsThreshold);
2056449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("      Default: %d", CompilerOptions::kDefaultNumDexMethodsThreshold);
2066449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  UsageError("");
207265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("  --host: used with Portable backend to link against host runtime libraries");
208265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  UsageError("");
20946398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers  UsageError("  --dump-timing: display a breakdown of where time was spent");
21046398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers  UsageError("");
21153cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --include-patch-information: Include patching information so the generated code");
21253cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("      can have its base address moved without full recompilation.");
21353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
21453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("  --no-include-patch-information: Do not include patching information.");
21553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  UsageError("");
21678382fa44ee505cf16835e4d22515e7252a90864Alex Light  UsageError("  --include-debug-symbols: Include ELF symbols in this oat file");
21778382fa44ee505cf16835e4d22515e7252a90864Alex Light  UsageError("");
21878382fa44ee505cf16835e4d22515e7252a90864Alex Light  UsageError("  --no-include-debug-symbols: Do not include ELF symbols in this oat file");
21978382fa44ee505cf16835e4d22515e7252a90864Alex Light  UsageError("");
220cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("  --runtime-arg <argument>: used to specify various arguments for the runtime,");
221cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      such as initial heap size, maximum heap size, and verbose output.");
222cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Use a separate --runtime-arg switch for each argument.");
223cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("      Example: --runtime-arg -Xms256m");
2244a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  UsageError("");
225d6ed642458c8820e1beca72f3d7b5f0be4a4b64bDave Allison  UsageError("  --profile-file=<filename>: specify profiler output file to use for compilation.");
226cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  UsageError("");
227cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu  UsageError("  --print-pass-names: print a list of pass names");
228cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu  UsageError("");
229cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu  UsageError("  --disable-passes=<pass-names>:  disable one or more passes separated by comma.");
230cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu  UsageError("      Example: --disable-passes=UseCount,BBOptimizations");
231cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu  UsageError("");
23262746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  UsageError("  --swap-file=<file-name>:  specifies a file to use for swap.");
23362746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  UsageError("      Example: --swap-file=/data/tmp/swap.001");
23462746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  UsageError("");
23562746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  UsageError("  --swap-fd=<file-descriptor>:  specifies a file to use for swap (by descriptor).");
23662746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  UsageError("      Example: --swap-fd=10");
23762746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  UsageError("");
238cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom  std::cerr << "See log for usage error information\n";
23969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  exit(EXIT_FAILURE);
24069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom}
24169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
242ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstromclass Dex2Oat {
243ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom public:
2444560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  static bool Create(Dex2Oat** p_dex2oat,
245e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers                     const RuntimeOptions& runtime_options,
2466449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                     const CompilerOptions& compiler_options,
247b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray                     Compiler::Kind compiler_kind,
2484560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                     InstructionSet instruction_set,
2497020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison                     InstructionSetFeatures instruction_set_features,
2506449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                     VerificationResults* verification_results,
2516449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                     DexFileToMethodInlinerMap* method_inliner_map,
2524560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                     size_t thread_count)
253b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_) {
2546449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    CHECK(verification_results != nullptr);
2556449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    CHECK(method_inliner_map != nullptr);
256700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers    std::unique_ptr<Dex2Oat> dex2oat(new Dex2Oat(&compiler_options,
257b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray                                           compiler_kind,
2586449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                           instruction_set,
2596449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                           instruction_set_features,
2606449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                           verification_results,
2616449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                           method_inliner_map,
2626449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                                           thread_count));
2636449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    if (!dex2oat->CreateRuntime(runtime_options, instruction_set)) {
2645131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      *p_dex2oat = nullptr;
26500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      return false;
266254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson    }
2672b5eaa2b49f7489bafdadc4b4463ae27e4261817Vladimir Marko    *p_dex2oat = dex2oat.release();
26800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return true;
269ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
270ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
271ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  ~Dex2Oat() {
272ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    delete runtime_;
27365c23bbb25f069b3b49761468b848c4e5d1aa879Brian Carlstrom  }
27465c23bbb25f069b3b49761468b848c4e5d1aa879Brian Carlstrom
2753029df6d212894647ba0e5c23443c40912c6ecc8Mathieu Chartier  void LogCompletionTime(const CompilerDriver* compiler) {
27665c23bbb25f069b3b49761468b848c4e5d1aa879Brian Carlstrom    LOG(INFO) << "dex2oat took " << PrettyDuration(NanoTime() - start_ns_)
277aa3eff991fc34d6434465bf6bf49ef2e2fb286b7Andreas Gampe              << " (threads: " << thread_count_ << ") "
278aa3eff991fc34d6434465bf6bf49ef2e2fb286b7Andreas Gampe              << compiler->GetMemoryUsageString(kIsDebugBuild || VLOG_IS_ON(compiler));
279ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
280ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
281c4f105d75cd0cbc5145620068bbb8a819148e535Anwar Ghuloum
2824560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  // Reads the class names (java.lang.Object) and returns a set of descriptors (Ljava/lang/Object;)
283cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers  std::set<std::string>* ReadImageClassesFromFile(const char* image_classes_filename) {
284700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers    std::unique_ptr<std::ifstream> image_classes_file(new std::ifstream(image_classes_filename,
2854560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                                                                  std::ifstream::in));
2865131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (image_classes_file.get() == nullptr) {
287ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      LOG(ERROR) << "Failed to open image classes file " << image_classes_filename;
2885131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      return nullptr;
289ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
290cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers    std::unique_ptr<std::set<std::string>> result(ReadImageClasses(*image_classes_file));
2914922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    image_classes_file->close();
2924922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    return result.release();
2934922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom  }
294ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
295cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers  std::set<std::string>* ReadImageClasses(std::istream& image_classes_stream) {
296cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers    std::unique_ptr<std::set<std::string>> image_classes(new std::set<std::string>);
2974922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    while (image_classes_stream.good()) {
298ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      std::string dot;
2994922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      std::getline(image_classes_stream, dot);
300f1a5adc87760f938b01df26d906295063546b259Elliott Hughes      if (StartsWith(dot, "#") || dot.empty()) {
301ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        continue;
302ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
303955724179c6c739524f610023287f56b24dc31deElliott Hughes      std::string descriptor(DotToDescriptor(dot.c_str()));
30496391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom      image_classes->insert(descriptor);
305ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
306ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    return image_classes.release();
307254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson  }
308254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson
3094560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  // Reads the class names (java.lang.Object) and returns a set of descriptors (Ljava/lang/Object;)
310cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers  std::set<std::string>* ReadImageClassesFromZip(const char* zip_filename,
3118d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                         const char* image_classes_filename,
3128d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                         std::string* error_msg) {
313700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers    std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(zip_filename, error_msg));
3145131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (zip_archive.get() == nullptr) {
3155131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      return nullptr;
3164922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    }
317700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers    std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(image_classes_filename, error_msg));
3185131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (zip_entry.get() == nullptr) {
3198d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      *error_msg = StringPrintf("Failed to find '%s' within '%s': %s", image_classes_filename,
3208d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                zip_filename, error_msg->c_str());
3215131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      return nullptr;
3224922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    }
3230aa504b5bb19f0944d50941b20c8eeaca4165328Brian Carlstrom    std::unique_ptr<MemMap> image_classes_file(zip_entry->ExtractToMemMap(zip_filename,
3240aa504b5bb19f0944d50941b20c8eeaca4165328Brian Carlstrom                                                                          image_classes_filename,
3250aa504b5bb19f0944d50941b20c8eeaca4165328Brian Carlstrom                                                                          error_msg));
3265131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (image_classes_file.get() == nullptr) {
3278d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", image_classes_filename,
3288d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                zip_filename, error_msg->c_str());
3295131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      return nullptr;
3304922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    }
3314922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    const std::string image_classes_string(reinterpret_cast<char*>(image_classes_file->Begin()),
3324922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom                                           image_classes_file->Size());
3334922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    std::istringstream image_classes_stream(image_classes_string);
3344922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    return ReadImageClasses(image_classes_stream);
3354922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom  }
3364922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom
337a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  bool PatchOatCode(const CompilerDriver* compiler_driver, File* oat_file,
338a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                    const std::string& oat_location, std::string* error_msg) {
339a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    // We asked to include patch information but we are not making an image. We need to fix
340a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    // everything up manually.
341a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    std::unique_ptr<ElfFile> elf_file(ElfFile::Open(oat_file, PROT_READ|PROT_WRITE,
342a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                                                    MAP_SHARED, error_msg));
343a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    if (elf_file.get() == NULL) {
344a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      LOG(ERROR) << error_msg;
345a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      return false;
346a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    }
347a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    {
348a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      ReaderMutexLock mu(Thread::Current(), *Locks::mutator_lock_);
349a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      return ElfPatcher::Patch(compiler_driver, elf_file.get(), oat_location, error_msg);
350a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    }
351a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  }
352a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
3531212a022fa5f8ef9585d765b1809521812af882cIan Rogers  const CompilerDriver* CreateOatFile(const std::string& boot_image_option,
3543f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      const std::string& android_root,
3553f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      bool is_host,
3563f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      const std::vector<const DexFile*>& dex_files,
3573f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      File* oat_file,
358a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                                      const std::string& oat_location,
3593f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      const std::string& bitcode_filename,
3603f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      bool image,
361cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers                                      std::unique_ptr<std::set<std::string>>& image_classes,
36226318f722958ac1cba6a812026a1377f37c54941Andreas Gampe                                      std::unique_ptr<std::set<std::string>>& compiled_classes,
3633f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom                                      bool dump_stats,
364ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray                                      bool dump_passes,
365ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray                                      TimingLogger& timings,
36639c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison                                      CumulativeLogger& compiler_phases_timings,
36762746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe                                      int swap_fd,
36822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                      std::string profile_file,
36922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                      SafeMap<std::string, std::string>* key_value_store) {
37022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe    CHECK(key_value_store != nullptr);
37122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
372eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    // Handle and ClassLoader creation needs to come after Runtime::Create
3735131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    jobject class_loader = nullptr;
3743f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers    Thread* self = Thread::Current();
375ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    if (!boot_image_option.empty()) {
376ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
377ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      std::vector<const DexFile*> class_path_files(dex_files);
378a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      OpenClassPathFiles(runtime_->GetClassPathString(), class_path_files);
3793f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers      ScopedObjectAccess soa(self);
380ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      for (size_t i = 0; i < class_path_files.size(); i++) {
381ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        class_linker->RegisterDexFile(*class_path_files[i]);
382ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
38300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader);
38400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      ScopedLocalRef<jobject> class_loader_local(soa.Env(),
38500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers          soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
38600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
38700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path_files);
388254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson    }
389ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
390700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers    std::unique_ptr<CompilerDriver> driver(new CompilerDriver(compiler_options_,
39122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              verification_results_,
39222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              method_inliner_map_,
39322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              compiler_kind_,
39422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              instruction_set_,
39522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              instruction_set_features_,
39622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              image,
39722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              image_classes.release(),
39826318f722958ac1cba6a812026a1377f37c54941Andreas Gampe                                                              compiled_classes.release(),
39922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              thread_count_,
40022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              dump_stats,
40122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              dump_passes,
40222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              &compiler_phases_timings,
40362746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe                                                              swap_fd,
40422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                              profile_file));
4058b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien
406b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray    driver->GetCompiler()->SetBitcodeFileName(*driver.get(), bitcode_filename);
4078b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien
4083d504075f7c1204d581923460754bf6d3714b13fIan Rogers    driver->CompileAll(class_loader, dex_files, &timings);
40900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
410f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier    TimingLogger::ScopedTiming t2("dex2oat OatWriter", &timings);
41181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom    std::string image_file_location;
41228db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom    uint32_t image_file_location_oat_checksum = 0;
413ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers    uintptr_t image_file_location_oat_data_begin = 0;
414a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    int32_t image_patch_delta = 0;
4150aba0ba155bef7346bde19e53581200b89ae8a7aJeff Hao    if (!driver->IsImage()) {
416f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier      TimingLogger::ScopedTiming t3("Loading image checksum", &timings);
4171d54e73444e017d3a65234e0f193846f3e27472bIan Rogers      gc::space::ImageSpace* image_space = Runtime::Current()->GetHeap()->GetImageSpace();
41828db0129e5d7ef642cf8845c86c0e11832817085Brian Carlstrom      image_file_location_oat_checksum = image_space->GetImageHeader().GetOatChecksum();
41939ebcb800aabedd0ffa6aa4aeac8aa4194c66e61Ian Rogers      image_file_location_oat_data_begin =
420ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers          reinterpret_cast<uintptr_t>(image_space->GetImageHeader().GetOatDataBegin());
42181f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom      image_file_location = image_space->GetImageFilename();
422a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      image_patch_delta = image_space->GetImageHeader().GetPatchDelta();
42381f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom    }
42481f3ca17e9e8d360cc4a1b6c3155cf01ba3be3bcBrian Carlstrom
42522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe    if (!image_file_location.empty()) {
42622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe      key_value_store->Put(OatHeader::kImageLocationKey, image_file_location);
42722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe    }
42822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
429f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier    OatWriter oat_writer(dex_files, image_file_location_oat_checksum,
430c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom                         image_file_location_oat_data_begin,
431a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                         image_patch_delta,
432ca368cb576cf6a436a32c357fca51fbb3082d7a9Ian Rogers                         driver.get(),
43322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                         &timings,
43422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                         key_value_store);
435700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
436f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier    t2.NewTiming("Writing ELF");
4373d504075f7c1204d581923460754bf6d3714b13fIan Rogers    if (!driver->WriteElf(android_root, is_host, dex_files, &oat_writer, oat_file)) {
438700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      LOG(ERROR) << "Failed to write ELF file " << oat_file->GetPath();
439d97465c3742cc3c82843665f2678b881de29854bAndreas Gampe      oat_file->Erase();
4405131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      return nullptr;
441700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    }
442700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
443035592c51fee2995a3d90a9043f91a7a3128df2bAndreas Gampe    // Flush result to disk. Patching code will re-open the file (mmap), so ensure that our view
444035592c51fee2995a3d90a9043f91a7a3128df2bAndreas Gampe    // of the file already made it there and won't be re-ordered with writes from PatchOat or
445035592c51fee2995a3d90a9043f91a7a3128df2bAndreas Gampe    // image patching.
4469433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    if (oat_file->Flush() != 0) {
4479433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      PLOG(ERROR) << "Failed flushing oat file " << oat_file->GetPath();
4489433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      oat_file->Erase();
4499433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      return nullptr;
4509433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    }
451035592c51fee2995a3d90a9043f91a7a3128df2bAndreas Gampe
452a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    if (!driver->IsImage() && driver->GetCompilerOptions().GetIncludePatchInformation()) {
453a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      t2.NewTiming("Patching ELF");
454a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      std::string error_msg;
455a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      if (!PatchOatCode(driver.get(), oat_file, oat_location, &error_msg)) {
456a62a588a9202f69e53fbeb3045ea8ea5ec2587f8Jim_Guo        LOG(ERROR) << "Failed to fixup ELF file " << oat_file->GetPath() << ": " << error_msg;
457d97465c3742cc3c82843665f2678b881de29854bAndreas Gampe        oat_file->Erase();
458a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light        return nullptr;
459a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light      }
460a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light    }
461a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
4621212a022fa5f8ef9585d765b1809521812af882cIan Rogers    return driver.release();
463254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson  }
464ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
465a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  bool CreateImageFile(const std::string& image_filename,
466ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                       uintptr_t image_base,
467ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom                       const std::string& oat_filename,
468f582258f0e296223a091fd64231a203ad71e9649Brian Carlstrom                       const std::string& oat_location,
4691212a022fa5f8ef9585d765b1809521812af882cIan Rogers                       const CompilerDriver& compiler)
470b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      LOCKS_EXCLUDED(Locks::mutator_lock_) {
471700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    uintptr_t oat_data_begin;
472700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    {
473700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      // ImageWriter is scoped so it can free memory before doing FixupElf
47496391606d8adfc661e1c21703ded1e7a39377a76Brian Carlstrom      ImageWriter image_writer(compiler);
47590ca5c0301651101de0e363842e5d08ae65233f7Igor Murashkin      if (!image_writer.Write(image_filename, image_base, oat_filename, oat_location,
47690ca5c0301651101de0e363842e5d08ae65233f7Igor Murashkin                              compiler_options_->GetCompilePic())) {
477700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom        LOG(ERROR) << "Failed to create image file " << image_filename;
478700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom        return false;
479700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      }
480700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom      oat_data_begin = image_writer.GetOatDataBegin();
481700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom    }
482700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom
4839433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe
48490ca5c0301651101de0e363842e5d08ae65233f7Igor Murashkin    // Do not fix up the ELF file if we are --compile-pic
48590ca5c0301651101de0e363842e5d08ae65233f7Igor Murashkin    if (!compiler_options_->GetCompilePic()) {
4869433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      std::unique_ptr<File> oat_file(OS::OpenFileReadWrite(oat_filename.c_str()));
4879433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      if (oat_file.get() == nullptr) {
4889433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe        PLOG(ERROR) << "Failed to open ELF file: " << oat_filename;
4899433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe        return false;
4909433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      }
4919433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe
49290ca5c0301651101de0e363842e5d08ae65233f7Igor Murashkin      if (!ElfFixup::Fixup(oat_file.get(), oat_data_begin)) {
49390ca5c0301651101de0e363842e5d08ae65233f7Igor Murashkin        LOG(ERROR) << "Failed to fixup ELF file " << oat_file->GetPath();
4949433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe        oat_file->Erase();
4959433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe        return false;
4969433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      }
4979433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe
4989433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      if (oat_file->FlushCloseOrErase() != 0) {
4999433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe        PLOG(ERROR) << "Failed to flush and close patched oat file " << oat_filename;
50090ca5c0301651101de0e363842e5d08ae65233f7Igor Murashkin        return false;
50190ca5c0301651101de0e363842e5d08ae65233f7Igor Murashkin      }
502ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
50390ca5c0301651101de0e363842e5d08ae65233f7Igor Murashkin
504ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    return true;
505ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
506ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
507ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom private:
5086449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  explicit Dex2Oat(const CompilerOptions* compiler_options,
509b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray                   Compiler::Kind compiler_kind,
5104560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                   InstructionSet instruction_set,
5117020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison                   InstructionSetFeatures instruction_set_features,
5126449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                   VerificationResults* verification_results,
5136449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                   DexFileToMethodInlinerMap* method_inliner_map,
5140177fe200efc1bf4d433955ee7920c683fdf5901Brian Carlstrom                   size_t thread_count)
5156449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      : compiler_options_(compiler_options),
516b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray        compiler_kind_(compiler_kind),
517c531cefbfb5394413122e9f57d211ba436cff012buzbee        instruction_set_(instruction_set),
5187020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison        instruction_set_features_(instruction_set_features),
5196449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        verification_results_(verification_results),
5206449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        method_inliner_map_(method_inliner_map),
5212b5eaa2b49f7489bafdadc4b4463ae27e4261817Vladimir Marko        runtime_(nullptr),
522de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes        thread_count_(thread_count),
523de6e4cf1b63acd7032a52826d9df21ff649d7128Elliott Hughes        start_ns_(NanoTime()) {
5246449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    CHECK(compiler_options != nullptr);
5256449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    CHECK(verification_results != nullptr);
5266449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    CHECK(method_inliner_map != nullptr);
527bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  }
528ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
529e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers  bool CreateRuntime(const RuntimeOptions& runtime_options, InstructionSet instruction_set)
530b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers      SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_) {
5316449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    if (!Runtime::Create(runtime_options, false)) {
532ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      LOG(ERROR) << "Failed to create runtime";
53300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers      return false;
534ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
53500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    Runtime* runtime = Runtime::Current();
5367624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko    runtime->SetInstructionSet(instruction_set);
537ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
538ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i);
539ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (!runtime->HasCalleeSaveMethod(type)) {
5407624d25dad2d1ba25969ae704fccf68649103ae5Vladimir Marko        runtime->SetCalleeSaveMethod(runtime->CreateCalleeSaveMethod(type), type);
541ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
542ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
5431984651929744dd603fd082e23eacd877b9bc177Ian Rogers    runtime->GetClassLinker()->FixupDexCaches(runtime->GetResolutionMethod());
5444e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz    runtime->GetClassLinker()->RunRootClinits();
5452b5eaa2b49f7489bafdadc4b4463ae27e4261817Vladimir Marko    runtime_ = runtime;
54600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return true;
547ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
548ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
549ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // Appends to dex_files any elements of class_path that it doesn't already
550ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // contain. This will open those dex files as necessary.
5514560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  static void OpenClassPathFiles(const std::string& class_path,
5524560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                                 std::vector<const DexFile*>& dex_files) {
553ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    std::vector<std::string> parsed;
554ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    Split(class_path, ':', parsed);
55533e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers    // Take Locks::mutator_lock_ so that lock ordering on the ClassLinker::dex_lock_ is maintained.
55633e9566255c426e7a2c8fca5b8a1b6a94a5d352cIan Rogers    ScopedObjectAccess soa(Thread::Current());
557ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    for (size_t i = 0; i < parsed.size(); ++i) {
558ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (DexFilesContains(dex_files, parsed[i])) {
559ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        continue;
560ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
5618d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      std::string error_msg;
562833a48501d560c9fa7fc78ef619888138c2d374fAndreas Gampe      if (!DexFile::Open(parsed[i].c_str(), parsed[i].c_str(), &error_msg, &dex_files)) {
5638d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers        LOG(WARNING) << "Failed to open dex file '" << parsed[i] << "': " << error_msg;
564ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
565ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
566ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
567ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
568ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  // Returns true if dex_files has a dex with the named location.
5694560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  static bool DexFilesContains(const std::vector<const DexFile*>& dex_files,
5704560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom                               const std::string& location) {
571ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    for (size_t i = 0; i < dex_files.size(); ++i) {
572ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      if (dex_files[i]->GetLocation() == location) {
573ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom        return true;
574ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      }
575ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    }
576ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    return false;
577ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
578ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
579ae7083dac2db59dcdef869e35ac44a039d888ee9Brian Carlstrom  const CompilerOptions* const compiler_options_;
580b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray  const Compiler::Kind compiler_kind_;
581c531cefbfb5394413122e9f57d211ba436cff012buzbee
58249c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers  const InstructionSet instruction_set_;
5837020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  const InstructionSetFeatures instruction_set_features_;
584ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
585ae7083dac2db59dcdef869e35ac44a039d888ee9Brian Carlstrom  VerificationResults* const verification_results_;
586ae7083dac2db59dcdef869e35ac44a039d888ee9Brian Carlstrom  DexFileToMethodInlinerMap* const method_inliner_map_;
587bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  Runtime* runtime_;
5885523ee070b005576c6f889415205d49ea77cf243Elliott Hughes  size_t thread_count_;
589bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  uint64_t start_ns_;
590bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes
591ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  DISALLOW_IMPLICIT_CONSTRUCTORS(Dex2Oat);
592ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom};
593254db0ff7ea6509a1c2914b1d9532e2041a0c4c4Jesse Wilson
5943cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstromstatic size_t OpenDexFiles(const std::vector<const char*>& dex_filenames,
5953cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom                           const std::vector<const char*>& dex_locations,
5963cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom                           std::vector<const DexFile*>& dex_files) {
5973cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom  size_t failure_count = 0;
5985b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  for (size_t i = 0; i < dex_filenames.size(); i++) {
5995b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom    const char* dex_filename = dex_filenames[i];
600a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    const char* dex_location = dex_locations[i];
601740a11d0bfeaef36d910669844d01f3957dbe696Ian Rogers    ATRACE_BEGIN(StringPrintf("Opening dex file '%s'", dex_filenames[i]).c_str());
6028d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers    std::string error_msg;
603d5aba599561d8d14bb8c19fd633bfcd05af3c264Brian Carlstrom    if (!OS::FileExists(dex_filename)) {
604d5aba599561d8d14bb8c19fd633bfcd05af3c264Brian Carlstrom      LOG(WARNING) << "Skipping non-existent dex file '" << dex_filename << "'";
605d5aba599561d8d14bb8c19fd633bfcd05af3c264Brian Carlstrom      continue;
606d5aba599561d8d14bb8c19fd633bfcd05af3c264Brian Carlstrom    }
607833a48501d560c9fa7fc78ef619888138c2d374fAndreas Gampe    if (!DexFile::Open(dex_filename, dex_location, &error_msg, &dex_files)) {
6088d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      LOG(WARNING) << "Failed to open .dex from file '" << dex_filename << "': " << error_msg;
6093cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      ++failure_count;
6105b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom    }
611740a11d0bfeaef36d910669844d01f3957dbe696Ian Rogers    ATRACE_END();
6125b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom  }
6133cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom  return failure_count;
6145b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom}
6155b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom
616bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// The primary goal of the watchdog is to prevent stuck build servers
617bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// during development when fatal aborts lead to a cascade of failures
618bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom// that result in a deadlock.
619bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstromclass WatchDog {
620c1bfaa22570b4f771ae1cd832201b01ec84e32c1Brian Carlstrom// WatchDog defines its own CHECK_PTHREAD_CALL to avoid using LOG which uses locks
621bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#undef CHECK_PTHREAD_CALL
622bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#define CHECK_WATCH_DOG_PTHREAD_CALL(call, args, what) \
623bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  do { \
624bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    int rc = call args; \
625bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    if (rc != 0) { \
626bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      errno = rc; \
627bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      std::string message(# call); \
628bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      message += " failed for "; \
629bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      message += reason; \
630ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom      Fatal(message); \
631bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    } \
632bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  } while (false)
633bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
634bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom public:
63593ba893c20532990a430741e0a97212900094e8cBrian Carlstrom  explicit WatchDog(bool is_watch_dog_enabled) {
636994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    is_watch_dog_enabled_ = is_watch_dog_enabled;
637994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    if (!is_watch_dog_enabled_) {
638bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      return;
639bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    }
640bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    shutting_down_ = false;
641bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    const char* reason = "dex2oat watch dog thread startup";
6425131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_init, (&mutex_, nullptr), reason);
6435131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_init, (&cond_, nullptr), reason);
644bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_init, (&attr_), reason);
645bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_create, (&pthread_, &attr_, &CallBack, this), reason);
646bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_destroy, (&attr_), reason);
647bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
648bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  ~WatchDog() {
649994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    if (!is_watch_dog_enabled_) {
650bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      return;
651bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    }
652bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    const char* reason = "dex2oat watch dog thread shutdown";
653bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason);
654bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    shutting_down_ = true;
655bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_signal, (&cond_), reason);
656bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason);
657bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
6585131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_join, (pthread_, nullptr), reason);
659bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
660bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_destroy, (&cond_), reason);
661bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_destroy, (&mutex_), reason);
662bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
663bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
664bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom private:
665bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  static void* CallBack(void* arg) {
666bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    WatchDog* self = reinterpret_cast<WatchDog*>(arg);
6671d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    ::art::SetThreadName("dex2oat watch dog");
668bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    self->Wait();
6695131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    return nullptr;
670bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
671bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
672ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  static void Message(char severity, const std::string& message) {
6731d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    // TODO: Remove when we switch to LOG when we can guarantee it won't prevent shutdown in error
6741d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    //       cases.
675ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    fprintf(stderr, "dex2oat%s %c %d %d %s\n",
676ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            kIsDebugBuild ? "d" : "",
677ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            severity,
678ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            getpid(),
679ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            GetTid(),
680ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom            message.c_str());
681ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  }
682ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom
683ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  static void Fatal(const std::string& message) {
684ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    Message('F', message);
685bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    exit(1);
686bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
687bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
688bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  void Wait() {
6891d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    // TODO: tune the multiplier for GC verification, the following is just to make the timeout
6901d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    //       large.
6914e30541a92381fb280cd0be9a1763b713ee4d64cMathieu Chartier    int64_t multiplier = kVerifyObjectSupport > kVerifyObjectModeFast ? 100 : 1;
692ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom    timespec timeout_ts;
6931d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    InitTimeSpec(true, CLOCK_REALTIME, multiplier * kWatchDogTimeoutSeconds * 1000, 0, &timeout_ts);
694bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    const char* reason = "dex2oat watch dog thread waiting";
695bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason);
696bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    while (!shutting_down_) {
697c1bfaa22570b4f771ae1cd832201b01ec84e32c1Brian Carlstrom      int rc = TEMP_FAILURE_RETRY(pthread_cond_timedwait(&cond_, &mutex_, &timeout_ts));
698bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      if (rc == ETIMEDOUT) {
699c1bfaa22570b4f771ae1cd832201b01ec84e32c1Brian Carlstrom        Fatal(StringPrintf("dex2oat did not finish after %d seconds", kWatchDogTimeoutSeconds));
700eb5cb608fcb0d636961653ad561b2c7ee40de1adIan Rogers      } else if (rc != 0) {
701bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom        std::string message(StringPrintf("pthread_cond_timedwait failed: %s",
702bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom                                         strerror(errno)));
703ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom        Fatal(message.c_str());
704bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom      }
705bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    }
706bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom    CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason);
707bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  }
708bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
709ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom  // When setting timeouts, keep in mind that the build server may not be as fast as your desktop.
7100bff4f375d8013a4a59cf70b3427fb461a17e6deMathieu Chartier  // Debug builds are slower so they have larger timeouts.
7110bff4f375d8013a4a59cf70b3427fb461a17e6deMathieu Chartier  static const unsigned int kSlowdownFactor = kIsDebugBuild ? 5U : 1U;
712ed115647f6ae7cfb6c2c22a7aea33b5802b57a86Brian Carlstrom#if ART_USE_PORTABLE_COMPILER
7130bff4f375d8013a4a59cf70b3427fb461a17e6deMathieu Chartier  // 30 minutes scaled by kSlowdownFactor.
7140bff4f375d8013a4a59cf70b3427fb461a17e6deMathieu Chartier  static const unsigned int kWatchDogTimeoutSeconds = kSlowdownFactor * 30 * 60;
715bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#else
7160bff4f375d8013a4a59cf70b3427fb461a17e6deMathieu Chartier  // 6 minutes scaled by kSlowdownFactor.
7170bff4f375d8013a4a59cf70b3427fb461a17e6deMathieu Chartier  static const unsigned int kWatchDogTimeoutSeconds = kSlowdownFactor * 6 * 60;
718bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom#endif
719bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
720994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  bool is_watch_dog_enabled_;
721bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  bool shutting_down_;
7221d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  // TODO: Switch to Mutex when we can guarantee it won't prevent shutdown in error cases.
723bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_mutex_t mutex_;
724bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_cond_t cond_;
725bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_attr_t attr_;
726bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom  pthread_t pthread_;
727bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom};
7281c653d545058a1a850fb6d07d74e607fa1ddf48eIan Rogersconst unsigned int WatchDog::kWatchDogTimeoutSeconds;
729bcc2926b9721f94c17ed98fae5264cc98f0e066fBrian Carlstrom
7307020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison// Given a set of instruction features from the build, parse it.  The
7317020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison// input 'str' is a comma separated list of feature names.  Parse it and
7327020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison// return the InstructionSetFeatures object.
7337020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allisonstatic InstructionSetFeatures ParseFeatureList(std::string str) {
7347020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  InstructionSetFeatures result;
7357020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  typedef std::vector<std::string> FeatureList;
7367020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  FeatureList features;
7377020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  Split(str, ',', features);
7387020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  for (FeatureList::iterator i = features.begin(); i != features.end(); i++) {
7397020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    std::string feature = Trim(*i);
7407020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    if (feature == "default") {
7417020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      // Nothing to do.
7427020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    } else if (feature == "div") {
7437020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      // Supports divide instruction.
7447020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison       result.SetHasDivideInstruction(true);
7457020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    } else if (feature == "nodiv") {
7467020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      // Turn off support for divide instruction.
7477020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      result.SetHasDivideInstruction(false);
748674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko    } else if (feature == "lpae") {
749674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko      // Supports Large Physical Address Extension.
750674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko      result.SetHasLpae(true);
751674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko    } else if (feature == "nolpae") {
752674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko      // Turn off support for Large Physical Address Extension.
753674744e635ddbdfb311fbd25b5a27356560d30c3Vladimir Marko      result.SetHasLpae(false);
7547020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    } else {
7557020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      Usage("Unknown instruction set feature: '%s'", feature.c_str());
7567020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    }
7577020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  }
7587020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  // others...
7597020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  return result;
7607020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison}
7617020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
762c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravlevoid ParseStringAfterChar(const std::string& s, char c, std::string* parsed_value) {
763c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  std::string::size_type colon = s.find(c);
764c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  if (colon == std::string::npos) {
765c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    Usage("Missing char %c in option %s\n", c, s.c_str());
766c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  }
767c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  // Add one to remove the char we were trimming until.
768c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  *parsed_value = s.substr(colon + 1);
769c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle}
770c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle
771c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravlevoid ParseDouble(const std::string& option, char after_char,
772c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle                 double min, double max, double* parsed_value) {
773c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  std::string substring;
774c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  ParseStringAfterChar(option, after_char, &substring);
775c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  bool sane_val = true;
776c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  double value;
777c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  if (false) {
778c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    // TODO: this doesn't seem to work on the emulator.  b/15114595
779c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    std::stringstream iss(substring);
780c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    iss >> value;
781c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    // Ensure that we have a value, there was no cruft after it and it satisfies a sensible range.
782c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    sane_val = iss.eof() && (value >= min) && (value <= max);
783c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  } else {
784c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    char* end = nullptr;
785c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    value = strtod(substring.c_str(), &end);
786c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    sane_val = *end == '\0' && value >= min && value <= max;
787c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  }
788c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  if (!sane_val) {
789c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    Usage("Invalid double value %s for option %s\n", substring.c_str(), option.c_str());
790c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  }
791c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  *parsed_value = value;
792c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle}
793c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle
794d7392faea80acb5d73a027bb384e3222bc2c2e43Andreas Gampestatic void b13564922() {
795f94b781745e715463482695e22addfa95198b548Vladimir Marko#if defined(__linux__) && defined(__arm__)
796f94b781745e715463482695e22addfa95198b548Vladimir Marko  int major, minor;
797f94b781745e715463482695e22addfa95198b548Vladimir Marko  struct utsname uts;
798f94b781745e715463482695e22addfa95198b548Vladimir Marko  if (uname(&uts) != -1 &&
799f94b781745e715463482695e22addfa95198b548Vladimir Marko      sscanf(uts.release, "%d.%d", &major, &minor) == 2 &&
800f94b781745e715463482695e22addfa95198b548Vladimir Marko      ((major < 3) || ((major == 3) && (minor < 4)))) {
801f94b781745e715463482695e22addfa95198b548Vladimir Marko    // Kernels before 3.4 don't handle the ASLR well and we can run out of address
802f94b781745e715463482695e22addfa95198b548Vladimir Marko    // space (http://b/13564922). Work around the issue by inhibiting further mmap() randomization.
803f94b781745e715463482695e22addfa95198b548Vladimir Marko    int old_personality = personality(0xffffffff);
804f94b781745e715463482695e22addfa95198b548Vladimir Marko    if ((old_personality & ADDR_NO_RANDOMIZE) == 0) {
805f94b781745e715463482695e22addfa95198b548Vladimir Marko      int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE);
806f94b781745e715463482695e22addfa95198b548Vladimir Marko      if (new_personality == -1) {
807f94b781745e715463482695e22addfa95198b548Vladimir Marko        LOG(WARNING) << "personality(. | ADDR_NO_RANDOMIZE) failed.";
808f94b781745e715463482695e22addfa95198b548Vladimir Marko      }
809f94b781745e715463482695e22addfa95198b548Vladimir Marko    }
810f94b781745e715463482695e22addfa95198b548Vladimir Marko  }
811f94b781745e715463482695e22addfa95198b548Vladimir Marko#endif
812d7392faea80acb5d73a027bb384e3222bc2c2e43Andreas Gampe}
813d7392faea80acb5d73a027bb384e3222bc2c2e43Andreas Gampe
81462746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampestatic constexpr size_t kMinDexFilesForSwap = 2;
81562746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampestatic constexpr size_t kMinDexFileCumulativeSizeForSwap = 20 * MB;
81662746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe
81762746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampestatic bool UseSwap(bool is_image, std::vector<const DexFile*>& dex_files) {
81862746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  if (is_image) {
81962746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    // Don't use swap, we know generation should succeed, and we don't want to slow it down.
82062746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    return false;
82162746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  }
82262746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  if (dex_files.size() < kMinDexFilesForSwap) {
82362746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    // If there are less dex files than the threshold, assume it's gonna be fine.
82462746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    return false;
82562746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  }
82662746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  size_t dex_files_size = 0;
82762746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  for (const auto* dex_file : dex_files) {
82862746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    dex_files_size += dex_file->GetHeader().file_size_;
82962746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  }
83062746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  return dex_files_size >= kMinDexFileCumulativeSizeForSwap;
83162746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe}
83262746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe
833d7392faea80acb5d73a027bb384e3222bc2c2e43Andreas Gampestatic int dex2oat(int argc, char** argv) {
834d7392faea80acb5d73a027bb384e3222bc2c2e43Andreas Gampe  b13564922();
835f94b781745e715463482695e22addfa95198b548Vladimir Marko
8366449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  original_argc = argc;
8376449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  original_argv = argv;
8386449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
8395fe9af720048673e62ee29597a30bb9e54c903c5Ian Rogers  TimingLogger timings("compiler", false, false);
840ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray  CumulativeLogger compiler_phases_timings("compilation times");
8414560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom
8420d39c12238499ca9ccc34d1532c443335e7c1044Elliott Hughes  InitLogging(argv);
84372395bf298b7707ad9d93c3e51b57e1b8e010311Elliott Hughes
84469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  // Skip over argv[0].
84569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  argv++;
84669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  argc--;
84769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
84869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  if (argc == 0) {
849e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom    Usage("No arguments specified");
85069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
85169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
85269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  std::vector<const char*> dex_filenames;
853a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::vector<const char*> dex_locations;
854a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  int zip_fd = -1;
855a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::string zip_location;
856e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  std::string oat_filename;
857265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  std::string oat_symbols;
858a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::string oat_location;
859a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  int oat_fd = -1;
8608b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien  std::string bitcode_filename;
8615131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  const char* image_classes_zip_filename = nullptr;
8625131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  const char* image_classes_filename = nullptr;
86326318f722958ac1cba6a812026a1377f37c54941Andreas Gampe  const char* compiled_classes_zip_filename = nullptr;
86426318f722958ac1cba6a812026a1377f37c54941Andreas Gampe  const char* compiled_classes_filename = nullptr;
865a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::string image_filename;
866b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  std::string boot_image_filename;
86769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  uintptr_t image_base = 0;
8683f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  std::string android_root;
8695d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao  std::vector<const char*> runtime_args;
8705c599943f8c347acd84c4d9fda56a9df70649b78Elliott Hughes  int thread_count = sysconf(_SC_NPROCESSORS_CONF);
871b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray  Compiler::Kind compiler_kind = kUsePortableCompiler
872b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray      ? Compiler::kPortable
873b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray      : Compiler::kQuick;
8745131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  const char* compiler_filter_string = nullptr;
875643b5df2b065ccf5bb19a183573da691e9d0311fIgor Murashkin  bool compile_pic = false;
8766449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int huge_method_threshold = CompilerOptions::kDefaultHugeMethodThreshold;
8776449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int large_method_threshold = CompilerOptions::kDefaultLargeMethodThreshold;
8786449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int small_method_threshold = CompilerOptions::kDefaultSmallMethodThreshold;
8796449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int tiny_method_threshold = CompilerOptions::kDefaultTinyMethodThreshold;
8806449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  int num_dex_methods_threshold = CompilerOptions::kDefaultNumDexMethodsThreshold;
8817020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
8821bd2ceb3a8c68ae6ea1f9627b588a7bc7a74487fBrian Carlstrom  // Take the default set of instruction features from the build.
8837020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison  InstructionSetFeatures instruction_set_features =
8848afeb85d3def12b559b7565fb6d3956f81b55132Ian Rogers      ParseFeatureList(Runtime::GetDefaultInstructionSetFeatures());
8857020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
88691268c1afd6c0d4fad55b7c86d907233d4660205Andreas Gampe  InstructionSet instruction_set = kRuntimeISA;
8877020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
88839c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison  // Profile file to use
88939c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison  std::string profile_file;
890c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle  double top_k_profile_threshold = CompilerOptions::kDefaultTopKProfileThreshold;
8917020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison
892265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  bool is_host = false;
893e732ef1c0192acd71925bd0ff1ab09640d45531dIan Rogers  bool dump_stats = false;
89446398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers  bool dump_timing = false;
895ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray  bool dump_passes = false;
89653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  bool include_patch_information = CompilerOptions::kDefaultIncludePatchInformation;
89778382fa44ee505cf16835e4d22515e7252a90864Alex Light  bool include_debug_symbols = kIsDebugBuild;
89846398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers  bool dump_slow_timing = kIsDebugBuild;
899b28a16147f5b3503d9ca9e95ff56bdeb449e17d6Andreas Gampe  bool watch_dog_enabled = true;
900ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell  bool generate_gdb_information = kIsDebugBuild;
901161928613d3f097108319de60494fab1aab8d48aBrian Carlstrom
90269dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison  // Checks are all explicit until we know the architecture.
90369dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison  bool implicit_null_checks = false;
90469dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison  bool implicit_so_checks = false;
90569dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison  bool implicit_suspend_checks = false;
9065655e84e8d71697d8ef3ea901a0b853af42c559eAndreas Gampe
90762746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  // Swap file.
90862746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  std::string swap_file_name;
90962746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  int swap_fd = -1;  // No swap file descriptor;
91062746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe
91169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  for (int i = 0; i < argc; i++) {
91269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    const StringPiece option(argv[i]);
913b9beb2e2efb6a204a69ca660d478b45f851e8f09Ian Rogers    const bool log_options = false;
914a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    if (log_options) {
915b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom      LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i];
916b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom    }
91769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    if (option.starts_with("--dex-file=")) {
91869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      dex_filenames.push_back(option.substr(strlen("--dex-file=")).data());
919a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    } else if (option.starts_with("--dex-location=")) {
920a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      dex_locations.push_back(option.substr(strlen("--dex-location=")).data());
921a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else if (option.starts_with("--zip-fd=")) {
922a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      const char* zip_fd_str = option.substr(strlen("--zip-fd=")).data();
923bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes      if (!ParseInt(zip_fd_str, &zip_fd)) {
924e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom        Usage("Failed to parse --zip-fd argument '%s' as an integer", zip_fd_str);
925a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
9266449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (zip_fd < 0) {
9276449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--zip-fd passed a negative value %d", zip_fd);
9286449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
929a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    } else if (option.starts_with("--zip-location=")) {
930a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      zip_location = option.substr(strlen("--zip-location=")).data();
931a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else if (option.starts_with("--oat-file=")) {
932a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      oat_filename = option.substr(strlen("--oat-file=")).data();
933265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    } else if (option.starts_with("--oat-symbols=")) {
934265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      oat_symbols = option.substr(strlen("--oat-symbols=")).data();
935a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else if (option.starts_with("--oat-fd=")) {
936a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      const char* oat_fd_str = option.substr(strlen("--oat-fd=")).data();
937bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes      if (!ParseInt(oat_fd_str, &oat_fd)) {
938e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom        Usage("Failed to parse --oat-fd argument '%s' as an integer", oat_fd_str);
939a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
9406449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (oat_fd < 0) {
9416449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--oat-fd passed a negative value %d", oat_fd);
9426449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
943994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    } else if (option == "--watch-dog") {
944994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom      watch_dog_enabled = true;
945994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom    } else if (option == "--no-watch-dog") {
946994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom      watch_dog_enabled = false;
947ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell    } else if (option == "--gen-gdb-info") {
948ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell      generate_gdb_information = true;
9493470ab4011b5e18d590d5375e2f13a1e3bd69222Alex Light      // Debug symbols are needed for gdb information.
9503470ab4011b5e18d590d5375e2f13a1e3bd69222Alex Light      include_debug_symbols = true;
951ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell    } else if (option == "--no-gen-gdb-info") {
952ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell      generate_gdb_information = false;
9535523ee070b005576c6f889415205d49ea77cf243Elliott Hughes    } else if (option.starts_with("-j")) {
954b12552a95d68b9e4a567103190074ae47b6a61dcBrian Carlstrom      const char* thread_count_str = option.substr(strlen("-j")).data();
9555523ee070b005576c6f889415205d49ea77cf243Elliott Hughes      if (!ParseInt(thread_count_str, &thread_count)) {
956e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom        Usage("Failed to parse -j argument '%s' as an integer", thread_count_str);
9575523ee070b005576c6f889415205d49ea77cf243Elliott Hughes      }
958a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    } else if (option.starts_with("--oat-location=")) {
959a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      oat_location = option.substr(strlen("--oat-location=")).data();
9608b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien    } else if (option.starts_with("--bitcode=")) {
9618b977d38483aaa08abcbdaa5fa888076c1142169Logan Chien      bitcode_filename = option.substr(strlen("--bitcode=")).data();
96269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    } else if (option.starts_with("--image=")) {
96369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      image_filename = option.substr(strlen("--image=")).data();
964ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom    } else if (option.starts_with("--image-classes=")) {
965ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      image_classes_filename = option.substr(strlen("--image-classes=")).data();
9664922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    } else if (option.starts_with("--image-classes-zip=")) {
9674922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      image_classes_zip_filename = option.substr(strlen("--image-classes-zip=")).data();
96826318f722958ac1cba6a812026a1377f37c54941Andreas Gampe    } else if (option.starts_with("--compiled-classes=")) {
96926318f722958ac1cba6a812026a1377f37c54941Andreas Gampe      compiled_classes_filename = option.substr(strlen("--compiled-classes=")).data();
97026318f722958ac1cba6a812026a1377f37c54941Andreas Gampe    } else if (option.starts_with("--compiled-classes-zip=")) {
97126318f722958ac1cba6a812026a1377f37c54941Andreas Gampe      compiled_classes_zip_filename = option.substr(strlen("--compiled-classes-zip=")).data();
97269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    } else if (option.starts_with("--base=")) {
97369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      const char* image_base_str = option.substr(strlen("--base=")).data();
97469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      char* end;
97569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      image_base = strtoul(image_base_str, &end, 16);
97669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      if (end == image_base_str || *end != '\0') {
977cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom        Usage("Failed to parse hexadecimal value for option %s", option.data());
97869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom      }
979e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom    } else if (option.starts_with("--boot-image=")) {
980b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom      boot_image_filename = option.substr(strlen("--boot-image=")).data();
9813f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    } else if (option.starts_with("--android-root=")) {
9823f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom      android_root = option.substr(strlen("--android-root=")).data();
98349c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers    } else if (option.starts_with("--instruction-set=")) {
98449c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers      StringPiece instruction_set_str = option.substr(strlen("--instruction-set=")).data();
9851f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao      if (instruction_set_str == "arm") {
98649c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        instruction_set = kThumb2;
987b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith      } else if (instruction_set_str == "arm64") {
988b95a5345ae4217b70ca36f0cced92f68dda7caf5Stuart Monteith        instruction_set = kArm64;
9891f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao      } else if (instruction_set_str == "mips") {
99049c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        instruction_set = kMips;
9911f71ae819e506c40ad5adccec4b2e57699e0b5c4jeffhao      } else if (instruction_set_str == "x86") {
99249c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers        instruction_set = kX86;
993ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers      } else if (instruction_set_str == "x86_64") {
994ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers        instruction_set = kX86_64;
99549c4894f76f6a7aec4d6a1ec2c901700c9108944Ian Rogers      }
9967020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison    } else if (option.starts_with("--instruction-set-features=")) {
9977020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      StringPiece str = option.substr(strlen("--instruction-set-features=")).data();
9987020278bce98a0735dc6abcbd33bdf1ed2634f1dDave Allison      instruction_set_features = ParseFeatureList(str.as_string());
999c531cefbfb5394413122e9f57d211ba436cff012buzbee    } else if (option.starts_with("--compiler-backend=")) {
1000c531cefbfb5394413122e9f57d211ba436cff012buzbee      StringPiece backend_str = option.substr(strlen("--compiler-backend=")).data();
1001c531cefbfb5394413122e9f57d211ba436cff012buzbee      if (backend_str == "Quick") {
1002b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray        compiler_kind = Compiler::kQuick;
1003b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray      } else if (backend_str == "Optimizing") {
1004b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray        compiler_kind = Compiler::kOptimizing;
1005c531cefbfb5394413122e9f57d211ba436cff012buzbee      } else if (backend_str == "Portable") {
1006b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray        compiler_kind = Compiler::kPortable;
1007c531cefbfb5394413122e9f57d211ba436cff012buzbee      }
10086449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--compiler-filter=")) {
10096449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      compiler_filter_string = option.substr(strlen("--compiler-filter=")).data();
1010643b5df2b065ccf5bb19a183573da691e9d0311fIgor Murashkin    } else if (option == "--compile-pic") {
1011643b5df2b065ccf5bb19a183573da691e9d0311fIgor Murashkin      compile_pic = true;
10126449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--huge-method-max=")) {
10136449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--huge-method-max=")).data();
10146449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &huge_method_threshold)) {
10156449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --huge-method-max '%s' as an integer", threshold);
10166449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
10176449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (huge_method_threshold < 0) {
10186449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--huge-method-max passed a negative value %s", huge_method_threshold);
10196449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
10206449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--large-method-max=")) {
10216449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--large-method-max=")).data();
10226449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &large_method_threshold)) {
10236449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --large-method-max '%s' as an integer", threshold);
10246449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
10256449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (large_method_threshold < 0) {
10266449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--large-method-max passed a negative value %s", large_method_threshold);
10276449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
10286449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--small-method-max=")) {
10296449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--small-method-max=")).data();
10306449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &small_method_threshold)) {
10316449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --small-method-max '%s' as an integer", threshold);
10326449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
10336449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (small_method_threshold < 0) {
10346449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--small-method-max passed a negative value %s", small_method_threshold);
10356449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
10366449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--tiny-method-max=")) {
10376449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--tiny-method-max=")).data();
10386449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &tiny_method_threshold)) {
10396449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --tiny-method-max '%s' as an integer", threshold);
10406449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
10416449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (tiny_method_threshold < 0) {
10426449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--tiny-method-max passed a negative value %s", tiny_method_threshold);
10436449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
10446449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else if (option.starts_with("--num-dex-methods=")) {
10456449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      const char* threshold = option.substr(strlen("--num-dex-methods=")).data();
10466449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (!ParseInt(threshold, &num_dex_methods_threshold)) {
10476449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("Failed to parse --num-dex-methods '%s' as an integer", threshold);
10486449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
10496449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      if (num_dex_methods_threshold < 0) {
10506449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom        Usage("--num-dex-methods passed a negative value %s", num_dex_methods_threshold);
10516449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      }
1052265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    } else if (option == "--host") {
1053265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      is_host = true;
10545d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao    } else if (option == "--runtime-arg") {
10555d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao      if (++i >= argc) {
1056cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom        Usage("Missing required argument for --runtime-arg");
10575d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao      }
1058a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      if (log_options) {
1059a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom        LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i];
1060a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
10615d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao      runtime_args.push_back(argv[i]);
106246398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers    } else if (option == "--dump-timing") {
106346398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers      dump_timing = true;
1064ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray    } else if (option == "--dump-passes") {
1065ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray      dump_passes = true;
1066e732ef1c0192acd71925bd0ff1ab09640d45531dIan Rogers    } else if (option == "--dump-stats") {
1067e732ef1c0192acd71925bd0ff1ab09640d45531dIan Rogers      dump_stats = true;
106878382fa44ee505cf16835e4d22515e7252a90864Alex Light    } else if (option == "--include-debug-symbols" || option == "--no-strip-symbols") {
106978382fa44ee505cf16835e4d22515e7252a90864Alex Light      include_debug_symbols = true;
107078382fa44ee505cf16835e4d22515e7252a90864Alex Light    } else if (option == "--no-include-debug-symbols" || option == "--strip-symbols") {
107178382fa44ee505cf16835e4d22515e7252a90864Alex Light      include_debug_symbols = false;
1072afa6b8e93a0dc0de33c9d404945c7c5621e20b1aAndreas Gampe      generate_gdb_information = false;  // Depends on debug symbols, see above.
107339c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison    } else if (option.starts_with("--profile-file=")) {
107439c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison      profile_file = option.substr(strlen("--profile-file=")).data();
107539c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison      VLOG(compiler) << "dex2oat: profile file is " << profile_file;
107639c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison    } else if (option == "--no-profile-file") {
107739c3bfbd03d85c63cfbe69f17ce5800ccc7d6c13Dave Allison      // No profile
1078c1b643cc6ac45dbd0eabdcd7425c7e86006c27d6Calin Juravle    } else if (option.starts_with("--top-k-profile-threshold=")) {
107944c5ee7a14bde25207032ac7c2427e8629b8ff42Calin Juravle      ParseDouble(option.data(), '=', 0.0, 100.0, &top_k_profile_threshold);
1080cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu    } else if (option == "--print-pass-names") {
10812469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler      PassDriverMEOpts::PrintPassNames();
1082cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu    } else if (option.starts_with("--disable-passes=")) {
1083cd8ce66a83af05d5ecb59aa6a8aad89a29e0a844Chao-ying Fu      std::string disable_passes = option.substr(strlen("--disable-passes=")).data();
10842469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler      PassDriverMEOpts::CreateDefaultPassList(disable_passes);
10858bceccec7eddff8cd872aa20505b4a3a6be60a16Jean Christophe Beyler    } else if (option.starts_with("--print-passes=")) {
10868bceccec7eddff8cd872aa20505b4a3a6be60a16Jean Christophe Beyler      std::string print_passes = option.substr(strlen("--print-passes=")).data();
10872469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler      PassDriverMEOpts::SetPrintPassList(print_passes);
10888bceccec7eddff8cd872aa20505b4a3a6be60a16Jean Christophe Beyler    } else if (option == "--print-all-passes") {
10892469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler      PassDriverMEOpts::SetPrintAllPasses();
10908bceccec7eddff8cd872aa20505b4a3a6be60a16Jean Christophe Beyler    } else if (option.starts_with("--dump-cfg-passes=")) {
10918bceccec7eddff8cd872aa20505b4a3a6be60a16Jean Christophe Beyler      std::string dump_passes = option.substr(strlen("--dump-cfg-passes=")).data();
10922469e60e6ff08c2a0b4cd1e209246c5d91027679Jean Christophe Beyler      PassDriverMEOpts::SetDumpPassList(dump_passes);
109353cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option == "--include-patch-information") {
109453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      include_patch_information = true;
109553cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light    } else if (option == "--no-include-patch-information") {
109653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light      include_patch_information = false;
109762746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    } else if (option.starts_with("--swap-file=")) {
109862746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      swap_file_name = option.substr(strlen("--swap-file=")).data();
109962746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    } else if (option.starts_with("--swap-fd=")) {
110062746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      const char* swap_fd_str = option.substr(strlen("--swap-fd=")).data();
110162746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      if (!ParseInt(swap_fd_str, &swap_fd)) {
110262746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe        Usage("Failed to parse --swap-fd argument '%s' as an integer", swap_fd_str);
110362746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      }
110462746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      if (swap_fd < 0) {
110562746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe        Usage("--swap-fd passed a negative value %d", swap_fd);
110662746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      }
110769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    } else {
1108e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom      Usage("Unknown argument %s", option.data());
110969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    }
111069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
111169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
1112a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (oat_filename.empty() && oat_fd == -1) {
1113cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("Output must be supplied with either --oat-file or --oat-fd");
1114a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1115a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1116a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (!oat_filename.empty() && oat_fd != -1) {
1117cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--oat-file should not be used with --oat-fd");
1118a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1119a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1120265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (!oat_symbols.empty() && oat_fd != -1) {
1121265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    Usage("--oat-symbols should not be used with --oat-fd");
1122265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  }
1123265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
1124265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (!oat_symbols.empty() && is_host) {
1125265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    Usage("--oat-symbols should not be used with --host");
1126a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1127a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1128a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (oat_fd != -1 && !image_filename.empty()) {
1129cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--oat-fd should not be used with --image");
1130e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  }
1131e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
11323f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  if (android_root.empty()) {
11333f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    const char* android_root_env_var = getenv("ANDROID_ROOT");
11345131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    if (android_root_env_var == nullptr) {
113554d22c2bb47da44ef586b9de94749d5648178a26Brian Carlstrom      Usage("--android-root unspecified and ANDROID_ROOT not set");
11363f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    }
11373f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom    android_root += android_root_env_var;
11383f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom  }
11393f47c12487250f61f3be95e9f275e3b08e2c49fbBrian Carlstrom
1140a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  bool image = (!image_filename.empty());
1141b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  if (!image && boot_image_filename.empty()) {
1142887235845e203fce046c17120e86d4cac4c56035Ian Rogers    boot_image_filename += android_root;
11433ac05bba3eadccb33d26b41d9797f63e8378125fBrian Carlstrom    boot_image_filename += "/framework/boot.art";
1144b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  }
1145b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom  std::string boot_image_option;
1146a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (!boot_image_filename.empty()) {
1147b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom    boot_image_option += "-Ximage:";
1148b001126eb9e47d0088b3672652454c53f4e17e9fBrian Carlstrom    boot_image_option += boot_image_filename;
114969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
115069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
11515131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (image_classes_filename != nullptr && !image) {
1152cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--image-classes should only be used with --image");
1153ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom  }
1154ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom
11555131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (image_classes_filename != nullptr && !boot_image_option.empty()) {
1156cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--image-classes should not be used with --boot-image");
115778128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom  }
115878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom
11595131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (image_classes_zip_filename != nullptr && image_classes_filename == nullptr) {
11604922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    Usage("--image-classes-zip should be used with --image-classes");
11614922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom  }
11624922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom
116326318f722958ac1cba6a812026a1377f37c54941Andreas Gampe  if (compiled_classes_filename != nullptr && !image) {
116426318f722958ac1cba6a812026a1377f37c54941Andreas Gampe    Usage("--compiled-classes should only be used with --image");
116526318f722958ac1cba6a812026a1377f37c54941Andreas Gampe  }
116626318f722958ac1cba6a812026a1377f37c54941Andreas Gampe
116726318f722958ac1cba6a812026a1377f37c54941Andreas Gampe  if (compiled_classes_filename != nullptr && !boot_image_option.empty()) {
116826318f722958ac1cba6a812026a1377f37c54941Andreas Gampe    Usage("--compiled-classes should not be used with --boot-image");
116926318f722958ac1cba6a812026a1377f37c54941Andreas Gampe  }
117026318f722958ac1cba6a812026a1377f37c54941Andreas Gampe
117126318f722958ac1cba6a812026a1377f37c54941Andreas Gampe  if (compiled_classes_zip_filename != nullptr && compiled_classes_filename == nullptr) {
117226318f722958ac1cba6a812026a1377f37c54941Andreas Gampe    Usage("--compiled-classes-zip should be used with --compiled-classes");
117326318f722958ac1cba6a812026a1377f37c54941Andreas Gampe  }
117426318f722958ac1cba6a812026a1377f37c54941Andreas Gampe
1175a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (dex_filenames.empty() && zip_fd == -1) {
1176cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("Input must be supplied with either --dex-file or --zip-fd");
1177a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1178a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1179a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (!dex_filenames.empty() && zip_fd != -1) {
1180cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--dex-file should not be used with --zip-fd");
1181a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1182a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1183a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (!dex_filenames.empty() && !zip_location.empty()) {
1184cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--dex-file should not be used with --zip-location");
1185a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1186a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1187a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (dex_locations.empty()) {
1188a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    for (size_t i = 0; i < dex_filenames.size(); i++) {
1189a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      dex_locations.push_back(dex_filenames[i]);
1190a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    }
1191a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  } else if (dex_locations.size() != dex_filenames.size()) {
1192cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--dex-location arguments do not match --dex-file arguments");
1193a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  }
1194a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom
1195a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  if (zip_fd != -1 && zip_location.empty()) {
1196cbfe6fea382328cd5a0a9906b61da5ed4ae3eaabBrian Carlstrom    Usage("--zip-location should be supplied with --zip-fd");
1197a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
1198a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
119969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  if (boot_image_option.empty()) {
120069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    if (image_base == 0) {
1201e0948e13d5a4552e6a2728087573c07961e4a4f9Brian Carlstrom      Usage("Non-zero --base not specified");
120269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    }
120369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
120469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
1205265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  std::string oat_stripped(oat_filename);
1206265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  std::string oat_unstripped;
1207265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (!oat_symbols.empty()) {
1208265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    oat_unstripped += oat_symbols;
1209265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  } else {
1210265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    oat_unstripped += oat_filename;
1211265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  }
1212265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
12135131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (compiler_filter_string == nullptr) {
12142db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung    if (instruction_set == kMips64) {
12152db3e269e3051dacb3c8a4af8f03fdad9b0fd740Douglas Leung      // TODO: fix compiler for Mips64.
1216befbd5731ecca08f08780ee28a913d08ffb14656Ian Rogers      compiler_filter_string = "interpret-only";
1217befbd5731ecca08f08780ee28a913d08ffb14656Ian Rogers    } else if (image) {
12185e754d88c73f1f1fafbbf87d564df000d5a0a12cBrian Carlstrom      compiler_filter_string = "speed";
12196449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    } else {
12206449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#if ART_SMALL_MODE
12216449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      compiler_filter_string = "interpret-only";
12226449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#else
12236449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom      compiler_filter_string = "speed";
12246449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#endif
12256449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    }
12266449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  }
12276449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  CHECK(compiler_filter_string != nullptr);
12286449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  CompilerOptions::CompilerFilter compiler_filter = CompilerOptions::kDefaultCompilerFilter;
12294a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  if (strcmp(compiler_filter_string, "verify-none") == 0) {
12304a200f56b7075309316b04d550c9cc50f8314eddJeff Hao    compiler_filter = CompilerOptions::kVerifyNone;
12314a200f56b7075309316b04d550c9cc50f8314eddJeff Hao  } else if (strcmp(compiler_filter_string, "interpret-only") == 0) {
12326449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kInterpretOnly;
12336449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else if (strcmp(compiler_filter_string, "space") == 0) {
12346449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kSpace;
12356449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else if (strcmp(compiler_filter_string, "balanced") == 0) {
12366449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kBalanced;
12376449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else if (strcmp(compiler_filter_string, "speed") == 0) {
12386449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kSpeed;
12396449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else if (strcmp(compiler_filter_string, "everything") == 0) {
12406449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    compiler_filter = CompilerOptions::kEverything;
12416449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  } else {
12426449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    Usage("Unknown --compiler-filter value %s", compiler_filter_string);
12436449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  }
12446449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
124569dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison  // Set the compilation target's implicit checks options.
124669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison  switch (instruction_set) {
124769dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison    case kArm:
124869dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison    case kThumb2:
12497204c04dd86ae8ce05690e38737b2abf017a0a69Stuart Monteith    case kArm64:
125069dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison    case kX86:
1251b0f05b9654eb005bc8c8e15f615a7f5a312f640cDave Allison    case kX86_64:
125269dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison      implicit_null_checks = true;
125369dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison      implicit_so_checks = true;
125469dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison      break;
125569dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison
125669dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison    default:
125769dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison      // Defaults are correct.
125869dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison      break;
125969dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison  }
126069dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison
126122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  std::unique_ptr<CompilerOptions> compiler_options(new CompilerOptions(compiler_filter,
126222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        huge_method_threshold,
126322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        large_method_threshold,
126422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        small_method_threshold,
126522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        tiny_method_threshold,
126622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        num_dex_methods_threshold,
126722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        generate_gdb_information,
126822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        include_patch_information,
126922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        top_k_profile_threshold,
127022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        include_debug_symbols,
127169dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison                                                                        implicit_null_checks,
127269dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison                                                                        implicit_so_checks,
1273643b5df2b065ccf5bb19a183573da691e9d0311fIgor Murashkin                                                                        implicit_suspend_checks,
1274643b5df2b065ccf5bb19a183573da691e9d0311fIgor Murashkin                                                                        compile_pic
12756449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#ifdef ART_SEA_IR_MODE
127622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        , compiler_options.sea_ir_ =
127722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                              true;
12786449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom#endif
127922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  ));  // NOLINT(whitespace/parens)
12806449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom
1281994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  // Done with usage checks, enable watchdog if requested
1282994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom  WatchDog watch_dog(watch_dog_enabled);
1283994d62a359188354de6ad01699b2ae6698db16f9Brian Carlstrom
12846ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom  // Check early that the result of compilation can be written
1285700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<File> oat_file;
1286265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  bool create_file = !oat_unstripped.empty();  // as opposed to using open file descriptor
12876cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom  if (create_file) {
12887571e8b761ebc2c923525e12ea9fcf07e62cb33eBrian Carlstrom    oat_file.reset(OS::CreateEmptyFile(oat_unstripped.c_str()));
1289a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    if (oat_location.empty()) {
1290a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom      oat_location = oat_filename;
1291a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    }
1292a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  } else {
12939433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    oat_file.reset(new File(oat_fd, oat_location, true));
1294761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes    oat_file->DisableAutoClose();
12959433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    if (oat_file->SetLength(0)) {  // Only warn for truncation error.
12969433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      PLOG(WARNING) << "Truncating oat file " << oat_location << " failed.";
12979433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    }
1298a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
12995131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (oat_file.get() == nullptr) {
13006cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom    PLOG(ERROR) << "Failed to create oat file: " << oat_location;
13016cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom    return EXIT_FAILURE;
13026cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom  }
13036cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom  if (create_file && fchmod(oat_file->Fd(), 0644) != 0) {
13046cd40e5cc59259a0b7636eb5532c76de9b8a7286Brian Carlstrom    PLOG(ERROR) << "Failed to make oat file world readable: " << oat_location;
1305d97465c3742cc3c82843665f2678b881de29854bAndreas Gampe    oat_file->Erase();
13066ef827a33b04fd5413d2ad88fd4599ca1920c824Brian Carlstrom    return EXIT_FAILURE;
1307234da578a2d91ed7f2ef47b2ec23fb0033e2746bElliott Hughes  }
1308a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
130962746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  // Swap file handling.
131062746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  //
131162746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  // If the swap fd is not -1, we assume this is the file descriptor of an open but unlinked file
131262746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  // that we can use for swap.
131362746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  //
131462746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  // If the swap fd is -1 and we have a swap-file string, open the given file as a swap file. We
131562746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  // will immediately unlink to satisfy the swap fd assumption.
131662746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  std::unique_ptr<File> swap_file;
131762746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  if (swap_fd == -1 && !swap_file_name.empty()) {
131862746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    swap_file.reset(OS::CreateEmptyFile(swap_file_name.c_str()));
131962746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    if (swap_file.get() == nullptr) {
132062746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      PLOG(ERROR) << "Failed to create swap file: " << swap_file_name;
132162746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      return EXIT_FAILURE;
132262746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    }
132362746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    swap_fd = swap_file->Fd();
132462746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    swap_file->MarkUnchecked();  // We don't we to track this, it will be unlinked immediately.
132562746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    unlink(swap_file_name.c_str());
132662746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  }
132762746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe
1328f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier  timings.StartTiming("dex2oat Setup");
132909881a85579cab1779ddf6ba9a91eed861a13cb2Brian Carlstrom  LOG(INFO) << CommandLine();
13305e863ddd72a70d33525f7403a695f7bc1c218938Ian Rogers
1331e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers  RuntimeOptions runtime_options;
1332a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom  std::vector<const DexFile*> boot_class_path;
1333c54e12a413e16f90526318f1f466a900a717fbb0Mathieu Chartier  art::MemMap::Init();  // For ZipEntry::ExtractToMemMap.
133469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  if (boot_image_option.empty()) {
13353cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom    size_t failure_count = OpenDexFiles(dex_filenames, dex_locations, boot_class_path);
13363cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom    if (failure_count > 0) {
13373cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      LOG(ERROR) << "Failed to open some dex files: " << failure_count;
1338d97465c3742cc3c82843665f2678b881de29854bAndreas Gampe      oat_file->Erase();
13393cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      return EXIT_FAILURE;
13403cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom    }
13416449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom    runtime_options.push_back(std::make_pair("bootclasspath", &boot_class_path));
134269b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  } else {
13435131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    runtime_options.push_back(std::make_pair(boot_image_option.c_str(), nullptr));
134469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
13455d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao  for (size_t i = 0; i < runtime_args.size(); i++) {
13465131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root    runtime_options.push_back(std::make_pair(runtime_args[i], nullptr));
13475d84040e2231de1d48e6f30cab2cc8d4beb8effejeffhao  }
134869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
134922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  std::unique_ptr<VerificationResults> verification_results(new VerificationResults(
135069dfe51b684dd9d510dbcb63295fe180f998efdeDave Allison                                                            compiler_options.get()));
13516449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  DexFileToMethodInlinerMap method_inliner_map;
1352e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers  QuickCompilerCallbacks callbacks(verification_results.get(), &method_inliner_map);
13536449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  runtime_options.push_back(std::make_pair("compilercallbacks", &callbacks));
135411d9f06a96a6909905c248ed684366190140095cNarayan Kamath  runtime_options.push_back(
135511d9f06a96a6909905c248ed684366190140095cNarayan Kamath      std::make_pair("imageinstructionset",
135611d9f06a96a6909905c248ed684366190140095cNarayan Kamath                     reinterpret_cast<const void*>(GetInstructionSetString(instruction_set))));
13577467ee05012e1fd9834df74663c1ebda46f5636bDragos Sbirlea
135862746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  if (swap_fd != -1) {
135962746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    // Swap file indicates low-memory mode. Use GC.
136062746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    runtime_options.push_back(std::make_pair("-Xgc:MS", nullptr));
136162746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  }
136262746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe
136300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  Dex2Oat* p_dex2oat;
13646449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  if (!Dex2Oat::Create(&p_dex2oat,
13656449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       runtime_options,
136622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                       *compiler_options,
1367b34f69ab43aaf7a6e6045c95f398baf566ef5023Nicolas Geoffray                       compiler_kind,
13686449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       instruction_set,
13696449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       instruction_set_features,
137022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                       verification_results.get(),
13716449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       &method_inliner_map,
13726449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                       thread_count)) {
137300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    LOG(ERROR) << "Failed to create dex2oat";
1374f0cb1eb5b2020c3c527aca3ff458801b90b5e06cAndreas Gampe    timings.EndTiming();
1375d97465c3742cc3c82843665f2678b881de29854bAndreas Gampe    oat_file->Erase();
137600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return EXIT_FAILURE;
137700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
1378700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<Dex2Oat> dex2oat(p_dex2oat);
13795655e84e8d71697d8ef3ea901a0b853af42c559eAndreas Gampe
138000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start,
13813f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers  // give it away now so that we don't starve GC.
13823f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers  Thread* self = Thread::Current();
13833f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers  self->TransitionFromRunnableToSuspended(kNative);
13840f40ac31134d9ae0f059d4c448165599dc8459c1Ian Rogers  // If we're doing the image, override the compiler filter to force full compilation. Must be
1385fe9ca4028f379688ecba6132ac3738171176b3e4buzbee  // done ahead of WellKnownClasses::Init that causes verification.  Note: doesn't force
1386fe9ca4028f379688ecba6132ac3738171176b3e4buzbee  // compilation of class initializers.
138700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Whilst we're in native take the opportunity to initialize well known classes.
13883f3d22c8fc89d754172858d1770f16916b407d8bIan Rogers  WellKnownClasses::Init(self->GetJniEnv());
138969b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
1390bb551fa68ffc57f679b8c914ac856666f0348b77Elliott Hughes  // If --image-classes was specified, calculate the full list of classes to include in the image
1391cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers  std::unique_ptr<std::set<std::string>> image_classes(nullptr);
1392d5185344e19d9feb7ac268369e0af6a467d1cb48Kenny Root  if (image_classes_filename != nullptr) {
13938d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers    std::string error_msg;
1394d5185344e19d9feb7ac268369e0af6a467d1cb48Kenny Root    if (image_classes_zip_filename != nullptr) {
13954922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      image_classes.reset(dex2oat->ReadImageClassesFromZip(image_classes_zip_filename,
13968d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                           image_classes_filename,
13978d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                           &error_msg));
13984922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    } else {
13994922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom      image_classes.reset(dex2oat->ReadImageClassesFromFile(image_classes_filename));
14004922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom    }
1401d5185344e19d9feb7ac268369e0af6a467d1cb48Kenny Root    if (image_classes.get() == nullptr) {
14028d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      LOG(ERROR) << "Failed to create list of image classes from '" << image_classes_filename <<
14038d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers          "': " << error_msg;
1404f0cb1eb5b2020c3c527aca3ff458801b90b5e06cAndreas Gampe      timings.EndTiming();
1405d97465c3742cc3c82843665f2678b881de29854bAndreas Gampe      oat_file->Erase();
1406ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom      return EXIT_FAILURE;
140769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom    }
1408d5185344e19d9feb7ac268369e0af6a467d1cb48Kenny Root  } else if (image) {
1409cb6b0f31ede2275e79e6199ec391147585a37a2aIan Rogers    image_classes.reset(new std::set<std::string>);
141069b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
141126318f722958ac1cba6a812026a1377f37c54941Andreas Gampe  // If --compiled-classes was specified, calculate the full list of classes to compile in the
141226318f722958ac1cba6a812026a1377f37c54941Andreas Gampe  // image.
141326318f722958ac1cba6a812026a1377f37c54941Andreas Gampe  std::unique_ptr<std::set<std::string>> compiled_classes(nullptr);
141426318f722958ac1cba6a812026a1377f37c54941Andreas Gampe  if (compiled_classes_filename != nullptr) {
141526318f722958ac1cba6a812026a1377f37c54941Andreas Gampe    std::string error_msg;
141626318f722958ac1cba6a812026a1377f37c54941Andreas Gampe    if (compiled_classes_zip_filename != nullptr) {
141726318f722958ac1cba6a812026a1377f37c54941Andreas Gampe      compiled_classes.reset(dex2oat->ReadImageClassesFromZip(compiled_classes_zip_filename,
141826318f722958ac1cba6a812026a1377f37c54941Andreas Gampe                                                              compiled_classes_filename,
141926318f722958ac1cba6a812026a1377f37c54941Andreas Gampe                                                              &error_msg));
142026318f722958ac1cba6a812026a1377f37c54941Andreas Gampe    } else {
142126318f722958ac1cba6a812026a1377f37c54941Andreas Gampe      compiled_classes.reset(dex2oat->ReadImageClassesFromFile(compiled_classes_filename));
142226318f722958ac1cba6a812026a1377f37c54941Andreas Gampe    }
142326318f722958ac1cba6a812026a1377f37c54941Andreas Gampe    if (compiled_classes.get() == nullptr) {
142426318f722958ac1cba6a812026a1377f37c54941Andreas Gampe      LOG(ERROR) << "Failed to create list of compiled classes from '" << compiled_classes_filename
142526318f722958ac1cba6a812026a1377f37c54941Andreas Gampe                 << "': " << error_msg;
142626318f722958ac1cba6a812026a1377f37c54941Andreas Gampe      timings.EndTiming();
1427d97465c3742cc3c82843665f2678b881de29854bAndreas Gampe      oat_file->Erase();
142826318f722958ac1cba6a812026a1377f37c54941Andreas Gampe      return EXIT_FAILURE;
142926318f722958ac1cba6a812026a1377f37c54941Andreas Gampe    }
143026318f722958ac1cba6a812026a1377f37c54941Andreas Gampe  } else if (image) {
143126318f722958ac1cba6a812026a1377f37c54941Andreas Gampe    compiled_classes.reset(nullptr);  // By default compile everything.
143226318f722958ac1cba6a812026a1377f37c54941Andreas Gampe  }
143369b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
1434a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  std::vector<const DexFile*> dex_files;
1435a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  if (boot_image_option.empty()) {
1436a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    dex_files = Runtime::Current()->GetClassLinker()->GetBootClassPath();
1437a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  } else {
1438a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    if (dex_filenames.empty()) {
1439740a11d0bfeaef36d910669844d01f3957dbe696Ian Rogers      ATRACE_BEGIN("Opening zip archive from file descriptor");
14408d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers      std::string error_msg;
1441700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers      std::unique_ptr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(zip_fd, zip_location.c_str(),
14428d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers                                                               &error_msg));
14435131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      if (zip_archive.get() == nullptr) {
14448d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers        LOG(ERROR) << "Failed to open zip from file descriptor for '" << zip_location << "': "
14458d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers            << error_msg;
1446f0cb1eb5b2020c3c527aca3ff458801b90b5e06cAndreas Gampe        timings.EndTiming();
1447d97465c3742cc3c82843665f2678b881de29854bAndreas Gampe        oat_file->Erase();
14482e3d1b262af0839380e1d60e86d8b281943ef944Brian Carlstrom        return EXIT_FAILURE;
1449a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
1450833a48501d560c9fa7fc78ef619888138c2d374fAndreas Gampe      if (!DexFile::OpenFromZip(*zip_archive.get(), zip_location, &error_msg, &dex_files)) {
14518d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers        LOG(ERROR) << "Failed to open dex from file descriptor for zip file '" << zip_location
14528d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers            << "': " << error_msg;
1453f0cb1eb5b2020c3c527aca3ff458801b90b5e06cAndreas Gampe        timings.EndTiming();
1454d97465c3742cc3c82843665f2678b881de29854bAndreas Gampe        oat_file->Erase();
1455a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom        return EXIT_FAILURE;
1456a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom      }
1457740a11d0bfeaef36d910669844d01f3957dbe696Ian Rogers      ATRACE_END();
1458a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    } else {
14593cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      size_t failure_count = OpenDexFiles(dex_filenames, dex_locations, dex_files);
14603cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      if (failure_count > 0) {
14613cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom        LOG(ERROR) << "Failed to open some dex files: " << failure_count;
1462f0cb1eb5b2020c3c527aca3ff458801b90b5e06cAndreas Gampe        timings.EndTiming();
1463d97465c3742cc3c82843665f2678b881de29854bAndreas Gampe        oat_file->Erase();
14643cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom        return EXIT_FAILURE;
14653cf59d567072562e120b9524f47ad2bd373f8333Brian Carlstrom      }
1466a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom    }
1467d76e08323893c60df77eccca6e882279e7246d8cBrian Carlstrom
1468f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom    const bool kSaveDexInput = false;
1469f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom    if (kSaveDexInput) {
1470f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom      for (size_t i = 0; i < dex_files.size(); ++i) {
1471f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom        const DexFile* dex_file = dex_files[i];
14725180cc1cddc5112ea544bf9d8323f1d27db56f75Ian Rogers        std::string tmp_file_name(StringPrintf("/data/local/tmp/dex2oat.%d.%zd.dex", getpid(), i));
1473700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers        std::unique_ptr<File> tmp_file(OS::CreateEmptyFile(tmp_file_name.c_str()));
1474f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom        if (tmp_file.get() == nullptr) {
14756449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom            PLOG(ERROR) << "Failed to open file " << tmp_file_name
14766449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom                        << ". Try: adb shell chmod 777 /data/local/tmp";
1477f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom            continue;
1478f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom        }
14799433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe        // This is just dumping files for debugging. Ignore errors, and leave remnants.
14809433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe        UNUSED(tmp_file->WriteFully(dex_file->Begin(), dex_file->Size()));
14819433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe        UNUSED(tmp_file->Flush());
14829433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe        UNUSED(tmp_file->Close());
1483f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom        LOG(INFO) << "Wrote input to " << tmp_file_name;
1484f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom      }
1485f79fccbf8b5e59a0f48bec754cb7a53877b3c90fBrian Carlstrom    }
14862ec6520d57479d393bffa05defa1479b25ca8382Brian Carlstrom  }
14872ec6520d57479d393bffa05defa1479b25ca8382Brian Carlstrom  // Ensure opened dex files are writable for dex-to-dex transformations.
14882ec6520d57479d393bffa05defa1479b25ca8382Brian Carlstrom  for (const auto& dex_file : dex_files) {
14892ec6520d57479d393bffa05defa1479b25ca8382Brian Carlstrom    if (!dex_file->EnableWrite()) {
14902ec6520d57479d393bffa05defa1479b25ca8382Brian Carlstrom      PLOG(ERROR) << "Failed to make .dex file writeable '" << dex_file->GetLocation() << "'\n";
1491d76e08323893c60df77eccca6e882279e7246d8cBrian Carlstrom    }
1492a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom  }
149362746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  // If we use a swap file, ensure we are above the threshold to make it necessary.
149462746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  if (swap_fd != -1) {
149562746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    if (!UseSwap(image, dex_files)) {
149662746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      close(swap_fd);
149762746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      swap_fd = -1;
149862746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      LOG(INFO) << "Decided to run without swap.";
149962746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    } else {
150062746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe      LOG(INFO) << "Accepted running with swap.";
150162746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe    }
150262746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe  }
1503a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom
1504a024a0686c3b0fea13f362bff70d65981e5febc5buzbee  /*
15054a200f56b7075309316b04d550c9cc50f8314eddJeff Hao   * If we're not in interpret-only or verify-none mode, go ahead and compile small applications.
15064a200f56b7075309316b04d550c9cc50f8314eddJeff Hao   * Don't bother to check if we're doing the image.
1507a024a0686c3b0fea13f362bff70d65981e5febc5buzbee   */
150822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  if (!image && compiler_options->IsCompilationEnabled()) {
15098447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum    size_t num_methods = 0;
15108447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum    for (size_t i = 0; i != dex_files.size(); ++i) {
15118447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum      const DexFile* dex_file = dex_files[i];
15125131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root      CHECK(dex_file != nullptr);
15138447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum      num_methods += dex_file->NumMethodIds();
15148447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum    }
151522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe    if (num_methods <= compiler_options->GetNumDexMethodsThreshold()) {
151622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe      compiler_options->SetCompilerFilter(CompilerOptions::kSpeed);
151775a43f10f55e2aa550de51e969cc1e60d583b632Anwar Ghuloum      VLOG(compiler) << "Below method threshold, compiling anyways";
15188447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum    }
15198447d84d847d4562d7a7bce62768c27e7d20a9aaAnwar Ghuloum  }
1520c4f105d75cd0cbc5145620068bbb8a819148e535Anwar Ghuloum
152122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  // Fill some values into the key-value store for the oat header.
152222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  std::unique_ptr<SafeMap<std::string, std::string> > key_value_store(
152322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe      new SafeMap<std::string, std::string>());
152422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
152522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  // Insert some compiler things.
1526d7392faea80acb5d73a027bb384e3222bc2c2e43Andreas Gampe  {
1527d7392faea80acb5d73a027bb384e3222bc2c2e43Andreas Gampe    std::ostringstream oss;
1528d7392faea80acb5d73a027bb384e3222bc2c2e43Andreas Gampe    for (int i = 0; i < argc; ++i) {
1529d7392faea80acb5d73a027bb384e3222bc2c2e43Andreas Gampe      if (i > 0) {
1530d7392faea80acb5d73a027bb384e3222bc2c2e43Andreas Gampe        oss << ' ';
1531d7392faea80acb5d73a027bb384e3222bc2c2e43Andreas Gampe      }
1532d7392faea80acb5d73a027bb384e3222bc2c2e43Andreas Gampe      oss << argv[i];
153322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe    }
1534d7392faea80acb5d73a027bb384e3222bc2c2e43Andreas Gampe    key_value_store->Put(OatHeader::kDex2OatCmdLineKey, oss.str());
1535d7392faea80acb5d73a027bb384e3222bc2c2e43Andreas Gampe    oss.str("");  // Reset.
1536d7392faea80acb5d73a027bb384e3222bc2c2e43Andreas Gampe    oss << kRuntimeISA;
1537d7392faea80acb5d73a027bb384e3222bc2c2e43Andreas Gampe    key_value_store->Put(OatHeader::kDex2OatHostKey, oss.str());
1538d7392faea80acb5d73a027bb384e3222bc2c2e43Andreas Gampe    key_value_store->Put(OatHeader::kPicKey, compile_pic ? "true" : "false");
153922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  }
154022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
1541700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<const CompilerDriver> compiler(dex2oat->CreateOatFile(boot_image_option,
154222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        android_root,
154322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        is_host,
154422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        dex_files,
154522f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        oat_file.get(),
1546a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                                                                        oat_location,
154722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        bitcode_filename,
154822f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        image,
154922f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        image_classes,
155026318f722958ac1cba6a812026a1377f37c54941Andreas Gampe                                                                        compiled_classes,
155122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        dump_stats,
155222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        dump_passes,
155322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        timings,
155422f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        compiler_phases_timings,
155562746d8d9c4400e4764f162b22bfb1a32be287a9Andreas Gampe                                                                        swap_fd,
155622f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        profile_file,
155722f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe                                                                        key_value_store.get()));
15585131638f826b74c4e2af62b8ac70eeef1232c99bKenny Root  if (compiler.get() == nullptr) {
1559a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom    LOG(ERROR) << "Failed to create oat file: " << oat_location;
1560f0cb1eb5b2020c3c527aca3ff458801b90b5e06cAndreas Gampe    timings.EndTiming();
1561e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom    return EXIT_FAILURE;
1562e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom  }
1563e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom
15649433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  if (!kUsePortableCompiler) {
15659433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    if (oat_file->FlushCloseOrErase() != 0) {
15669433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      PLOG(ERROR) << "Failed to flush and close oat file: " << oat_location;
15679433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      timings.EndTiming();
15689433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      return EXIT_FAILURE;
15699433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    }
15709433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    oat_file.reset();
15719433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  }
1572aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom
15739433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  VLOG(compiler) << "Oat file written successfully (unstripped): " << oat_location;
1574700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // Notes on the interleaving of creating the image and oat file to
1575700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // ensure the references between the two are correct.
1576700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1577700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // Currently we have a memory layout that looks something like this:
1578700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1579700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // +--------------+
1580700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // | image        |
1581700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // +--------------+
1582700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // | boot oat     |
1583700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // +--------------+
1584700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // | alloc spaces |
1585700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // +--------------+
1586700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
15874560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  // There are several constraints on the loading of the image and boot.oat.
1588700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1589700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 1. The image is expected to be loaded at an absolute address and
1590700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // contains Objects with absolute pointers within the image.
1591700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1592700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 2. There are absolute pointers from Methods in the image to their
1593700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // code in the oat.
1594700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1595700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 3. There are absolute pointers from the code in the oat to Methods
1596700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // in the image.
1597700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1598700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 4. There are absolute pointers from code in the oat to other code
1599700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // in the oat.
1600700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1601700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // To get this all correct, we go through several steps.
1602700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1603700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 1. We have already created that oat file above with
1604700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // CreateOatFile. Originally this was just our own proprietary file
16054560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  // but now it is contained within an ELF dynamic object (aka an .so
1606700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // file). The Compiler returned by CreateOatFile provides
1607700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // PatchInformation for references to oat code and Methods that need
1608700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // to be update once we know where the oat file will be located
1609700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // after the image.
1610700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1611700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 2. We create the image file. It needs to know where the oat file
1612700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // will be loaded after itself. Originally when oat file was simply
1613700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // memory mapped so we could predict where its contents were based
1614700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // on the file size. Now that it is an ELF file, we need to inspect
1615700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // the ELF file to understand the in memory segment layout including
1616a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  // where the oat header is located within. ElfPatcher's Patch method
1617a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  // uses the PatchInformation from the Compiler to touch up absolute
1618a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  // references in the oat file.
1619700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1620700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // 3. We fixup the ELF program headers so that dlopen will try to
1621700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // load the .so at the desired location at runtime by offsetting the
1622700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  // Elf32_Phdr.p_vaddr values by the desired base address.
1623700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom  //
1624265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (image) {
1625f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier    TimingLogger::ScopedTiming t("dex2oat ImageWriter", &timings);
1626265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    bool image_creation_success = dex2oat->CreateImageFile(image_filename,
1627265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                                                           image_base,
1628265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                                                           oat_unstripped,
1629265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                                                           oat_location,
1630265091e581c9f643b37e7966890911f09e223269Brian Carlstrom                                                           *compiler.get());
1631265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    if (!image_creation_success) {
1632f0cb1eb5b2020c3c527aca3ff458801b90b5e06cAndreas Gampe      timings.EndTiming();
1633265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      return EXIT_FAILURE;
1634265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    }
163575a43f10f55e2aa550de51e969cc1e60d583b632Anwar Ghuloum    VLOG(compiler) << "Image written successfully: " << image_filename;
1636265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  }
1637265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
1638265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (is_host) {
1639f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier    timings.EndTiming();
164046398608eaa47afe5a4cfb91e3f43211bf937d68Ian Rogers    if (dump_timing || (dump_slow_timing && timings.GetTotalNs() > MsToNs(1000))) {
16415fe9af720048673e62ee29597a30bb9e54c903c5Ian Rogers      LOG(INFO) << Dumpable<TimingLogger>(timings);
16424560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom    }
1643ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray    if (dump_passes) {
16443d504075f7c1204d581923460754bf6d3714b13fIan Rogers      LOG(INFO) << Dumpable<CumulativeLogger>(*compiler.get()->GetTimingsLogger());
1645ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray    }
1646265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    return EXIT_SUCCESS;
164769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  }
164869b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
1649265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // If we don't want to strip in place, copy from unstripped location to stripped location.
1650265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  // We need to strip after image creation because FixupElf needs to use .strtab.
1651265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  if (oat_unstripped != oat_stripped) {
1652f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier    TimingLogger::ScopedTiming t("dex2oat OatFile copy", &timings);
16539433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    if (kUsePortableCompiler) {
16549433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      if (oat_file->FlushCloseOrErase() != 0) {
16559433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe        PLOG(ERROR) << "Failed to flush and close oat file: " << oat_location;
16569433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe        return EXIT_FAILURE;
16579433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      }
16589433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      oat_file.reset();
16599433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    }
16609433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    std::unique_ptr<File> in(OS::OpenFileForReading(oat_unstripped.c_str()));
1661700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers    std::unique_ptr<File> out(OS::CreateEmptyFile(oat_stripped.c_str()));
1662265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    size_t buffer_size = 8192;
1663700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers    std::unique_ptr<uint8_t> buffer(new uint8_t[buffer_size]);
1664265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    while (true) {
1665265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      int bytes_read = TEMP_FAILURE_RETRY(read(in->Fd(), buffer.get(), buffer_size));
1666265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      if (bytes_read <= 0) {
1667265091e581c9f643b37e7966890911f09e223269Brian Carlstrom        break;
1668265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      }
1669265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      bool write_ok = out->WriteFully(buffer.get(), bytes_read);
1670265091e581c9f643b37e7966890911f09e223269Brian Carlstrom      CHECK(write_ok);
1671265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    }
1672265091e581c9f643b37e7966890911f09e223269Brian Carlstrom    oat_file.reset(out.release());
167375a43f10f55e2aa550de51e969cc1e60d583b632Anwar Ghuloum    VLOG(compiler) << "Oat file copied successfully (stripped): " << oat_stripped;
1674265091e581c9f643b37e7966890911f09e223269Brian Carlstrom  }
1675265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
16769433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  if (kUsePortableCompiler) {
16779433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    if (!compiler_options->GetIncludeDebugSymbols()) {
16789433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      timings.NewTiming("dex2oat ElfStripper");
16799433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      // Strip unneeded sections for target
16809433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      off_t seek_actual = lseek(oat_file->Fd(), 0, SEEK_SET);
16819433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      CHECK_EQ(0, seek_actual);
16829433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      std::string error_msg;
16839433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      CHECK(ElfStripper::Strip(oat_file.get(), &error_msg)) << error_msg;
16846f28d91aab952e3244fbb4e707fa38f85538f374Anwar Ghuloum
1685265091e581c9f643b37e7966890911f09e223269Brian Carlstrom
16869433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      // We wrote the oat file successfully, and want to keep it.
16879433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      VLOG(compiler) << "Oat file written successfully (stripped): " << oat_location;
16889433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    } else {
16899433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      VLOG(compiler) << "Oat file written successfully without stripping: " << oat_location;
16909433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    }
16919433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    if (oat_file->FlushCloseOrErase() != 0) {
16929433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      LOG(ERROR) << "Failed to flush and close oat file: " << oat_location;
16939433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      return EXIT_FAILURE;
16949433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    }
16959433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    oat_file.reset(nullptr);
16969433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  }
16979433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe
16989433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe  if (oat_file.get() != nullptr) {
16999433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    if (oat_file->FlushCloseOrErase() != 0) {
17009433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      PLOG(ERROR) << "Failed to flush and close oat file: " << oat_location << "/" << oat_filename;
17019433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe      return EXIT_FAILURE;
17029433ec60b325b708b9fa87e699ab4a6565741494Andreas Gampe    }
170378382fa44ee505cf16835e4d22515e7252a90864Alex Light  }
17044560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom
1705f5997b4d3f889569d5a2b724d83d764bfbb8d106Mathieu Chartier  timings.EndTiming();
17066f28d91aab952e3244fbb4e707fa38f85538f374Anwar Ghuloum
1707c6dfdacea2fd9e268f70328805b0366cdd6b7b9eBrian Carlstrom  if (dump_timing || (dump_slow_timing && timings.GetTotalNs() > MsToNs(1000))) {
17085fe9af720048673e62ee29597a30bb9e54c903c5Ian Rogers    LOG(INFO) << Dumpable<TimingLogger>(timings);
17094560248d4c85cade7f4fc7b30c3fb41b95a04a7fBrian Carlstrom  }
1710ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray  if (dump_passes) {
1711ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray    LOG(INFO) << Dumpable<CumulativeLogger>(compiler_phases_timings);
1712ea3fa0b4ba13d7bd7f7c1cd85202ccbe141a35aeNicolas Geoffray  }
17132672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers
17143029df6d212894647ba0e5c23443c40912c6ecc8Mathieu Chartier  dex2oat->LogCompletionTime(compiler.get());
17152672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers  // Everything was successfully written, do an explicit exit here to avoid running Runtime
17162672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers  // destructors that take time (bug 10645725) unless we're a debug build or running on valgrind.
17176449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom  if (!kIsDebugBuild && (RUNNING_ON_VALGRIND == 0)) {
17182672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers    exit(EXIT_SUCCESS);
17192672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers  }
17202672a9f93caa66add6ca48a8e38ba1661ef43959Ian Rogers
172169b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  return EXIT_SUCCESS;
17226449c62e40ef3a9bb75f664f922555affb532ee4Brian Carlstrom}  // NOLINT(readability/fn_size)
17237934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom}  // namespace art
172469b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom
172569b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstromint main(int argc, char** argv) {
172669b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom  return art::dex2oat(argc, argv);
172769b15fb098162f19a4c20e6dccdcead04d9c77f0Brian Carlstrom}
1728