dex2oat.cc revision 6e73272f093e9dc045c08baae57eebb5dcd6e044
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 */ 1610037c866b04550fc5461058c398c2e3e509381ajeffhao 1710037c866b04550fc5461058c398c2e3e509381ajeffhao#include <stdio.h> 1810037c866b04550fc5461058c398c2e3e509381ajeffhao#include <stdlib.h> 1992572be7f754c213e615a62955cc5f65ca8c0c0eNarayan Kamath#include <sys/stat.h> 20700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <valgrind.h> 2192572be7f754c213e615a62955cc5f65ca8c0c0eNarayan Kamath 22e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include <fstream> 234f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include <iostream> 2410037c866b04550fc5461058c398c2e3e509381ajeffhao#include <sstream> 25a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include <string> 26a67249065e4c9b3cf4a7c081d95a78df28291ee9Ian Rogers#include <vector> 272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 2810037c866b04550fc5461058c398c2e3e509381ajeffhao#if defined(__linux__) && defined(__arm__) 2910037c866b04550fc5461058c398c2e3e509381ajeffhao#include <sys/personality.h> 3010037c866b04550fc5461058c398c2e3e509381ajeffhao#include <sys/utsname.h> 3110037c866b04550fc5461058c398c2e3e509381ajeffhao#endif 3210037c866b04550fc5461058c398c2e3e509381ajeffhao 3310037c866b04550fc5461058c398c2e3e509381ajeffhao#define ATRACE_TAG ATRACE_TAG_DALVIK 3410037c866b04550fc5461058c398c2e3e509381ajeffhao#include <cutils/trace.h> 3510037c866b04550fc5461058c398c2e3e509381ajeffhao 3610037c866b04550fc5461058c398c2e3e509381ajeffhao#include "arch/instruction_set_features.h" 3710037c866b04550fc5461058c398c2e3e509381ajeffhao#include "base/dumpable.h" 3810037c866b04550fc5461058c398c2e3e509381ajeffhao#include "base/stl_util.h" 3910037c866b04550fc5461058c398c2e3e509381ajeffhao#include "base/stringpiece.h" 4010037c866b04550fc5461058c398c2e3e509381ajeffhao#include "base/timing_logger.h" 4110037c866b04550fc5461058c398c2e3e509381ajeffhao#include "base/unix_file/fd_file.h" 4210037c866b04550fc5461058c398c2e3e509381ajeffhao#include "class_linker.h" 4310037c866b04550fc5461058c398c2e3e509381ajeffhao#include "compiler.h" 4410037c866b04550fc5461058c398c2e3e509381ajeffhao#include "compiler_callbacks.h" 4510037c866b04550fc5461058c398c2e3e509381ajeffhao#include "dex_file-inl.h" 4610037c866b04550fc5461058c398c2e3e509381ajeffhao#include "dex/pass_driver_me_opts.h" 4710037c866b04550fc5461058c398c2e3e509381ajeffhao#include "dex/verification_results.h" 4810037c866b04550fc5461058c398c2e3e509381ajeffhao#include "dex/quick_compiler_callbacks.h" 4910037c866b04550fc5461058c398c2e3e509381ajeffhao#include "dex/quick/dex_file_to_method_inliner_map.h" 5010037c866b04550fc5461058c398c2e3e509381ajeffhao#include "driver/compiler_driver.h" 5110037c866b04550fc5461058c398c2e3e509381ajeffhao#include "driver/compiler_options.h" 5210037c866b04550fc5461058c398c2e3e509381ajeffhao#include "elf_file.h" 5310037c866b04550fc5461058c398c2e3e509381ajeffhao#include "elf_writer.h" 5410037c866b04550fc5461058c398c2e3e509381ajeffhao#include "gc/space/image_space.h" 5510037c866b04550fc5461058c398c2e3e509381ajeffhao#include "gc/space/space-inl.h" 5610037c866b04550fc5461058c398c2e3e509381ajeffhao#include "image_writer.h" 5710037c866b04550fc5461058c398c2e3e509381ajeffhao#include "leb128.h" 5810037c866b04550fc5461058c398c2e3e509381ajeffhao#include "mirror/art_method-inl.h" 5910037c866b04550fc5461058c398c2e3e509381ajeffhao#include "mirror/class-inl.h" 6010037c866b04550fc5461058c398c2e3e509381ajeffhao#include "mirror/class_loader.h" 6110037c866b04550fc5461058c398c2e3e509381ajeffhao#include "mirror/object-inl.h" 6210037c866b04550fc5461058c398c2e3e509381ajeffhao#include "mirror/object_array-inl.h" 6310037c866b04550fc5461058c398c2e3e509381ajeffhao#include "oat_writer.h" 6410037c866b04550fc5461058c398c2e3e509381ajeffhao#include "os.h" 6510037c866b04550fc5461058c398c2e3e509381ajeffhao#include "runtime.h" 6610037c866b04550fc5461058c398c2e3e509381ajeffhao#include "ScopedLocalRef.h" 6710037c866b04550fc5461058c398c2e3e509381ajeffhao#include "scoped_thread_state_change.h" 6810037c866b04550fc5461058c398c2e3e509381ajeffhao#include "utils.h" 698d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers#include "vector_output_stream.h" 708d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers#include "well_known_classes.h" 71700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include "zip_archive.h" 728d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 738d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogersnamespace art { 748d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 758d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogersstatic int original_argc; 768d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogersstatic char** original_argv; 778d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 788d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogersstatic std::string CommandLine() { 798d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers std::vector<std::string> command; 808d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers for (int i = 0; i < original_argc; ++i) { 8110037c866b04550fc5461058c398c2e3e509381ajeffhao command.push_back(original_argv[i]); 8210037c866b04550fc5461058c398c2e3e509381ajeffhao } 838d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers return Join(command, ' '); 848d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers} 8510037c866b04550fc5461058c398c2e3e509381ajeffhao 8610037c866b04550fc5461058c398c2e3e509381ajeffhaostatic void UsageErrorV(const char* fmt, va_list ap) { 8710037c866b04550fc5461058c398c2e3e509381ajeffhao std::string error; 8810037c866b04550fc5461058c398c2e3e509381ajeffhao StringAppendV(&error, fmt, ap); 8910037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(ERROR) << error; 9010037c866b04550fc5461058c398c2e3e509381ajeffhao} 9110037c866b04550fc5461058c398c2e3e509381ajeffhao 9210037c866b04550fc5461058c398c2e3e509381ajeffhaostatic void UsageError(const char* fmt, ...) { 9310037c866b04550fc5461058c398c2e3e509381ajeffhao va_list ap; 9410037c866b04550fc5461058c398c2e3e509381ajeffhao va_start(ap, fmt); 9510037c866b04550fc5461058c398c2e3e509381ajeffhao UsageErrorV(fmt, ap); 968d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers va_end(ap); 978d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers} 988d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 9910037c866b04550fc5461058c398c2e3e509381ajeffhao[[noreturn]] static void Usage(const char* fmt, ...) { 10010037c866b04550fc5461058c398c2e3e509381ajeffhao va_list ap; 10110037c866b04550fc5461058c398c2e3e509381ajeffhao va_start(ap, fmt); 10210037c866b04550fc5461058c398c2e3e509381ajeffhao UsageErrorV(fmt, ap); 1038d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers va_end(ap); 1048d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 10510037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError("Command: %s", CommandLine().c_str()); 10610037c866b04550fc5461058c398c2e3e509381ajeffhao 10710037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError("Usage: dex2oat [options]..."); 10810037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 1098d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" --dex-file=<dex-file>: specifies a .dex file to compile."); 11010037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Example: --dex-file=/system/framework/core.jar"); 11110037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 11210037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --zip-fd=<file-descriptor>: specifies a file descriptor of a zip file"); 11310037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" containing a classes.dex file to compile."); 11410037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Example: --zip-fd=5"); 1158d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(""); 1168a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers UsageError(" --zip-location=<zip-location>: specifies a symbolic name for the file"); 1178a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers UsageError(" corresponding to the file descriptor specified by --zip-fd."); 1188a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers UsageError(" Example: --zip-location=/system/app/Calculator.apk"); 1198a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers UsageError(""); 1208d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" --oat-file=<file.oat>: specifies the oat output destination via a filename."); 1218d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" Example: --oat-file=/system/framework/boot.oat"); 1228a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers UsageError(""); 123e3d5581266301e6a672af6233220037abf52fea1Ian Rogers UsageError(" --oat-fd=<number>: specifies the oat output destination via a file descriptor."); 124e3d5581266301e6a672af6233220037abf52fea1Ian Rogers UsageError(" Example: --oat-fd=6"); 12510037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 12610037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --oat-location=<oat-name>: specifies a symbolic name for the file corresponding"); 12710037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" to the file descriptor specified by --oat-fd."); 12810037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Example: --oat-location=/data/dalvik-cache/system@app@Calculator.apk.oat"); 12910037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 13010037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --oat-symbols=<file.oat>: specifies the oat output destination with full symbols."); 1318d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" Example: --oat-symbols=/symbols/system/framework/boot.oat"); 13210037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 13310037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --image=<file.art>: specifies the output image filename."); 13410037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Example: --image=/system/framework/boot.art"); 13510037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 1368d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" --image-classes=<classname-file>: specifies classes to include in an image."); 1378d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" Example: --image=frameworks/base/preloaded-classes"); 1388d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(""); 13910037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --base=<hex-address>: specifies the base address when creating a boot image."); 14010037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Example: --base=0x50000000"); 14110037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 14210037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --boot-image=<file.art>: provide the image file for the boot class path."); 14310037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Example: --boot-image=/system/framework/boot.art"); 1448d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" Default: $ANDROID_ROOT/system/framework/boot.art"); 145f6174e8a1566bb357e82506f7ec97dc359c90eb2jeffhao UsageError(""); 146f6174e8a1566bb357e82506f7ec97dc359c90eb2jeffhao UsageError(" --android-root=<path>: used to locate libraries for portable linking."); 147f6174e8a1566bb357e82506f7ec97dc359c90eb2jeffhao UsageError(" Example: --android-root=out/host/linux-x86"); 1488d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" Default: $ANDROID_ROOT"); 14910037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 15010037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --instruction-set=(arm|arm64|mips|x86|x86_64): compile for a particular"); 15110037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" instruction set."); 15210037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Example: --instruction-set=x86"); 15310037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Default: arm"); 15410037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 15510037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --instruction-set-features=...,: Specify instruction set features"); 156f6174e8a1566bb357e82506f7ec97dc359c90eb2jeffhao UsageError(" Example: --instruction-set-features=div"); 15710037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Default: default"); 1588d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(""); 15910037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --compile-pic: Force indirect use of code, methods, and classes"); 16010037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Default: disabled"); 16110037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 16210037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --compiler-backend=(Quick|Optimizing): select compiler backend"); 16310037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" set."); 1648d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" Example: --compiler-backend=Optimizing"); 16510037c866b04550fc5461058c398c2e3e509381ajeffhao if (kUseOptimizingCompiler) { 16610037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Default: Optimizing"); 16710037c866b04550fc5461058c398c2e3e509381ajeffhao } else { 16810037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Default: Quick"); 1698d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 17010037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 17110037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --compiler-filter=" 17210037c866b04550fc5461058c398c2e3e509381ajeffhao "(verify-none" 17310037c866b04550fc5461058c398c2e3e509381ajeffhao "|interpret-only" 17410037c866b04550fc5461058c398c2e3e509381ajeffhao "|space" 17510037c866b04550fc5461058c398c2e3e509381ajeffhao "|balanced" 1768d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers "|speed" 17730fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers "|everything" 17810037c866b04550fc5461058c398c2e3e509381ajeffhao "|time):"); 17910037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" select compiler filter."); 18010037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Example: --compiler-filter=everything"); 18110037c866b04550fc5461058c398c2e3e509381ajeffhao#if ART_SMALL_MODE 18210037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Default: interpret-only"); 18310037c866b04550fc5461058c398c2e3e509381ajeffhao#else 18410037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Default: speed"); 18510037c866b04550fc5461058c398c2e3e509381ajeffhao#endif 18610037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 18710037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --huge-method-max=<method-instruction-count>: the threshold size for a huge"); 18810037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" method for compiler filter tuning."); 18910037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Example: --huge-method-max=%d", CompilerOptions::kDefaultHugeMethodThreshold); 19010037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Default: %d", CompilerOptions::kDefaultHugeMethodThreshold); 19110037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 19210037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --huge-method-max=<method-instruction-count>: threshold size for a huge"); 1938d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" method for compiler filter tuning."); 1948d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" Example: --huge-method-max=%d", CompilerOptions::kDefaultHugeMethodThreshold); 19510037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Default: %d", CompilerOptions::kDefaultHugeMethodThreshold); 19610037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 1978d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" --large-method-max=<method-instruction-count>: threshold size for a large"); 1988d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" method for compiler filter tuning."); 1998d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" Example: --large-method-max=%d", CompilerOptions::kDefaultLargeMethodThreshold); 20010037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Default: %d", CompilerOptions::kDefaultLargeMethodThreshold); 20110037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 20210037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --small-method-max=<method-instruction-count>: threshold size for a small"); 20310037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" method for compiler filter tuning."); 20410037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Example: --small-method-max=%d", CompilerOptions::kDefaultSmallMethodThreshold); 2058d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" Default: %d", CompilerOptions::kDefaultSmallMethodThreshold); 2068d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(""); 20710037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --tiny-method-max=<method-instruction-count>: threshold size for a tiny"); 20810037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" method for compiler filter tuning."); 20910037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Example: --tiny-method-max=%d", CompilerOptions::kDefaultTinyMethodThreshold); 21010037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Default: %d", CompilerOptions::kDefaultTinyMethodThreshold); 21110037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 21210037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --num-dex-methods=<method-count>: threshold size for a small dex file for"); 21310037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" compiler filter tuning. If the input has fewer than this many methods"); 21410037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" and the filter is not interpret-only or verify-none, overrides the"); 2158d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" filter to use speed"); 2168d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" Example: --num-dex-method=%d", CompilerOptions::kDefaultNumDexMethodsThreshold); 21710037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Default: %d", CompilerOptions::kDefaultNumDexMethodsThreshold); 21810037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 21910037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --dump-timing: display a breakdown of where time was spent"); 2208d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(""); 2218d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" --include-patch-information: Include patching information so the generated code"); 22210037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" can have its base address moved without full recompilation."); 22310037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 22410037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --no-include-patch-information: Do not include patching information."); 22510037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 22610037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --include-debug-symbols: Include ELF symbols in this oat file"); 22710037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 22810037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --no-include-debug-symbols: Do not include ELF symbols in this oat file"); 22910037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 23010037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --runtime-arg <argument>: used to specify various arguments for the runtime,"); 2318d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" such as initial heap size, maximum heap size, and verbose output."); 2328d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" Use a separate --runtime-arg switch for each argument."); 23310037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Example: --runtime-arg -Xms256m"); 23410037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 2358d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" --profile-file=<filename>: specify profiler output file to use for compilation."); 2368d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(""); 23710037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --print-pass-names: print a list of pass names"); 23810037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 2398d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" --disable-passes=<pass-names>: disable one or more passes separated by comma."); 2408d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" Example: --disable-passes=UseCount,BBOptimizations"); 2418d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(""); 24210037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" --print-pass-options: print a list of passes that have configurable options along " 24310037c866b04550fc5461058c398c2e3e509381ajeffhao "with the setting."); 2448d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" Will print default if no overridden setting exists."); 2458d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(""); 2468d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" --pass-options=Pass1Name:Pass1OptionName:Pass1Option#," 24710037c866b04550fc5461058c398c2e3e509381ajeffhao "Pass2Name:Pass2OptionName:Pass2Option#"); 24810037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Used to specify a pass specific option. The setting itself must be integer."); 2498d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" Separator used between options is a comma."); 2508d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(""); 2518d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" --swap-file=<file-name>: specifies a file to use for swap."); 25210037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(" Example: --swap-file=/data/tmp/swap.001"); 25310037c866b04550fc5461058c398c2e3e509381ajeffhao UsageError(""); 2548d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" --swap-fd=<file-descriptor>: specifies a file to use for swap (by descriptor)."); 2558d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(" Example: --swap-fd=10"); 2568d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UsageError(""); 25710037c866b04550fc5461058c398c2e3e509381ajeffhao std::cerr << "See log for usage error information\n"; 25810037c866b04550fc5461058c398c2e3e509381ajeffhao exit(EXIT_FAILURE); 2598d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers} 2608d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 2618d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers// The primary goal of the watchdog is to prevent stuck build servers 26210037c866b04550fc5461058c398c2e3e509381ajeffhao// during development when fatal aborts lead to a cascade of failures 26310037c866b04550fc5461058c398c2e3e509381ajeffhao// that result in a deadlock. 2648d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogersclass WatchDog { 2658d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers// WatchDog defines its own CHECK_PTHREAD_CALL to avoid using LOG which uses locks 2668d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers#undef CHECK_PTHREAD_CALL 26710037c866b04550fc5461058c398c2e3e509381ajeffhao#define CHECK_WATCH_DOG_PTHREAD_CALL(call, args, what) \ 26810037c866b04550fc5461058c398c2e3e509381ajeffhao do { \ 26910037c866b04550fc5461058c398c2e3e509381ajeffhao int rc = call args; \ 27010037c866b04550fc5461058c398c2e3e509381ajeffhao if (rc != 0) { \ 27110037c866b04550fc5461058c398c2e3e509381ajeffhao errno = rc; \ 27210037c866b04550fc5461058c398c2e3e509381ajeffhao std::string message(# call); \ 27310037c866b04550fc5461058c398c2e3e509381ajeffhao message += " failed for "; \ 2748d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers message += reason; \ 2758d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers Fatal(message); \ 2768d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } \ 2778d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } while (false) 27810037c866b04550fc5461058c398c2e3e509381ajeffhao 27910037c866b04550fc5461058c398c2e3e509381ajeffhao public: 28010037c866b04550fc5461058c398c2e3e509381ajeffhao explicit WatchDog(bool is_watch_dog_enabled) { 28110037c866b04550fc5461058c398c2e3e509381ajeffhao is_watch_dog_enabled_ = is_watch_dog_enabled; 28210037c866b04550fc5461058c398c2e3e509381ajeffhao if (!is_watch_dog_enabled_) { 2838d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers return; 28410037c866b04550fc5461058c398c2e3e509381ajeffhao } 28510037c866b04550fc5461058c398c2e3e509381ajeffhao shutting_down_ = false; 28610037c866b04550fc5461058c398c2e3e509381ajeffhao const char* reason = "dex2oat watch dog thread startup"; 28710037c866b04550fc5461058c398c2e3e509381ajeffhao CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_init, (&mutex_, nullptr), reason); 2888a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_init, (&cond_, nullptr), reason); 28910037c866b04550fc5461058c398c2e3e509381ajeffhao CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_init, (&attr_), reason); 29010037c866b04550fc5461058c398c2e3e509381ajeffhao CHECK_WATCH_DOG_PTHREAD_CALL(pthread_create, (&pthread_, &attr_, &CallBack, this), reason); 2918d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_destroy, (&attr_), reason); 2928d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 29310037c866b04550fc5461058c398c2e3e509381ajeffhao ~WatchDog() { 29410037c866b04550fc5461058c398c2e3e509381ajeffhao if (!is_watch_dog_enabled_) { 29510037c866b04550fc5461058c398c2e3e509381ajeffhao return; 29610037c866b04550fc5461058c398c2e3e509381ajeffhao } 29710037c866b04550fc5461058c398c2e3e509381ajeffhao const char* reason = "dex2oat watch dog thread shutdown"; 29810037c866b04550fc5461058c398c2e3e509381ajeffhao CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason); 29910037c866b04550fc5461058c398c2e3e509381ajeffhao shutting_down_ = true; 30010037c866b04550fc5461058c398c2e3e509381ajeffhao CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_signal, (&cond_), reason); 30110037c866b04550fc5461058c398c2e3e509381ajeffhao CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason); 30210037c866b04550fc5461058c398c2e3e509381ajeffhao 3038a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers CHECK_WATCH_DOG_PTHREAD_CALL(pthread_join, (pthread_, nullptr), reason); 30410037c866b04550fc5461058c398c2e3e509381ajeffhao 30510037c866b04550fc5461058c398c2e3e509381ajeffhao CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_destroy, (&cond_), reason); 30610037c866b04550fc5461058c398c2e3e509381ajeffhao CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_destroy, (&mutex_), reason); 30710037c866b04550fc5461058c398c2e3e509381ajeffhao } 30810037c866b04550fc5461058c398c2e3e509381ajeffhao 30910037c866b04550fc5461058c398c2e3e509381ajeffhao private: 31010037c866b04550fc5461058c398c2e3e509381ajeffhao static void* CallBack(void* arg) { 31110037c866b04550fc5461058c398c2e3e509381ajeffhao WatchDog* self = reinterpret_cast<WatchDog*>(arg); 3128d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers ::art::SetThreadName("dex2oat watch dog"); 3138d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers self->Wait(); 31410037c866b04550fc5461058c398c2e3e509381ajeffhao return nullptr; 31510037c866b04550fc5461058c398c2e3e509381ajeffhao } 31610037c866b04550fc5461058c398c2e3e509381ajeffhao 31710037c866b04550fc5461058c398c2e3e509381ajeffhao static void Message(char severity, const std::string& message) { 31810037c866b04550fc5461058c398c2e3e509381ajeffhao // TODO: Remove when we switch to LOG when we can guarantee it won't prevent shutdown in error 31910037c866b04550fc5461058c398c2e3e509381ajeffhao // cases. 3208d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers fprintf(stderr, "dex2oat%s %c %d %d %s\n", 3218d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers kIsDebugBuild ? "d" : "", 32210037c866b04550fc5461058c398c2e3e509381ajeffhao severity, 32310037c866b04550fc5461058c398c2e3e509381ajeffhao getpid(), 32410037c866b04550fc5461058c398c2e3e509381ajeffhao GetTid(), 32510037c866b04550fc5461058c398c2e3e509381ajeffhao message.c_str()); 32610037c866b04550fc5461058c398c2e3e509381ajeffhao } 32710037c866b04550fc5461058c398c2e3e509381ajeffhao 32810037c866b04550fc5461058c398c2e3e509381ajeffhao [[noreturn]] static void Fatal(const std::string& message) { 32910037c866b04550fc5461058c398c2e3e509381ajeffhao Message('F', message); 33010037c866b04550fc5461058c398c2e3e509381ajeffhao exit(1); 3318d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 33210037c866b04550fc5461058c398c2e3e509381ajeffhao 33310037c866b04550fc5461058c398c2e3e509381ajeffhao void Wait() { 33410037c866b04550fc5461058c398c2e3e509381ajeffhao // TODO: tune the multiplier for GC verification, the following is just to make the timeout 33510037c866b04550fc5461058c398c2e3e509381ajeffhao // large. 33610037c866b04550fc5461058c398c2e3e509381ajeffhao int64_t multiplier = kVerifyObjectSupport > kVerifyObjectModeFast ? 100 : 1; 3378d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers timespec timeout_ts; 3388d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers InitTimeSpec(true, CLOCK_REALTIME, multiplier * kWatchDogTimeoutSeconds * 1000, 0, &timeout_ts); 33910037c866b04550fc5461058c398c2e3e509381ajeffhao const char* reason = "dex2oat watch dog thread waiting"; 34010037c866b04550fc5461058c398c2e3e509381ajeffhao CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason); 34110037c866b04550fc5461058c398c2e3e509381ajeffhao while (!shutting_down_) { 34210037c866b04550fc5461058c398c2e3e509381ajeffhao int rc = TEMP_FAILURE_RETRY(pthread_cond_timedwait(&cond_, &mutex_, &timeout_ts)); 34310037c866b04550fc5461058c398c2e3e509381ajeffhao if (rc == ETIMEDOUT) { 3448d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers Fatal(StringPrintf("dex2oat did not finish after %d seconds", kWatchDogTimeoutSeconds)); 3458d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } else if (rc != 0) { 34610037c866b04550fc5461058c398c2e3e509381ajeffhao std::string message(StringPrintf("pthread_cond_timedwait failed: %s", 34710037c866b04550fc5461058c398c2e3e509381ajeffhao strerror(errno))); 34810037c866b04550fc5461058c398c2e3e509381ajeffhao Fatal(message.c_str()); 34910037c866b04550fc5461058c398c2e3e509381ajeffhao } 35010037c866b04550fc5461058c398c2e3e509381ajeffhao } 35110037c866b04550fc5461058c398c2e3e509381ajeffhao CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason); 35210037c866b04550fc5461058c398c2e3e509381ajeffhao } 3538d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 35410037c866b04550fc5461058c398c2e3e509381ajeffhao // When setting timeouts, keep in mind that the build server may not be as fast as your desktop. 35510037c866b04550fc5461058c398c2e3e509381ajeffhao // Debug builds are slower so they have larger timeouts. 35610037c866b04550fc5461058c398c2e3e509381ajeffhao static const unsigned int kSlowdownFactor = kIsDebugBuild ? 5U : 1U; 35710037c866b04550fc5461058c398c2e3e509381ajeffhao 35810037c866b04550fc5461058c398c2e3e509381ajeffhao // 6 minutes scaled by kSlowdownFactor. 35910037c866b04550fc5461058c398c2e3e509381ajeffhao static const unsigned int kWatchDogTimeoutSeconds = kSlowdownFactor * 6 * 60; 36010037c866b04550fc5461058c398c2e3e509381ajeffhao 36110037c866b04550fc5461058c398c2e3e509381ajeffhao bool is_watch_dog_enabled_; 36210037c866b04550fc5461058c398c2e3e509381ajeffhao bool shutting_down_; 3638d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers // TODO: Switch to Mutex when we can guarantee it won't prevent shutdown in error cases. 3648d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers pthread_mutex_t mutex_; 36510037c866b04550fc5461058c398c2e3e509381ajeffhao pthread_cond_t cond_; 36610037c866b04550fc5461058c398c2e3e509381ajeffhao pthread_attr_t attr_; 36710037c866b04550fc5461058c398c2e3e509381ajeffhao pthread_t pthread_; 36810037c866b04550fc5461058c398c2e3e509381ajeffhao}; 36910037c866b04550fc5461058c398c2e3e509381ajeffhao 37010037c866b04550fc5461058c398c2e3e509381ajeffhaostatic void ParseStringAfterChar(const std::string& s, char c, std::string* parsed_value) { 3718d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers std::string::size_type colon = s.find(c); 3728d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (colon == std::string::npos) { 3738d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers Usage("Missing char %c in option %s\n", c, s.c_str()); 37410037c866b04550fc5461058c398c2e3e509381ajeffhao } 37510037c866b04550fc5461058c398c2e3e509381ajeffhao // Add one to remove the char we were trimming until. 37610037c866b04550fc5461058c398c2e3e509381ajeffhao *parsed_value = s.substr(colon + 1); 3778d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers} 3788d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 3798d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogersstatic void ParseDouble(const std::string& option, char after_char, double min, double max, 38010037c866b04550fc5461058c398c2e3e509381ajeffhao double* parsed_value) { 3818d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers std::string substring; 3828d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers ParseStringAfterChar(option, after_char, &substring); 3838d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers bool sane_val = true; 38410037c866b04550fc5461058c398c2e3e509381ajeffhao double value; 38510037c866b04550fc5461058c398c2e3e509381ajeffhao if (false) { 38610037c866b04550fc5461058c398c2e3e509381ajeffhao // TODO: this doesn't seem to work on the emulator. b/15114595 38710037c866b04550fc5461058c398c2e3e509381ajeffhao std::stringstream iss(substring); 38810037c866b04550fc5461058c398c2e3e509381ajeffhao iss >> value; 38910037c866b04550fc5461058c398c2e3e509381ajeffhao // Ensure that we have a value, there was no cruft after it and it satisfies a sensible range. 3908a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers sane_val = iss.eof() && (value >= min) && (value <= max); 39110037c866b04550fc5461058c398c2e3e509381ajeffhao } else { 39230fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers char* end = nullptr; 39310037c866b04550fc5461058c398c2e3e509381ajeffhao value = strtod(substring.c_str(), &end); 39410037c866b04550fc5461058c398c2e3e509381ajeffhao sane_val = *end == '\0' && value >= min && value <= max; 39510037c866b04550fc5461058c398c2e3e509381ajeffhao } 3968d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (!sane_val) { 3978a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers Usage("Invalid double value %s for option %s\n", substring.c_str(), option.c_str()); 39810037c866b04550fc5461058c398c2e3e509381ajeffhao } 39910037c866b04550fc5461058c398c2e3e509381ajeffhao *parsed_value = value; 40010037c866b04550fc5461058c398c2e3e509381ajeffhao} 40110037c866b04550fc5461058c398c2e3e509381ajeffhao 40210037c866b04550fc5461058c398c2e3e509381ajeffhaostatic constexpr size_t kMinDexFilesForSwap = 2; 40310037c866b04550fc5461058c398c2e3e509381ajeffhaostatic constexpr size_t kMinDexFileCumulativeSizeForSwap = 20 * MB; 40410037c866b04550fc5461058c398c2e3e509381ajeffhao 40510037c866b04550fc5461058c398c2e3e509381ajeffhaostatic bool UseSwap(bool is_image, std::vector<const DexFile*>& dex_files) { 40610037c866b04550fc5461058c398c2e3e509381ajeffhao if (is_image) { 40710037c866b04550fc5461058c398c2e3e509381ajeffhao // Don't use swap, we know generation should succeed, and we don't want to slow it down. 40810037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 40910037c866b04550fc5461058c398c2e3e509381ajeffhao } 41010037c866b04550fc5461058c398c2e3e509381ajeffhao if (dex_files.size() < kMinDexFilesForSwap) { 41110037c866b04550fc5461058c398c2e3e509381ajeffhao // If there are less dex files than the threshold, assume it's gonna be fine. 41210037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 41310037c866b04550fc5461058c398c2e3e509381ajeffhao } 41410037c866b04550fc5461058c398c2e3e509381ajeffhao size_t dex_files_size = 0; 41510037c866b04550fc5461058c398c2e3e509381ajeffhao for (const auto* dex_file : dex_files) { 41610037c866b04550fc5461058c398c2e3e509381ajeffhao dex_files_size += dex_file->GetHeader().file_size_; 41710037c866b04550fc5461058c398c2e3e509381ajeffhao } 4188d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers return dex_files_size >= kMinDexFileCumulativeSizeForSwap; 4198d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers} 42010037c866b04550fc5461058c398c2e3e509381ajeffhao 42110037c866b04550fc5461058c398c2e3e509381ajeffhaoclass Dex2Oat FINAL { 42210037c866b04550fc5461058c398c2e3e509381ajeffhao public: 42310037c866b04550fc5461058c398c2e3e509381ajeffhao explicit Dex2Oat(TimingLogger* timings) : 42410037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_kind_(kUseOptimizingCompiler ? Compiler::kOptimizing : Compiler::kQuick), 42510037c866b04550fc5461058c398c2e3e509381ajeffhao instruction_set_(kRuntimeISA), 4268d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers // Take the default set of instruction features from the build. 4278d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers method_inliner_map_(), 42810037c866b04550fc5461058c398c2e3e509381ajeffhao runtime_(nullptr), 42910037c866b04550fc5461058c398c2e3e509381ajeffhao thread_count_(sysconf(_SC_NPROCESSORS_CONF)), 43010037c866b04550fc5461058c398c2e3e509381ajeffhao start_ns_(NanoTime()), 43110037c866b04550fc5461058c398c2e3e509381ajeffhao oat_fd_(-1), 43210037c866b04550fc5461058c398c2e3e509381ajeffhao zip_fd_(-1), 43310037c866b04550fc5461058c398c2e3e509381ajeffhao image_base_(0U), 4348d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers image_classes_zip_filename_(nullptr), 4358d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers image_classes_filename_(nullptr), 43610037c866b04550fc5461058c398c2e3e509381ajeffhao compiled_classes_zip_filename_(nullptr), 43710037c866b04550fc5461058c398c2e3e509381ajeffhao compiled_classes_filename_(nullptr), 43810037c866b04550fc5461058c398c2e3e509381ajeffhao image_(false), 43910037c866b04550fc5461058c398c2e3e509381ajeffhao is_host_(false), 44010037c866b04550fc5461058c398c2e3e509381ajeffhao dump_stats_(false), 44110037c866b04550fc5461058c398c2e3e509381ajeffhao dump_passes_(false), 44210037c866b04550fc5461058c398c2e3e509381ajeffhao dump_timing_(false), 44310037c866b04550fc5461058c398c2e3e509381ajeffhao dump_slow_timing_(kIsDebugBuild), 44410037c866b04550fc5461058c398c2e3e509381ajeffhao swap_fd_(-1), 4458d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers timings_(timings) {} 4468d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 44710037c866b04550fc5461058c398c2e3e509381ajeffhao ~Dex2Oat() { 44810037c866b04550fc5461058c398c2e3e509381ajeffhao LogCompletionTime(); // Needs to be before since it accesses the runtime. 44910037c866b04550fc5461058c398c2e3e509381ajeffhao if (kIsDebugBuild || (RUNNING_ON_VALGRIND != 0)) { 45010037c866b04550fc5461058c398c2e3e509381ajeffhao delete runtime_; // See field declaration for why this is manual. 45110037c866b04550fc5461058c398c2e3e509381ajeffhao } 45210037c866b04550fc5461058c398c2e3e509381ajeffhao } 45310037c866b04550fc5461058c398c2e3e509381ajeffhao 45410037c866b04550fc5461058c398c2e3e509381ajeffhao // Parse the arguments from the command line. In case of an unrecognized option or impossible 45510037c866b04550fc5461058c398c2e3e509381ajeffhao // values/combinations, a usage error will be displayed and exit() is called. Thus, if the method 4568d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers // returns, arguments have been successfully parsed. 4578d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers void ParseArgs(int argc, char** argv) { 45810037c866b04550fc5461058c398c2e3e509381ajeffhao original_argc = argc; 45910037c866b04550fc5461058c398c2e3e509381ajeffhao original_argv = argv; 46010037c866b04550fc5461058c398c2e3e509381ajeffhao 46110037c866b04550fc5461058c398c2e3e509381ajeffhao InitLogging(argv); 46210037c866b04550fc5461058c398c2e3e509381ajeffhao 46310037c866b04550fc5461058c398c2e3e509381ajeffhao // Skip over argv[0]. 46410037c866b04550fc5461058c398c2e3e509381ajeffhao argv++; 46510037c866b04550fc5461058c398c2e3e509381ajeffhao argc--; 46610037c866b04550fc5461058c398c2e3e509381ajeffhao 46710037c866b04550fc5461058c398c2e3e509381ajeffhao if (argc == 0) { 4688d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers Usage("No arguments specified"); 4698d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 47010037c866b04550fc5461058c398c2e3e509381ajeffhao 47110037c866b04550fc5461058c398c2e3e509381ajeffhao std::string oat_symbols; 47210037c866b04550fc5461058c398c2e3e509381ajeffhao std::string boot_image_filename; 47310037c866b04550fc5461058c398c2e3e509381ajeffhao const char* compiler_filter_string = nullptr; 47410037c866b04550fc5461058c398c2e3e509381ajeffhao bool compile_pic = false; 47510037c866b04550fc5461058c398c2e3e509381ajeffhao int huge_method_threshold = CompilerOptions::kDefaultHugeMethodThreshold; 47610037c866b04550fc5461058c398c2e3e509381ajeffhao int large_method_threshold = CompilerOptions::kDefaultLargeMethodThreshold; 47710037c866b04550fc5461058c398c2e3e509381ajeffhao int small_method_threshold = CompilerOptions::kDefaultSmallMethodThreshold; 47810037c866b04550fc5461058c398c2e3e509381ajeffhao int tiny_method_threshold = CompilerOptions::kDefaultTinyMethodThreshold; 4798d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers int num_dex_methods_threshold = CompilerOptions::kDefaultNumDexMethodsThreshold; 4808d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 48110037c866b04550fc5461058c398c2e3e509381ajeffhao // Profile file to use 48210037c866b04550fc5461058c398c2e3e509381ajeffhao double top_k_profile_threshold = CompilerOptions::kDefaultTopKProfileThreshold; 48310037c866b04550fc5461058c398c2e3e509381ajeffhao 48410037c866b04550fc5461058c398c2e3e509381ajeffhao bool print_pass_options = false; 48510037c866b04550fc5461058c398c2e3e509381ajeffhao bool include_patch_information = CompilerOptions::kDefaultIncludePatchInformation; 48610037c866b04550fc5461058c398c2e3e509381ajeffhao bool include_debug_symbols = kIsDebugBuild; 48710037c866b04550fc5461058c398c2e3e509381ajeffhao bool watch_dog_enabled = true; 48810037c866b04550fc5461058c398c2e3e509381ajeffhao bool generate_gdb_information = kIsDebugBuild; 48910037c866b04550fc5461058c398c2e3e509381ajeffhao 4908d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers std::string error_msg; 4918d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 49210037c866b04550fc5461058c398c2e3e509381ajeffhao for (int i = 0; i < argc; i++) { 49310037c866b04550fc5461058c398c2e3e509381ajeffhao const StringPiece option(argv[i]); 49410037c866b04550fc5461058c398c2e3e509381ajeffhao const bool log_options = false; 49510037c866b04550fc5461058c398c2e3e509381ajeffhao if (log_options) { 49610037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i]; 49710037c866b04550fc5461058c398c2e3e509381ajeffhao } 49810037c866b04550fc5461058c398c2e3e509381ajeffhao if (option.starts_with("--dex-file=")) { 4998d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers dex_filenames_.push_back(option.substr(strlen("--dex-file=")).data()); 5008d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } else if (option.starts_with("--dex-location=")) { 50110037c866b04550fc5461058c398c2e3e509381ajeffhao dex_locations_.push_back(option.substr(strlen("--dex-location=")).data()); 50210037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--zip-fd=")) { 50310037c866b04550fc5461058c398c2e3e509381ajeffhao const char* zip_fd_str = option.substr(strlen("--zip-fd=")).data(); 50410037c866b04550fc5461058c398c2e3e509381ajeffhao if (!ParseInt(zip_fd_str, &zip_fd_)) { 50510037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("Failed to parse --zip-fd argument '%s' as an integer", zip_fd_str); 50610037c866b04550fc5461058c398c2e3e509381ajeffhao } 50710037c866b04550fc5461058c398c2e3e509381ajeffhao if (zip_fd_ < 0) { 5088d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers Usage("--zip-fd passed a negative value %d", zip_fd_); 5098d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 51010037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--zip-location=")) { 51110037c866b04550fc5461058c398c2e3e509381ajeffhao zip_location_ = option.substr(strlen("--zip-location=")).data(); 51210037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--oat-file=")) { 51310037c866b04550fc5461058c398c2e3e509381ajeffhao oat_filename_ = option.substr(strlen("--oat-file=")).data(); 5148d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } else if (option.starts_with("--oat-symbols=")) { 5158d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers oat_symbols = option.substr(strlen("--oat-symbols=")).data(); 51610037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--oat-fd=")) { 51710037c866b04550fc5461058c398c2e3e509381ajeffhao const char* oat_fd_str = option.substr(strlen("--oat-fd=")).data(); 51810037c866b04550fc5461058c398c2e3e509381ajeffhao if (!ParseInt(oat_fd_str, &oat_fd_)) { 51910037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("Failed to parse --oat-fd argument '%s' as an integer", oat_fd_str); 5208d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 52110037c866b04550fc5461058c398c2e3e509381ajeffhao if (oat_fd_ < 0) { 52210037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--oat-fd passed a negative value %d", oat_fd_); 52310037c866b04550fc5461058c398c2e3e509381ajeffhao } 52410037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option == "--watch-dog") { 52510037c866b04550fc5461058c398c2e3e509381ajeffhao watch_dog_enabled = true; 52610037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option == "--no-watch-dog") { 52710037c866b04550fc5461058c398c2e3e509381ajeffhao watch_dog_enabled = false; 52810037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option == "--gen-gdb-info") { 52910037c866b04550fc5461058c398c2e3e509381ajeffhao generate_gdb_information = true; 53010037c866b04550fc5461058c398c2e3e509381ajeffhao // Debug symbols are needed for gdb information. 53110037c866b04550fc5461058c398c2e3e509381ajeffhao include_debug_symbols = true; 5328d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } else if (option == "--no-gen-gdb-info") { 53310037c866b04550fc5461058c398c2e3e509381ajeffhao generate_gdb_information = false; 53410037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("-j")) { 53510037c866b04550fc5461058c398c2e3e509381ajeffhao const char* thread_count_str = option.substr(strlen("-j")).data(); 53610037c866b04550fc5461058c398c2e3e509381ajeffhao if (!ParseUint(thread_count_str, &thread_count_)) { 53710037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("Failed to parse -j argument '%s' as an integer", thread_count_str); 53810037c866b04550fc5461058c398c2e3e509381ajeffhao } 53910037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--oat-location=")) { 54010037c866b04550fc5461058c398c2e3e509381ajeffhao oat_location_ = option.substr(strlen("--oat-location=")).data(); 54110037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--image=")) { 54210037c866b04550fc5461058c398c2e3e509381ajeffhao image_filename_ = option.substr(strlen("--image=")).data(); 54310037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--image-classes=")) { 54410037c866b04550fc5461058c398c2e3e509381ajeffhao image_classes_filename_ = option.substr(strlen("--image-classes=")).data(); 54510037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--image-classes-zip=")) { 54610037c866b04550fc5461058c398c2e3e509381ajeffhao image_classes_zip_filename_ = option.substr(strlen("--image-classes-zip=")).data(); 54710037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--compiled-classes=")) { 54810037c866b04550fc5461058c398c2e3e509381ajeffhao compiled_classes_filename_ = option.substr(strlen("--compiled-classes=")).data(); 54910037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--compiled-classes-zip=")) { 55010037c866b04550fc5461058c398c2e3e509381ajeffhao compiled_classes_zip_filename_ = option.substr(strlen("--compiled-classes-zip=")).data(); 55110037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--base=")) { 55210037c866b04550fc5461058c398c2e3e509381ajeffhao const char* image_base_str = option.substr(strlen("--base=")).data(); 55310037c866b04550fc5461058c398c2e3e509381ajeffhao char* end; 5548d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers image_base_ = strtoul(image_base_str, &end, 16); 5558d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (end == image_base_str || *end != '\0') { 5568d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers Usage("Failed to parse hexadecimal value for option %s", option.data()); 55710037c866b04550fc5461058c398c2e3e509381ajeffhao } 55810037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--boot-image=")) { 55910037c866b04550fc5461058c398c2e3e509381ajeffhao boot_image_filename = option.substr(strlen("--boot-image=")).data(); 56010037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--android-root=")) { 56110037c866b04550fc5461058c398c2e3e509381ajeffhao android_root_ = option.substr(strlen("--android-root=")).data(); 56210037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--instruction-set=")) { 56310037c866b04550fc5461058c398c2e3e509381ajeffhao StringPiece instruction_set_str = option.substr(strlen("--instruction-set=")).data(); 56410037c866b04550fc5461058c398c2e3e509381ajeffhao // StringPiece is not necessarily zero-terminated, so need to make a copy and ensure it. 56510037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<char[]> buf(new char[instruction_set_str.length() + 1]); 56610037c866b04550fc5461058c398c2e3e509381ajeffhao strncpy(buf.get(), instruction_set_str.data(), instruction_set_str.length()); 56710037c866b04550fc5461058c398c2e3e509381ajeffhao buf.get()[instruction_set_str.length()] = 0; 56810037c866b04550fc5461058c398c2e3e509381ajeffhao instruction_set_ = GetInstructionSetFromString(buf.get()); 56910037c866b04550fc5461058c398c2e3e509381ajeffhao // arm actually means thumb2. 57010037c866b04550fc5461058c398c2e3e509381ajeffhao if (instruction_set_ == InstructionSet::kArm) { 57110037c866b04550fc5461058c398c2e3e509381ajeffhao instruction_set_ = InstructionSet::kThumb2; 57210037c866b04550fc5461058c398c2e3e509381ajeffhao } 57310037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--instruction-set-variant=")) { 57410037c866b04550fc5461058c398c2e3e509381ajeffhao StringPiece str = option.substr(strlen("--instruction-set-variant=")).data(); 57510037c866b04550fc5461058c398c2e3e509381ajeffhao instruction_set_features_.reset( 57610037c866b04550fc5461058c398c2e3e509381ajeffhao InstructionSetFeatures::FromVariant(instruction_set_, str.as_string(), &error_msg)); 57710037c866b04550fc5461058c398c2e3e509381ajeffhao if (instruction_set_features_.get() == nullptr) { 57810037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("%s", error_msg.c_str()); 57910037c866b04550fc5461058c398c2e3e509381ajeffhao } 58010037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--instruction-set-features=")) { 58110037c866b04550fc5461058c398c2e3e509381ajeffhao StringPiece str = option.substr(strlen("--instruction-set-features=")).data(); 58210037c866b04550fc5461058c398c2e3e509381ajeffhao if (instruction_set_features_.get() == nullptr) { 58310037c866b04550fc5461058c398c2e3e509381ajeffhao instruction_set_features_.reset( 58410037c866b04550fc5461058c398c2e3e509381ajeffhao InstructionSetFeatures::FromVariant(instruction_set_, "default", &error_msg)); 58510037c866b04550fc5461058c398c2e3e509381ajeffhao if (instruction_set_features_.get() == nullptr) { 58610037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("Problem initializing default instruction set features variant: %s", 58710037c866b04550fc5461058c398c2e3e509381ajeffhao error_msg.c_str()); 58810037c866b04550fc5461058c398c2e3e509381ajeffhao } 58910037c866b04550fc5461058c398c2e3e509381ajeffhao } 59010037c866b04550fc5461058c398c2e3e509381ajeffhao instruction_set_features_.reset( 59110037c866b04550fc5461058c398c2e3e509381ajeffhao instruction_set_features_->AddFeaturesFromString(str.as_string(), &error_msg)); 59210037c866b04550fc5461058c398c2e3e509381ajeffhao if (instruction_set_features_.get() == nullptr) { 59310037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("Error parsing '%s': %s", option.data(), error_msg.c_str()); 59410037c866b04550fc5461058c398c2e3e509381ajeffhao } 59510037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--compiler-backend=")) { 59610037c866b04550fc5461058c398c2e3e509381ajeffhao StringPiece backend_str = option.substr(strlen("--compiler-backend=")).data(); 59710037c866b04550fc5461058c398c2e3e509381ajeffhao if (backend_str == "Quick") { 59810037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_kind_ = Compiler::kQuick; 59910037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (backend_str == "Optimizing") { 60010037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_kind_ = Compiler::kOptimizing; 60110037c866b04550fc5461058c398c2e3e509381ajeffhao } else { 60210037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("Unknown compiler backend: %s", backend_str.data()); 60310037c866b04550fc5461058c398c2e3e509381ajeffhao } 60410037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--compiler-filter=")) { 6058d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers compiler_filter_string = option.substr(strlen("--compiler-filter=")).data(); 6068d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } else if (option == "--compile-pic") { 6078d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers compile_pic = true; 60810037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--huge-method-max=")) { 60910037c866b04550fc5461058c398c2e3e509381ajeffhao const char* threshold = option.substr(strlen("--huge-method-max=")).data(); 61010037c866b04550fc5461058c398c2e3e509381ajeffhao if (!ParseInt(threshold, &huge_method_threshold)) { 6118d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers Usage("Failed to parse --huge-method-max '%s' as an integer", threshold); 6128d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 61310037c866b04550fc5461058c398c2e3e509381ajeffhao if (huge_method_threshold < 0) { 61410037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--huge-method-max passed a negative value %s", huge_method_threshold); 61510037c866b04550fc5461058c398c2e3e509381ajeffhao } 61610037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--large-method-max=")) { 61710037c866b04550fc5461058c398c2e3e509381ajeffhao const char* threshold = option.substr(strlen("--large-method-max=")).data(); 61810037c866b04550fc5461058c398c2e3e509381ajeffhao if (!ParseInt(threshold, &large_method_threshold)) { 6198d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers Usage("Failed to parse --large-method-max '%s' as an integer", threshold); 6208d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 62110037c866b04550fc5461058c398c2e3e509381ajeffhao if (large_method_threshold < 0) { 62210037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--large-method-max passed a negative value %s", large_method_threshold); 62310037c866b04550fc5461058c398c2e3e509381ajeffhao } 62410037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--small-method-max=")) { 62510037c866b04550fc5461058c398c2e3e509381ajeffhao const char* threshold = option.substr(strlen("--small-method-max=")).data(); 62610037c866b04550fc5461058c398c2e3e509381ajeffhao if (!ParseInt(threshold, &small_method_threshold)) { 62710037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("Failed to parse --small-method-max '%s' as an integer", threshold); 62810037c866b04550fc5461058c398c2e3e509381ajeffhao } 62910037c866b04550fc5461058c398c2e3e509381ajeffhao if (small_method_threshold < 0) { 63010037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--small-method-max passed a negative value %s", small_method_threshold); 63110037c866b04550fc5461058c398c2e3e509381ajeffhao } 63210037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--tiny-method-max=")) { 63310037c866b04550fc5461058c398c2e3e509381ajeffhao const char* threshold = option.substr(strlen("--tiny-method-max=")).data(); 63410037c866b04550fc5461058c398c2e3e509381ajeffhao if (!ParseInt(threshold, &tiny_method_threshold)) { 63510037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("Failed to parse --tiny-method-max '%s' as an integer", threshold); 63610037c866b04550fc5461058c398c2e3e509381ajeffhao } 63710037c866b04550fc5461058c398c2e3e509381ajeffhao if (tiny_method_threshold < 0) { 6388a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers Usage("--tiny-method-max passed a negative value %s", tiny_method_threshold); 6398d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 64010037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--num-dex-methods=")) { 64110037c866b04550fc5461058c398c2e3e509381ajeffhao const char* threshold = option.substr(strlen("--num-dex-methods=")).data(); 64210037c866b04550fc5461058c398c2e3e509381ajeffhao if (!ParseInt(threshold, &num_dex_methods_threshold)) { 64310037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("Failed to parse --num-dex-methods '%s' as an integer", threshold); 64410037c866b04550fc5461058c398c2e3e509381ajeffhao } 64510037c866b04550fc5461058c398c2e3e509381ajeffhao if (num_dex_methods_threshold < 0) { 64610037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--num-dex-methods passed a negative value %s", num_dex_methods_threshold); 64710037c866b04550fc5461058c398c2e3e509381ajeffhao } 64810037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option == "--host") { 64910037c866b04550fc5461058c398c2e3e509381ajeffhao is_host_ = true; 65010037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option == "--runtime-arg") { 6518d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (++i >= argc) { 6528d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers Usage("Missing required argument for --runtime-arg"); 65310037c866b04550fc5461058c398c2e3e509381ajeffhao } 65410037c866b04550fc5461058c398c2e3e509381ajeffhao if (log_options) { 65510037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i]; 656700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers } 657ee0fa76b2e5d39ad36d1ff144b2d0270df81e606Elliott Hughes runtime_args_.push_back(argv[i]); 65810037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option == "--dump-timing") { 65910037c866b04550fc5461058c398c2e3e509381ajeffhao dump_timing_ = true; 66010037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option == "--dump-passes") { 66110037c866b04550fc5461058c398c2e3e509381ajeffhao dump_passes_ = true; 66210037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option == "--dump-stats") { 6638d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers dump_stats_ = true; 6648d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } else if (option == "--include-debug-symbols" || option == "--no-strip-symbols") { 66510037c866b04550fc5461058c398c2e3e509381ajeffhao include_debug_symbols = true; 66610037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option == "--no-include-debug-symbols" || option == "--strip-symbols") { 66710037c866b04550fc5461058c398c2e3e509381ajeffhao include_debug_symbols = false; 6688d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers generate_gdb_information = false; // Depends on debug symbols, see above. 6698d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } else if (option.starts_with("--profile-file=")) { 67010037c866b04550fc5461058c398c2e3e509381ajeffhao profile_file_ = option.substr(strlen("--profile-file=")).data(); 67110037c866b04550fc5461058c398c2e3e509381ajeffhao VLOG(compiler) << "dex2oat: profile file is " << profile_file_; 67210037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option == "--no-profile-file") { 67310037c866b04550fc5461058c398c2e3e509381ajeffhao // No profile 67410037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--top-k-profile-threshold=")) { 67510037c866b04550fc5461058c398c2e3e509381ajeffhao ParseDouble(option.data(), '=', 0.0, 100.0, &top_k_profile_threshold); 67610037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option == "--print-pass-names") { 67710037c866b04550fc5461058c398c2e3e509381ajeffhao PassDriverMEOpts::PrintPassNames(); 67810037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--disable-passes=")) { 67910037c866b04550fc5461058c398c2e3e509381ajeffhao std::string disable_passes = option.substr(strlen("--disable-passes=")).data(); 6808d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers PassDriverMEOpts::CreateDefaultPassList(disable_passes); 6818d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } else if (option.starts_with("--print-passes=")) { 68210037c866b04550fc5461058c398c2e3e509381ajeffhao std::string print_passes = option.substr(strlen("--print-passes=")).data(); 68310037c866b04550fc5461058c398c2e3e509381ajeffhao PassDriverMEOpts::SetPrintPassList(print_passes); 68410037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option == "--print-all-passes") { 68510037c866b04550fc5461058c398c2e3e509381ajeffhao PassDriverMEOpts::SetPrintAllPasses(); 6868d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } else if (option.starts_with("--dump-cfg-passes=")) { 6878d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers std::string dump_passes_string = option.substr(strlen("--dump-cfg-passes=")).data(); 68810037c866b04550fc5461058c398c2e3e509381ajeffhao PassDriverMEOpts::SetDumpPassList(dump_passes_string); 68910037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option == "--print-pass-options") { 69010037c866b04550fc5461058c398c2e3e509381ajeffhao print_pass_options = true; 69110037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--pass-options=")) { 69210037c866b04550fc5461058c398c2e3e509381ajeffhao std::string options = option.substr(strlen("--pass-options=")).data(); 69310037c866b04550fc5461058c398c2e3e509381ajeffhao PassDriverMEOpts::SetOverriddenPassOptions(options); 69410037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option == "--include-patch-information") { 69510037c866b04550fc5461058c398c2e3e509381ajeffhao include_patch_information = true; 69610037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option == "--no-include-patch-information") { 69710037c866b04550fc5461058c398c2e3e509381ajeffhao include_patch_information = false; 69810037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--verbose-methods=")) { 699f6174e8a1566bb357e82506f7ec97dc359c90eb2jeffhao // TODO: rather than switch off compiler logging, make all VLOG(compiler) messages 70010037c866b04550fc5461058c398c2e3e509381ajeffhao // conditional on having verbost methods. 70110037c866b04550fc5461058c398c2e3e509381ajeffhao gLogVerbosity.compiler = false; 702c647564845429bd709ed3338c13f15063c2f9fd9Brian Carlstrom Split(option.substr(strlen("--verbose-methods=")).ToString(), ',', &verbose_methods_); 7038d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } else if (option.starts_with("--dump-init-failures=")) { 7048d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers std::string file_name = option.substr(strlen("--dump-init-failures=")).data(); 70510037c866b04550fc5461058c398c2e3e509381ajeffhao init_failure_output_.reset(new std::ofstream(file_name)); 70610037c866b04550fc5461058c398c2e3e509381ajeffhao if (init_failure_output_.get() == nullptr) { 70710037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(ERROR) << "Failed to allocate ofstream"; 70810037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (init_failure_output_->fail()) { 70910037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(ERROR) << "Failed to open " << file_name << " for writing the initialization " 71010037c866b04550fc5461058c398c2e3e509381ajeffhao << "failures."; 71110037c866b04550fc5461058c398c2e3e509381ajeffhao init_failure_output_.reset(); 71210037c866b04550fc5461058c398c2e3e509381ajeffhao } 71310037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (option.starts_with("--swap-file=")) { 7148d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers swap_file_name_ = option.substr(strlen("--swap-file=")).data(); 715c647564845429bd709ed3338c13f15063c2f9fd9Brian Carlstrom } else if (option.starts_with("--swap-fd=")) { 7168d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers const char* swap_fd_str = option.substr(strlen("--swap-fd=")).data(); 71710037c866b04550fc5461058c398c2e3e509381ajeffhao if (!ParseInt(swap_fd_str, &swap_fd_)) { 71810037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("Failed to parse --swap-fd argument '%s' as an integer", swap_fd_str); 71910037c866b04550fc5461058c398c2e3e509381ajeffhao } 72010037c866b04550fc5461058c398c2e3e509381ajeffhao if (swap_fd_ < 0) { 72110037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--swap-fd passed a negative value %d", swap_fd_); 72210037c866b04550fc5461058c398c2e3e509381ajeffhao } 72310037c866b04550fc5461058c398c2e3e509381ajeffhao } else { 72410037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("Unknown argument %s", option.data()); 72510037c866b04550fc5461058c398c2e3e509381ajeffhao } 72610037c866b04550fc5461058c398c2e3e509381ajeffhao } 72710037c866b04550fc5461058c398c2e3e509381ajeffhao 72810037c866b04550fc5461058c398c2e3e509381ajeffhao if (compiler_kind_ == Compiler::kOptimizing) { 72910037c866b04550fc5461058c398c2e3e509381ajeffhao // Optimizing only supports PIC mode. 73010037c866b04550fc5461058c398c2e3e509381ajeffhao compile_pic = true; 73110037c866b04550fc5461058c398c2e3e509381ajeffhao } 73210037c866b04550fc5461058c398c2e3e509381ajeffhao 73310037c866b04550fc5461058c398c2e3e509381ajeffhao if (oat_filename_.empty() && oat_fd_ == -1) { 73410037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("Output must be supplied with either --oat-file or --oat-fd"); 73510037c866b04550fc5461058c398c2e3e509381ajeffhao } 7368d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 73710037c866b04550fc5461058c398c2e3e509381ajeffhao if (!oat_filename_.empty() && oat_fd_ != -1) { 73810037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--oat-file should not be used with --oat-fd"); 73910037c866b04550fc5461058c398c2e3e509381ajeffhao } 74010037c866b04550fc5461058c398c2e3e509381ajeffhao 74110037c866b04550fc5461058c398c2e3e509381ajeffhao if (!oat_symbols.empty() && oat_fd_ != -1) { 7428d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers Usage("--oat-symbols should not be used with --oat-fd"); 7438d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 74410037c866b04550fc5461058c398c2e3e509381ajeffhao 74510037c866b04550fc5461058c398c2e3e509381ajeffhao if (!oat_symbols.empty() && is_host_) { 74610037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--oat-symbols should not be used with --host"); 7478d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 7488d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 74910037c866b04550fc5461058c398c2e3e509381ajeffhao if (oat_fd_ != -1 && !image_filename_.empty()) { 75010037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--oat-fd should not be used with --image"); 75110037c866b04550fc5461058c398c2e3e509381ajeffhao } 75210037c866b04550fc5461058c398c2e3e509381ajeffhao 75310037c866b04550fc5461058c398c2e3e509381ajeffhao if (android_root_.empty()) { 75410037c866b04550fc5461058c398c2e3e509381ajeffhao const char* android_root_env_var = getenv("ANDROID_ROOT"); 75510037c866b04550fc5461058c398c2e3e509381ajeffhao if (android_root_env_var == nullptr) { 7568d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers Usage("--android-root unspecified and ANDROID_ROOT not set"); 7578d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 75810037c866b04550fc5461058c398c2e3e509381ajeffhao android_root_ += android_root_env_var; 75910037c866b04550fc5461058c398c2e3e509381ajeffhao } 76010037c866b04550fc5461058c398c2e3e509381ajeffhao 7618d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers image_ = (!image_filename_.empty()); 7628d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (!image_ && boot_image_filename.empty()) { 76310037c866b04550fc5461058c398c2e3e509381ajeffhao boot_image_filename += android_root_; 76410037c866b04550fc5461058c398c2e3e509381ajeffhao boot_image_filename += "/framework/boot.art"; 76510037c866b04550fc5461058c398c2e3e509381ajeffhao } 7668d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (!boot_image_filename.empty()) { 7678d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers boot_image_option_ += "-Ximage:"; 76810037c866b04550fc5461058c398c2e3e509381ajeffhao boot_image_option_ += boot_image_filename; 76910037c866b04550fc5461058c398c2e3e509381ajeffhao } 77010037c866b04550fc5461058c398c2e3e509381ajeffhao 77110037c866b04550fc5461058c398c2e3e509381ajeffhao if (image_classes_filename_ != nullptr && !image_) { 77210037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--image-classes should only be used with --image"); 77310037c866b04550fc5461058c398c2e3e509381ajeffhao } 77410037c866b04550fc5461058c398c2e3e509381ajeffhao 7758d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (image_classes_filename_ != nullptr && !boot_image_option_.empty()) { 7768d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers Usage("--image-classes should not be used with --boot-image"); 77710037c866b04550fc5461058c398c2e3e509381ajeffhao } 77810037c866b04550fc5461058c398c2e3e509381ajeffhao 77910037c866b04550fc5461058c398c2e3e509381ajeffhao if (image_classes_zip_filename_ != nullptr && image_classes_filename_ == nullptr) { 78010037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--image-classes-zip should be used with --image-classes"); 78110037c866b04550fc5461058c398c2e3e509381ajeffhao } 78210037c866b04550fc5461058c398c2e3e509381ajeffhao 78310037c866b04550fc5461058c398c2e3e509381ajeffhao if (compiled_classes_filename_ != nullptr && !image_) { 78410037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--compiled-classes should only be used with --image"); 78510037c866b04550fc5461058c398c2e3e509381ajeffhao } 7868d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 7878d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (compiled_classes_filename_ != nullptr && !boot_image_option_.empty()) { 78810037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--compiled-classes should not be used with --boot-image"); 78910037c866b04550fc5461058c398c2e3e509381ajeffhao } 79010037c866b04550fc5461058c398c2e3e509381ajeffhao 79110037c866b04550fc5461058c398c2e3e509381ajeffhao if (compiled_classes_zip_filename_ != nullptr && compiled_classes_filename_ == nullptr) { 79210037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--compiled-classes-zip should be used with --compiled-classes"); 79310037c866b04550fc5461058c398c2e3e509381ajeffhao } 79410037c866b04550fc5461058c398c2e3e509381ajeffhao 79510037c866b04550fc5461058c398c2e3e509381ajeffhao if (dex_filenames_.empty() && zip_fd_ == -1) { 79610037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("Input must be supplied with either --dex-file or --zip-fd"); 79710037c866b04550fc5461058c398c2e3e509381ajeffhao } 79810037c866b04550fc5461058c398c2e3e509381ajeffhao 79910037c866b04550fc5461058c398c2e3e509381ajeffhao if (!dex_filenames_.empty() && zip_fd_ != -1) { 80010037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--dex-file should not be used with --zip-fd"); 80110037c866b04550fc5461058c398c2e3e509381ajeffhao } 80210037c866b04550fc5461058c398c2e3e509381ajeffhao 80310037c866b04550fc5461058c398c2e3e509381ajeffhao if (!dex_filenames_.empty() && !zip_location_.empty()) { 80410037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--dex-file should not be used with --zip-location"); 80510037c866b04550fc5461058c398c2e3e509381ajeffhao } 80610037c866b04550fc5461058c398c2e3e509381ajeffhao 80710037c866b04550fc5461058c398c2e3e509381ajeffhao if (dex_locations_.empty()) { 80810037c866b04550fc5461058c398c2e3e509381ajeffhao for (const char* dex_file_name : dex_filenames_) { 80910037c866b04550fc5461058c398c2e3e509381ajeffhao dex_locations_.push_back(dex_file_name); 81010037c866b04550fc5461058c398c2e3e509381ajeffhao } 81110037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (dex_locations_.size() != dex_filenames_.size()) { 81210037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--dex-location arguments do not match --dex-file arguments"); 81310037c866b04550fc5461058c398c2e3e509381ajeffhao } 81410037c866b04550fc5461058c398c2e3e509381ajeffhao 81510037c866b04550fc5461058c398c2e3e509381ajeffhao if (zip_fd_ != -1 && zip_location_.empty()) { 81610037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("--zip-location should be supplied with --zip-fd"); 8178d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 8188d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 81910037c866b04550fc5461058c398c2e3e509381ajeffhao if (boot_image_option_.empty()) { 82010037c866b04550fc5461058c398c2e3e509381ajeffhao if (image_base_ == 0) { 82110037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("Non-zero --base not specified"); 82210037c866b04550fc5461058c398c2e3e509381ajeffhao } 82310037c866b04550fc5461058c398c2e3e509381ajeffhao } 82410037c866b04550fc5461058c398c2e3e509381ajeffhao 82510037c866b04550fc5461058c398c2e3e509381ajeffhao oat_stripped_ = oat_filename_; 82610037c866b04550fc5461058c398c2e3e509381ajeffhao if (!oat_symbols.empty()) { 82710037c866b04550fc5461058c398c2e3e509381ajeffhao oat_unstripped_ = oat_symbols; 82810037c866b04550fc5461058c398c2e3e509381ajeffhao } else { 82910037c866b04550fc5461058c398c2e3e509381ajeffhao oat_unstripped_ = oat_filename_; 83010037c866b04550fc5461058c398c2e3e509381ajeffhao } 83110037c866b04550fc5461058c398c2e3e509381ajeffhao 83210037c866b04550fc5461058c398c2e3e509381ajeffhao // If no instruction set feature was given, use the default one for the target 83310037c866b04550fc5461058c398c2e3e509381ajeffhao // instruction set. 83410037c866b04550fc5461058c398c2e3e509381ajeffhao if (instruction_set_features_.get() == nullptr) { 83510037c866b04550fc5461058c398c2e3e509381ajeffhao instruction_set_features_.reset( 83610037c866b04550fc5461058c398c2e3e509381ajeffhao InstructionSetFeatures::FromVariant(instruction_set_, "default", &error_msg)); 83710037c866b04550fc5461058c398c2e3e509381ajeffhao if (instruction_set_features_.get() == nullptr) { 83810037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("Problem initializing default instruction set features variant: %s", 83910037c866b04550fc5461058c398c2e3e509381ajeffhao error_msg.c_str()); 8408d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 8418d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 84210037c866b04550fc5461058c398c2e3e509381ajeffhao 84310037c866b04550fc5461058c398c2e3e509381ajeffhao if (instruction_set_ == kRuntimeISA) { 84410037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<const InstructionSetFeatures> runtime_features( 84510037c866b04550fc5461058c398c2e3e509381ajeffhao InstructionSetFeatures::FromCppDefines()); 84610037c866b04550fc5461058c398c2e3e509381ajeffhao if (!instruction_set_features_->Equals(runtime_features.get())) { 84710037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(WARNING) << "Mismatch between dex2oat instruction set features (" 8488d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers << *instruction_set_features_ << ") and those of dex2oat executable (" 8498d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers << *runtime_features <<") for the command line:\n" 85010037c866b04550fc5461058c398c2e3e509381ajeffhao << CommandLine(); 85110037c866b04550fc5461058c398c2e3e509381ajeffhao } 85210037c866b04550fc5461058c398c2e3e509381ajeffhao } 85310037c866b04550fc5461058c398c2e3e509381ajeffhao 85410037c866b04550fc5461058c398c2e3e509381ajeffhao if (compiler_filter_string == nullptr) { 85510037c866b04550fc5461058c398c2e3e509381ajeffhao if (instruction_set_ == kMips64) { 85610037c866b04550fc5461058c398c2e3e509381ajeffhao // TODO: fix compiler for Mips64. 85710037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_filter_string = "interpret-only"; 85810037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (image_) { 85910037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_filter_string = "speed"; 86010037c866b04550fc5461058c398c2e3e509381ajeffhao } else { 86110037c866b04550fc5461058c398c2e3e509381ajeffhao // TODO: Migrate SMALL mode to command line option. 86210037c866b04550fc5461058c398c2e3e509381ajeffhao #if ART_SMALL_MODE 86310037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_filter_string = "interpret-only"; 86410037c866b04550fc5461058c398c2e3e509381ajeffhao #else 86510037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_filter_string = "speed"; 86610037c866b04550fc5461058c398c2e3e509381ajeffhao #endif 86710037c866b04550fc5461058c398c2e3e509381ajeffhao } 86810037c866b04550fc5461058c398c2e3e509381ajeffhao } 86910037c866b04550fc5461058c398c2e3e509381ajeffhao CHECK(compiler_filter_string != nullptr); 87010037c866b04550fc5461058c398c2e3e509381ajeffhao CompilerOptions::CompilerFilter compiler_filter = CompilerOptions::kDefaultCompilerFilter; 87110037c866b04550fc5461058c398c2e3e509381ajeffhao if (strcmp(compiler_filter_string, "verify-none") == 0) { 87210037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_filter = CompilerOptions::kVerifyNone; 87310037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (strcmp(compiler_filter_string, "interpret-only") == 0) { 87410037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_filter = CompilerOptions::kInterpretOnly; 87510037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (strcmp(compiler_filter_string, "space") == 0) { 87610037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_filter = CompilerOptions::kSpace; 87710037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (strcmp(compiler_filter_string, "balanced") == 0) { 87810037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_filter = CompilerOptions::kBalanced; 87910037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (strcmp(compiler_filter_string, "speed") == 0) { 88010037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_filter = CompilerOptions::kSpeed; 88110037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (strcmp(compiler_filter_string, "everything") == 0) { 88210037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_filter = CompilerOptions::kEverything; 88310037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (strcmp(compiler_filter_string, "time") == 0) { 88410037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_filter = CompilerOptions::kTime; 88510037c866b04550fc5461058c398c2e3e509381ajeffhao } else { 88610037c866b04550fc5461058c398c2e3e509381ajeffhao Usage("Unknown --compiler-filter value %s", compiler_filter_string); 88710037c866b04550fc5461058c398c2e3e509381ajeffhao } 88810037c866b04550fc5461058c398c2e3e509381ajeffhao 88910037c866b04550fc5461058c398c2e3e509381ajeffhao // Checks are all explicit until we know the architecture. 89010037c866b04550fc5461058c398c2e3e509381ajeffhao bool implicit_null_checks = false; 89110037c866b04550fc5461058c398c2e3e509381ajeffhao bool implicit_so_checks = false; 89210037c866b04550fc5461058c398c2e3e509381ajeffhao bool implicit_suspend_checks = false; 89310037c866b04550fc5461058c398c2e3e509381ajeffhao // Set the compilation target's implicit checks options. 89410037c866b04550fc5461058c398c2e3e509381ajeffhao switch (instruction_set_) { 89510037c866b04550fc5461058c398c2e3e509381ajeffhao case kArm: 89610037c866b04550fc5461058c398c2e3e509381ajeffhao case kThumb2: 89710037c866b04550fc5461058c398c2e3e509381ajeffhao case kArm64: 89810037c866b04550fc5461058c398c2e3e509381ajeffhao case kX86: 89910037c866b04550fc5461058c398c2e3e509381ajeffhao case kX86_64: 90010037c866b04550fc5461058c398c2e3e509381ajeffhao implicit_null_checks = true; 9018d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers implicit_so_checks = true; 90210037c866b04550fc5461058c398c2e3e509381ajeffhao break; 90310037c866b04550fc5461058c398c2e3e509381ajeffhao 90410037c866b04550fc5461058c398c2e3e509381ajeffhao default: 90510037c866b04550fc5461058c398c2e3e509381ajeffhao // Defaults are correct. 90610037c866b04550fc5461058c398c2e3e509381ajeffhao break; 90710037c866b04550fc5461058c398c2e3e509381ajeffhao } 90810037c866b04550fc5461058c398c2e3e509381ajeffhao 90910037c866b04550fc5461058c398c2e3e509381ajeffhao if (print_pass_options) { 91010037c866b04550fc5461058c398c2e3e509381ajeffhao PassDriverMEOpts::PrintPassOptions(); 91110037c866b04550fc5461058c398c2e3e509381ajeffhao } 91210037c866b04550fc5461058c398c2e3e509381ajeffhao 91310037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_options_.reset(new CompilerOptions(compiler_filter, 91410037c866b04550fc5461058c398c2e3e509381ajeffhao huge_method_threshold, 91510037c866b04550fc5461058c398c2e3e509381ajeffhao large_method_threshold, 91610037c866b04550fc5461058c398c2e3e509381ajeffhao small_method_threshold, 91710037c866b04550fc5461058c398c2e3e509381ajeffhao tiny_method_threshold, 91810037c866b04550fc5461058c398c2e3e509381ajeffhao num_dex_methods_threshold, 91910037c866b04550fc5461058c398c2e3e509381ajeffhao generate_gdb_information, 92010037c866b04550fc5461058c398c2e3e509381ajeffhao include_patch_information, 92110037c866b04550fc5461058c398c2e3e509381ajeffhao top_k_profile_threshold, 92210037c866b04550fc5461058c398c2e3e509381ajeffhao include_debug_symbols, 92310037c866b04550fc5461058c398c2e3e509381ajeffhao implicit_null_checks, 92410037c866b04550fc5461058c398c2e3e509381ajeffhao implicit_so_checks, 92510037c866b04550fc5461058c398c2e3e509381ajeffhao implicit_suspend_checks, 92610037c866b04550fc5461058c398c2e3e509381ajeffhao compile_pic, 92710037c866b04550fc5461058c398c2e3e509381ajeffhao verbose_methods_.empty() ? 92810037c866b04550fc5461058c398c2e3e509381ajeffhao nullptr : 9298d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers &verbose_methods_, 9308d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers init_failure_output_.get())); 93110037c866b04550fc5461058c398c2e3e509381ajeffhao 93210037c866b04550fc5461058c398c2e3e509381ajeffhao // Done with usage checks, enable watchdog if requested 93310037c866b04550fc5461058c398c2e3e509381ajeffhao if (watch_dog_enabled) { 93410037c866b04550fc5461058c398c2e3e509381ajeffhao watchdog_.reset(new WatchDog(true)); 93510037c866b04550fc5461058c398c2e3e509381ajeffhao } 93610037c866b04550fc5461058c398c2e3e509381ajeffhao 93710037c866b04550fc5461058c398c2e3e509381ajeffhao // Fill some values into the key-value store for the oat header. 93810037c866b04550fc5461058c398c2e3e509381ajeffhao key_value_store_.reset(new SafeMap<std::string, std::string>()); 93910037c866b04550fc5461058c398c2e3e509381ajeffhao 94010037c866b04550fc5461058c398c2e3e509381ajeffhao // Insert some compiler things. 94110037c866b04550fc5461058c398c2e3e509381ajeffhao { 94210037c866b04550fc5461058c398c2e3e509381ajeffhao std::ostringstream oss; 94310037c866b04550fc5461058c398c2e3e509381ajeffhao for (int i = 0; i < argc; ++i) { 94410037c866b04550fc5461058c398c2e3e509381ajeffhao if (i > 0) { 94510037c866b04550fc5461058c398c2e3e509381ajeffhao oss << ' '; 94610037c866b04550fc5461058c398c2e3e509381ajeffhao } 9478d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers oss << argv[i]; 9488d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 9498d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers key_value_store_->Put(OatHeader::kDex2OatCmdLineKey, oss.str()); 95010037c866b04550fc5461058c398c2e3e509381ajeffhao oss.str(""); // Reset. 95110037c866b04550fc5461058c398c2e3e509381ajeffhao oss << kRuntimeISA; 95210037c866b04550fc5461058c398c2e3e509381ajeffhao key_value_store_->Put(OatHeader::kDex2OatHostKey, oss.str()); 95310037c866b04550fc5461058c398c2e3e509381ajeffhao key_value_store_->Put(OatHeader::kPicKey, compile_pic ? "true" : "false"); 95410037c866b04550fc5461058c398c2e3e509381ajeffhao } 95510037c866b04550fc5461058c398c2e3e509381ajeffhao } 95610037c866b04550fc5461058c398c2e3e509381ajeffhao 95710037c866b04550fc5461058c398c2e3e509381ajeffhao // Check whether the oat output file is writable, and open it for later. Also open a swap file, 95810037c866b04550fc5461058c398c2e3e509381ajeffhao // if a name is given. 95910037c866b04550fc5461058c398c2e3e509381ajeffhao bool OpenFile() { 9602b87ddf36abff711fa2233c49bffc7ceb03b15d7Dragos Sbirlea bool create_file = !oat_unstripped_.empty(); // as opposed to using open file descriptor 9618d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (create_file) { 96210037c866b04550fc5461058c398c2e3e509381ajeffhao oat_file_.reset(OS::CreateEmptyFile(oat_unstripped_.c_str())); 96310037c866b04550fc5461058c398c2e3e509381ajeffhao if (oat_location_.empty()) { 96410037c866b04550fc5461058c398c2e3e509381ajeffhao oat_location_ = oat_filename_; 96510037c866b04550fc5461058c398c2e3e509381ajeffhao } 96610037c866b04550fc5461058c398c2e3e509381ajeffhao } else { 9678d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers oat_file_.reset(new File(oat_fd_, oat_location_, true)); 9688d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers oat_file_->DisableAutoClose(); 9698d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (oat_file_->SetLength(0) != 0) { 97010037c866b04550fc5461058c398c2e3e509381ajeffhao PLOG(WARNING) << "Truncating oat file " << oat_location_ << " failed."; 97110037c866b04550fc5461058c398c2e3e509381ajeffhao } 97210037c866b04550fc5461058c398c2e3e509381ajeffhao } 97310037c866b04550fc5461058c398c2e3e509381ajeffhao if (oat_file_.get() == nullptr) { 97410037c866b04550fc5461058c398c2e3e509381ajeffhao PLOG(ERROR) << "Failed to create oat file: " << oat_location_; 97510037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 97610037c866b04550fc5461058c398c2e3e509381ajeffhao } 97710037c866b04550fc5461058c398c2e3e509381ajeffhao if (create_file && fchmod(oat_file_->Fd(), 0644) != 0) { 97810037c866b04550fc5461058c398c2e3e509381ajeffhao PLOG(ERROR) << "Failed to make oat file world readable: " << oat_location_; 97910037c866b04550fc5461058c398c2e3e509381ajeffhao oat_file_->Erase(); 98010037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 9818a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers } 98210037c866b04550fc5461058c398c2e3e509381ajeffhao 9838a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers // Swap file handling. 98410037c866b04550fc5461058c398c2e3e509381ajeffhao // 98510037c866b04550fc5461058c398c2e3e509381ajeffhao // If the swap fd is not -1, we assume this is the file descriptor of an open but unlinked file 98610037c866b04550fc5461058c398c2e3e509381ajeffhao // that we can use for swap. 98710037c866b04550fc5461058c398c2e3e509381ajeffhao // 98810037c866b04550fc5461058c398c2e3e509381ajeffhao // If the swap fd is -1 and we have a swap-file string, open the given file as a swap file. We 98910037c866b04550fc5461058c398c2e3e509381ajeffhao // will immediately unlink to satisfy the swap fd assumption. 99010037c866b04550fc5461058c398c2e3e509381ajeffhao if (swap_fd_ == -1 && !swap_file_name_.empty()) { 99110037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<File> swap_file(OS::CreateEmptyFile(swap_file_name_.c_str())); 99210037c866b04550fc5461058c398c2e3e509381ajeffhao if (swap_file.get() == nullptr) { 99310037c866b04550fc5461058c398c2e3e509381ajeffhao PLOG(ERROR) << "Failed to create swap file: " << swap_file_name_; 99410037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 99510037c866b04550fc5461058c398c2e3e509381ajeffhao } 99610037c866b04550fc5461058c398c2e3e509381ajeffhao swap_fd_ = swap_file->Fd(); 99710037c866b04550fc5461058c398c2e3e509381ajeffhao swap_file->MarkUnchecked(); // We don't we to track this, it will be unlinked immediately. 99810037c866b04550fc5461058c398c2e3e509381ajeffhao swap_file->DisableAutoClose(); // We'll handle it ourselves, the File object will be 9998a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers // released immediately. 100010037c866b04550fc5461058c398c2e3e509381ajeffhao unlink(swap_file_name_.c_str()); 100110037c866b04550fc5461058c398c2e3e509381ajeffhao } 100210037c866b04550fc5461058c398c2e3e509381ajeffhao 100310037c866b04550fc5461058c398c2e3e509381ajeffhao return true; 100410037c866b04550fc5461058c398c2e3e509381ajeffhao } 100510037c866b04550fc5461058c398c2e3e509381ajeffhao 100610037c866b04550fc5461058c398c2e3e509381ajeffhao void EraseOatFile() { 100710037c866b04550fc5461058c398c2e3e509381ajeffhao DCHECK(oat_file_.get() != nullptr); 100810037c866b04550fc5461058c398c2e3e509381ajeffhao oat_file_->Erase(); 100910037c866b04550fc5461058c398c2e3e509381ajeffhao oat_file_.reset(); 101010037c866b04550fc5461058c398c2e3e509381ajeffhao } 101110037c866b04550fc5461058c398c2e3e509381ajeffhao 101210037c866b04550fc5461058c398c2e3e509381ajeffhao // Set up the environment for compilation. Includes starting the runtime and loading/opening the 101310037c866b04550fc5461058c398c2e3e509381ajeffhao // boot class path. 101410037c866b04550fc5461058c398c2e3e509381ajeffhao bool Setup() { 101510037c866b04550fc5461058c398c2e3e509381ajeffhao TimingLogger::ScopedTiming t("dex2oat Setup", timings_); 101610037c866b04550fc5461058c398c2e3e509381ajeffhao RuntimeOptions runtime_options; 101710037c866b04550fc5461058c398c2e3e509381ajeffhao art::MemMap::Init(); // For ZipEntry::ExtractToMemMap. 101810037c866b04550fc5461058c398c2e3e509381ajeffhao if (boot_image_option_.empty()) { 101910037c866b04550fc5461058c398c2e3e509381ajeffhao std::string boot_class_path = "-Xbootclasspath:"; 102010037c866b04550fc5461058c398c2e3e509381ajeffhao boot_class_path += Join(dex_filenames_, ':'); 102110037c866b04550fc5461058c398c2e3e509381ajeffhao runtime_options.push_back(std::make_pair(boot_class_path, nullptr)); 102210037c866b04550fc5461058c398c2e3e509381ajeffhao std::string boot_class_path_locations = "-Xbootclasspath-locations:"; 102310037c866b04550fc5461058c398c2e3e509381ajeffhao boot_class_path_locations += Join(dex_locations_, ':'); 102410037c866b04550fc5461058c398c2e3e509381ajeffhao runtime_options.push_back(std::make_pair(boot_class_path_locations, nullptr)); 102510037c866b04550fc5461058c398c2e3e509381ajeffhao } else { 102610037c866b04550fc5461058c398c2e3e509381ajeffhao runtime_options.push_back(std::make_pair(boot_image_option_, nullptr)); 102710037c866b04550fc5461058c398c2e3e509381ajeffhao } 102810037c866b04550fc5461058c398c2e3e509381ajeffhao for (size_t i = 0; i < runtime_args_.size(); i++) { 102910037c866b04550fc5461058c398c2e3e509381ajeffhao runtime_options.push_back(std::make_pair(runtime_args_[i], nullptr)); 103010037c866b04550fc5461058c398c2e3e509381ajeffhao } 103110037c866b04550fc5461058c398c2e3e509381ajeffhao 103210037c866b04550fc5461058c398c2e3e509381ajeffhao verification_results_.reset(new VerificationResults(compiler_options_.get())); 103310037c866b04550fc5461058c398c2e3e509381ajeffhao callbacks_.reset(new QuickCompilerCallbacks(verification_results_.get(), &method_inliner_map_)); 103410037c866b04550fc5461058c398c2e3e509381ajeffhao runtime_options.push_back(std::make_pair("compilercallbacks", callbacks_.get())); 103510037c866b04550fc5461058c398c2e3e509381ajeffhao runtime_options.push_back( 103610037c866b04550fc5461058c398c2e3e509381ajeffhao std::make_pair("imageinstructionset", GetInstructionSetString(instruction_set_))); 103710037c866b04550fc5461058c398c2e3e509381ajeffhao 103810037c866b04550fc5461058c398c2e3e509381ajeffhao if (!CreateRuntime(runtime_options)) { 103910037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 104010037c866b04550fc5461058c398c2e3e509381ajeffhao } 104110037c866b04550fc5461058c398c2e3e509381ajeffhao 104210037c866b04550fc5461058c398c2e3e509381ajeffhao // Runtime::Create acquired the mutator_lock_ that is normally given away when we 104310037c866b04550fc5461058c398c2e3e509381ajeffhao // Runtime::Start, give it away now so that we don't starve GC. 104410037c866b04550fc5461058c398c2e3e509381ajeffhao Thread* self = Thread::Current(); 104510037c866b04550fc5461058c398c2e3e509381ajeffhao self->TransitionFromRunnableToSuspended(kNative); 104610037c866b04550fc5461058c398c2e3e509381ajeffhao // If we're doing the image, override the compiler filter to force full compilation. Must be 104710037c866b04550fc5461058c398c2e3e509381ajeffhao // done ahead of WellKnownClasses::Init that causes verification. Note: doesn't force 104810037c866b04550fc5461058c398c2e3e509381ajeffhao // compilation of class initializers. 104910037c866b04550fc5461058c398c2e3e509381ajeffhao // Whilst we're in native take the opportunity to initialize well known classes. 105010037c866b04550fc5461058c398c2e3e509381ajeffhao WellKnownClasses::Init(self->GetJniEnv()); 105110037c866b04550fc5461058c398c2e3e509381ajeffhao 105210037c866b04550fc5461058c398c2e3e509381ajeffhao // If --image-classes was specified, calculate the full list of classes to include in the image 105310037c866b04550fc5461058c398c2e3e509381ajeffhao if (image_classes_filename_ != nullptr) { 105410037c866b04550fc5461058c398c2e3e509381ajeffhao std::string error_msg; 105510037c866b04550fc5461058c398c2e3e509381ajeffhao if (image_classes_zip_filename_ != nullptr) { 105610037c866b04550fc5461058c398c2e3e509381ajeffhao image_classes_.reset(ReadImageClassesFromZip(image_classes_zip_filename_, 105710037c866b04550fc5461058c398c2e3e509381ajeffhao image_classes_filename_, 105810037c866b04550fc5461058c398c2e3e509381ajeffhao &error_msg)); 105910037c866b04550fc5461058c398c2e3e509381ajeffhao } else { 106010037c866b04550fc5461058c398c2e3e509381ajeffhao image_classes_.reset(ReadImageClassesFromFile(image_classes_filename_)); 106110037c866b04550fc5461058c398c2e3e509381ajeffhao } 106210037c866b04550fc5461058c398c2e3e509381ajeffhao if (image_classes_.get() == nullptr) { 106310037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(ERROR) << "Failed to create list of image classes from '" << image_classes_filename_ << 106410037c866b04550fc5461058c398c2e3e509381ajeffhao "': " << error_msg; 106510037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 106610037c866b04550fc5461058c398c2e3e509381ajeffhao } 106710037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (image_) { 106810037c866b04550fc5461058c398c2e3e509381ajeffhao image_classes_.reset(new std::set<std::string>); 10692b87ddf36abff711fa2233c49bffc7ceb03b15d7Dragos Sbirlea } 10708d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers // If --compiled-classes was specified, calculate the full list of classes to compile in the 107110037c866b04550fc5461058c398c2e3e509381ajeffhao // image. 107210037c866b04550fc5461058c398c2e3e509381ajeffhao if (compiled_classes_filename_ != nullptr) { 107310037c866b04550fc5461058c398c2e3e509381ajeffhao std::string error_msg; 107410037c866b04550fc5461058c398c2e3e509381ajeffhao if (compiled_classes_zip_filename_ != nullptr) { 107510037c866b04550fc5461058c398c2e3e509381ajeffhao compiled_classes_.reset(ReadImageClassesFromZip(compiled_classes_zip_filename_, 107610037c866b04550fc5461058c398c2e3e509381ajeffhao compiled_classes_filename_, 107710037c866b04550fc5461058c398c2e3e509381ajeffhao &error_msg)); 107810037c866b04550fc5461058c398c2e3e509381ajeffhao } else { 107910037c866b04550fc5461058c398c2e3e509381ajeffhao compiled_classes_.reset(ReadImageClassesFromFile(compiled_classes_filename_)); 108010037c866b04550fc5461058c398c2e3e509381ajeffhao } 108110037c866b04550fc5461058c398c2e3e509381ajeffhao if (compiled_classes_.get() == nullptr) { 108210037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(ERROR) << "Failed to create list of compiled classes from '" 108310037c866b04550fc5461058c398c2e3e509381ajeffhao << compiled_classes_filename_ << "': " << error_msg; 108410037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 108510037c866b04550fc5461058c398c2e3e509381ajeffhao } 108610037c866b04550fc5461058c398c2e3e509381ajeffhao } else if (image_) { 108710037c866b04550fc5461058c398c2e3e509381ajeffhao compiled_classes_.reset(nullptr); // By default compile everything. 108810037c866b04550fc5461058c398c2e3e509381ajeffhao } 108910037c866b04550fc5461058c398c2e3e509381ajeffhao 109010037c866b04550fc5461058c398c2e3e509381ajeffhao if (boot_image_option_.empty()) { 109110037c866b04550fc5461058c398c2e3e509381ajeffhao dex_files_ = Runtime::Current()->GetClassLinker()->GetBootClassPath(); 109210037c866b04550fc5461058c398c2e3e509381ajeffhao } else { 109310037c866b04550fc5461058c398c2e3e509381ajeffhao if (dex_filenames_.empty()) { 109410037c866b04550fc5461058c398c2e3e509381ajeffhao ATRACE_BEGIN("Opening zip archive from file descriptor"); 109510037c866b04550fc5461058c398c2e3e509381ajeffhao std::string error_msg; 109610037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(zip_fd_, 109710037c866b04550fc5461058c398c2e3e509381ajeffhao zip_location_.c_str(), 109810037c866b04550fc5461058c398c2e3e509381ajeffhao &error_msg)); 109910037c866b04550fc5461058c398c2e3e509381ajeffhao if (zip_archive.get() == nullptr) { 110010037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(ERROR) << "Failed to open zip from file descriptor for '" << zip_location_ << "': " 110110037c866b04550fc5461058c398c2e3e509381ajeffhao << error_msg; 110210037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 110310037c866b04550fc5461058c398c2e3e509381ajeffhao } 110410037c866b04550fc5461058c398c2e3e509381ajeffhao if (!DexFile::OpenFromZip(*zip_archive.get(), zip_location_, &error_msg, &dex_files_)) { 110510037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(ERROR) << "Failed to open dex from file descriptor for zip file '" << zip_location_ 110610037c866b04550fc5461058c398c2e3e509381ajeffhao << "': " << error_msg; 110710037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 110810037c866b04550fc5461058c398c2e3e509381ajeffhao } 110910037c866b04550fc5461058c398c2e3e509381ajeffhao ATRACE_END(); 111010037c866b04550fc5461058c398c2e3e509381ajeffhao } else { 111110037c866b04550fc5461058c398c2e3e509381ajeffhao size_t failure_count = OpenDexFiles(dex_filenames_, dex_locations_, dex_files_); 111210037c866b04550fc5461058c398c2e3e509381ajeffhao if (failure_count > 0) { 111310037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(ERROR) << "Failed to open some dex files: " << failure_count; 111410037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 111510037c866b04550fc5461058c398c2e3e509381ajeffhao } 111610037c866b04550fc5461058c398c2e3e509381ajeffhao } 111710037c866b04550fc5461058c398c2e3e509381ajeffhao 111810037c866b04550fc5461058c398c2e3e509381ajeffhao constexpr bool kSaveDexInput = false; 111910037c866b04550fc5461058c398c2e3e509381ajeffhao if (kSaveDexInput) { 112010037c866b04550fc5461058c398c2e3e509381ajeffhao for (size_t i = 0; i < dex_files_.size(); ++i) { 112110037c866b04550fc5461058c398c2e3e509381ajeffhao const DexFile* dex_file = dex_files_[i]; 112210037c866b04550fc5461058c398c2e3e509381ajeffhao std::string tmp_file_name(StringPrintf("/data/local/tmp/dex2oat.%d.%zd.dex", 112310037c866b04550fc5461058c398c2e3e509381ajeffhao getpid(), i)); 112410037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<File> tmp_file(OS::CreateEmptyFile(tmp_file_name.c_str())); 112510037c866b04550fc5461058c398c2e3e509381ajeffhao if (tmp_file.get() == nullptr) { 112610037c866b04550fc5461058c398c2e3e509381ajeffhao PLOG(ERROR) << "Failed to open file " << tmp_file_name 112710037c866b04550fc5461058c398c2e3e509381ajeffhao << ". Try: adb shell chmod 777 /data/local/tmp"; 112810037c866b04550fc5461058c398c2e3e509381ajeffhao continue; 112910037c866b04550fc5461058c398c2e3e509381ajeffhao } 113010037c866b04550fc5461058c398c2e3e509381ajeffhao // This is just dumping files for debugging. Ignore errors, and leave remnants. 113110037c866b04550fc5461058c398c2e3e509381ajeffhao UNUSED(tmp_file->WriteFully(dex_file->Begin(), dex_file->Size())); 11328d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers UNUSED(tmp_file->Flush()); 113310037c866b04550fc5461058c398c2e3e509381ajeffhao UNUSED(tmp_file->Close()); 113410037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(INFO) << "Wrote input to " << tmp_file_name; 113510037c866b04550fc5461058c398c2e3e509381ajeffhao } 113610037c866b04550fc5461058c398c2e3e509381ajeffhao } 1137a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes } 113810037c866b04550fc5461058c398c2e3e509381ajeffhao // Ensure opened dex files are writable for dex-to-dex transformations. 113910037c866b04550fc5461058c398c2e3e509381ajeffhao for (const auto& dex_file : dex_files_) { 11408a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers if (!dex_file->EnableWrite()) { 11418d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers PLOG(ERROR) << "Failed to make .dex file writeable '" << dex_file->GetLocation() << "'\n"; 11428d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 114310037c866b04550fc5461058c398c2e3e509381ajeffhao } 114410037c866b04550fc5461058c398c2e3e509381ajeffhao 114510037c866b04550fc5461058c398c2e3e509381ajeffhao // If we use a swap file, ensure we are above the threshold to make it necessary. 114610037c866b04550fc5461058c398c2e3e509381ajeffhao if (swap_fd_ != -1) { 114710037c866b04550fc5461058c398c2e3e509381ajeffhao if (!UseSwap(image_, dex_files_)) { 114810037c866b04550fc5461058c398c2e3e509381ajeffhao close(swap_fd_); 114910037c866b04550fc5461058c398c2e3e509381ajeffhao swap_fd_ = -1; 115010037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(INFO) << "Decided to run without swap."; 115110037c866b04550fc5461058c398c2e3e509381ajeffhao } else { 11528a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers LOG(INFO) << "Accepted running with swap."; 115310037c866b04550fc5461058c398c2e3e509381ajeffhao } 115410037c866b04550fc5461058c398c2e3e509381ajeffhao } 115510037c866b04550fc5461058c398c2e3e509381ajeffhao // Note that dex2oat won't close the swap_fd_. The compiler driver's swap space will do that. 115610037c866b04550fc5461058c398c2e3e509381ajeffhao 115710037c866b04550fc5461058c398c2e3e509381ajeffhao /* 115810037c866b04550fc5461058c398c2e3e509381ajeffhao * If we're not in interpret-only or verify-none mode, go ahead and compile small applications. 115910037c866b04550fc5461058c398c2e3e509381ajeffhao * Don't bother to check if we're doing the image. 116010037c866b04550fc5461058c398c2e3e509381ajeffhao */ 116110037c866b04550fc5461058c398c2e3e509381ajeffhao if (!image_ && 116210037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_options_->IsCompilationEnabled() && 116310037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_kind_ == Compiler::kQuick) { 116410037c866b04550fc5461058c398c2e3e509381ajeffhao size_t num_methods = 0; 116510037c866b04550fc5461058c398c2e3e509381ajeffhao for (size_t i = 0; i != dex_files_.size(); ++i) { 116610037c866b04550fc5461058c398c2e3e509381ajeffhao const DexFile* dex_file = dex_files_[i]; 116710037c866b04550fc5461058c398c2e3e509381ajeffhao CHECK(dex_file != nullptr); 116810037c866b04550fc5461058c398c2e3e509381ajeffhao num_methods += dex_file->NumMethodIds(); 116910037c866b04550fc5461058c398c2e3e509381ajeffhao } 117010037c866b04550fc5461058c398c2e3e509381ajeffhao if (num_methods <= compiler_options_->GetNumDexMethodsThreshold()) { 117110037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_options_->SetCompilerFilter(CompilerOptions::kSpeed); 117210037c866b04550fc5461058c398c2e3e509381ajeffhao VLOG(compiler) << "Below method threshold, compiling anyways"; 117310037c866b04550fc5461058c398c2e3e509381ajeffhao } 117410037c866b04550fc5461058c398c2e3e509381ajeffhao } 117510037c866b04550fc5461058c398c2e3e509381ajeffhao 117610037c866b04550fc5461058c398c2e3e509381ajeffhao return true; 117710037c866b04550fc5461058c398c2e3e509381ajeffhao } 117810037c866b04550fc5461058c398c2e3e509381ajeffhao 117910037c866b04550fc5461058c398c2e3e509381ajeffhao // Create and invoke the compiler driver. This will compile all the dex files. 118010037c866b04550fc5461058c398c2e3e509381ajeffhao void Compile() { 118110037c866b04550fc5461058c398c2e3e509381ajeffhao TimingLogger::ScopedTiming t("dex2oat Compile", timings_); 118210037c866b04550fc5461058c398c2e3e509381ajeffhao compiler_phases_timings_.reset(new CumulativeLogger("compilation times")); 11838d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 118410037c866b04550fc5461058c398c2e3e509381ajeffhao // Handle and ClassLoader creation needs to come after Runtime::Create 118510037c866b04550fc5461058c398c2e3e509381ajeffhao jobject class_loader = nullptr; 118610037c866b04550fc5461058c398c2e3e509381ajeffhao Thread* self = Thread::Current(); 118710037c866b04550fc5461058c398c2e3e509381ajeffhao if (!boot_image_option_.empty()) { 11888d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 11898a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers std::vector<const DexFile*> class_path_files(dex_files_); 119010037c866b04550fc5461058c398c2e3e509381ajeffhao OpenClassPathFiles(runtime_->GetClassPathString(), class_path_files); 119110037c866b04550fc5461058c398c2e3e509381ajeffhao ScopedObjectAccess soa(self); 11928d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers for (size_t i = 0; i < class_path_files.size(); i++) { 11938d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers class_linker->RegisterDexFile(*class_path_files[i]); 119410037c866b04550fc5461058c398c2e3e509381ajeffhao } 119510037c866b04550fc5461058c398c2e3e509381ajeffhao soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader); 119610037c866b04550fc5461058c398c2e3e509381ajeffhao ScopedLocalRef<jobject> class_loader_local(soa.Env(), 119710037c866b04550fc5461058c398c2e3e509381ajeffhao soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader)); 119810037c866b04550fc5461058c398c2e3e509381ajeffhao class_loader = soa.Env()->NewGlobalRef(class_loader_local.get()); 119910037c866b04550fc5461058c398c2e3e509381ajeffhao Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path_files); 12008a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers } 12018a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers 12028a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers driver_.reset(new CompilerDriver(compiler_options_.get(), 120310037c866b04550fc5461058c398c2e3e509381ajeffhao verification_results_.get(), 120410037c866b04550fc5461058c398c2e3e509381ajeffhao &method_inliner_map_, 12058d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers compiler_kind_, 12068a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers instruction_set_, 120710037c866b04550fc5461058c398c2e3e509381ajeffhao instruction_set_features_.get(), 120810037c866b04550fc5461058c398c2e3e509381ajeffhao image_, 120910037c866b04550fc5461058c398c2e3e509381ajeffhao image_classes_.release(), 121010037c866b04550fc5461058c398c2e3e509381ajeffhao compiled_classes_.release(), 121110037c866b04550fc5461058c398c2e3e509381ajeffhao thread_count_, 121210037c866b04550fc5461058c398c2e3e509381ajeffhao dump_stats_, 121310037c866b04550fc5461058c398c2e3e509381ajeffhao dump_passes_, 12148a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers compiler_phases_timings_.get(), 121510037c866b04550fc5461058c398c2e3e509381ajeffhao swap_fd_, 12168a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers profile_file_)); 121710037c866b04550fc5461058c398c2e3e509381ajeffhao 121810037c866b04550fc5461058c398c2e3e509381ajeffhao driver_->CompileAll(class_loader, dex_files_, timings_); 121910037c866b04550fc5461058c398c2e3e509381ajeffhao } 122010037c866b04550fc5461058c398c2e3e509381ajeffhao 122110037c866b04550fc5461058c398c2e3e509381ajeffhao // Notes on the interleaving of creating the image and oat file to 122210037c866b04550fc5461058c398c2e3e509381ajeffhao // ensure the references between the two are correct. 122310037c866b04550fc5461058c398c2e3e509381ajeffhao // 122430fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers // Currently we have a memory layout that looks something like this: 122510037c866b04550fc5461058c398c2e3e509381ajeffhao // 122610037c866b04550fc5461058c398c2e3e509381ajeffhao // +--------------+ 122710037c866b04550fc5461058c398c2e3e509381ajeffhao // | image | 12288a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers // +--------------+ 122930fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers // | boot oat | 123010037c866b04550fc5461058c398c2e3e509381ajeffhao // +--------------+ 123110037c866b04550fc5461058c398c2e3e509381ajeffhao // | alloc spaces | 123210037c866b04550fc5461058c398c2e3e509381ajeffhao // +--------------+ 123310037c866b04550fc5461058c398c2e3e509381ajeffhao // 123410037c866b04550fc5461058c398c2e3e509381ajeffhao // There are several constraints on the loading of the image and boot.oat. 123510037c866b04550fc5461058c398c2e3e509381ajeffhao // 123610037c866b04550fc5461058c398c2e3e509381ajeffhao // 1. The image is expected to be loaded at an absolute address and 123710037c866b04550fc5461058c398c2e3e509381ajeffhao // contains Objects with absolute pointers within the image. 123810037c866b04550fc5461058c398c2e3e509381ajeffhao // 123910037c866b04550fc5461058c398c2e3e509381ajeffhao // 2. There are absolute pointers from Methods in the image to their 12408d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers // code in the oat. 12418a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers // 124210037c866b04550fc5461058c398c2e3e509381ajeffhao // 3. There are absolute pointers from the code in the oat to Methods 124310037c866b04550fc5461058c398c2e3e509381ajeffhao // in the image. 124410037c866b04550fc5461058c398c2e3e509381ajeffhao // 124510037c866b04550fc5461058c398c2e3e509381ajeffhao // 4. There are absolute pointers from code in the oat to other code 124610037c866b04550fc5461058c398c2e3e509381ajeffhao // in the oat. 124710037c866b04550fc5461058c398c2e3e509381ajeffhao // 12488d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers // To get this all correct, we go through several steps. 12498d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers // 125010037c866b04550fc5461058c398c2e3e509381ajeffhao // 1. We prepare offsets for all data in the oat file and calculate 125110037c866b04550fc5461058c398c2e3e509381ajeffhao // the oat data size and code size. During this stage, we also set 12528d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers // oat code offsets in methods for use by the image writer. 12538d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers // 125410037c866b04550fc5461058c398c2e3e509381ajeffhao // 2. We prepare offsets for the objects in the image and calculate 125510037c866b04550fc5461058c398c2e3e509381ajeffhao // the image size. 125630fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers // 125710037c866b04550fc5461058c398c2e3e509381ajeffhao // 3. We create the oat file. Originally this was just our own proprietary 125810037c866b04550fc5461058c398c2e3e509381ajeffhao // file but now it is contained within an ELF dynamic object (aka an .so 125910037c866b04550fc5461058c398c2e3e509381ajeffhao // file). Since we know the image size and oat data size and code size we 126010037c866b04550fc5461058c398c2e3e509381ajeffhao // can prepare the ELF headers and we then know the ELF memory segment 126110037c866b04550fc5461058c398c2e3e509381ajeffhao // layout and we can now resolve all references. The compiler provides 126210037c866b04550fc5461058c398c2e3e509381ajeffhao // LinkerPatch information in each CompiledMethod and we resolve these, 126310037c866b04550fc5461058c398c2e3e509381ajeffhao // using the layout information and image object locations provided by 126410037c866b04550fc5461058c398c2e3e509381ajeffhao // image writer, as we're writing the method code. 126510037c866b04550fc5461058c398c2e3e509381ajeffhao // 126610037c866b04550fc5461058c398c2e3e509381ajeffhao // 4. We create the image file. It needs to know where the oat file 126710037c866b04550fc5461058c398c2e3e509381ajeffhao // will be loaded after itself. Originally when oat file was simply 12688a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers // memory mapped so we could predict where its contents were based 126910037c866b04550fc5461058c398c2e3e509381ajeffhao // on the file size. Now that it is an ELF file, we need to inspect 127010037c866b04550fc5461058c398c2e3e509381ajeffhao // the ELF file to understand the in memory segment layout including 12718d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers // where the oat header is located within. 12728d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers // TODO: We could just remember this information from step 3. 127310037c866b04550fc5461058c398c2e3e509381ajeffhao // 127410037c866b04550fc5461058c398c2e3e509381ajeffhao // 5. We fixup the ELF program headers so that dlopen will try to 12758d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers // load the .so at the desired location at runtime by offsetting the 12768d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers // Elf32_Phdr.p_vaddr values by the desired base address. 12778d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers // TODO: Do this in step 3. We already know the layout there. 127810037c866b04550fc5461058c398c2e3e509381ajeffhao // 127910037c866b04550fc5461058c398c2e3e509381ajeffhao // Steps 1.-3. are done by the CreateOatFile() above, steps 4.-5. 128010037c866b04550fc5461058c398c2e3e509381ajeffhao // are done by the CreateImageFile() below. 128110037c866b04550fc5461058c398c2e3e509381ajeffhao 128210037c866b04550fc5461058c398c2e3e509381ajeffhao 128310037c866b04550fc5461058c398c2e3e509381ajeffhao // Write out the generated code part. Calls the OatWriter and ElfBuilder. Also prepares the 128410037c866b04550fc5461058c398c2e3e509381ajeffhao // ImageWriter, if necessary. 128510037c866b04550fc5461058c398c2e3e509381ajeffhao // Note: Flushing (and closing) the file is the caller's responsibility, except for the failure 128610037c866b04550fc5461058c398c2e3e509381ajeffhao // case (when the file will be explicitly erased). 128710037c866b04550fc5461058c398c2e3e509381ajeffhao bool CreateOatFile() { 128810037c866b04550fc5461058c398c2e3e509381ajeffhao CHECK(key_value_store_.get() != nullptr); 128910037c866b04550fc5461058c398c2e3e509381ajeffhao 129010037c866b04550fc5461058c398c2e3e509381ajeffhao TimingLogger::ScopedTiming t("dex2oat Oat", timings_); 129110037c866b04550fc5461058c398c2e3e509381ajeffhao 129210037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<OatWriter> oat_writer; 129310037c866b04550fc5461058c398c2e3e509381ajeffhao { 129410037c866b04550fc5461058c398c2e3e509381ajeffhao TimingLogger::ScopedTiming t2("dex2oat OatWriter", timings_); 129510037c866b04550fc5461058c398c2e3e509381ajeffhao std::string image_file_location; 12968a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers uint32_t image_file_location_oat_checksum = 0; 129710037c866b04550fc5461058c398c2e3e509381ajeffhao uintptr_t image_file_location_oat_data_begin = 0; 129810037c866b04550fc5461058c398c2e3e509381ajeffhao int32_t image_patch_delta = 0; 12998d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (image_) { 130010037c866b04550fc5461058c398c2e3e509381ajeffhao PrepareImageWriter(image_base_); 130110037c866b04550fc5461058c398c2e3e509381ajeffhao } else { 130210037c866b04550fc5461058c398c2e3e509381ajeffhao TimingLogger::ScopedTiming t3("Loading image checksum", timings_); 130310037c866b04550fc5461058c398c2e3e509381ajeffhao gc::space::ImageSpace* image_space = Runtime::Current()->GetHeap()->GetImageSpace(); 130410037c866b04550fc5461058c398c2e3e509381ajeffhao image_file_location_oat_checksum = image_space->GetImageHeader().GetOatChecksum(); 130510037c866b04550fc5461058c398c2e3e509381ajeffhao image_file_location_oat_data_begin = 130610037c866b04550fc5461058c398c2e3e509381ajeffhao reinterpret_cast<uintptr_t>(image_space->GetImageHeader().GetOatDataBegin()); 130710037c866b04550fc5461058c398c2e3e509381ajeffhao image_file_location = image_space->GetImageFilename(); 130810037c866b04550fc5461058c398c2e3e509381ajeffhao image_patch_delta = image_space->GetImageHeader().GetPatchDelta(); 13098a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers } 131002e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier 13118d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (!image_file_location.empty()) { 13128a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers key_value_store_->Put(OatHeader::kImageLocationKey, image_file_location); 131310037c866b04550fc5461058c398c2e3e509381ajeffhao } 131410037c866b04550fc5461058c398c2e3e509381ajeffhao 13158d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers oat_writer.reset(new OatWriter(dex_files_, image_file_location_oat_checksum, 13168a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers image_file_location_oat_data_begin, 13178d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers image_patch_delta, 131810037c866b04550fc5461058c398c2e3e509381ajeffhao driver_.get(), 131910037c866b04550fc5461058c398c2e3e509381ajeffhao image_writer_.get(), 132010037c866b04550fc5461058c398c2e3e509381ajeffhao timings_, 132110037c866b04550fc5461058c398c2e3e509381ajeffhao key_value_store_.get())); 132210037c866b04550fc5461058c398c2e3e509381ajeffhao } 132310037c866b04550fc5461058c398c2e3e509381ajeffhao 132410037c866b04550fc5461058c398c2e3e509381ajeffhao if (image_) { 132510037c866b04550fc5461058c398c2e3e509381ajeffhao // The OatWriter constructor has already updated offsets in methods and we need to 132610037c866b04550fc5461058c398c2e3e509381ajeffhao // prepare method offsets in the image address space for direct method patching. 132710037c866b04550fc5461058c398c2e3e509381ajeffhao TimingLogger::ScopedTiming t2("dex2oat Prepare image address space", timings_); 132810037c866b04550fc5461058c398c2e3e509381ajeffhao if (!image_writer_->PrepareImageAddressSpace()) { 132910037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(ERROR) << "Failed to prepare image address space."; 133010037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 133110037c866b04550fc5461058c398c2e3e509381ajeffhao } 133210037c866b04550fc5461058c398c2e3e509381ajeffhao } 133310037c866b04550fc5461058c398c2e3e509381ajeffhao 133410037c866b04550fc5461058c398c2e3e509381ajeffhao { 133510037c866b04550fc5461058c398c2e3e509381ajeffhao TimingLogger::ScopedTiming t2("dex2oat Write ELF", timings_); 133610037c866b04550fc5461058c398c2e3e509381ajeffhao if (!driver_->WriteElf(android_root_, is_host_, dex_files_, oat_writer.get(), 133710037c866b04550fc5461058c398c2e3e509381ajeffhao oat_file_.get())) { 133810037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(ERROR) << "Failed to write ELF file " << oat_file_->GetPath(); 133910037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 134010037c866b04550fc5461058c398c2e3e509381ajeffhao } 134110037c866b04550fc5461058c398c2e3e509381ajeffhao } 134210037c866b04550fc5461058c398c2e3e509381ajeffhao 134310037c866b04550fc5461058c398c2e3e509381ajeffhao VLOG(compiler) << "Oat file written successfully (unstripped): " << oat_location_; 134410037c866b04550fc5461058c398c2e3e509381ajeffhao return true; 134510037c866b04550fc5461058c398c2e3e509381ajeffhao } 134610037c866b04550fc5461058c398c2e3e509381ajeffhao 134710037c866b04550fc5461058c398c2e3e509381ajeffhao // If we are compiling an image, invoke the image creation routine. Else just skip. 134810037c866b04550fc5461058c398c2e3e509381ajeffhao bool HandleImage() { 134910037c866b04550fc5461058c398c2e3e509381ajeffhao if (image_) { 135010037c866b04550fc5461058c398c2e3e509381ajeffhao TimingLogger::ScopedTiming t("dex2oat ImageWriter", timings_); 135110037c866b04550fc5461058c398c2e3e509381ajeffhao if (!CreateImageFile()) { 135210037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 135310037c866b04550fc5461058c398c2e3e509381ajeffhao } 135410037c866b04550fc5461058c398c2e3e509381ajeffhao VLOG(compiler) << "Image written successfully: " << image_filename_; 135510037c866b04550fc5461058c398c2e3e509381ajeffhao } 135610037c866b04550fc5461058c398c2e3e509381ajeffhao return true; 135710037c866b04550fc5461058c398c2e3e509381ajeffhao } 135810037c866b04550fc5461058c398c2e3e509381ajeffhao 135910037c866b04550fc5461058c398c2e3e509381ajeffhao // Create a copy from unstripped to stripped. 136010037c866b04550fc5461058c398c2e3e509381ajeffhao bool CopyUnstrippedToStripped() { 136110037c866b04550fc5461058c398c2e3e509381ajeffhao // If we don't want to strip in place, copy from unstripped location to stripped location. 136210037c866b04550fc5461058c398c2e3e509381ajeffhao // We need to strip after image creation because FixupElf needs to use .strtab. 136310037c866b04550fc5461058c398c2e3e509381ajeffhao if (oat_unstripped_ != oat_stripped_) { 136410037c866b04550fc5461058c398c2e3e509381ajeffhao // If the oat file is still open, flush it. 136510037c866b04550fc5461058c398c2e3e509381ajeffhao if (oat_file_.get() != nullptr && oat_file_->IsOpened()) { 136610037c866b04550fc5461058c398c2e3e509381ajeffhao if (!FlushCloseOatFile()) { 136710037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 136810037c866b04550fc5461058c398c2e3e509381ajeffhao } 136910037c866b04550fc5461058c398c2e3e509381ajeffhao } 137010037c866b04550fc5461058c398c2e3e509381ajeffhao 137110037c866b04550fc5461058c398c2e3e509381ajeffhao TimingLogger::ScopedTiming t("dex2oat OatFile copy", timings_); 137210037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<File> in(OS::OpenFileForReading(oat_unstripped_.c_str())); 137310037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<File> out(OS::CreateEmptyFile(oat_stripped_.c_str())); 137410037c866b04550fc5461058c398c2e3e509381ajeffhao size_t buffer_size = 8192; 137510037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]); 13768d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers while (true) { 13778d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers int bytes_read = TEMP_FAILURE_RETRY(read(in->Fd(), buffer.get(), buffer_size)); 137810037c866b04550fc5461058c398c2e3e509381ajeffhao if (bytes_read <= 0) { 137910037c866b04550fc5461058c398c2e3e509381ajeffhao break; 138010037c866b04550fc5461058c398c2e3e509381ajeffhao } 138110037c866b04550fc5461058c398c2e3e509381ajeffhao bool write_ok = out->WriteFully(buffer.get(), bytes_read); 138210037c866b04550fc5461058c398c2e3e509381ajeffhao CHECK(write_ok); 138310037c866b04550fc5461058c398c2e3e509381ajeffhao } 138410037c866b04550fc5461058c398c2e3e509381ajeffhao if (out->FlushCloseOrErase() != 0) { 138510037c866b04550fc5461058c398c2e3e509381ajeffhao PLOG(ERROR) << "Failed to flush and close copied oat file: " << oat_stripped_; 138610037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 138710037c866b04550fc5461058c398c2e3e509381ajeffhao } 138810037c866b04550fc5461058c398c2e3e509381ajeffhao VLOG(compiler) << "Oat file copied successfully (stripped): " << oat_stripped_; 138910037c866b04550fc5461058c398c2e3e509381ajeffhao } 139010037c866b04550fc5461058c398c2e3e509381ajeffhao return true; 13918d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 13928d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 139310037c866b04550fc5461058c398c2e3e509381ajeffhao bool FlushOatFile() { 139410037c866b04550fc5461058c398c2e3e509381ajeffhao if (oat_file_.get() != nullptr) { 139510037c866b04550fc5461058c398c2e3e509381ajeffhao TimingLogger::ScopedTiming t2("dex2oat Flush ELF", timings_); 139610037c866b04550fc5461058c398c2e3e509381ajeffhao if (oat_file_->Flush() != 0) { 139710037c866b04550fc5461058c398c2e3e509381ajeffhao PLOG(ERROR) << "Failed to flush oat file: " << oat_location_ << " / " 139810037c866b04550fc5461058c398c2e3e509381ajeffhao << oat_filename_; 13998d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers oat_file_->Erase(); 14008d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers return false; 14018d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 140210037c866b04550fc5461058c398c2e3e509381ajeffhao } 140310037c866b04550fc5461058c398c2e3e509381ajeffhao return true; 140410037c866b04550fc5461058c398c2e3e509381ajeffhao } 140510037c866b04550fc5461058c398c2e3e509381ajeffhao 140610037c866b04550fc5461058c398c2e3e509381ajeffhao bool FlushCloseOatFile() { 140710037c866b04550fc5461058c398c2e3e509381ajeffhao if (oat_file_.get() != nullptr) { 140810037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<File> tmp(oat_file_.release()); 140910037c866b04550fc5461058c398c2e3e509381ajeffhao if (tmp->FlushCloseOrErase() != 0) { 141010037c866b04550fc5461058c398c2e3e509381ajeffhao PLOG(ERROR) << "Failed to flush and close oat file: " << oat_location_ << " / " 141110037c866b04550fc5461058c398c2e3e509381ajeffhao << oat_filename_; 141210037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 141310037c866b04550fc5461058c398c2e3e509381ajeffhao } 141410037c866b04550fc5461058c398c2e3e509381ajeffhao } 141510037c866b04550fc5461058c398c2e3e509381ajeffhao return true; 141610037c866b04550fc5461058c398c2e3e509381ajeffhao } 141710037c866b04550fc5461058c398c2e3e509381ajeffhao 141810037c866b04550fc5461058c398c2e3e509381ajeffhao void DumpTiming() { 141910037c866b04550fc5461058c398c2e3e509381ajeffhao if (dump_timing_ || (dump_slow_timing_ && timings_->GetTotalNs() > MsToNs(1000))) { 142010037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(INFO) << Dumpable<TimingLogger>(*timings_); 142110037c866b04550fc5461058c398c2e3e509381ajeffhao } 142210037c866b04550fc5461058c398c2e3e509381ajeffhao if (dump_passes_) { 142310037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(INFO) << Dumpable<CumulativeLogger>(*driver_->GetTimingsLogger()); 142410037c866b04550fc5461058c398c2e3e509381ajeffhao } 142510037c866b04550fc5461058c398c2e3e509381ajeffhao } 142610037c866b04550fc5461058c398c2e3e509381ajeffhao 142710037c866b04550fc5461058c398c2e3e509381ajeffhao CompilerOptions* GetCompilerOptions() const { 142810037c866b04550fc5461058c398c2e3e509381ajeffhao return compiler_options_.get(); 142910037c866b04550fc5461058c398c2e3e509381ajeffhao } 143010037c866b04550fc5461058c398c2e3e509381ajeffhao 143110037c866b04550fc5461058c398c2e3e509381ajeffhao bool IsImage() const { 143210037c866b04550fc5461058c398c2e3e509381ajeffhao return image_; 14338d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 14348d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 143510037c866b04550fc5461058c398c2e3e509381ajeffhao bool IsHost() const { 143610037c866b04550fc5461058c398c2e3e509381ajeffhao return is_host_; 143710037c866b04550fc5461058c398c2e3e509381ajeffhao } 143810037c866b04550fc5461058c398c2e3e509381ajeffhao 143910037c866b04550fc5461058c398c2e3e509381ajeffhao private: 144010037c866b04550fc5461058c398c2e3e509381ajeffhao static size_t OpenDexFiles(const std::vector<const char*>& dex_filenames, 14418d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers const std::vector<const char*>& dex_locations, 14428d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers std::vector<const DexFile*>& dex_files) { 144310037c866b04550fc5461058c398c2e3e509381ajeffhao size_t failure_count = 0; 144410037c866b04550fc5461058c398c2e3e509381ajeffhao for (size_t i = 0; i < dex_filenames.size(); i++) { 144510037c866b04550fc5461058c398c2e3e509381ajeffhao const char* dex_filename = dex_filenames[i]; 144610037c866b04550fc5461058c398c2e3e509381ajeffhao const char* dex_location = dex_locations[i]; 144710037c866b04550fc5461058c398c2e3e509381ajeffhao ATRACE_BEGIN(StringPrintf("Opening dex file '%s'", dex_filenames[i]).c_str()); 144810037c866b04550fc5461058c398c2e3e509381ajeffhao std::string error_msg; 144910037c866b04550fc5461058c398c2e3e509381ajeffhao if (!OS::FileExists(dex_filename)) { 145010037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(WARNING) << "Skipping non-existent dex file '" << dex_filename << "'"; 145110037c866b04550fc5461058c398c2e3e509381ajeffhao continue; 145210037c866b04550fc5461058c398c2e3e509381ajeffhao } 145310037c866b04550fc5461058c398c2e3e509381ajeffhao if (!DexFile::Open(dex_filename, dex_location, &error_msg, &dex_files)) { 14548d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers LOG(WARNING) << "Failed to open .dex from file '" << dex_filename << "': " << error_msg; 14558d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers ++failure_count; 145610037c866b04550fc5461058c398c2e3e509381ajeffhao } 145710037c866b04550fc5461058c398c2e3e509381ajeffhao ATRACE_END(); 145810037c866b04550fc5461058c398c2e3e509381ajeffhao } 145910037c866b04550fc5461058c398c2e3e509381ajeffhao return failure_count; 146010037c866b04550fc5461058c398c2e3e509381ajeffhao } 14618d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 14628d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers // Returns true if dex_files has a dex with the named location. 146310037c866b04550fc5461058c398c2e3e509381ajeffhao static bool DexFilesContains(const std::vector<const DexFile*>& dex_files, 146410037c866b04550fc5461058c398c2e3e509381ajeffhao const std::string& location) { 146510037c866b04550fc5461058c398c2e3e509381ajeffhao for (size_t i = 0; i < dex_files.size(); ++i) { 146610037c866b04550fc5461058c398c2e3e509381ajeffhao if (dex_files[i]->GetLocation() == location) { 146710037c866b04550fc5461058c398c2e3e509381ajeffhao return true; 146810037c866b04550fc5461058c398c2e3e509381ajeffhao } 146910037c866b04550fc5461058c398c2e3e509381ajeffhao } 147010037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 147110037c866b04550fc5461058c398c2e3e509381ajeffhao } 147210037c866b04550fc5461058c398c2e3e509381ajeffhao 147310037c866b04550fc5461058c398c2e3e509381ajeffhao // Appends to dex_files any elements of class_path that it doesn't already 147410037c866b04550fc5461058c398c2e3e509381ajeffhao // contain. This will open those dex files as necessary. 147510037c866b04550fc5461058c398c2e3e509381ajeffhao static void OpenClassPathFiles(const std::string& class_path, 147610037c866b04550fc5461058c398c2e3e509381ajeffhao std::vector<const DexFile*>& dex_files) { 147710037c866b04550fc5461058c398c2e3e509381ajeffhao std::vector<std::string> parsed; 147810037c866b04550fc5461058c398c2e3e509381ajeffhao Split(class_path, ':', &parsed); 147910037c866b04550fc5461058c398c2e3e509381ajeffhao // Take Locks::mutator_lock_ so that lock ordering on the ClassLinker::dex_lock_ is maintained. 148010037c866b04550fc5461058c398c2e3e509381ajeffhao ScopedObjectAccess soa(Thread::Current()); 14818d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers for (size_t i = 0; i < parsed.size(); ++i) { 14828d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (DexFilesContains(dex_files, parsed[i])) { 148310037c866b04550fc5461058c398c2e3e509381ajeffhao continue; 148410037c866b04550fc5461058c398c2e3e509381ajeffhao } 148510037c866b04550fc5461058c398c2e3e509381ajeffhao std::string error_msg; 148610037c866b04550fc5461058c398c2e3e509381ajeffhao if (!DexFile::Open(parsed[i].c_str(), parsed[i].c_str(), &error_msg, &dex_files)) { 148710037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(WARNING) << "Failed to open dex file '" << parsed[i] << "': " << error_msg; 14888d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 14898d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 149010037c866b04550fc5461058c398c2e3e509381ajeffhao } 149110037c866b04550fc5461058c398c2e3e509381ajeffhao 149210037c866b04550fc5461058c398c2e3e509381ajeffhao // Create a runtime necessary for compilation. 149310037c866b04550fc5461058c398c2e3e509381ajeffhao bool CreateRuntime(const RuntimeOptions& runtime_options) 149410037c866b04550fc5461058c398c2e3e509381ajeffhao SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_) { 14958d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (!Runtime::Create(runtime_options, false)) { 14968d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers LOG(ERROR) << "Failed to create runtime"; 149710037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 149810037c866b04550fc5461058c398c2e3e509381ajeffhao } 149910037c866b04550fc5461058c398c2e3e509381ajeffhao Runtime* runtime = Runtime::Current(); 150010037c866b04550fc5461058c398c2e3e509381ajeffhao runtime->SetInstructionSet(instruction_set_); 150110037c866b04550fc5461058c398c2e3e509381ajeffhao for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { 150210037c866b04550fc5461058c398c2e3e509381ajeffhao Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i); 15038d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (!runtime->HasCalleeSaveMethod(type)) { 15048d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers runtime->SetCalleeSaveMethod(runtime->CreateCalleeSaveMethod(), type); 150510037c866b04550fc5461058c398c2e3e509381ajeffhao } 150610037c866b04550fc5461058c398c2e3e509381ajeffhao } 15078d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers runtime->GetClassLinker()->FixupDexCaches(runtime->GetResolutionMethod()); 15088d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers runtime->GetClassLinker()->RunRootClinits(); 150910037c866b04550fc5461058c398c2e3e509381ajeffhao runtime_ = runtime; 151010037c866b04550fc5461058c398c2e3e509381ajeffhao return true; 15118d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 15128d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 151310037c866b04550fc5461058c398c2e3e509381ajeffhao void PrepareImageWriter(uintptr_t image_base) { 151410037c866b04550fc5461058c398c2e3e509381ajeffhao image_writer_.reset(new ImageWriter(*driver_, image_base, compiler_options_->GetCompilePic())); 151510037c866b04550fc5461058c398c2e3e509381ajeffhao } 151610037c866b04550fc5461058c398c2e3e509381ajeffhao 151710037c866b04550fc5461058c398c2e3e509381ajeffhao // Let the ImageWriter write the image file. If we do not compile PIC, also fix up the oat file. 151810037c866b04550fc5461058c398c2e3e509381ajeffhao bool CreateImageFile() 151910037c866b04550fc5461058c398c2e3e509381ajeffhao LOCKS_EXCLUDED(Locks::mutator_lock_) { 152010037c866b04550fc5461058c398c2e3e509381ajeffhao CHECK(image_writer_ != nullptr); 152110037c866b04550fc5461058c398c2e3e509381ajeffhao if (!image_writer_->Write(image_filename_, oat_unstripped_, oat_location_)) { 152210037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(ERROR) << "Failed to create image file " << image_filename_; 152310037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 152410037c866b04550fc5461058c398c2e3e509381ajeffhao } 152510037c866b04550fc5461058c398c2e3e509381ajeffhao uintptr_t oat_data_begin = image_writer_->GetOatDataBegin(); 152610037c866b04550fc5461058c398c2e3e509381ajeffhao 152710037c866b04550fc5461058c398c2e3e509381ajeffhao // Destroy ImageWriter before doing FixupElf. 15288d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers image_writer_.reset(); 15298d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 153010037c866b04550fc5461058c398c2e3e509381ajeffhao // Do not fix up the ELF file if we are --compile-pic 153110037c866b04550fc5461058c398c2e3e509381ajeffhao if (!compiler_options_->GetCompilePic()) { 153210037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<File> oat_file(OS::OpenFileReadWrite(oat_unstripped_.c_str())); 153310037c866b04550fc5461058c398c2e3e509381ajeffhao if (oat_file.get() == nullptr) { 153410037c866b04550fc5461058c398c2e3e509381ajeffhao PLOG(ERROR) << "Failed to open ELF file: " << oat_unstripped_; 15358d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers return false; 15368d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 153710037c866b04550fc5461058c398c2e3e509381ajeffhao 153810037c866b04550fc5461058c398c2e3e509381ajeffhao if (!ElfWriter::Fixup(oat_file.get(), oat_data_begin)) { 153910037c866b04550fc5461058c398c2e3e509381ajeffhao oat_file->Erase(); 154010037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(ERROR) << "Failed to fixup ELF file " << oat_file->GetPath(); 154110037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 154210037c866b04550fc5461058c398c2e3e509381ajeffhao } 15438d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 15448d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (oat_file->FlushCloseOrErase()) { 154510037c866b04550fc5461058c398c2e3e509381ajeffhao PLOG(ERROR) << "Failed to flush and close fixed ELF file " << oat_file->GetPath(); 154610037c866b04550fc5461058c398c2e3e509381ajeffhao return false; 15478d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 15488d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 154910037c866b04550fc5461058c398c2e3e509381ajeffhao 155010037c866b04550fc5461058c398c2e3e509381ajeffhao return true; 15518d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 15528d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 155310037c866b04550fc5461058c398c2e3e509381ajeffhao // Reads the class names (java.lang.Object) and returns a set of descriptors (Ljava/lang/Object;) 155410037c866b04550fc5461058c398c2e3e509381ajeffhao static std::set<std::string>* ReadImageClassesFromFile(const char* image_classes_filename) { 155510037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<std::ifstream> image_classes_file(new std::ifstream(image_classes_filename, 155610037c866b04550fc5461058c398c2e3e509381ajeffhao std::ifstream::in)); 155710037c866b04550fc5461058c398c2e3e509381ajeffhao if (image_classes_file.get() == nullptr) { 155810037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(ERROR) << "Failed to open image classes file " << image_classes_filename; 155910037c866b04550fc5461058c398c2e3e509381ajeffhao return nullptr; 156010037c866b04550fc5461058c398c2e3e509381ajeffhao } 156110037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<std::set<std::string>> result(ReadImageClasses(*image_classes_file)); 156210037c866b04550fc5461058c398c2e3e509381ajeffhao image_classes_file->close(); 156310037c866b04550fc5461058c398c2e3e509381ajeffhao return result.release(); 156410037c866b04550fc5461058c398c2e3e509381ajeffhao } 156510037c866b04550fc5461058c398c2e3e509381ajeffhao 156610037c866b04550fc5461058c398c2e3e509381ajeffhao static std::set<std::string>* ReadImageClasses(std::istream& image_classes_stream) { 156710037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<std::set<std::string>> image_classes(new std::set<std::string>); 15688d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers while (image_classes_stream.good()) { 15698d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers std::string dot; 157010037c866b04550fc5461058c398c2e3e509381ajeffhao std::getline(image_classes_stream, dot); 157110037c866b04550fc5461058c398c2e3e509381ajeffhao if (StartsWith(dot, "#") || dot.empty()) { 157210037c866b04550fc5461058c398c2e3e509381ajeffhao continue; 157310037c866b04550fc5461058c398c2e3e509381ajeffhao } 157410037c866b04550fc5461058c398c2e3e509381ajeffhao std::string descriptor(DotToDescriptor(dot.c_str())); 157510037c866b04550fc5461058c398c2e3e509381ajeffhao image_classes->insert(descriptor); 157610037c866b04550fc5461058c398c2e3e509381ajeffhao } 157710037c866b04550fc5461058c398c2e3e509381ajeffhao return image_classes.release(); 157810037c866b04550fc5461058c398c2e3e509381ajeffhao } 157910037c866b04550fc5461058c398c2e3e509381ajeffhao 158010037c866b04550fc5461058c398c2e3e509381ajeffhao // Reads the class names (java.lang.Object) and returns a set of descriptors (Ljava/lang/Object;) 158110037c866b04550fc5461058c398c2e3e509381ajeffhao static std::set<std::string>* ReadImageClassesFromZip(const char* zip_filename, 158210037c866b04550fc5461058c398c2e3e509381ajeffhao const char* image_classes_filename, 158310037c866b04550fc5461058c398c2e3e509381ajeffhao std::string* error_msg) { 158410037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(zip_filename, error_msg)); 158510037c866b04550fc5461058c398c2e3e509381ajeffhao if (zip_archive.get() == nullptr) { 158610037c866b04550fc5461058c398c2e3e509381ajeffhao return nullptr; 158710037c866b04550fc5461058c398c2e3e509381ajeffhao } 158810037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(image_classes_filename, error_msg)); 158910037c866b04550fc5461058c398c2e3e509381ajeffhao if (zip_entry.get() == nullptr) { 159010037c866b04550fc5461058c398c2e3e509381ajeffhao *error_msg = StringPrintf("Failed to find '%s' within '%s': %s", image_classes_filename, 159110037c866b04550fc5461058c398c2e3e509381ajeffhao zip_filename, error_msg->c_str()); 15928d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers return nullptr; 15938d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 159410037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<MemMap> image_classes_file(zip_entry->ExtractToMemMap(zip_filename, 159510037c866b04550fc5461058c398c2e3e509381ajeffhao image_classes_filename, 159610037c866b04550fc5461058c398c2e3e509381ajeffhao error_msg)); 159710037c866b04550fc5461058c398c2e3e509381ajeffhao if (image_classes_file.get() == nullptr) { 159810037c866b04550fc5461058c398c2e3e509381ajeffhao *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", image_classes_filename, 159910037c866b04550fc5461058c398c2e3e509381ajeffhao zip_filename, error_msg->c_str()); 160010037c866b04550fc5461058c398c2e3e509381ajeffhao return nullptr; 160110037c866b04550fc5461058c398c2e3e509381ajeffhao } 160210037c866b04550fc5461058c398c2e3e509381ajeffhao const std::string image_classes_string(reinterpret_cast<char*>(image_classes_file->Begin()), 160310037c866b04550fc5461058c398c2e3e509381ajeffhao image_classes_file->Size()); 160410037c866b04550fc5461058c398c2e3e509381ajeffhao std::istringstream image_classes_stream(image_classes_string); 16058d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers return ReadImageClasses(image_classes_stream); 16068d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 160710037c866b04550fc5461058c398c2e3e509381ajeffhao 160810037c866b04550fc5461058c398c2e3e509381ajeffhao void LogCompletionTime() { 160910037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(INFO) << "dex2oat took " << PrettyDuration(NanoTime() - start_ns_) 161010037c866b04550fc5461058c398c2e3e509381ajeffhao << " (threads: " << thread_count_ << ") " 161110037c866b04550fc5461058c398c2e3e509381ajeffhao << driver_->GetMemoryUsageString(); 161210037c866b04550fc5461058c398c2e3e509381ajeffhao } 161310037c866b04550fc5461058c398c2e3e509381ajeffhao 161410037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<CompilerOptions> compiler_options_; 161510037c866b04550fc5461058c398c2e3e509381ajeffhao Compiler::Kind compiler_kind_; 161610037c866b04550fc5461058c398c2e3e509381ajeffhao 161710037c866b04550fc5461058c398c2e3e509381ajeffhao InstructionSet instruction_set_; 161810037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<const InstructionSetFeatures> instruction_set_features_; 16198d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 16208d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers std::unique_ptr<SafeMap<std::string, std::string> > key_value_store_; 162110037c866b04550fc5461058c398c2e3e509381ajeffhao 162210037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<VerificationResults> verification_results_; 162310037c866b04550fc5461058c398c2e3e509381ajeffhao DexFileToMethodInlinerMap method_inliner_map_; 162410037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<QuickCompilerCallbacks> callbacks_; 162510037c866b04550fc5461058c398c2e3e509381ajeffhao 162610037c866b04550fc5461058c398c2e3e509381ajeffhao // Not a unique_ptr as we want to just exit on non-debug builds, not bringing the runtime down 162710037c866b04550fc5461058c398c2e3e509381ajeffhao // in an orderly fashion. The destructor takes care of deleting this. 162810037c866b04550fc5461058c398c2e3e509381ajeffhao Runtime* runtime_; 162930fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers 163010037c866b04550fc5461058c398c2e3e509381ajeffhao size_t thread_count_; 16318d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers uint64_t start_ns_; 16328d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers std::unique_ptr<WatchDog> watchdog_; 163310037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<File> oat_file_; 163410037c866b04550fc5461058c398c2e3e509381ajeffhao std::string oat_stripped_; 163510037c866b04550fc5461058c398c2e3e509381ajeffhao std::string oat_unstripped_; 163610037c866b04550fc5461058c398c2e3e509381ajeffhao std::string oat_location_; 163710037c866b04550fc5461058c398c2e3e509381ajeffhao std::string oat_filename_; 163810037c866b04550fc5461058c398c2e3e509381ajeffhao int oat_fd_; 163930fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers std::vector<const char*> dex_filenames_; 164010037c866b04550fc5461058c398c2e3e509381ajeffhao std::vector<const char*> dex_locations_; 16418d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers int zip_fd_; 16428d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers std::string zip_location_; 16438d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers std::string boot_image_option_; 164410037c866b04550fc5461058c398c2e3e509381ajeffhao std::vector<const char*> runtime_args_; 164510037c866b04550fc5461058c398c2e3e509381ajeffhao std::string image_filename_; 164610037c866b04550fc5461058c398c2e3e509381ajeffhao uintptr_t image_base_; 164710037c866b04550fc5461058c398c2e3e509381ajeffhao const char* image_classes_zip_filename_; 164810037c866b04550fc5461058c398c2e3e509381ajeffhao const char* image_classes_filename_; 164910037c866b04550fc5461058c398c2e3e509381ajeffhao const char* compiled_classes_zip_filename_; 165010037c866b04550fc5461058c398c2e3e509381ajeffhao const char* compiled_classes_filename_; 165110037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<std::set<std::string>> image_classes_; 165210037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<std::set<std::string>> compiled_classes_; 165310037c866b04550fc5461058c398c2e3e509381ajeffhao bool image_; 165410037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<ImageWriter> image_writer_; 165510037c866b04550fc5461058c398c2e3e509381ajeffhao bool is_host_; 165610037c866b04550fc5461058c398c2e3e509381ajeffhao std::string android_root_; 165710037c866b04550fc5461058c398c2e3e509381ajeffhao std::vector<const DexFile*> dex_files_; 165810037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<CompilerDriver> driver_; 165910037c866b04550fc5461058c398c2e3e509381ajeffhao std::vector<std::string> verbose_methods_; 166010037c866b04550fc5461058c398c2e3e509381ajeffhao bool dump_stats_; 166110037c866b04550fc5461058c398c2e3e509381ajeffhao bool dump_passes_; 166210037c866b04550fc5461058c398c2e3e509381ajeffhao bool dump_timing_; 166310037c866b04550fc5461058c398c2e3e509381ajeffhao bool dump_slow_timing_; 166410037c866b04550fc5461058c398c2e3e509381ajeffhao std::string swap_file_name_; 166510037c866b04550fc5461058c398c2e3e509381ajeffhao int swap_fd_; 166610037c866b04550fc5461058c398c2e3e509381ajeffhao std::string profile_file_; // Profile file to use 166710037c866b04550fc5461058c398c2e3e509381ajeffhao TimingLogger* timings_; 166810037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<CumulativeLogger> compiler_phases_timings_; 166910037c866b04550fc5461058c398c2e3e509381ajeffhao std::unique_ptr<std::ostream> init_failure_output_; 167010037c866b04550fc5461058c398c2e3e509381ajeffhao 167110037c866b04550fc5461058c398c2e3e509381ajeffhao DISALLOW_IMPLICIT_CONSTRUCTORS(Dex2Oat); 167210037c866b04550fc5461058c398c2e3e509381ajeffhao}; 167310037c866b04550fc5461058c398c2e3e509381ajeffhao 167410037c866b04550fc5461058c398c2e3e509381ajeffhaoconst unsigned int WatchDog::kWatchDogTimeoutSeconds; 167510037c866b04550fc5461058c398c2e3e509381ajeffhao 167610037c866b04550fc5461058c398c2e3e509381ajeffhaostatic void b13564922() { 167710037c866b04550fc5461058c398c2e3e509381ajeffhao#if defined(__linux__) && defined(__arm__) 167810037c866b04550fc5461058c398c2e3e509381ajeffhao int major, minor; 167910037c866b04550fc5461058c398c2e3e509381ajeffhao struct utsname uts; 168010037c866b04550fc5461058c398c2e3e509381ajeffhao if (uname(&uts) != -1 && 168110037c866b04550fc5461058c398c2e3e509381ajeffhao sscanf(uts.release, "%d.%d", &major, &minor) == 2 && 168210037c866b04550fc5461058c398c2e3e509381ajeffhao ((major < 3) || ((major == 3) && (minor < 4)))) { 168330fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers // Kernels before 3.4 don't handle the ASLR well and we can run out of address 168410037c866b04550fc5461058c398c2e3e509381ajeffhao // space (http://b/13564922). Work around the issue by inhibiting further mmap() randomization. 168510037c866b04550fc5461058c398c2e3e509381ajeffhao int old_personality = personality(0xffffffff); 168610037c866b04550fc5461058c398c2e3e509381ajeffhao if ((old_personality & ADDR_NO_RANDOMIZE) == 0) { 16878d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE); 16888d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (new_personality == -1) { 168910037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(WARNING) << "personality(. | ADDR_NO_RANDOMIZE) failed."; 169010037c866b04550fc5461058c398c2e3e509381ajeffhao } 169110037c866b04550fc5461058c398c2e3e509381ajeffhao } 169210037c866b04550fc5461058c398c2e3e509381ajeffhao } 169310037c866b04550fc5461058c398c2e3e509381ajeffhao#endif 169410037c866b04550fc5461058c398c2e3e509381ajeffhao} 169510037c866b04550fc5461058c398c2e3e509381ajeffhao 169610037c866b04550fc5461058c398c2e3e509381ajeffhaostatic int CompileImage(Dex2Oat& dex2oat) { 169710037c866b04550fc5461058c398c2e3e509381ajeffhao dex2oat.Compile(); 169810037c866b04550fc5461058c398c2e3e509381ajeffhao 169910037c866b04550fc5461058c398c2e3e509381ajeffhao // Create the boot.oat. 170010037c866b04550fc5461058c398c2e3e509381ajeffhao if (!dex2oat.CreateOatFile()) { 170110037c866b04550fc5461058c398c2e3e509381ajeffhao dex2oat.EraseOatFile(); 170210037c866b04550fc5461058c398c2e3e509381ajeffhao return EXIT_FAILURE; 170310037c866b04550fc5461058c398c2e3e509381ajeffhao } 170410037c866b04550fc5461058c398c2e3e509381ajeffhao 170510037c866b04550fc5461058c398c2e3e509381ajeffhao // Flush and close the boot.oat. We always expect the output file by name, and it will be 17068d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers // re-opened from the unstripped name. 17078d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (!dex2oat.FlushCloseOatFile()) { 170810037c866b04550fc5461058c398c2e3e509381ajeffhao return EXIT_FAILURE; 170910037c866b04550fc5461058c398c2e3e509381ajeffhao } 171010037c866b04550fc5461058c398c2e3e509381ajeffhao 171110037c866b04550fc5461058c398c2e3e509381ajeffhao // Creates the boot.art and patches the boot.oat. 171210037c866b04550fc5461058c398c2e3e509381ajeffhao if (!dex2oat.HandleImage()) { 171310037c866b04550fc5461058c398c2e3e509381ajeffhao return EXIT_FAILURE; 171410037c866b04550fc5461058c398c2e3e509381ajeffhao } 171510037c866b04550fc5461058c398c2e3e509381ajeffhao 171610037c866b04550fc5461058c398c2e3e509381ajeffhao // When given --host, finish early without stripping. 17178d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers if (dex2oat.IsHost()) { 17188d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers dex2oat.DumpTiming(); 171910037c866b04550fc5461058c398c2e3e509381ajeffhao return EXIT_SUCCESS; 172010037c866b04550fc5461058c398c2e3e509381ajeffhao } 172110037c866b04550fc5461058c398c2e3e509381ajeffhao 172210037c866b04550fc5461058c398c2e3e509381ajeffhao // Copy unstripped to stripped location, if necessary. 172310037c866b04550fc5461058c398c2e3e509381ajeffhao if (!dex2oat.CopyUnstrippedToStripped()) { 172410037c866b04550fc5461058c398c2e3e509381ajeffhao return EXIT_FAILURE; 172510037c866b04550fc5461058c398c2e3e509381ajeffhao } 172610037c866b04550fc5461058c398c2e3e509381ajeffhao 172710037c866b04550fc5461058c398c2e3e509381ajeffhao // FlushClose again, as stripping might have re-opened the oat file. 172810037c866b04550fc5461058c398c2e3e509381ajeffhao if (!dex2oat.FlushCloseOatFile()) { 172910037c866b04550fc5461058c398c2e3e509381ajeffhao return EXIT_FAILURE; 173010037c866b04550fc5461058c398c2e3e509381ajeffhao } 173110037c866b04550fc5461058c398c2e3e509381ajeffhao 173210037c866b04550fc5461058c398c2e3e509381ajeffhao dex2oat.DumpTiming(); 173310037c866b04550fc5461058c398c2e3e509381ajeffhao return EXIT_SUCCESS; 173410037c866b04550fc5461058c398c2e3e509381ajeffhao} 173510037c866b04550fc5461058c398c2e3e509381ajeffhao 173610037c866b04550fc5461058c398c2e3e509381ajeffhaostatic int CompileApp(Dex2Oat& dex2oat) { 173710037c866b04550fc5461058c398c2e3e509381ajeffhao dex2oat.Compile(); 173810037c866b04550fc5461058c398c2e3e509381ajeffhao 173910037c866b04550fc5461058c398c2e3e509381ajeffhao // Create the app oat. 174010037c866b04550fc5461058c398c2e3e509381ajeffhao if (!dex2oat.CreateOatFile()) { 174110037c866b04550fc5461058c398c2e3e509381ajeffhao dex2oat.EraseOatFile(); 174210037c866b04550fc5461058c398c2e3e509381ajeffhao return EXIT_FAILURE; 17438d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 17448d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 174510037c866b04550fc5461058c398c2e3e509381ajeffhao // Do not close the oat file here. We might haven gotten the output file by file descriptor, 174610037c866b04550fc5461058c398c2e3e509381ajeffhao // which we would lose. 174710037c866b04550fc5461058c398c2e3e509381ajeffhao if (!dex2oat.FlushOatFile()) { 174810037c866b04550fc5461058c398c2e3e509381ajeffhao return EXIT_FAILURE; 174910037c866b04550fc5461058c398c2e3e509381ajeffhao } 175010037c866b04550fc5461058c398c2e3e509381ajeffhao 175110037c866b04550fc5461058c398c2e3e509381ajeffhao // When given --host, finish early without stripping. 175210037c866b04550fc5461058c398c2e3e509381ajeffhao if (dex2oat.IsHost()) { 175310037c866b04550fc5461058c398c2e3e509381ajeffhao if (!dex2oat.FlushCloseOatFile()) { 175410037c866b04550fc5461058c398c2e3e509381ajeffhao return EXIT_FAILURE; 175510037c866b04550fc5461058c398c2e3e509381ajeffhao } 175610037c866b04550fc5461058c398c2e3e509381ajeffhao 175710037c866b04550fc5461058c398c2e3e509381ajeffhao dex2oat.DumpTiming(); 175810037c866b04550fc5461058c398c2e3e509381ajeffhao return EXIT_SUCCESS; 17598d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers } 17608d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 176110037c866b04550fc5461058c398c2e3e509381ajeffhao // Copy unstripped to stripped location, if necessary. This will implicitly flush & close the 176210037c866b04550fc5461058c398c2e3e509381ajeffhao // unstripped version. If this is given, we expect to be able to open writable files by name. 176310037c866b04550fc5461058c398c2e3e509381ajeffhao if (!dex2oat.CopyUnstrippedToStripped()) { 176410037c866b04550fc5461058c398c2e3e509381ajeffhao return EXIT_FAILURE; 176510037c866b04550fc5461058c398c2e3e509381ajeffhao } 176610037c866b04550fc5461058c398c2e3e509381ajeffhao 176710037c866b04550fc5461058c398c2e3e509381ajeffhao // Flush and close the file. 176810037c866b04550fc5461058c398c2e3e509381ajeffhao if (!dex2oat.FlushCloseOatFile()) { 176910037c866b04550fc5461058c398c2e3e509381ajeffhao return EXIT_FAILURE; 177010037c866b04550fc5461058c398c2e3e509381ajeffhao } 177110037c866b04550fc5461058c398c2e3e509381ajeffhao 177210037c866b04550fc5461058c398c2e3e509381ajeffhao dex2oat.DumpTiming(); 177310037c866b04550fc5461058c398c2e3e509381ajeffhao return EXIT_SUCCESS; 177410037c866b04550fc5461058c398c2e3e509381ajeffhao} 17758d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers 17768d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogersstatic int dex2oat(int argc, char** argv) { 177710037c866b04550fc5461058c398c2e3e509381ajeffhao b13564922(); 177810037c866b04550fc5461058c398c2e3e509381ajeffhao 17792b87ddf36abff711fa2233c49bffc7ceb03b15d7Dragos Sbirlea TimingLogger timings("compiler", false, false); 17802b87ddf36abff711fa2233c49bffc7ceb03b15d7Dragos Sbirlea 178110037c866b04550fc5461058c398c2e3e509381ajeffhao Dex2Oat dex2oat(&timings); 178210037c866b04550fc5461058c398c2e3e509381ajeffhao 178310037c866b04550fc5461058c398c2e3e509381ajeffhao // Parse arguments. Argument mistakes will lead to exit(EXIT_FAILURE) in UsageError. 178410037c866b04550fc5461058c398c2e3e509381ajeffhao dex2oat.ParseArgs(argc, argv); 178510037c866b04550fc5461058c398c2e3e509381ajeffhao 178610037c866b04550fc5461058c398c2e3e509381ajeffhao // Check early that the result of compilation can be written 178710037c866b04550fc5461058c398c2e3e509381ajeffhao if (!dex2oat.OpenFile()) { 178810037c866b04550fc5461058c398c2e3e509381ajeffhao return EXIT_FAILURE; 178910037c866b04550fc5461058c398c2e3e509381ajeffhao } 17908a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers 179110037c866b04550fc5461058c398c2e3e509381ajeffhao LOG(INFO) << CommandLine(); 17928a6bbfc66e3cf01d4aa07ee08b515beee481d553Ian Rogers 179310037c866b04550fc5461058c398c2e3e509381ajeffhao if (!dex2oat.Setup()) { 179410037c866b04550fc5461058c398c2e3e509381ajeffhao dex2oat.EraseOatFile(); 179510037c866b04550fc5461058c398c2e3e509381ajeffhao return EXIT_FAILURE; 179610037c866b04550fc5461058c398c2e3e509381ajeffhao } 179710037c866b04550fc5461058c398c2e3e509381ajeffhao 179810037c866b04550fc5461058c398c2e3e509381ajeffhao if (dex2oat.IsImage()) { 179910037c866b04550fc5461058c398c2e3e509381ajeffhao return CompileImage(dex2oat); 180010037c866b04550fc5461058c398c2e3e509381ajeffhao } else { 180110037c866b04550fc5461058c398c2e3e509381ajeffhao return CompileApp(dex2oat); 180210037c866b04550fc5461058c398c2e3e509381ajeffhao } 180310037c866b04550fc5461058c398c2e3e509381ajeffhao} 180410037c866b04550fc5461058c398c2e3e509381ajeffhao} // namespace art 180510037c866b04550fc5461058c398c2e3e509381ajeffhao 180630fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogersint main(int argc, char** argv) { 180710037c866b04550fc5461058c398c2e3e509381ajeffhao int result = art::dex2oat(argc, argv); 180810037c866b04550fc5461058c398c2e3e509381ajeffhao // Everything was done, do an explicit exit here to avoid running Runtime destructors that take 180910037c866b04550fc5461058c398c2e3e509381ajeffhao // time (bug 10645725) unless we're a debug build or running on valgrind. Note: The Dex2Oat class 181010037c866b04550fc5461058c398c2e3e509381ajeffhao // should not destruct the runtime in this case. 181110037c866b04550fc5461058c398c2e3e509381ajeffhao if (!art::kIsDebugBuild && (RUNNING_ON_VALGRIND == 0)) { 181210037c866b04550fc5461058c398c2e3e509381ajeffhao exit(result); 181310037c866b04550fc5461058c398c2e3e509381ajeffhao } 181410037c866b04550fc5461058c398c2e3e509381ajeffhao return result; 181510037c866b04550fc5461058c398c2e3e509381ajeffhao} 181610037c866b04550fc5461058c398c2e3e509381ajeffhao