dex2oat.cc revision 3a2bd29d274f60fdcfabebb052078edef0190164
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <inttypes.h> 18#include <stdio.h> 19#include <stdlib.h> 20#include <sys/stat.h> 21#include "base/memory_tool.h" 22 23#include <fstream> 24#include <iostream> 25#include <sstream> 26#include <string> 27#include <unordered_set> 28#include <vector> 29 30#if defined(__linux__) && defined(__arm__) 31#include <sys/personality.h> 32#include <sys/utsname.h> 33#endif 34 35#define ATRACE_TAG ATRACE_TAG_DALVIK 36#include <cutils/trace.h> 37 38#include "art_method-inl.h" 39#include "arch/instruction_set_features.h" 40#include "arch/mips/instruction_set_features_mips.h" 41#include "base/dumpable.h" 42#include "base/macros.h" 43#include "base/stl_util.h" 44#include "base/stringpiece.h" 45#include "base/time_utils.h" 46#include "base/timing_logger.h" 47#include "base/unix_file/fd_file.h" 48#include "class_linker.h" 49#include "compiler.h" 50#include "compiler_callbacks.h" 51#include "dex_file-inl.h" 52#include "dex/pass_manager.h" 53#include "dex/verification_results.h" 54#include "dex/quick_compiler_callbacks.h" 55#include "dex/quick/dex_file_to_method_inliner_map.h" 56#include "driver/compiler_driver.h" 57#include "driver/compiler_options.h" 58#include "dwarf/method_debug_info.h" 59#include "elf_file.h" 60#include "elf_writer.h" 61#include "elf_writer_quick.h" 62#include "gc/space/image_space.h" 63#include "gc/space/space-inl.h" 64#include "image_writer.h" 65#include "interpreter/unstarted_runtime.h" 66#include "jit/offline_profiling_info.h" 67#include "leb128.h" 68#include "mirror/class-inl.h" 69#include "mirror/class_loader.h" 70#include "mirror/object-inl.h" 71#include "mirror/object_array-inl.h" 72#include "oat_writer.h" 73#include "os.h" 74#include "profile_assistant.h" 75#include "runtime.h" 76#include "runtime_options.h" 77#include "ScopedLocalRef.h" 78#include "scoped_thread_state_change.h" 79#include "utils.h" 80#include "well_known_classes.h" 81#include "zip_archive.h" 82 83namespace art { 84 85static int original_argc; 86static char** original_argv; 87 88static std::string CommandLine() { 89 std::vector<std::string> command; 90 for (int i = 0; i < original_argc; ++i) { 91 command.push_back(original_argv[i]); 92 } 93 return Join(command, ' '); 94} 95 96// A stripped version. Remove some less essential parameters. If we see a "--zip-fd=" parameter, be 97// even more aggressive. There won't be much reasonable data here for us in that case anyways (the 98// locations are all staged). 99static std::string StrippedCommandLine() { 100 std::vector<std::string> command; 101 102 // Do a pre-pass to look for zip-fd. 103 bool saw_zip_fd = false; 104 for (int i = 0; i < original_argc; ++i) { 105 if (StartsWith(original_argv[i], "--zip-fd=")) { 106 saw_zip_fd = true; 107 break; 108 } 109 } 110 111 // Now filter out things. 112 for (int i = 0; i < original_argc; ++i) { 113 // All runtime-arg parameters are dropped. 114 if (strcmp(original_argv[i], "--runtime-arg") == 0) { 115 i++; // Drop the next part, too. 116 continue; 117 } 118 119 // Any instruction-setXXX is dropped. 120 if (StartsWith(original_argv[i], "--instruction-set")) { 121 continue; 122 } 123 124 // The boot image is dropped. 125 if (StartsWith(original_argv[i], "--boot-image=")) { 126 continue; 127 } 128 129 // This should leave any dex-file and oat-file options, describing what we compiled. 130 131 // However, we prefer to drop this when we saw --zip-fd. 132 if (saw_zip_fd) { 133 // Drop anything --zip-X, --dex-X, --oat-X, --swap-X, or --app-image-X 134 if (StartsWith(original_argv[i], "--zip-") || 135 StartsWith(original_argv[i], "--dex-") || 136 StartsWith(original_argv[i], "--oat-") || 137 StartsWith(original_argv[i], "--swap-") || 138 StartsWith(original_argv[i], "--app-image-")) { 139 continue; 140 } 141 } 142 143 command.push_back(original_argv[i]); 144 } 145 146 // Construct the final output. 147 if (command.size() <= 1U) { 148 // It seems only "/system/bin/dex2oat" is left, or not even that. Use a pretty line. 149 return "Starting dex2oat."; 150 } 151 return Join(command, ' '); 152} 153 154static void UsageErrorV(const char* fmt, va_list ap) { 155 std::string error; 156 StringAppendV(&error, fmt, ap); 157 LOG(ERROR) << error; 158} 159 160static void UsageError(const char* fmt, ...) { 161 va_list ap; 162 va_start(ap, fmt); 163 UsageErrorV(fmt, ap); 164 va_end(ap); 165} 166 167NO_RETURN static void Usage(const char* fmt, ...) { 168 va_list ap; 169 va_start(ap, fmt); 170 UsageErrorV(fmt, ap); 171 va_end(ap); 172 173 UsageError("Command: %s", CommandLine().c_str()); 174 175 UsageError("Usage: dex2oat [options]..."); 176 UsageError(""); 177 UsageError(" -j<number>: specifies the number of threads used for compilation."); 178 UsageError(" Default is the number of detected hardware threads available on the"); 179 UsageError(" host system."); 180 UsageError(" Example: -j12"); 181 UsageError(""); 182 UsageError(" --dex-file=<dex-file>: specifies a .dex, .jar, or .apk file to compile."); 183 UsageError(" Example: --dex-file=/system/framework/core.jar"); 184 UsageError(""); 185 UsageError(" --dex-location=<dex-location>: specifies an alternative dex location to"); 186 UsageError(" encode in the oat file for the corresponding --dex-file argument."); 187 UsageError(" Example: --dex-file=/home/build/out/system/framework/core.jar"); 188 UsageError(" --dex-location=/system/framework/core.jar"); 189 UsageError(""); 190 UsageError(" --zip-fd=<file-descriptor>: specifies a file descriptor of a zip file"); 191 UsageError(" containing a classes.dex file to compile."); 192 UsageError(" Example: --zip-fd=5"); 193 UsageError(""); 194 UsageError(" --zip-location=<zip-location>: specifies a symbolic name for the file"); 195 UsageError(" corresponding to the file descriptor specified by --zip-fd."); 196 UsageError(" Example: --zip-location=/system/app/Calculator.apk"); 197 UsageError(""); 198 UsageError(" --oat-file=<file.oat>: specifies an oat output destination via a filename."); 199 UsageError(" Example: --oat-file=/system/framework/boot.oat"); 200 UsageError(""); 201 UsageError(" --oat-fd=<number>: specifies the oat output destination via a file descriptor."); 202 UsageError(" Example: --oat-fd=6"); 203 UsageError(""); 204 UsageError(" --oat-location=<oat-name>: specifies a symbolic name for the file corresponding"); 205 UsageError(" to the file descriptor specified by --oat-fd."); 206 UsageError(" Example: --oat-location=/data/dalvik-cache/system@app@Calculator.apk.oat"); 207 UsageError(""); 208 UsageError(" --oat-symbols=<file.oat>: specifies an oat output destination with full symbols."); 209 UsageError(" Example: --oat-symbols=/symbols/system/framework/boot.oat"); 210 UsageError(""); 211 UsageError(" --image=<file.art>: specifies an output image filename."); 212 UsageError(" Example: --image=/system/framework/boot.art"); 213 UsageError(""); 214 UsageError(" --image-format=(uncompressed|lz4):"); 215 UsageError(" Which format to store the image."); 216 UsageError(" Example: --image-format=lz4"); 217 UsageError(" Default: uncompressed"); 218 UsageError(""); 219 UsageError(" --image-classes=<classname-file>: specifies classes to include in an image."); 220 UsageError(" Example: --image=frameworks/base/preloaded-classes"); 221 UsageError(""); 222 UsageError(" --base=<hex-address>: specifies the base address when creating a boot image."); 223 UsageError(" Example: --base=0x50000000"); 224 UsageError(""); 225 UsageError(" --boot-image=<file.art>: provide the image file for the boot class path."); 226 UsageError(" Do not include the arch as part of the name, it is added automatically."); 227 UsageError(" Example: --boot-image=/system/framework/boot.art"); 228 UsageError(" (specifies /system/framework/<arch>/boot.art as the image file)"); 229 UsageError(" Default: $ANDROID_ROOT/system/framework/boot.art"); 230 UsageError(""); 231 UsageError(" --android-root=<path>: used to locate libraries for portable linking."); 232 UsageError(" Example: --android-root=out/host/linux-x86"); 233 UsageError(" Default: $ANDROID_ROOT"); 234 UsageError(""); 235 UsageError(" --instruction-set=(arm|arm64|mips|mips64|x86|x86_64): compile for a particular"); 236 UsageError(" instruction set."); 237 UsageError(" Example: --instruction-set=x86"); 238 UsageError(" Default: arm"); 239 UsageError(""); 240 UsageError(" --instruction-set-features=...,: Specify instruction set features"); 241 UsageError(" Example: --instruction-set-features=div"); 242 UsageError(" Default: default"); 243 UsageError(""); 244 UsageError(" --compile-pic: Force indirect use of code, methods, and classes"); 245 UsageError(" Default: disabled"); 246 UsageError(""); 247 UsageError(" --compiler-backend=(Quick|Optimizing): select compiler backend"); 248 UsageError(" set."); 249 UsageError(" Example: --compiler-backend=Optimizing"); 250 UsageError(" Default: Optimizing"); 251 UsageError(""); 252 UsageError(" --compiler-filter=" 253 "(verify-none" 254 "|interpret-only" 255 "|space" 256 "|balanced" 257 "|speed" 258 "|everything" 259 "|time):"); 260 UsageError(" select compiler filter."); 261 UsageError(" Example: --compiler-filter=everything"); 262 UsageError(" Default: speed"); 263 UsageError(""); 264 UsageError(" --huge-method-max=<method-instruction-count>: threshold size for a huge"); 265 UsageError(" method for compiler filter tuning."); 266 UsageError(" Example: --huge-method-max=%d", CompilerOptions::kDefaultHugeMethodThreshold); 267 UsageError(" Default: %d", CompilerOptions::kDefaultHugeMethodThreshold); 268 UsageError(""); 269 UsageError(" --large-method-max=<method-instruction-count>: threshold size for a large"); 270 UsageError(" method for compiler filter tuning."); 271 UsageError(" Example: --large-method-max=%d", CompilerOptions::kDefaultLargeMethodThreshold); 272 UsageError(" Default: %d", CompilerOptions::kDefaultLargeMethodThreshold); 273 UsageError(""); 274 UsageError(" --small-method-max=<method-instruction-count>: threshold size for a small"); 275 UsageError(" method for compiler filter tuning."); 276 UsageError(" Example: --small-method-max=%d", CompilerOptions::kDefaultSmallMethodThreshold); 277 UsageError(" Default: %d", CompilerOptions::kDefaultSmallMethodThreshold); 278 UsageError(""); 279 UsageError(" --tiny-method-max=<method-instruction-count>: threshold size for a tiny"); 280 UsageError(" method for compiler filter tuning."); 281 UsageError(" Example: --tiny-method-max=%d", CompilerOptions::kDefaultTinyMethodThreshold); 282 UsageError(" Default: %d", CompilerOptions::kDefaultTinyMethodThreshold); 283 UsageError(""); 284 UsageError(" --num-dex-methods=<method-count>: threshold size for a small dex file for"); 285 UsageError(" compiler filter tuning. If the input has fewer than this many methods"); 286 UsageError(" and the filter is not interpret-only or verify-none, overrides the"); 287 UsageError(" filter to use speed"); 288 UsageError(" Example: --num-dex-method=%d", CompilerOptions::kDefaultNumDexMethodsThreshold); 289 UsageError(" Default: %d", CompilerOptions::kDefaultNumDexMethodsThreshold); 290 UsageError(""); 291 UsageError(" --inline-depth-limit=<depth-limit>: the depth limit of inlining for fine tuning"); 292 UsageError(" the compiler. A zero value will disable inlining. Honored only by Optimizing."); 293 UsageError(" Has priority over the --compiler-filter option. Intended for "); 294 UsageError(" development/experimental use."); 295 UsageError(" Example: --inline-depth-limit=%d", CompilerOptions::kDefaultInlineDepthLimit); 296 UsageError(" Default: %d", CompilerOptions::kDefaultInlineDepthLimit); 297 UsageError(""); 298 UsageError(" --inline-max-code-units=<code-units-count>: the maximum code units that a method"); 299 UsageError(" can have to be considered for inlining. A zero value will disable inlining."); 300 UsageError(" Honored only by Optimizing. Has priority over the --compiler-filter option."); 301 UsageError(" Intended for development/experimental use."); 302 UsageError(" Example: --inline-max-code-units=%d", 303 CompilerOptions::kDefaultInlineMaxCodeUnits); 304 UsageError(" Default: %d", CompilerOptions::kDefaultInlineMaxCodeUnits); 305 UsageError(""); 306 UsageError(" --dump-timing: display a breakdown of where time was spent"); 307 UsageError(""); 308 UsageError(" --include-patch-information: Include patching information so the generated code"); 309 UsageError(" can have its base address moved without full recompilation."); 310 UsageError(""); 311 UsageError(" --no-include-patch-information: Do not include patching information."); 312 UsageError(""); 313 UsageError(" -g"); 314 UsageError(" --generate-debug-info: Generate debug information for native debugging,"); 315 UsageError(" such as stack unwinding information, ELF symbols and DWARF sections."); 316 UsageError(" If used without --native-debuggable, it will be best-effort only."); 317 UsageError(" This option does not affect the generated code. (disabled by default)"); 318 UsageError(""); 319 UsageError(" --no-generate-debug-info: Do not generate debug information for native debugging."); 320 UsageError(""); 321 UsageError(" --debuggable: Produce code debuggable with Java debugger."); 322 UsageError(""); 323 UsageError(" --native-debuggable: Produce code debuggable with native debugger (like LLDB)."); 324 UsageError(" Implies --debuggable."); 325 UsageError(""); 326 UsageError(" --runtime-arg <argument>: used to specify various arguments for the runtime,"); 327 UsageError(" such as initial heap size, maximum heap size, and verbose output."); 328 UsageError(" Use a separate --runtime-arg switch for each argument."); 329 UsageError(" Example: --runtime-arg -Xms256m"); 330 UsageError(""); 331 UsageError(" --profile-file=<filename>: specify profiler output file to use for compilation."); 332 UsageError(" Can be specified multiple time, in which case the data from the different"); 333 UsageError(" profiles will be aggregated."); 334 UsageError(""); 335 UsageError(" --reference-profile-file=<filename>: specify a reference profile file to use when"); 336 UsageError(" compiling. The data in this file will be compared with the data in the"); 337 UsageError(" associated --profile-file and the compilation will proceed only if there is"); 338 UsageError(" a significant difference (--reference-profile-file is paired with"); 339 UsageError(" --profile-file in the natural order). If the compilation was attempted then"); 340 UsageError(" --profile-file will be merged into --reference-profile-file. Valid only when"); 341 UsageError(" specified together with --profile-file."); 342 UsageError(""); 343 UsageError(" --profile-file-fd=<number>: same as --profile-file but accepts a file descriptor."); 344 UsageError(" Cannot be used together with --profile-file."); 345 UsageError(""); 346 UsageError(" --reference-profile-file-fd=<number>: same as --reference-profile-file but"); 347 UsageError(" accepts a file descriptor. Cannot be used together with"); 348 UsageError(" --reference-profile-file."); 349 UsageError(" --print-pass-names: print a list of pass names"); 350 UsageError(""); 351 UsageError(" --disable-passes=<pass-names>: disable one or more passes separated by comma."); 352 UsageError(" Example: --disable-passes=UseCount,BBOptimizations"); 353 UsageError(""); 354 UsageError(" --print-pass-options: print a list of passes that have configurable options along " 355 "with the setting."); 356 UsageError(" Will print default if no overridden setting exists."); 357 UsageError(""); 358 UsageError(" --pass-options=Pass1Name:Pass1OptionName:Pass1Option#," 359 "Pass2Name:Pass2OptionName:Pass2Option#"); 360 UsageError(" Used to specify a pass specific option. The setting itself must be integer."); 361 UsageError(" Separator used between options is a comma."); 362 UsageError(""); 363 UsageError(" --swap-file=<file-name>: specifies a file to use for swap."); 364 UsageError(" Example: --swap-file=/data/tmp/swap.001"); 365 UsageError(""); 366 UsageError(" --swap-fd=<file-descriptor>: specifies a file to use for swap (by descriptor)."); 367 UsageError(" Example: --swap-fd=10"); 368 UsageError(""); 369 UsageError(" --app-image-fd=<file-descriptor>: specify output file descriptor for app image."); 370 UsageError(" Example: --app-image-fd=10"); 371 UsageError(""); 372 UsageError(" --app-image-file=<file-name>: specify a file name for app image."); 373 UsageError(" Example: --app-image-file=/data/dalvik-cache/system@app@Calculator.apk.art"); 374 UsageError(""); 375 UsageError(" --multi-image: specify that separate oat and image files be generated for each " 376 "input dex file."); 377 UsageError(""); 378 std::cerr << "See log for usage error information\n"; 379 exit(EXIT_FAILURE); 380} 381 382// The primary goal of the watchdog is to prevent stuck build servers 383// during development when fatal aborts lead to a cascade of failures 384// that result in a deadlock. 385class WatchDog { 386// WatchDog defines its own CHECK_PTHREAD_CALL to avoid using LOG which uses locks 387#undef CHECK_PTHREAD_CALL 388#define CHECK_WATCH_DOG_PTHREAD_CALL(call, args, what) \ 389 do { \ 390 int rc = call args; \ 391 if (rc != 0) { \ 392 errno = rc; \ 393 std::string message(# call); \ 394 message += " failed for "; \ 395 message += reason; \ 396 Fatal(message); \ 397 } \ 398 } while (false) 399 400 public: 401 explicit WatchDog(bool is_watch_dog_enabled) { 402 is_watch_dog_enabled_ = is_watch_dog_enabled; 403 if (!is_watch_dog_enabled_) { 404 return; 405 } 406 shutting_down_ = false; 407 const char* reason = "dex2oat watch dog thread startup"; 408 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_init, (&mutex_, nullptr), reason); 409 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_init, (&cond_, nullptr), reason); 410 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_init, (&attr_), reason); 411 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_create, (&pthread_, &attr_, &CallBack, this), reason); 412 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_destroy, (&attr_), reason); 413 } 414 ~WatchDog() { 415 if (!is_watch_dog_enabled_) { 416 return; 417 } 418 const char* reason = "dex2oat watch dog thread shutdown"; 419 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason); 420 shutting_down_ = true; 421 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_signal, (&cond_), reason); 422 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason); 423 424 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_join, (pthread_, nullptr), reason); 425 426 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_destroy, (&cond_), reason); 427 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_destroy, (&mutex_), reason); 428 } 429 430 private: 431 static void* CallBack(void* arg) { 432 WatchDog* self = reinterpret_cast<WatchDog*>(arg); 433 ::art::SetThreadName("dex2oat watch dog"); 434 self->Wait(); 435 return nullptr; 436 } 437 438 NO_RETURN static void Fatal(const std::string& message) { 439 // TODO: When we can guarantee it won't prevent shutdown in error cases, move to LOG. However, 440 // it's rather easy to hang in unwinding. 441 // LogLine also avoids ART logging lock issues, as it's really only a wrapper around 442 // logcat logging or stderr output. 443 LogMessage::LogLine(__FILE__, __LINE__, LogSeverity::FATAL, message.c_str()); 444 exit(1); 445 } 446 447 void Wait() { 448 // TODO: tune the multiplier for GC verification, the following is just to make the timeout 449 // large. 450 constexpr int64_t multiplier = kVerifyObjectSupport > kVerifyObjectModeFast ? 100 : 1; 451 timespec timeout_ts; 452 InitTimeSpec(true, CLOCK_REALTIME, multiplier * kWatchDogTimeoutSeconds * 1000, 0, &timeout_ts); 453 const char* reason = "dex2oat watch dog thread waiting"; 454 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason); 455 while (!shutting_down_) { 456 int rc = TEMP_FAILURE_RETRY(pthread_cond_timedwait(&cond_, &mutex_, &timeout_ts)); 457 if (rc == ETIMEDOUT) { 458 Fatal(StringPrintf("dex2oat did not finish after %" PRId64 " seconds", 459 kWatchDogTimeoutSeconds)); 460 } else if (rc != 0) { 461 std::string message(StringPrintf("pthread_cond_timedwait failed: %s", 462 strerror(errno))); 463 Fatal(message.c_str()); 464 } 465 } 466 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason); 467 } 468 469 // When setting timeouts, keep in mind that the build server may not be as fast as your desktop. 470 // Debug builds are slower so they have larger timeouts. 471 static constexpr int64_t kSlowdownFactor = kIsDebugBuild ? 5U : 1U; 472 473 // 9.5 minutes scaled by kSlowdownFactor. This is slightly smaller than the Package Manager 474 // watchdog (PackageManagerService.WATCHDOG_TIMEOUT, 10 minutes), so that dex2oat will abort 475 // itself before that watchdog would take down the system server. 476 static constexpr int64_t kWatchDogTimeoutSeconds = kSlowdownFactor * (9 * 60 + 30); 477 478 bool is_watch_dog_enabled_; 479 bool shutting_down_; 480 // TODO: Switch to Mutex when we can guarantee it won't prevent shutdown in error cases. 481 pthread_mutex_t mutex_; 482 pthread_cond_t cond_; 483 pthread_attr_t attr_; 484 pthread_t pthread_; 485}; 486 487static constexpr size_t kMinDexFilesForSwap = 2; 488static constexpr size_t kMinDexFileCumulativeSizeForSwap = 20 * MB; 489 490static bool UseSwap(bool is_image, std::vector<const DexFile*>& dex_files) { 491 if (is_image) { 492 // Don't use swap, we know generation should succeed, and we don't want to slow it down. 493 return false; 494 } 495 if (dex_files.size() < kMinDexFilesForSwap) { 496 // If there are less dex files than the threshold, assume it's gonna be fine. 497 return false; 498 } 499 size_t dex_files_size = 0; 500 for (const auto* dex_file : dex_files) { 501 dex_files_size += dex_file->GetHeader().file_size_; 502 } 503 return dex_files_size >= kMinDexFileCumulativeSizeForSwap; 504} 505 506static void CloseAllFds(const std::vector<uint32_t>& fds, const char* descriptor) { 507 for (size_t i = 0; i < fds.size(); i++) { 508 if (close(fds[i]) < 0) { 509 PLOG(WARNING) << "Failed to close descriptor for " << descriptor << " at index " << i; 510 } 511 } 512} 513 514class Dex2Oat FINAL { 515 public: 516 explicit Dex2Oat(TimingLogger* timings) : 517 compiler_kind_(Compiler::kOptimizing), 518 instruction_set_(kRuntimeISA), 519 // Take the default set of instruction features from the build. 520 image_file_location_oat_checksum_(0), 521 image_file_location_oat_data_begin_(0), 522 image_patch_delta_(0), 523 key_value_store_(nullptr), 524 verification_results_(nullptr), 525 method_inliner_map_(), 526 runtime_(nullptr), 527 thread_count_(sysconf(_SC_NPROCESSORS_CONF)), 528 start_ns_(NanoTime()), 529 oat_fd_(-1), 530 zip_fd_(-1), 531 image_base_(0U), 532 image_classes_zip_filename_(nullptr), 533 image_classes_filename_(nullptr), 534 image_storage_mode_(ImageHeader::kStorageModeUncompressed), 535 compiled_classes_zip_filename_(nullptr), 536 compiled_classes_filename_(nullptr), 537 compiled_methods_zip_filename_(nullptr), 538 compiled_methods_filename_(nullptr), 539 app_image_(false), 540 boot_image_(false), 541 multi_image_(false), 542 is_host_(false), 543 class_loader_(nullptr), 544 elf_writers_(), 545 oat_writers_(), 546 rodata_(), 547 image_writer_(nullptr), 548 driver_(nullptr), 549 opened_dex_files_maps_(), 550 opened_dex_files_(), 551 dump_stats_(false), 552 dump_passes_(false), 553 dump_timing_(false), 554 dump_slow_timing_(kIsDebugBuild), 555 swap_fd_(-1), 556 app_image_fd_(kInvalidFd), 557 timings_(timings) {} 558 559 ~Dex2Oat() { 560 // Log completion time before deleting the runtime_, because this accesses 561 // the runtime. 562 LogCompletionTime(); 563 564 if (!kIsDebugBuild && !(RUNNING_ON_MEMORY_TOOL && kMemoryToolDetectsLeaks)) { 565 // We want to just exit on non-debug builds, not bringing the runtime down 566 // in an orderly fashion. So release the following fields. 567 driver_.release(); 568 image_writer_.release(); 569 for (std::unique_ptr<const DexFile>& dex_file : opened_dex_files_) { 570 dex_file.release(); 571 } 572 for (std::unique_ptr<MemMap>& map : opened_dex_files_maps_) { 573 map.release(); 574 } 575 for (std::unique_ptr<File>& oat_file : oat_files_) { 576 oat_file.release(); 577 } 578 runtime_.release(); 579 verification_results_.release(); 580 key_value_store_.release(); 581 } 582 } 583 584 struct ParserOptions { 585 std::vector<const char*> oat_symbols; 586 std::string boot_image_filename; 587 bool watch_dog_enabled = true; 588 bool requested_specific_compiler = false; 589 std::string error_msg; 590 }; 591 592 void ParseZipFd(const StringPiece& option) { 593 ParseUintOption(option, "--zip-fd", &zip_fd_, Usage); 594 } 595 596 void ParseOatFd(const StringPiece& option) { 597 ParseUintOption(option, "--oat-fd", &oat_fd_, Usage); 598 } 599 600 void ParseFdForCollection(const StringPiece& option, 601 const char* arg_name, 602 std::vector<uint32_t>* fds) { 603 uint32_t fd; 604 ParseUintOption(option, arg_name, &fd, Usage); 605 fds->push_back(fd); 606 } 607 608 void ParseJ(const StringPiece& option) { 609 ParseUintOption(option, "-j", &thread_count_, Usage, /* is_long_option */ false); 610 } 611 612 void ParseBase(const StringPiece& option) { 613 DCHECK(option.starts_with("--base=")); 614 const char* image_base_str = option.substr(strlen("--base=")).data(); 615 char* end; 616 image_base_ = strtoul(image_base_str, &end, 16); 617 if (end == image_base_str || *end != '\0') { 618 Usage("Failed to parse hexadecimal value for option %s", option.data()); 619 } 620 } 621 622 void ParseInstructionSet(const StringPiece& option) { 623 DCHECK(option.starts_with("--instruction-set=")); 624 StringPiece instruction_set_str = option.substr(strlen("--instruction-set=")).data(); 625 // StringPiece is not necessarily zero-terminated, so need to make a copy and ensure it. 626 std::unique_ptr<char[]> buf(new char[instruction_set_str.length() + 1]); 627 strncpy(buf.get(), instruction_set_str.data(), instruction_set_str.length()); 628 buf.get()[instruction_set_str.length()] = 0; 629 instruction_set_ = GetInstructionSetFromString(buf.get()); 630 // arm actually means thumb2. 631 if (instruction_set_ == InstructionSet::kArm) { 632 instruction_set_ = InstructionSet::kThumb2; 633 } 634 } 635 636 void ParseInstructionSetVariant(const StringPiece& option, ParserOptions* parser_options) { 637 DCHECK(option.starts_with("--instruction-set-variant=")); 638 StringPiece str = option.substr(strlen("--instruction-set-variant=")).data(); 639 instruction_set_features_.reset( 640 InstructionSetFeatures::FromVariant( 641 instruction_set_, str.as_string(), &parser_options->error_msg)); 642 if (instruction_set_features_.get() == nullptr) { 643 Usage("%s", parser_options->error_msg.c_str()); 644 } 645 } 646 647 void ParseInstructionSetFeatures(const StringPiece& option, ParserOptions* parser_options) { 648 DCHECK(option.starts_with("--instruction-set-features=")); 649 StringPiece str = option.substr(strlen("--instruction-set-features=")).data(); 650 if (instruction_set_features_.get() == nullptr) { 651 instruction_set_features_.reset( 652 InstructionSetFeatures::FromVariant( 653 instruction_set_, "default", &parser_options->error_msg)); 654 if (instruction_set_features_.get() == nullptr) { 655 Usage("Problem initializing default instruction set features variant: %s", 656 parser_options->error_msg.c_str()); 657 } 658 } 659 instruction_set_features_.reset( 660 instruction_set_features_->AddFeaturesFromString(str.as_string(), 661 &parser_options->error_msg)); 662 if (instruction_set_features_.get() == nullptr) { 663 Usage("Error parsing '%s': %s", option.data(), parser_options->error_msg.c_str()); 664 } 665 } 666 667 void ParseCompilerBackend(const StringPiece& option, ParserOptions* parser_options) { 668 DCHECK(option.starts_with("--compiler-backend=")); 669 parser_options->requested_specific_compiler = true; 670 StringPiece backend_str = option.substr(strlen("--compiler-backend=")).data(); 671 if (backend_str == "Quick") { 672 compiler_kind_ = Compiler::kQuick; 673 } else if (backend_str == "Optimizing") { 674 compiler_kind_ = Compiler::kOptimizing; 675 } else { 676 Usage("Unknown compiler backend: %s", backend_str.data()); 677 } 678 } 679 680 void ParseImageFormat(const StringPiece& option) { 681 const StringPiece substr("--image-format="); 682 DCHECK(option.starts_with(substr)); 683 const StringPiece format_str = option.substr(substr.length()); 684 if (format_str == "lz4") { 685 image_storage_mode_ = ImageHeader::kStorageModeLZ4; 686 } else if (format_str == "uncompressed") { 687 image_storage_mode_ = ImageHeader::kStorageModeUncompressed; 688 } else { 689 Usage("Unknown image format: %s", format_str.data()); 690 } 691 } 692 693 void ProcessOptions(ParserOptions* parser_options) { 694 boot_image_ = !image_filenames_.empty(); 695 app_image_ = app_image_fd_ != -1 || !app_image_file_name_.empty(); 696 697 if (IsAppImage() && IsBootImage()) { 698 Usage("Can't have both --image and (--app-image-fd or --app-image-file)"); 699 } 700 701 if (IsBootImage()) { 702 // We need the boot image to always be debuggable. 703 compiler_options_->debuggable_ = true; 704 } 705 706 if (oat_filenames_.empty() && oat_fd_ == -1) { 707 Usage("Output must be supplied with either --oat-file or --oat-fd"); 708 } 709 710 if (!oat_filenames_.empty() && oat_fd_ != -1) { 711 Usage("--oat-file should not be used with --oat-fd"); 712 } 713 714 if (!parser_options->oat_symbols.empty() && oat_fd_ != -1) { 715 Usage("--oat-symbols should not be used with --oat-fd"); 716 } 717 718 if (!parser_options->oat_symbols.empty() && is_host_) { 719 Usage("--oat-symbols should not be used with --host"); 720 } 721 722 if (oat_fd_ != -1 && !image_filenames_.empty()) { 723 Usage("--oat-fd should not be used with --image"); 724 } 725 726 if (!parser_options->oat_symbols.empty() && 727 parser_options->oat_symbols.size() != oat_filenames_.size()) { 728 Usage("--oat-file arguments do not match --oat-symbols arguments"); 729 } 730 731 if (!image_filenames_.empty() && image_filenames_.size() != oat_filenames_.size()) { 732 Usage("--oat-file arguments do not match --image arguments"); 733 } 734 735 if (android_root_.empty()) { 736 const char* android_root_env_var = getenv("ANDROID_ROOT"); 737 if (android_root_env_var == nullptr) { 738 Usage("--android-root unspecified and ANDROID_ROOT not set"); 739 } 740 android_root_ += android_root_env_var; 741 } 742 743 if (!boot_image_ && parser_options->boot_image_filename.empty()) { 744 parser_options->boot_image_filename += android_root_; 745 parser_options->boot_image_filename += "/framework/boot.art"; 746 } 747 if (!parser_options->boot_image_filename.empty()) { 748 boot_image_filename_ = parser_options->boot_image_filename; 749 } 750 751 if (image_classes_filename_ != nullptr && !IsBootImage()) { 752 Usage("--image-classes should only be used with --image"); 753 } 754 755 if (image_classes_filename_ != nullptr && !boot_image_filename_.empty()) { 756 Usage("--image-classes should not be used with --boot-image"); 757 } 758 759 if (image_classes_zip_filename_ != nullptr && image_classes_filename_ == nullptr) { 760 Usage("--image-classes-zip should be used with --image-classes"); 761 } 762 763 if (compiled_classes_filename_ != nullptr && !IsBootImage()) { 764 Usage("--compiled-classes should only be used with --image"); 765 } 766 767 if (compiled_classes_filename_ != nullptr && !boot_image_filename_.empty()) { 768 Usage("--compiled-classes should not be used with --boot-image"); 769 } 770 771 if (compiled_classes_zip_filename_ != nullptr && compiled_classes_filename_ == nullptr) { 772 Usage("--compiled-classes-zip should be used with --compiled-classes"); 773 } 774 775 if (dex_filenames_.empty() && zip_fd_ == -1) { 776 Usage("Input must be supplied with either --dex-file or --zip-fd"); 777 } 778 779 if (!dex_filenames_.empty() && zip_fd_ != -1) { 780 Usage("--dex-file should not be used with --zip-fd"); 781 } 782 783 if (!dex_filenames_.empty() && !zip_location_.empty()) { 784 Usage("--dex-file should not be used with --zip-location"); 785 } 786 787 if (dex_locations_.empty()) { 788 for (const char* dex_file_name : dex_filenames_) { 789 dex_locations_.push_back(dex_file_name); 790 } 791 } else if (dex_locations_.size() != dex_filenames_.size()) { 792 Usage("--dex-location arguments do not match --dex-file arguments"); 793 } 794 795 if (!dex_filenames_.empty() && !oat_filenames_.empty()) { 796 if (oat_filenames_.size() != 1 && oat_filenames_.size() != dex_filenames_.size()) { 797 Usage("--oat-file arguments must be singular or match --dex-file arguments"); 798 } 799 } 800 801 if (zip_fd_ != -1 && zip_location_.empty()) { 802 Usage("--zip-location should be supplied with --zip-fd"); 803 } 804 805 if (boot_image_filename_.empty()) { 806 if (image_base_ == 0) { 807 Usage("Non-zero --base not specified"); 808 } 809 } 810 811 if (!profile_files_.empty() && !profile_files_fd_.empty()) { 812 Usage("Profile files should not be specified with both --profile-file-fd and --profile-file"); 813 } 814 if (!profile_files_.empty()) { 815 if (!reference_profile_files_.empty() && 816 (reference_profile_files_.size() != profile_files_.size())) { 817 Usage("If specified, --reference-profile-file should match the number of --profile-file."); 818 } 819 } else if (!reference_profile_files_.empty()) { 820 Usage("--reference-profile-file should only be supplied with --profile-file"); 821 } 822 if (!profile_files_fd_.empty()) { 823 if (!reference_profile_files_fd_.empty() && 824 (reference_profile_files_fd_.size() != profile_files_fd_.size())) { 825 Usage("If specified, --reference-profile-file-fd should match the number", 826 " of --profile-file-fd."); 827 } 828 } else if (!reference_profile_files_fd_.empty()) { 829 Usage("--reference-profile-file-fd should only be supplied with --profile-file-fd"); 830 } 831 832 if (!parser_options->oat_symbols.empty()) { 833 oat_unstripped_ = std::move(parser_options->oat_symbols); 834 } 835 836 // If no instruction set feature was given, use the default one for the target 837 // instruction set. 838 if (instruction_set_features_.get() == nullptr) { 839 instruction_set_features_.reset( 840 InstructionSetFeatures::FromVariant( 841 instruction_set_, "default", &parser_options->error_msg)); 842 if (instruction_set_features_.get() == nullptr) { 843 Usage("Problem initializing default instruction set features variant: %s", 844 parser_options->error_msg.c_str()); 845 } 846 } 847 848 if (instruction_set_ == kRuntimeISA) { 849 std::unique_ptr<const InstructionSetFeatures> runtime_features( 850 InstructionSetFeatures::FromCppDefines()); 851 if (!instruction_set_features_->Equals(runtime_features.get())) { 852 LOG(WARNING) << "Mismatch between dex2oat instruction set features (" 853 << *instruction_set_features_ << ") and those of dex2oat executable (" 854 << *runtime_features <<") for the command line:\n" 855 << CommandLine(); 856 } 857 } 858 859 // It they are not set, use default values for inlining settings. 860 // TODO: We should rethink the compiler filter. We mostly save 861 // time here, which is orthogonal to space. 862 if (compiler_options_->inline_depth_limit_ == CompilerOptions::kUnsetInlineDepthLimit) { 863 compiler_options_->inline_depth_limit_ = 864 (compiler_options_->compiler_filter_ == CompilerOptions::kSpace) 865 // Implementation of the space filter: limit inlining depth. 866 ? CompilerOptions::kSpaceFilterInlineDepthLimit 867 : CompilerOptions::kDefaultInlineDepthLimit; 868 } 869 if (compiler_options_->inline_max_code_units_ == CompilerOptions::kUnsetInlineMaxCodeUnits) { 870 compiler_options_->inline_max_code_units_ = 871 (compiler_options_->compiler_filter_ == CompilerOptions::kSpace) 872 // Implementation of the space filter: limit inlining max code units. 873 ? CompilerOptions::kSpaceFilterInlineMaxCodeUnits 874 : CompilerOptions::kDefaultInlineMaxCodeUnits; 875 } 876 877 // Checks are all explicit until we know the architecture. 878 // Set the compilation target's implicit checks options. 879 switch (instruction_set_) { 880 case kArm: 881 case kThumb2: 882 case kArm64: 883 case kX86: 884 case kX86_64: 885 case kMips: 886 case kMips64: 887 compiler_options_->implicit_null_checks_ = true; 888 compiler_options_->implicit_so_checks_ = true; 889 break; 890 891 default: 892 // Defaults are correct. 893 break; 894 } 895 896 compiler_options_->verbose_methods_ = verbose_methods_.empty() ? nullptr : &verbose_methods_; 897 898 if (!IsBootImage() && multi_image_) { 899 Usage("--multi-image can only be used when creating boot images"); 900 } 901 if (IsBootImage() && multi_image_ && image_filenames_.size() > 1) { 902 Usage("--multi-image cannot be used with multiple image names"); 903 } 904 905 // For now, if we're on the host and compile the boot image, *always* use multiple image files. 906 if (!kIsTargetBuild && IsBootImage()) { 907 if (image_filenames_.size() == 1) { 908 multi_image_ = true; 909 } 910 } 911 912 // Done with usage checks, enable watchdog if requested 913 if (parser_options->watch_dog_enabled) { 914 watchdog_.reset(new WatchDog(true)); 915 } 916 917 // Fill some values into the key-value store for the oat header. 918 key_value_store_.reset(new SafeMap<std::string, std::string>()); 919 } 920 921 void ExpandOatAndImageFilenames() { 922 std::string base_oat = oat_filenames_[0]; 923 size_t last_oat_slash = base_oat.rfind('/'); 924 if (last_oat_slash == std::string::npos) { 925 Usage("--multi-image used with unusable oat filename %s", base_oat.c_str()); 926 } 927 // We also need to honor path components that were encoded through '@'. Otherwise the loading 928 // code won't be able to find the images. 929 if (base_oat.find('@', last_oat_slash) != std::string::npos) { 930 last_oat_slash = base_oat.rfind('@'); 931 } 932 base_oat = base_oat.substr(0, last_oat_slash + 1); 933 934 std::string base_img = image_filenames_[0]; 935 size_t last_img_slash = base_img.rfind('/'); 936 if (last_img_slash == std::string::npos) { 937 Usage("--multi-image used with unusable image filename %s", base_img.c_str()); 938 } 939 // We also need to honor path components that were encoded through '@'. Otherwise the loading 940 // code won't be able to find the images. 941 if (base_img.find('@', last_img_slash) != std::string::npos) { 942 last_img_slash = base_img.rfind('@'); 943 } 944 945 // Get the prefix, which is the primary image name (without path components). Strip the 946 // extension. 947 std::string prefix = base_img.substr(last_img_slash + 1); 948 if (prefix.rfind('.') != std::string::npos) { 949 prefix = prefix.substr(0, prefix.rfind('.')); 950 } 951 if (!prefix.empty()) { 952 prefix = prefix + "-"; 953 } 954 955 base_img = base_img.substr(0, last_img_slash + 1); 956 957 // Note: we have some special case here for our testing. We have to inject the differentiating 958 // parts for the different core images. 959 std::string infix; // Empty infix by default. 960 { 961 // Check the first name. 962 std::string dex_file = oat_filenames_[0]; 963 size_t last_dex_slash = dex_file.rfind('/'); 964 if (last_dex_slash != std::string::npos) { 965 dex_file = dex_file.substr(last_dex_slash + 1); 966 } 967 size_t last_dex_dot = dex_file.rfind('.'); 968 if (last_dex_dot != std::string::npos) { 969 dex_file = dex_file.substr(0, last_dex_dot); 970 } 971 if (StartsWith(dex_file, "core-")) { 972 infix = dex_file.substr(strlen("core")); 973 } 974 } 975 976 // Now create the other names. Use a counted loop to skip the first one. 977 for (size_t i = 1; i < dex_locations_.size(); ++i) { 978 // TODO: Make everything properly std::string. 979 std::string image_name = CreateMultiImageName(dex_locations_[i], prefix, infix, ".art"); 980 char_backing_storage_.push_back(base_img + image_name); 981 image_filenames_.push_back((char_backing_storage_.end() - 1)->c_str()); 982 983 std::string oat_name = CreateMultiImageName(dex_locations_[i], prefix, infix, ".oat"); 984 char_backing_storage_.push_back(base_oat + oat_name); 985 oat_filenames_.push_back((char_backing_storage_.end() - 1)->c_str()); 986 } 987 } 988 989 // Modify the input string in the following way: 990 // 0) Assume input is /a/b/c.d 991 // 1) Strip the path -> c.d 992 // 2) Inject prefix p -> pc.d 993 // 3) Inject infix i -> pci.d 994 // 4) Replace suffix with s if it's "jar" -> d == "jar" -> pci.s 995 static std::string CreateMultiImageName(std::string in, 996 const std::string& prefix, 997 const std::string& infix, 998 const char* replace_suffix) { 999 size_t last_dex_slash = in.rfind('/'); 1000 if (last_dex_slash != std::string::npos) { 1001 in = in.substr(last_dex_slash + 1); 1002 } 1003 if (!prefix.empty()) { 1004 in = prefix + in; 1005 } 1006 if (!infix.empty()) { 1007 // Inject infix. 1008 size_t last_dot = in.rfind('.'); 1009 if (last_dot != std::string::npos) { 1010 in.insert(last_dot, infix); 1011 } 1012 } 1013 if (EndsWith(in, ".jar")) { 1014 in = in.substr(0, in.length() - strlen(".jar")) + 1015 (replace_suffix != nullptr ? replace_suffix : ""); 1016 } 1017 return in; 1018 } 1019 1020 void InsertCompileOptions(int argc, char** argv) { 1021 std::ostringstream oss; 1022 for (int i = 0; i < argc; ++i) { 1023 if (i > 0) { 1024 oss << ' '; 1025 } 1026 oss << argv[i]; 1027 } 1028 key_value_store_->Put(OatHeader::kDex2OatCmdLineKey, oss.str()); 1029 oss.str(""); // Reset. 1030 oss << kRuntimeISA; 1031 key_value_store_->Put(OatHeader::kDex2OatHostKey, oss.str()); 1032 key_value_store_->Put( 1033 OatHeader::kPicKey, 1034 compiler_options_->compile_pic_ ? OatHeader::kTrueValue : OatHeader::kFalseValue); 1035 key_value_store_->Put( 1036 OatHeader::kDebuggableKey, 1037 compiler_options_->debuggable_ ? OatHeader::kTrueValue : OatHeader::kFalseValue); 1038 } 1039 1040 // Parse the arguments from the command line. In case of an unrecognized option or impossible 1041 // values/combinations, a usage error will be displayed and exit() is called. Thus, if the method 1042 // returns, arguments have been successfully parsed. 1043 void ParseArgs(int argc, char** argv) { 1044 original_argc = argc; 1045 original_argv = argv; 1046 1047 InitLogging(argv); 1048 1049 // Skip over argv[0]. 1050 argv++; 1051 argc--; 1052 1053 if (argc == 0) { 1054 Usage("No arguments specified"); 1055 } 1056 1057 std::unique_ptr<ParserOptions> parser_options(new ParserOptions()); 1058 compiler_options_.reset(new CompilerOptions()); 1059 1060 for (int i = 0; i < argc; i++) { 1061 const StringPiece option(argv[i]); 1062 const bool log_options = false; 1063 if (log_options) { 1064 LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i]; 1065 } 1066 if (option.starts_with("--dex-file=")) { 1067 dex_filenames_.push_back(option.substr(strlen("--dex-file=")).data()); 1068 } else if (option.starts_with("--dex-location=")) { 1069 dex_locations_.push_back(option.substr(strlen("--dex-location=")).data()); 1070 } else if (option.starts_with("--zip-fd=")) { 1071 ParseZipFd(option); 1072 } else if (option.starts_with("--zip-location=")) { 1073 zip_location_ = option.substr(strlen("--zip-location=")).data(); 1074 } else if (option.starts_with("--oat-file=")) { 1075 oat_filenames_.push_back(option.substr(strlen("--oat-file=")).data()); 1076 } else if (option.starts_with("--oat-symbols=")) { 1077 parser_options->oat_symbols.push_back(option.substr(strlen("--oat-symbols=")).data()); 1078 } else if (option.starts_with("--oat-fd=")) { 1079 ParseOatFd(option); 1080 } else if (option == "--watch-dog") { 1081 parser_options->watch_dog_enabled = true; 1082 } else if (option == "--no-watch-dog") { 1083 parser_options->watch_dog_enabled = false; 1084 } else if (option.starts_with("-j")) { 1085 ParseJ(option); 1086 } else if (option.starts_with("--oat-location=")) { 1087 oat_location_ = option.substr(strlen("--oat-location=")).data(); 1088 } else if (option.starts_with("--image=")) { 1089 image_filenames_.push_back(option.substr(strlen("--image=")).data()); 1090 } else if (option.starts_with("--image-classes=")) { 1091 image_classes_filename_ = option.substr(strlen("--image-classes=")).data(); 1092 } else if (option.starts_with("--image-classes-zip=")) { 1093 image_classes_zip_filename_ = option.substr(strlen("--image-classes-zip=")).data(); 1094 } else if (option.starts_with("--image-format=")) { 1095 ParseImageFormat(option); 1096 } else if (option.starts_with("--compiled-classes=")) { 1097 compiled_classes_filename_ = option.substr(strlen("--compiled-classes=")).data(); 1098 } else if (option.starts_with("--compiled-classes-zip=")) { 1099 compiled_classes_zip_filename_ = option.substr(strlen("--compiled-classes-zip=")).data(); 1100 } else if (option.starts_with("--compiled-methods=")) { 1101 compiled_methods_filename_ = option.substr(strlen("--compiled-methods=")).data(); 1102 } else if (option.starts_with("--compiled-methods-zip=")) { 1103 compiled_methods_zip_filename_ = option.substr(strlen("--compiled-methods-zip=")).data(); 1104 } else if (option.starts_with("--base=")) { 1105 ParseBase(option); 1106 } else if (option.starts_with("--boot-image=")) { 1107 parser_options->boot_image_filename = option.substr(strlen("--boot-image=")).data(); 1108 } else if (option.starts_with("--android-root=")) { 1109 android_root_ = option.substr(strlen("--android-root=")).data(); 1110 } else if (option.starts_with("--instruction-set=")) { 1111 ParseInstructionSet(option); 1112 } else if (option.starts_with("--instruction-set-variant=")) { 1113 ParseInstructionSetVariant(option, parser_options.get()); 1114 } else if (option.starts_with("--instruction-set-features=")) { 1115 ParseInstructionSetFeatures(option, parser_options.get()); 1116 } else if (option.starts_with("--compiler-backend=")) { 1117 ParseCompilerBackend(option, parser_options.get()); 1118 } else if (option.starts_with("--profile-file=")) { 1119 profile_files_.push_back(option.substr(strlen("--profile-file=")).ToString()); 1120 } else if (option.starts_with("--reference-profile-file=")) { 1121 reference_profile_files_.push_back( 1122 option.substr(strlen("--reference-profile-file=")).ToString()); 1123 } else if (option.starts_with("--profile-file-fd=")) { 1124 ParseFdForCollection(option, "--profile-file-fd", &profile_files_fd_); 1125 } else if (option.starts_with("--reference-profile-file-fd=")) { 1126 ParseFdForCollection(option, "--reference_profile-file-fd", &reference_profile_files_fd_); 1127 } else if (option == "--no-profile-file") { 1128 // No profile 1129 } else if (option == "--host") { 1130 is_host_ = true; 1131 } else if (option == "--runtime-arg") { 1132 if (++i >= argc) { 1133 Usage("Missing required argument for --runtime-arg"); 1134 } 1135 if (log_options) { 1136 LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i]; 1137 } 1138 runtime_args_.push_back(argv[i]); 1139 } else if (option == "--dump-timing") { 1140 dump_timing_ = true; 1141 } else if (option == "--dump-passes") { 1142 dump_passes_ = true; 1143 } else if (option == "--dump-stats") { 1144 dump_stats_ = true; 1145 } else if (option.starts_with("--swap-file=")) { 1146 swap_file_name_ = option.substr(strlen("--swap-file=")).data(); 1147 } else if (option.starts_with("--swap-fd=")) { 1148 ParseUintOption(option, "--swap-fd", &swap_fd_, Usage); 1149 } else if (option.starts_with("--app-image-file=")) { 1150 app_image_file_name_ = option.substr(strlen("--app-image-file=")).data(); 1151 } else if (option.starts_with("--app-image-fd=")) { 1152 ParseUintOption(option, "--app-image-fd", &app_image_fd_, Usage); 1153 } else if (option.starts_with("--verbose-methods=")) { 1154 // TODO: rather than switch off compiler logging, make all VLOG(compiler) messages 1155 // conditional on having verbost methods. 1156 gLogVerbosity.compiler = false; 1157 Split(option.substr(strlen("--verbose-methods=")).ToString(), ',', &verbose_methods_); 1158 } else if (option == "--multi-image") { 1159 multi_image_ = true; 1160 } else if (option.starts_with("--no-inline-from=")) { 1161 no_inline_from_string_ = option.substr(strlen("--no-inline-from=")).data(); 1162 } else if (!compiler_options_->ParseCompilerOption(option, Usage)) { 1163 Usage("Unknown argument %s", option.data()); 1164 } 1165 } 1166 1167 ProcessOptions(parser_options.get()); 1168 1169 // Insert some compiler things. 1170 InsertCompileOptions(argc, argv); 1171 } 1172 1173 // Check whether the oat output files are writable, and open them for later. Also open a swap 1174 // file, if a name is given. 1175 bool OpenFile() { 1176 // Prune non-existent dex files now so that we don't create empty oat files for multi-image. 1177 PruneNonExistentDexFiles(); 1178 1179 // Expand oat and image filenames for multi image. 1180 if (IsBootImage() && multi_image_) { 1181 ExpandOatAndImageFilenames(); 1182 } 1183 1184 bool create_file = oat_fd_ == -1; // as opposed to using open file descriptor 1185 if (create_file) { 1186 for (const char* oat_filename : oat_filenames_) { 1187 std::unique_ptr<File> oat_file(OS::CreateEmptyFile(oat_filename)); 1188 if (oat_file.get() == nullptr) { 1189 PLOG(ERROR) << "Failed to create oat file: " << oat_filename; 1190 return false; 1191 } 1192 if (create_file && fchmod(oat_file->Fd(), 0644) != 0) { 1193 PLOG(ERROR) << "Failed to make oat file world readable: " << oat_filename; 1194 oat_file->Erase(); 1195 return false; 1196 } 1197 oat_files_.push_back(std::move(oat_file)); 1198 } 1199 } else { 1200 std::unique_ptr<File> oat_file(new File(oat_fd_, oat_location_, true)); 1201 oat_file->DisableAutoClose(); 1202 if (oat_file->SetLength(0) != 0) { 1203 PLOG(WARNING) << "Truncating oat file " << oat_location_ << " failed."; 1204 } 1205 if (oat_file.get() == nullptr) { 1206 PLOG(ERROR) << "Failed to create oat file: " << oat_location_; 1207 return false; 1208 } 1209 if (create_file && fchmod(oat_file->Fd(), 0644) != 0) { 1210 PLOG(ERROR) << "Failed to make oat file world readable: " << oat_location_; 1211 oat_file->Erase(); 1212 return false; 1213 } 1214 oat_filenames_.push_back(oat_location_.c_str()); 1215 oat_files_.push_back(std::move(oat_file)); 1216 } 1217 1218 // Swap file handling. 1219 // 1220 // If the swap fd is not -1, we assume this is the file descriptor of an open but unlinked file 1221 // that we can use for swap. 1222 // 1223 // If the swap fd is -1 and we have a swap-file string, open the given file as a swap file. We 1224 // will immediately unlink to satisfy the swap fd assumption. 1225 if (swap_fd_ == -1 && !swap_file_name_.empty()) { 1226 std::unique_ptr<File> swap_file(OS::CreateEmptyFile(swap_file_name_.c_str())); 1227 if (swap_file.get() == nullptr) { 1228 PLOG(ERROR) << "Failed to create swap file: " << swap_file_name_; 1229 return false; 1230 } 1231 swap_fd_ = swap_file->Fd(); 1232 swap_file->MarkUnchecked(); // We don't we to track this, it will be unlinked immediately. 1233 swap_file->DisableAutoClose(); // We'll handle it ourselves, the File object will be 1234 // released immediately. 1235 unlink(swap_file_name_.c_str()); 1236 } 1237 1238 // If we use a swap file, ensure we are above the threshold to make it necessary. 1239 if (swap_fd_ != -1) { 1240 if (!UseSwap(IsBootImage(), dex_files_)) { 1241 close(swap_fd_); 1242 swap_fd_ = -1; 1243 VLOG(compiler) << "Decided to run without swap."; 1244 } else { 1245 LOG(INFO) << "Large app, accepted running with swap."; 1246 } 1247 } 1248 // Note that dex2oat won't close the swap_fd_. The compiler driver's swap space will do that. 1249 1250 return true; 1251 } 1252 1253 void EraseOatFiles() { 1254 for (size_t i = 0; i < oat_files_.size(); ++i) { 1255 DCHECK(oat_files_[i].get() != nullptr); 1256 oat_files_[i]->Erase(); 1257 oat_files_[i].reset(); 1258 } 1259 } 1260 1261 void Shutdown() { 1262 ScopedObjectAccess soa(Thread::Current()); 1263 for (jobject dex_cache : dex_caches_) { 1264 soa.Env()->DeleteLocalRef(dex_cache); 1265 } 1266 dex_caches_.clear(); 1267 } 1268 1269 // Set up the environment for compilation. Includes starting the runtime and loading/opening the 1270 // boot class path. 1271 bool Setup() { 1272 TimingLogger::ScopedTiming t("dex2oat Setup", timings_); 1273 art::MemMap::Init(); // For ZipEntry::ExtractToMemMap. 1274 1275 if (!PrepareImageClasses() || !PrepareCompiledClasses() || !PrepareCompiledMethods()) { 1276 return false; 1277 } 1278 1279 verification_results_.reset(new VerificationResults(compiler_options_.get())); 1280 callbacks_.reset(new QuickCompilerCallbacks( 1281 verification_results_.get(), 1282 &method_inliner_map_, 1283 IsBootImage() ? 1284 CompilerCallbacks::CallbackMode::kCompileBootImage : 1285 CompilerCallbacks::CallbackMode::kCompileApp)); 1286 1287 RuntimeArgumentMap runtime_options; 1288 if (!PrepareRuntimeOptions(&runtime_options)) { 1289 return false; 1290 } 1291 1292 CreateOatWriters(); 1293 if (!AddDexFileSources()) { 1294 return false; 1295 } 1296 1297 if (IsBootImage() && image_filenames_.size() > 1) { 1298 // If we're compiling the boot image, store the boot classpath into the Key-Value store. 1299 // We need this for the multi-image case. 1300 key_value_store_->Put(OatHeader::kBootClassPath, GetMultiImageBootClassPath()); 1301 } 1302 1303 if (!IsBootImage()) { 1304 // When compiling an app, create the runtime early to retrieve 1305 // the image location key needed for the oat header. 1306 if (!CreateRuntime(std::move(runtime_options))) { 1307 return false; 1308 } 1309 1310 { 1311 TimingLogger::ScopedTiming t3("Loading image checksum", timings_); 1312 std::vector<gc::space::ImageSpace*> image_spaces = 1313 Runtime::Current()->GetHeap()->GetBootImageSpaces(); 1314 image_file_location_oat_checksum_ = image_spaces[0]->GetImageHeader().GetOatChecksum(); 1315 image_file_location_oat_data_begin_ = 1316 reinterpret_cast<uintptr_t>(image_spaces[0]->GetImageHeader().GetOatDataBegin()); 1317 image_patch_delta_ = image_spaces[0]->GetImageHeader().GetPatchDelta(); 1318 // Store the boot image filename(s). 1319 std::vector<std::string> image_filenames; 1320 for (const gc::space::ImageSpace* image_space : image_spaces) { 1321 image_filenames.push_back(image_space->GetImageFilename()); 1322 } 1323 std::string image_file_location = Join(image_filenames, ':'); 1324 if (!image_file_location.empty()) { 1325 key_value_store_->Put(OatHeader::kImageLocationKey, image_file_location); 1326 } 1327 } 1328 1329 // Open dex files for class path. 1330 const std::vector<std::string> class_path_locations = 1331 GetClassPathLocations(runtime_->GetClassPathString()); 1332 OpenClassPathFiles(class_path_locations, &class_path_files_); 1333 1334 // Store the classpath we have right now. 1335 std::vector<const DexFile*> class_path_files = MakeNonOwningPointerVector(class_path_files_); 1336 key_value_store_->Put(OatHeader::kClassPathKey, 1337 OatFile::EncodeDexFileDependencies(class_path_files)); 1338 } 1339 1340 // Now that we have finalized key_value_store_, start writing the oat file. 1341 { 1342 TimingLogger::ScopedTiming t_dex("Writing and opening dex files", timings_); 1343 rodata_.reserve(oat_writers_.size()); 1344 for (size_t i = 0, size = oat_writers_.size(); i != size; ++i) { 1345 rodata_.push_back(elf_writers_[i]->StartRoData()); 1346 // Unzip or copy dex files straight to the oat file. 1347 std::unique_ptr<MemMap> opened_dex_files_map; 1348 std::vector<std::unique_ptr<const DexFile>> opened_dex_files; 1349 if (!oat_writers_[i]->WriteAndOpenDexFiles(rodata_.back(), 1350 oat_files_[i].get(), 1351 instruction_set_, 1352 instruction_set_features_.get(), 1353 key_value_store_.get(), 1354 /* verify */ true, 1355 &opened_dex_files_map, 1356 &opened_dex_files)) { 1357 return false; 1358 } 1359 dex_files_per_oat_file_.push_back(MakeNonOwningPointerVector(opened_dex_files)); 1360 if (opened_dex_files_map != nullptr) { 1361 opened_dex_files_maps_.push_back(std::move(opened_dex_files_map)); 1362 for (std::unique_ptr<const DexFile>& dex_file : opened_dex_files) { 1363 dex_file_oat_filename_map_.emplace(dex_file.get(), oat_filenames_[i]); 1364 opened_dex_files_.push_back(std::move(dex_file)); 1365 } 1366 } else { 1367 DCHECK(opened_dex_files.empty()); 1368 } 1369 } 1370 } 1371 1372 dex_files_ = MakeNonOwningPointerVector(opened_dex_files_); 1373 if (IsBootImage()) { 1374 // For boot image, pass opened dex files to the Runtime::Create(). 1375 // Note: Runtime acquires ownership of these dex files. 1376 runtime_options.Set(RuntimeArgumentMap::BootClassPathDexList, &opened_dex_files_); 1377 if (!CreateRuntime(std::move(runtime_options))) { 1378 return false; 1379 } 1380 } 1381 1382 // If we're doing the image, override the compiler filter to force full compilation. Must be 1383 // done ahead of WellKnownClasses::Init that causes verification. Note: doesn't force 1384 // compilation of class initializers. 1385 // Whilst we're in native take the opportunity to initialize well known classes. 1386 Thread* self = Thread::Current(); 1387 WellKnownClasses::Init(self->GetJniEnv()); 1388 1389 ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); 1390 if (!IsBootImage()) { 1391 constexpr bool kSaveDexInput = false; 1392 if (kSaveDexInput) { 1393 SaveDexInput(); 1394 } 1395 1396 // Handle and ClassLoader creation needs to come after Runtime::Create. 1397 ScopedObjectAccess soa(self); 1398 1399 // Classpath: first the class-path given. 1400 std::vector<const DexFile*> class_path_files = MakeNonOwningPointerVector(class_path_files_); 1401 1402 // Then the dex files we'll compile. Thus we'll resolve the class-path first. 1403 class_path_files.insert(class_path_files.end(), dex_files_.begin(), dex_files_.end()); 1404 1405 class_loader_ = class_linker->CreatePathClassLoader(self, class_path_files); 1406 } 1407 1408 // Ensure opened dex files are writable for dex-to-dex transformations. 1409 for (const std::unique_ptr<MemMap>& map : opened_dex_files_maps_) { 1410 if (!map->Protect(PROT_READ | PROT_WRITE)) { 1411 PLOG(ERROR) << "Failed to make .dex files writeable."; 1412 return false; 1413 } 1414 } 1415 1416 // Ensure that the dex caches stay live since we don't want class unloading 1417 // to occur during compilation. 1418 for (const auto& dex_file : dex_files_) { 1419 ScopedObjectAccess soa(self); 1420 dex_caches_.push_back(soa.AddLocalReference<jobject>( 1421 class_linker->RegisterDexFile(*dex_file, Runtime::Current()->GetLinearAlloc()))); 1422 } 1423 1424 /* 1425 * If we're not in interpret-only or verify-none mode, go ahead and compile small applications. 1426 * Don't bother to check if we're doing the image. 1427 */ 1428 if (!IsBootImage() && 1429 compiler_options_->IsCompilationEnabled() && 1430 compiler_kind_ == Compiler::kQuick) { 1431 size_t num_methods = 0; 1432 for (size_t i = 0; i != dex_files_.size(); ++i) { 1433 const DexFile* dex_file = dex_files_[i]; 1434 CHECK(dex_file != nullptr); 1435 num_methods += dex_file->NumMethodIds(); 1436 } 1437 if (num_methods <= compiler_options_->GetNumDexMethodsThreshold()) { 1438 compiler_options_->SetCompilerFilter(CompilerOptions::kSpeed); 1439 VLOG(compiler) << "Below method threshold, compiling anyways"; 1440 } 1441 } 1442 1443 return true; 1444 } 1445 1446 // If we need to keep the oat file open for the image writer. 1447 bool ShouldKeepOatFileOpen() const { 1448 return IsImage() && oat_fd_ != kInvalidFd; 1449 } 1450 1451 // Create and invoke the compiler driver. This will compile all the dex files. 1452 void Compile() { 1453 TimingLogger::ScopedTiming t("dex2oat Compile", timings_); 1454 compiler_phases_timings_.reset(new CumulativeLogger("compilation times")); 1455 1456 // Find the dex file we should not inline from. 1457 1458 // For now, on the host always have core-oj removed. 1459 if (!kIsTargetBuild && no_inline_from_string_.empty()) { 1460 no_inline_from_string_ = "core-oj"; 1461 } 1462 1463 if (!no_inline_from_string_.empty()) { 1464 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 1465 std::vector<const DexFile*> class_path_files = MakeNonOwningPointerVector(class_path_files_); 1466 std::vector<const std::vector<const DexFile*>*> dex_file_vectors = { 1467 &class_linker->GetBootClassPath(), 1468 &class_path_files, 1469 &dex_files_ 1470 }; 1471 for (const std::vector<const DexFile*>* dex_file_vector : dex_file_vectors) { 1472 if (dex_file_vector == nullptr) { 1473 continue; 1474 } 1475 1476 bool found = false; 1477 1478 for (const DexFile* dex_file : *dex_file_vector) { 1479 // Try the complete location first. 1480 found = no_inline_from_string_ == dex_file->GetLocation(); 1481 // The try just the name. 1482 if (!found) { 1483 size_t last_slash = dex_file->GetLocation().rfind('/'); 1484 if (last_slash != std::string::npos) { 1485 found = StartsWith(dex_file->GetLocation().substr(last_slash + 1), 1486 no_inline_from_string_.c_str()); 1487 } 1488 } 1489 1490 if (found) { 1491 VLOG(compiler) << "Disabling inlining from " << dex_file->GetLocation(); 1492 compiler_options_->no_inline_from_ = dex_file; 1493 break; 1494 } 1495 } 1496 1497 if (found) { 1498 break; 1499 } 1500 } 1501 } 1502 1503 driver_.reset(new CompilerDriver(compiler_options_.get(), 1504 verification_results_.get(), 1505 &method_inliner_map_, 1506 compiler_kind_, 1507 instruction_set_, 1508 instruction_set_features_.get(), 1509 IsBootImage(), 1510 image_classes_.release(), 1511 compiled_classes_.release(), 1512 nullptr, 1513 thread_count_, 1514 dump_stats_, 1515 dump_passes_, 1516 compiler_phases_timings_.get(), 1517 swap_fd_, 1518 &dex_file_oat_filename_map_, 1519 profile_compilation_info_.get())); 1520 driver_->SetDexFilesForOatFile(dex_files_); 1521 driver_->CompileAll(class_loader_, dex_files_, timings_); 1522 } 1523 1524 // Notes on the interleaving of creating the images and oat files to 1525 // ensure the references between the two are correct. 1526 // 1527 // Currently we have a memory layout that looks something like this: 1528 // 1529 // +--------------+ 1530 // | images | 1531 // +--------------+ 1532 // | oat files | 1533 // +--------------+ 1534 // | alloc spaces | 1535 // +--------------+ 1536 // 1537 // There are several constraints on the loading of the images and oat files. 1538 // 1539 // 1. The images are expected to be loaded at an absolute address and 1540 // contain Objects with absolute pointers within the images. 1541 // 1542 // 2. There are absolute pointers from Methods in the images to their 1543 // code in the oat files. 1544 // 1545 // 3. There are absolute pointers from the code in the oat files to Methods 1546 // in the images. 1547 // 1548 // 4. There are absolute pointers from code in the oat files to other code 1549 // in the oat files. 1550 // 1551 // To get this all correct, we go through several steps. 1552 // 1553 // 1. We prepare offsets for all data in the oat files and calculate 1554 // the oat data size and code size. During this stage, we also set 1555 // oat code offsets in methods for use by the image writer. 1556 // 1557 // 2. We prepare offsets for the objects in the images and calculate 1558 // the image sizes. 1559 // 1560 // 3. We create the oat files. Originally this was just our own proprietary 1561 // file but now it is contained within an ELF dynamic object (aka an .so 1562 // file). Since we know the image sizes and oat data sizes and code sizes we 1563 // can prepare the ELF headers and we then know the ELF memory segment 1564 // layout and we can now resolve all references. The compiler provides 1565 // LinkerPatch information in each CompiledMethod and we resolve these, 1566 // using the layout information and image object locations provided by 1567 // image writer, as we're writing the method code. 1568 // 1569 // 4. We create the image files. They need to know where the oat files 1570 // will be loaded after itself. Originally oat files were simply 1571 // memory mapped so we could predict where their contents were based 1572 // on the file size. Now that they are ELF files, we need to inspect 1573 // the ELF files to understand the in memory segment layout including 1574 // where the oat header is located within. 1575 // TODO: We could just remember this information from step 3. 1576 // 1577 // 5. We fixup the ELF program headers so that dlopen will try to 1578 // load the .so at the desired location at runtime by offsetting the 1579 // Elf32_Phdr.p_vaddr values by the desired base address. 1580 // TODO: Do this in step 3. We already know the layout there. 1581 // 1582 // Steps 1.-3. are done by the CreateOatFile() above, steps 4.-5. 1583 // are done by the CreateImageFile() below. 1584 1585 // Write out the generated code part. Calls the OatWriter and ElfBuilder. Also prepares the 1586 // ImageWriter, if necessary. 1587 // Note: Flushing (and closing) the file is the caller's responsibility, except for the failure 1588 // case (when the file will be explicitly erased). 1589 bool WriteOatFiles() { 1590 TimingLogger::ScopedTiming t("dex2oat Oat", timings_); 1591 1592 // Sync the data to the file, in case we did dex2dex transformations. 1593 for (const std::unique_ptr<MemMap>& map : opened_dex_files_maps_) { 1594 if (!map->Sync()) { 1595 PLOG(ERROR) << "Failed to Sync() dex2dex output. Map: " << map->GetName(); 1596 return false; 1597 } 1598 } 1599 1600 if (IsImage()) { 1601 if (app_image_ && image_base_ == 0) { 1602 gc::Heap* const heap = Runtime::Current()->GetHeap(); 1603 for (gc::space::ImageSpace* image_space : heap->GetBootImageSpaces()) { 1604 image_base_ = std::max(image_base_, RoundUp( 1605 reinterpret_cast<uintptr_t>(image_space->GetImageHeader().GetOatFileEnd()), 1606 kPageSize)); 1607 } 1608 // The non moving space is right after the oat file. Put the preferred app image location 1609 // right after the non moving space so that we ideally get a continuous immune region for 1610 // the GC. 1611 const size_t non_moving_space_capacity = heap->GetNonMovingSpace()->Capacity(); 1612 image_base_ += non_moving_space_capacity; 1613 VLOG(compiler) << "App image base=" << reinterpret_cast<void*>(image_base_); 1614 } 1615 1616 image_writer_.reset(new ImageWriter(*driver_, 1617 image_base_, 1618 compiler_options_->GetCompilePic(), 1619 IsAppImage(), 1620 image_storage_mode_, 1621 oat_filenames_, 1622 dex_file_oat_filename_map_)); 1623 1624 // We need to prepare method offsets in the image address space for direct method patching. 1625 TimingLogger::ScopedTiming t2("dex2oat Prepare image address space", timings_); 1626 if (!image_writer_->PrepareImageAddressSpace()) { 1627 LOG(ERROR) << "Failed to prepare image address space."; 1628 return false; 1629 } 1630 } 1631 1632 { 1633 TimingLogger::ScopedTiming t2("dex2oat Write ELF", timings_); 1634 for (size_t i = 0, size = oat_files_.size(); i != size; ++i) { 1635 std::unique_ptr<File>& oat_file = oat_files_[i]; 1636 std::unique_ptr<ElfWriter>& elf_writer = elf_writers_[i]; 1637 std::unique_ptr<OatWriter>& oat_writer = oat_writers_[i]; 1638 1639 std::vector<const DexFile*>& dex_files = dex_files_per_oat_file_[i]; 1640 oat_writer->PrepareLayout(driver_.get(), image_writer_.get(), dex_files); 1641 1642 OutputStream*& rodata = rodata_[i]; 1643 DCHECK(rodata != nullptr); 1644 if (!oat_writer->WriteRodata(rodata)) { 1645 LOG(ERROR) << "Failed to write .rodata section to the ELF file " << oat_file->GetPath(); 1646 return false; 1647 } 1648 elf_writer->EndRoData(rodata); 1649 rodata = nullptr; 1650 1651 OutputStream* text = elf_writer->StartText(); 1652 if (!oat_writer->WriteCode(text)) { 1653 LOG(ERROR) << "Failed to write .text section to the ELF file " << oat_file->GetPath(); 1654 return false; 1655 } 1656 elf_writer->EndText(text); 1657 1658 if (!oat_writer->WriteHeader(elf_writer->GetStream(), 1659 image_file_location_oat_checksum_, 1660 image_file_location_oat_data_begin_, 1661 image_patch_delta_)) { 1662 LOG(ERROR) << "Failed to write oat header to the ELF file " << oat_file->GetPath(); 1663 return false; 1664 } 1665 1666 elf_writer->SetBssSize(oat_writer->GetBssSize()); 1667 elf_writer->WriteDynamicSection(); 1668 elf_writer->WriteDebugInfo(oat_writer->GetMethodDebugInfo()); 1669 elf_writer->WritePatchLocations(oat_writer->GetAbsolutePatchLocations()); 1670 1671 if (!elf_writer->End()) { 1672 LOG(ERROR) << "Failed to write ELF file " << oat_file->GetPath(); 1673 return false; 1674 } 1675 1676 // Flush the oat file. 1677 if (oat_files_[i] != nullptr) { 1678 if (oat_files_[i]->Flush() != 0) { 1679 PLOG(ERROR) << "Failed to flush oat file: " << oat_filenames_[i]; 1680 oat_files_[i]->Erase(); 1681 return false; 1682 } 1683 } 1684 1685 if (IsImage()) { 1686 // Update oat estimates. 1687 UpdateImageWriter(i); 1688 } 1689 1690 VLOG(compiler) << "Oat file written successfully: " << oat_filenames_[i]; 1691 1692 oat_writer.reset(); 1693 elf_writer.reset(); 1694 } 1695 } 1696 1697 return true; 1698 } 1699 1700 // If we are compiling an image, invoke the image creation routine. Else just skip. 1701 bool HandleImage() { 1702 if (IsImage()) { 1703 TimingLogger::ScopedTiming t("dex2oat ImageWriter", timings_); 1704 if (!CreateImageFile()) { 1705 return false; 1706 } 1707 VLOG(compiler) << "Images written successfully"; 1708 } 1709 return true; 1710 } 1711 1712 // Create a copy from stripped to unstripped. 1713 bool CopyStrippedToUnstripped() { 1714 for (size_t i = 0; i < oat_unstripped_.size(); ++i) { 1715 // If we don't want to strip in place, copy from stripped location to unstripped location. 1716 // We need to strip after image creation because FixupElf needs to use .strtab. 1717 if (strcmp(oat_unstripped_[i], oat_filenames_[i]) != 0) { 1718 // If the oat file is still open, flush it. 1719 if (oat_files_[i].get() != nullptr && oat_files_[i]->IsOpened()) { 1720 if (!FlushCloseOatFile(i)) { 1721 return false; 1722 } 1723 } 1724 1725 TimingLogger::ScopedTiming t("dex2oat OatFile copy", timings_); 1726 std::unique_ptr<File> in(OS::OpenFileForReading(oat_filenames_[i])); 1727 std::unique_ptr<File> out(OS::CreateEmptyFile(oat_unstripped_[i])); 1728 size_t buffer_size = 8192; 1729 std::unique_ptr<uint8_t[]> buffer(new uint8_t[buffer_size]); 1730 while (true) { 1731 int bytes_read = TEMP_FAILURE_RETRY(read(in->Fd(), buffer.get(), buffer_size)); 1732 if (bytes_read <= 0) { 1733 break; 1734 } 1735 bool write_ok = out->WriteFully(buffer.get(), bytes_read); 1736 CHECK(write_ok); 1737 } 1738 if (out->FlushCloseOrErase() != 0) { 1739 PLOG(ERROR) << "Failed to flush and close copied oat file: " << oat_unstripped_[i]; 1740 return false; 1741 } 1742 VLOG(compiler) << "Oat file copied successfully (unstripped): " << oat_unstripped_[i]; 1743 } 1744 } 1745 return true; 1746 } 1747 1748 bool FlushOatFiles() { 1749 TimingLogger::ScopedTiming t2("dex2oat Flush ELF", timings_); 1750 for (size_t i = 0; i < oat_files_.size(); ++i) { 1751 if (oat_files_[i].get() != nullptr) { 1752 if (oat_files_[i]->Flush() != 0) { 1753 PLOG(ERROR) << "Failed to flush oat file: " << oat_filenames_[i]; 1754 oat_files_[i]->Erase(); 1755 return false; 1756 } 1757 } 1758 } 1759 return true; 1760 } 1761 1762 bool FlushCloseOatFile(size_t i) { 1763 if (oat_files_[i].get() != nullptr) { 1764 std::unique_ptr<File> tmp(oat_files_[i].release()); 1765 if (tmp->FlushCloseOrErase() != 0) { 1766 PLOG(ERROR) << "Failed to flush and close oat file: " << oat_filenames_[i]; 1767 return false; 1768 } 1769 } 1770 return true; 1771 } 1772 1773 bool FlushCloseOatFiles() { 1774 bool result = true; 1775 for (size_t i = 0; i < oat_files_.size(); ++i) { 1776 result &= FlushCloseOatFile(i); 1777 } 1778 return result; 1779 } 1780 1781 void DumpTiming() { 1782 if (dump_timing_ || (dump_slow_timing_ && timings_->GetTotalNs() > MsToNs(1000))) { 1783 LOG(INFO) << Dumpable<TimingLogger>(*timings_); 1784 } 1785 if (dump_passes_) { 1786 LOG(INFO) << Dumpable<CumulativeLogger>(*driver_->GetTimingsLogger()); 1787 } 1788 } 1789 1790 CompilerOptions* GetCompilerOptions() const { 1791 return compiler_options_.get(); 1792 } 1793 1794 bool IsImage() const { 1795 return IsAppImage() || IsBootImage(); 1796 } 1797 1798 bool IsAppImage() const { 1799 return app_image_; 1800 } 1801 1802 bool IsBootImage() const { 1803 return boot_image_; 1804 } 1805 1806 bool IsHost() const { 1807 return is_host_; 1808 } 1809 1810 bool UseProfileGuidedCompilation() const { 1811 return !profile_files_.empty() || !profile_files_fd_.empty(); 1812 } 1813 1814 bool ProcessProfiles() { 1815 DCHECK(UseProfileGuidedCompilation()); 1816 ProfileCompilationInfo* info = nullptr; 1817 bool result = false; 1818 if (profile_files_.empty()) { 1819 DCHECK(!profile_files_fd_.empty()); 1820 result = ProfileAssistant::ProcessProfiles( 1821 profile_files_fd_, reference_profile_files_fd_, &info); 1822 CloseAllFds(profile_files_fd_, "profile_files_fd_"); 1823 CloseAllFds(reference_profile_files_fd_, "reference_profile_files_fd_"); 1824 } else { 1825 result = ProfileAssistant::ProcessProfiles( 1826 profile_files_, reference_profile_files_, &info); 1827 } 1828 1829 profile_compilation_info_.reset(info); 1830 1831 return result; 1832 } 1833 1834 bool ShouldCompileBasedOnProfiles() const { 1835 DCHECK(UseProfileGuidedCompilation()); 1836 // If we are given profiles, compile only if we have new information. 1837 return profile_compilation_info_ != nullptr; 1838 } 1839 1840 private: 1841 template <typename T> 1842 static std::vector<T*> MakeNonOwningPointerVector(const std::vector<std::unique_ptr<T>>& src) { 1843 std::vector<T*> result; 1844 result.reserve(src.size()); 1845 for (const std::unique_ptr<T>& t : src) { 1846 result.push_back(t.get()); 1847 } 1848 return result; 1849 } 1850 1851 std::string GetMultiImageBootClassPath() { 1852 DCHECK(IsBootImage()); 1853 DCHECK_GT(oat_filenames_.size(), 1u); 1854 // If the image filename was adapted (e.g., for our tests), we need to change this here, 1855 // too, but need to strip all path components (they will be re-established when loading). 1856 std::ostringstream bootcp_oss; 1857 bool first_bootcp = true; 1858 for (size_t i = 0; i < dex_locations_.size(); ++i) { 1859 if (!first_bootcp) { 1860 bootcp_oss << ":"; 1861 } 1862 1863 std::string dex_loc = dex_locations_[i]; 1864 std::string image_filename = image_filenames_[i]; 1865 1866 // Use the dex_loc path, but the image_filename name (without path elements). 1867 size_t dex_last_slash = dex_loc.rfind('/'); 1868 1869 // npos is max(size_t). That makes this a bit ugly. 1870 size_t image_last_slash = image_filename.rfind('/'); 1871 size_t image_last_at = image_filename.rfind('@'); 1872 size_t image_last_sep = (image_last_slash == std::string::npos) 1873 ? image_last_at 1874 : (image_last_at == std::string::npos) 1875 ? std::string::npos 1876 : std::max(image_last_slash, image_last_at); 1877 // Note: whenever image_last_sep == npos, +1 overflow means using the full string. 1878 1879 if (dex_last_slash == std::string::npos) { 1880 dex_loc = image_filename.substr(image_last_sep + 1); 1881 } else { 1882 dex_loc = dex_loc.substr(0, dex_last_slash + 1) + 1883 image_filename.substr(image_last_sep + 1); 1884 } 1885 1886 // Image filenames already end with .art, no need to replace. 1887 1888 bootcp_oss << dex_loc; 1889 first_bootcp = false; 1890 } 1891 return bootcp_oss.str(); 1892 } 1893 1894 std::vector<std::string> GetClassPathLocations(const std::string& class_path) { 1895 // This function is used only for apps and for an app we have exactly one oat file. 1896 DCHECK(!IsBootImage()); 1897 DCHECK_EQ(oat_writers_.size(), 1u); 1898 std::vector<std::string> dex_files_canonical_locations; 1899 for (const char* location : oat_writers_[0]->GetSourceLocations()) { 1900 dex_files_canonical_locations.push_back(DexFile::GetDexCanonicalLocation(location)); 1901 } 1902 1903 std::vector<std::string> parsed; 1904 Split(class_path, ':', &parsed); 1905 auto kept_it = std::remove_if(parsed.begin(), 1906 parsed.end(), 1907 [dex_files_canonical_locations](const std::string& location) { 1908 return ContainsElement(dex_files_canonical_locations, 1909 DexFile::GetDexCanonicalLocation(location.c_str())); 1910 }); 1911 parsed.erase(kept_it, parsed.end()); 1912 return parsed; 1913 } 1914 1915 // Opens requested class path files and appends them to opened_dex_files. 1916 static void OpenClassPathFiles(const std::vector<std::string>& class_path_locations, 1917 std::vector<std::unique_ptr<const DexFile>>* opened_dex_files) { 1918 DCHECK(opened_dex_files != nullptr) << "OpenClassPathFiles out-param is nullptr"; 1919 for (const std::string& location : class_path_locations) { 1920 std::string error_msg; 1921 if (!DexFile::Open(location.c_str(), location.c_str(), &error_msg, opened_dex_files)) { 1922 LOG(WARNING) << "Failed to open dex file '" << location << "': " << error_msg; 1923 } 1924 } 1925 } 1926 1927 bool PrepareImageClasses() { 1928 // If --image-classes was specified, calculate the full list of classes to include in the image. 1929 if (image_classes_filename_ != nullptr) { 1930 image_classes_ = 1931 ReadClasses(image_classes_zip_filename_, image_classes_filename_, "image"); 1932 if (image_classes_ == nullptr) { 1933 return false; 1934 } 1935 } else if (IsBootImage()) { 1936 image_classes_.reset(new std::unordered_set<std::string>); 1937 } 1938 return true; 1939 } 1940 1941 bool PrepareCompiledClasses() { 1942 // If --compiled-classes was specified, calculate the full list of classes to compile in the 1943 // image. 1944 if (compiled_classes_filename_ != nullptr) { 1945 compiled_classes_ = 1946 ReadClasses(compiled_classes_zip_filename_, compiled_classes_filename_, "compiled"); 1947 if (compiled_classes_ == nullptr) { 1948 return false; 1949 } 1950 } else { 1951 compiled_classes_.reset(nullptr); // By default compile everything. 1952 } 1953 return true; 1954 } 1955 1956 static std::unique_ptr<std::unordered_set<std::string>> ReadClasses(const char* zip_filename, 1957 const char* classes_filename, 1958 const char* tag) { 1959 std::unique_ptr<std::unordered_set<std::string>> classes; 1960 std::string error_msg; 1961 if (zip_filename != nullptr) { 1962 classes.reset(ReadImageClassesFromZip(zip_filename, classes_filename, &error_msg)); 1963 } else { 1964 classes.reset(ReadImageClassesFromFile(classes_filename)); 1965 } 1966 if (classes == nullptr) { 1967 LOG(ERROR) << "Failed to create list of " << tag << " classes from '" 1968 << classes_filename << "': " << error_msg; 1969 } 1970 return classes; 1971 } 1972 1973 bool PrepareCompiledMethods() { 1974 // If --compiled-methods was specified, read the methods to compile from the given file(s). 1975 if (compiled_methods_filename_ != nullptr) { 1976 std::string error_msg; 1977 if (compiled_methods_zip_filename_ != nullptr) { 1978 compiled_methods_.reset(ReadCommentedInputFromZip(compiled_methods_zip_filename_, 1979 compiled_methods_filename_, 1980 nullptr, // No post-processing. 1981 &error_msg)); 1982 } else { 1983 compiled_methods_.reset(ReadCommentedInputFromFile(compiled_methods_filename_, 1984 nullptr)); // No post-processing. 1985 } 1986 if (compiled_methods_.get() == nullptr) { 1987 LOG(ERROR) << "Failed to create list of compiled methods from '" 1988 << compiled_methods_filename_ << "': " << error_msg; 1989 return false; 1990 } 1991 } else { 1992 compiled_methods_.reset(nullptr); // By default compile everything. 1993 } 1994 return true; 1995 } 1996 1997 void PruneNonExistentDexFiles() { 1998 DCHECK_EQ(dex_filenames_.size(), dex_locations_.size()); 1999 size_t kept = 0u; 2000 for (size_t i = 0, size = dex_filenames_.size(); i != size; ++i) { 2001 if (!OS::FileExists(dex_filenames_[i])) { 2002 LOG(WARNING) << "Skipping non-existent dex file '" << dex_filenames_[i] << "'"; 2003 } else { 2004 dex_filenames_[kept] = dex_filenames_[i]; 2005 dex_locations_[kept] = dex_locations_[i]; 2006 ++kept; 2007 } 2008 } 2009 dex_filenames_.resize(kept); 2010 dex_locations_.resize(kept); 2011 } 2012 2013 bool AddDexFileSources() { 2014 TimingLogger::ScopedTiming t2("AddDexFileSources", timings_); 2015 if (zip_fd_ != -1) { 2016 DCHECK_EQ(oat_writers_.size(), 1u); 2017 if (!oat_writers_[0]->AddZippedDexFilesSource(ScopedFd(zip_fd_), zip_location_.c_str())) { 2018 return false; 2019 } 2020 } else if (oat_writers_.size() > 1u) { 2021 // Multi-image. 2022 DCHECK_EQ(oat_writers_.size(), dex_filenames_.size()); 2023 DCHECK_EQ(oat_writers_.size(), dex_locations_.size()); 2024 for (size_t i = 0, size = oat_writers_.size(); i != size; ++i) { 2025 if (!oat_writers_[i]->AddDexFileSource(dex_filenames_[i], dex_locations_[i])) { 2026 return false; 2027 } 2028 } 2029 } else { 2030 DCHECK_EQ(oat_writers_.size(), 1u); 2031 DCHECK_EQ(dex_filenames_.size(), dex_locations_.size()); 2032 DCHECK_NE(dex_filenames_.size(), 0u); 2033 for (size_t i = 0; i != dex_filenames_.size(); ++i) { 2034 if (!oat_writers_[0]->AddDexFileSource(dex_filenames_[i], dex_locations_[i])) { 2035 return false; 2036 } 2037 } 2038 } 2039 return true; 2040 } 2041 2042 void CreateOatWriters() { 2043 TimingLogger::ScopedTiming t2("CreateOatWriters", timings_); 2044 elf_writers_.reserve(oat_files_.size()); 2045 oat_writers_.reserve(oat_files_.size()); 2046 for (const std::unique_ptr<File>& oat_file : oat_files_) { 2047 elf_writers_.emplace_back( 2048 CreateElfWriterQuick(instruction_set_, compiler_options_.get(), oat_file.get())); 2049 elf_writers_.back()->Start(); 2050 oat_writers_.emplace_back(new OatWriter(IsBootImage(), timings_)); 2051 } 2052 } 2053 2054 void SaveDexInput() { 2055 for (size_t i = 0; i < dex_files_.size(); ++i) { 2056 const DexFile* dex_file = dex_files_[i]; 2057 std::string tmp_file_name(StringPrintf("/data/local/tmp/dex2oat.%d.%zd.dex", 2058 getpid(), i)); 2059 std::unique_ptr<File> tmp_file(OS::CreateEmptyFile(tmp_file_name.c_str())); 2060 if (tmp_file.get() == nullptr) { 2061 PLOG(ERROR) << "Failed to open file " << tmp_file_name 2062 << ". Try: adb shell chmod 777 /data/local/tmp"; 2063 continue; 2064 } 2065 // This is just dumping files for debugging. Ignore errors, and leave remnants. 2066 UNUSED(tmp_file->WriteFully(dex_file->Begin(), dex_file->Size())); 2067 UNUSED(tmp_file->Flush()); 2068 UNUSED(tmp_file->Close()); 2069 LOG(INFO) << "Wrote input to " << tmp_file_name; 2070 } 2071 } 2072 2073 bool PrepareRuntimeOptions(RuntimeArgumentMap* runtime_options) { 2074 RuntimeOptions raw_options; 2075 if (boot_image_filename_.empty()) { 2076 std::string boot_class_path = "-Xbootclasspath:"; 2077 boot_class_path += Join(dex_filenames_, ':'); 2078 raw_options.push_back(std::make_pair(boot_class_path, nullptr)); 2079 std::string boot_class_path_locations = "-Xbootclasspath-locations:"; 2080 boot_class_path_locations += Join(dex_locations_, ':'); 2081 raw_options.push_back(std::make_pair(boot_class_path_locations, nullptr)); 2082 } else { 2083 std::string boot_image_option = "-Ximage:"; 2084 boot_image_option += boot_image_filename_; 2085 raw_options.push_back(std::make_pair(boot_image_option, nullptr)); 2086 } 2087 for (size_t i = 0; i < runtime_args_.size(); i++) { 2088 raw_options.push_back(std::make_pair(runtime_args_[i], nullptr)); 2089 } 2090 2091 raw_options.push_back(std::make_pair("compilercallbacks", callbacks_.get())); 2092 raw_options.push_back( 2093 std::make_pair("imageinstructionset", GetInstructionSetString(instruction_set_))); 2094 2095 // Only allow no boot image for the runtime if we're compiling one. When we compile an app, 2096 // we don't want fallback mode, it will abort as we do not push a boot classpath (it might 2097 // have been stripped in preopting, anyways). 2098 if (!IsBootImage()) { 2099 raw_options.push_back(std::make_pair("-Xno-dex-file-fallback", nullptr)); 2100 } 2101 // Disable libsigchain. We don't don't need it during compilation and it prevents us 2102 // from getting a statically linked version of dex2oat (because of dlsym and RTLD_NEXT). 2103 raw_options.push_back(std::make_pair("-Xno-sig-chain", nullptr)); 2104 // Disable Hspace compaction to save heap size virtual space. 2105 // Only need disable Hspace for OOM becasue background collector is equal to 2106 // foreground collector by default for dex2oat. 2107 raw_options.push_back(std::make_pair("-XX:DisableHSpaceCompactForOOM", nullptr)); 2108 2109 if (!Runtime::ParseOptions(raw_options, false, runtime_options)) { 2110 LOG(ERROR) << "Failed to parse runtime options"; 2111 return false; 2112 } 2113 return true; 2114 } 2115 2116 // Create a runtime necessary for compilation. 2117 bool CreateRuntime(RuntimeArgumentMap&& runtime_options) { 2118 TimingLogger::ScopedTiming t_runtime("Create runtime", timings_); 2119 if (!Runtime::Create(std::move(runtime_options))) { 2120 LOG(ERROR) << "Failed to create runtime"; 2121 return false; 2122 } 2123 runtime_.reset(Runtime::Current()); 2124 runtime_->SetInstructionSet(instruction_set_); 2125 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { 2126 Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i); 2127 if (!runtime_->HasCalleeSaveMethod(type)) { 2128 runtime_->SetCalleeSaveMethod(runtime_->CreateCalleeSaveMethod(), type); 2129 } 2130 } 2131 runtime_->GetClassLinker()->FixupDexCaches(runtime_->GetResolutionMethod()); 2132 2133 // Initialize maps for unstarted runtime. This needs to be here, as running clinits needs this 2134 // set up. 2135 interpreter::UnstartedRuntime::Initialize(); 2136 2137 runtime_->GetClassLinker()->RunRootClinits(); 2138 2139 // Runtime::Create acquired the mutator_lock_ that is normally given away when we 2140 // Runtime::Start, give it away now so that we don't starve GC. 2141 Thread* self = Thread::Current(); 2142 self->TransitionFromRunnableToSuspended(kNative); 2143 2144 return true; 2145 } 2146 2147 // Let the ImageWriter write the image files. If we do not compile PIC, also fix up the oat files. 2148 bool CreateImageFile() 2149 REQUIRES(!Locks::mutator_lock_) { 2150 CHECK(image_writer_ != nullptr); 2151 if (!IsBootImage()) { 2152 CHECK(image_filenames_.empty()); 2153 image_filenames_.push_back(app_image_file_name_.c_str()); 2154 } 2155 if (!image_writer_->Write(app_image_fd_, 2156 image_filenames_, 2157 oat_fd_, 2158 oat_filenames_, 2159 oat_location_)) { 2160 LOG(ERROR) << "Failure during image file creation"; 2161 return false; 2162 } 2163 2164 // We need the OatDataBegin entries. 2165 std::map<const char*, uintptr_t> oat_data_begins; 2166 for (const char* oat_filename : oat_filenames_) { 2167 oat_data_begins.emplace(oat_filename, image_writer_->GetOatDataBegin(oat_filename)); 2168 } 2169 // Destroy ImageWriter before doing FixupElf. 2170 image_writer_.reset(); 2171 2172 for (const char* oat_filename : oat_filenames_) { 2173 // Do not fix up the ELF file if we are --compile-pic or compiling the app image 2174 if (!compiler_options_->GetCompilePic() && IsBootImage()) { 2175 std::unique_ptr<File> oat_file(OS::OpenFileReadWrite(oat_filename)); 2176 if (oat_file.get() == nullptr) { 2177 PLOG(ERROR) << "Failed to open ELF file: " << oat_filename; 2178 return false; 2179 } 2180 2181 uintptr_t oat_data_begin = oat_data_begins.find(oat_filename)->second; 2182 2183 if (!ElfWriter::Fixup(oat_file.get(), oat_data_begin)) { 2184 oat_file->Erase(); 2185 LOG(ERROR) << "Failed to fixup ELF file " << oat_file->GetPath(); 2186 return false; 2187 } 2188 2189 if (oat_file->FlushCloseOrErase()) { 2190 PLOG(ERROR) << "Failed to flush and close fixed ELF file " << oat_file->GetPath(); 2191 return false; 2192 } 2193 } 2194 } 2195 2196 return true; 2197 } 2198 2199 // Reads the class names (java.lang.Object) and returns a set of descriptors (Ljava/lang/Object;) 2200 static std::unordered_set<std::string>* ReadImageClassesFromFile( 2201 const char* image_classes_filename) { 2202 std::function<std::string(const char*)> process = DotToDescriptor; 2203 return ReadCommentedInputFromFile(image_classes_filename, &process); 2204 } 2205 2206 // Reads the class names (java.lang.Object) and returns a set of descriptors (Ljava/lang/Object;) 2207 static std::unordered_set<std::string>* ReadImageClassesFromZip( 2208 const char* zip_filename, 2209 const char* image_classes_filename, 2210 std::string* error_msg) { 2211 std::function<std::string(const char*)> process = DotToDescriptor; 2212 return ReadCommentedInputFromZip(zip_filename, image_classes_filename, &process, error_msg); 2213 } 2214 2215 // Read lines from the given file, dropping comments and empty lines. Post-process each line with 2216 // the given function. 2217 static std::unordered_set<std::string>* ReadCommentedInputFromFile( 2218 const char* input_filename, std::function<std::string(const char*)>* process) { 2219 std::unique_ptr<std::ifstream> input_file(new std::ifstream(input_filename, std::ifstream::in)); 2220 if (input_file.get() == nullptr) { 2221 LOG(ERROR) << "Failed to open input file " << input_filename; 2222 return nullptr; 2223 } 2224 std::unique_ptr<std::unordered_set<std::string>> result( 2225 ReadCommentedInputStream(*input_file, process)); 2226 input_file->close(); 2227 return result.release(); 2228 } 2229 2230 // Read lines from the given file from the given zip file, dropping comments and empty lines. 2231 // Post-process each line with the given function. 2232 static std::unordered_set<std::string>* ReadCommentedInputFromZip( 2233 const char* zip_filename, 2234 const char* input_filename, 2235 std::function<std::string(const char*)>* process, 2236 std::string* error_msg) { 2237 std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(zip_filename, error_msg)); 2238 if (zip_archive.get() == nullptr) { 2239 return nullptr; 2240 } 2241 std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(input_filename, error_msg)); 2242 if (zip_entry.get() == nullptr) { 2243 *error_msg = StringPrintf("Failed to find '%s' within '%s': %s", input_filename, 2244 zip_filename, error_msg->c_str()); 2245 return nullptr; 2246 } 2247 std::unique_ptr<MemMap> input_file(zip_entry->ExtractToMemMap(zip_filename, 2248 input_filename, 2249 error_msg)); 2250 if (input_file.get() == nullptr) { 2251 *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", input_filename, 2252 zip_filename, error_msg->c_str()); 2253 return nullptr; 2254 } 2255 const std::string input_string(reinterpret_cast<char*>(input_file->Begin()), 2256 input_file->Size()); 2257 std::istringstream input_stream(input_string); 2258 return ReadCommentedInputStream(input_stream, process); 2259 } 2260 2261 // Read lines from the given stream, dropping comments and empty lines. Post-process each line 2262 // with the given function. 2263 static std::unordered_set<std::string>* ReadCommentedInputStream( 2264 std::istream& in_stream, 2265 std::function<std::string(const char*)>* process) { 2266 std::unique_ptr<std::unordered_set<std::string>> image_classes( 2267 new std::unordered_set<std::string>); 2268 while (in_stream.good()) { 2269 std::string dot; 2270 std::getline(in_stream, dot); 2271 if (StartsWith(dot, "#") || dot.empty()) { 2272 continue; 2273 } 2274 if (process != nullptr) { 2275 std::string descriptor((*process)(dot.c_str())); 2276 image_classes->insert(descriptor); 2277 } else { 2278 image_classes->insert(dot); 2279 } 2280 } 2281 return image_classes.release(); 2282 } 2283 2284 void LogCompletionTime() { 2285 // Note: when creation of a runtime fails, e.g., when trying to compile an app but when there 2286 // is no image, there won't be a Runtime::Current(). 2287 // Note: driver creation can fail when loading an invalid dex file. 2288 LOG(INFO) << "dex2oat took " << PrettyDuration(NanoTime() - start_ns_) 2289 << " (threads: " << thread_count_ << ") " 2290 << ((Runtime::Current() != nullptr && driver_ != nullptr) ? 2291 driver_->GetMemoryUsageString(kIsDebugBuild || VLOG_IS_ON(compiler)) : 2292 ""); 2293 } 2294 2295 std::string StripIsaFrom(const char* image_filename, InstructionSet isa) { 2296 std::string res(image_filename); 2297 size_t last_slash = res.rfind('/'); 2298 if (last_slash == std::string::npos || last_slash == 0) { 2299 return res; 2300 } 2301 size_t penultimate_slash = res.rfind('/', last_slash - 1); 2302 if (penultimate_slash == std::string::npos) { 2303 return res; 2304 } 2305 // Check that the string in-between is the expected one. 2306 if (res.substr(penultimate_slash + 1, last_slash - penultimate_slash - 1) != 2307 GetInstructionSetString(isa)) { 2308 LOG(WARNING) << "Unexpected string when trying to strip isa: " << res; 2309 return res; 2310 } 2311 return res.substr(0, penultimate_slash) + res.substr(last_slash); 2312 } 2313 2314 // Update the estimate for the oat file with the given index. 2315 void UpdateImageWriter(size_t index) { 2316 DCHECK(image_writer_ != nullptr); 2317 DCHECK_LT(index, oat_filenames_.size()); 2318 2319 image_writer_->UpdateOatFile(oat_filenames_[index]); 2320 } 2321 2322 std::unique_ptr<CompilerOptions> compiler_options_; 2323 Compiler::Kind compiler_kind_; 2324 2325 InstructionSet instruction_set_; 2326 std::unique_ptr<const InstructionSetFeatures> instruction_set_features_; 2327 2328 uint32_t image_file_location_oat_checksum_; 2329 uintptr_t image_file_location_oat_data_begin_; 2330 int32_t image_patch_delta_; 2331 std::unique_ptr<SafeMap<std::string, std::string> > key_value_store_; 2332 2333 std::unique_ptr<VerificationResults> verification_results_; 2334 2335 DexFileToMethodInlinerMap method_inliner_map_; 2336 std::unique_ptr<QuickCompilerCallbacks> callbacks_; 2337 2338 std::unique_ptr<Runtime> runtime_; 2339 2340 // Ownership for the class path files. 2341 std::vector<std::unique_ptr<const DexFile>> class_path_files_; 2342 2343 size_t thread_count_; 2344 uint64_t start_ns_; 2345 std::unique_ptr<WatchDog> watchdog_; 2346 std::vector<std::unique_ptr<File>> oat_files_; 2347 std::string oat_location_; 2348 std::vector<const char*> oat_filenames_; 2349 std::vector<const char*> oat_unstripped_; 2350 int oat_fd_; 2351 std::vector<const char*> dex_filenames_; 2352 std::vector<const char*> dex_locations_; 2353 int zip_fd_; 2354 std::string zip_location_; 2355 std::string boot_image_filename_; 2356 std::vector<const char*> runtime_args_; 2357 std::vector<const char*> image_filenames_; 2358 uintptr_t image_base_; 2359 const char* image_classes_zip_filename_; 2360 const char* image_classes_filename_; 2361 ImageHeader::StorageMode image_storage_mode_; 2362 const char* compiled_classes_zip_filename_; 2363 const char* compiled_classes_filename_; 2364 const char* compiled_methods_zip_filename_; 2365 const char* compiled_methods_filename_; 2366 std::unique_ptr<std::unordered_set<std::string>> image_classes_; 2367 std::unique_ptr<std::unordered_set<std::string>> compiled_classes_; 2368 std::unique_ptr<std::unordered_set<std::string>> compiled_methods_; 2369 bool app_image_; 2370 bool boot_image_; 2371 bool multi_image_; 2372 bool is_host_; 2373 std::string android_root_; 2374 std::vector<const DexFile*> dex_files_; 2375 std::string no_inline_from_string_; 2376 std::vector<jobject> dex_caches_; 2377 jobject class_loader_; 2378 2379 std::vector<std::unique_ptr<ElfWriter>> elf_writers_; 2380 std::vector<std::unique_ptr<OatWriter>> oat_writers_; 2381 std::vector<OutputStream*> rodata_; 2382 std::unique_ptr<ImageWriter> image_writer_; 2383 std::unique_ptr<CompilerDriver> driver_; 2384 2385 std::vector<std::unique_ptr<MemMap>> opened_dex_files_maps_; 2386 std::vector<std::unique_ptr<const DexFile>> opened_dex_files_; 2387 2388 std::vector<std::string> verbose_methods_; 2389 bool dump_stats_; 2390 bool dump_passes_; 2391 bool dump_timing_; 2392 bool dump_slow_timing_; 2393 std::string swap_file_name_; 2394 int swap_fd_; 2395 std::string app_image_file_name_; 2396 int app_image_fd_; 2397 std::vector<std::string> profile_files_; 2398 std::vector<std::string> reference_profile_files_; 2399 std::vector<uint32_t> profile_files_fd_; 2400 std::vector<uint32_t> reference_profile_files_fd_; 2401 std::unique_ptr<ProfileCompilationInfo> profile_compilation_info_; 2402 TimingLogger* timings_; 2403 std::unique_ptr<CumulativeLogger> compiler_phases_timings_; 2404 std::vector<std::vector<const DexFile*>> dex_files_per_oat_file_; 2405 std::unordered_map<const DexFile*, const char*> dex_file_oat_filename_map_; 2406 2407 // Backing storage. 2408 std::vector<std::string> char_backing_storage_; 2409 2410 DISALLOW_IMPLICIT_CONSTRUCTORS(Dex2Oat); 2411}; 2412 2413static void b13564922() { 2414#if defined(__linux__) && defined(__arm__) 2415 int major, minor; 2416 struct utsname uts; 2417 if (uname(&uts) != -1 && 2418 sscanf(uts.release, "%d.%d", &major, &minor) == 2 && 2419 ((major < 3) || ((major == 3) && (minor < 4)))) { 2420 // Kernels before 3.4 don't handle the ASLR well and we can run out of address 2421 // space (http://b/13564922). Work around the issue by inhibiting further mmap() randomization. 2422 int old_personality = personality(0xffffffff); 2423 if ((old_personality & ADDR_NO_RANDOMIZE) == 0) { 2424 int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE); 2425 if (new_personality == -1) { 2426 LOG(WARNING) << "personality(. | ADDR_NO_RANDOMIZE) failed."; 2427 } 2428 } 2429 } 2430#endif 2431} 2432 2433static int CompileImage(Dex2Oat& dex2oat) { 2434 dex2oat.Compile(); 2435 2436 if (!dex2oat.WriteOatFiles()) { 2437 dex2oat.EraseOatFiles(); 2438 return EXIT_FAILURE; 2439 } 2440 2441 // Flush boot.oat. We always expect the output file by name, and it will be re-opened from the 2442 // unstripped name. Do not close the file if we are compiling the image with an oat fd since the 2443 // image writer will require this fd to generate the image. 2444 if (dex2oat.ShouldKeepOatFileOpen()) { 2445 if (!dex2oat.FlushOatFiles()) { 2446 return EXIT_FAILURE; 2447 } 2448 } else if (!dex2oat.FlushCloseOatFiles()) { 2449 return EXIT_FAILURE; 2450 } 2451 2452 // Creates the boot.art and patches the oat files. 2453 if (!dex2oat.HandleImage()) { 2454 return EXIT_FAILURE; 2455 } 2456 2457 // When given --host, finish early without stripping. 2458 if (dex2oat.IsHost()) { 2459 dex2oat.DumpTiming(); 2460 return EXIT_SUCCESS; 2461 } 2462 2463 // Copy stripped to unstripped location, if necessary. 2464 if (!dex2oat.CopyStrippedToUnstripped()) { 2465 return EXIT_FAILURE; 2466 } 2467 2468 // FlushClose again, as stripping might have re-opened the oat files. 2469 if (!dex2oat.FlushCloseOatFiles()) { 2470 return EXIT_FAILURE; 2471 } 2472 2473 dex2oat.DumpTiming(); 2474 return EXIT_SUCCESS; 2475} 2476 2477static int CompileApp(Dex2Oat& dex2oat) { 2478 dex2oat.Compile(); 2479 2480 if (!dex2oat.WriteOatFiles()) { 2481 dex2oat.EraseOatFiles(); 2482 return EXIT_FAILURE; 2483 } 2484 2485 // Do not close the oat files here. We might have gotten the output file by file descriptor, 2486 // which we would lose. 2487 2488 // When given --host, finish early without stripping. 2489 if (dex2oat.IsHost()) { 2490 if (!dex2oat.FlushCloseOatFiles()) { 2491 return EXIT_FAILURE; 2492 } 2493 2494 dex2oat.DumpTiming(); 2495 return EXIT_SUCCESS; 2496 } 2497 2498 // Copy stripped to unstripped location, if necessary. This will implicitly flush & close the 2499 // stripped versions. If this is given, we expect to be able to open writable files by name. 2500 if (!dex2oat.CopyStrippedToUnstripped()) { 2501 return EXIT_FAILURE; 2502 } 2503 2504 // Flush and close the files. 2505 if (!dex2oat.FlushCloseOatFiles()) { 2506 return EXIT_FAILURE; 2507 } 2508 2509 dex2oat.DumpTiming(); 2510 return EXIT_SUCCESS; 2511} 2512 2513static int dex2oat(int argc, char** argv) { 2514 b13564922(); 2515 2516 TimingLogger timings("compiler", false, false); 2517 2518 Dex2Oat dex2oat(&timings); 2519 2520 // Parse arguments. Argument mistakes will lead to exit(EXIT_FAILURE) in UsageError. 2521 dex2oat.ParseArgs(argc, argv); 2522 2523 // Process profile information and assess if we need to do a profile guided compilation. 2524 // This operation involves I/O. 2525 if (dex2oat.UseProfileGuidedCompilation()) { 2526 if (dex2oat.ProcessProfiles()) { 2527 if (!dex2oat.ShouldCompileBasedOnProfiles()) { 2528 LOG(INFO) << "Skipped compilation because of insignificant profile delta"; 2529 return EXIT_SUCCESS; 2530 } 2531 } else { 2532 LOG(WARNING) << "Failed to process profile files"; 2533 return EXIT_FAILURE; 2534 } 2535 } 2536 2537 // Check early that the result of compilation can be written 2538 if (!dex2oat.OpenFile()) { 2539 return EXIT_FAILURE; 2540 } 2541 2542 // Print the complete line when any of the following is true: 2543 // 1) Debug build 2544 // 2) Compiling an image 2545 // 3) Compiling with --host 2546 // 4) Compiling on the host (not a target build) 2547 // Otherwise, print a stripped command line. 2548 if (kIsDebugBuild || dex2oat.IsBootImage() || dex2oat.IsHost() || !kIsTargetBuild) { 2549 LOG(INFO) << CommandLine(); 2550 } else { 2551 LOG(INFO) << StrippedCommandLine(); 2552 } 2553 2554 if (!dex2oat.Setup()) { 2555 dex2oat.EraseOatFiles(); 2556 return EXIT_FAILURE; 2557 } 2558 2559 bool result; 2560 if (dex2oat.IsImage()) { 2561 result = CompileImage(dex2oat); 2562 } else { 2563 result = CompileApp(dex2oat); 2564 } 2565 2566 dex2oat.Shutdown(); 2567 return result; 2568} 2569} // namespace art 2570 2571int main(int argc, char** argv) { 2572 int result = art::dex2oat(argc, argv); 2573 // Everything was done, do an explicit exit here to avoid running Runtime destructors that take 2574 // time (bug 10645725) unless we're a debug build or running on valgrind. Note: The Dex2Oat class 2575 // should not destruct the runtime in this case. 2576 if (!art::kIsDebugBuild && (RUNNING_ON_MEMORY_TOOL == 0)) { 2577 exit(result); 2578 } 2579 return result; 2580} 2581