dex2oat.cc revision 22d5e735f403c57525fe868304c7123f0ce66399
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 <stdio.h> 18#include <stdlib.h> 19#include <sys/stat.h> 20#include <valgrind.h> 21 22#include <fstream> 23#include <iostream> 24#include <sstream> 25#include <string> 26#include <vector> 27 28#if defined(__linux__) && defined(__arm__) 29#include <sys/personality.h> 30#include <sys/utsname.h> 31#endif 32 33#include "base/stl_util.h" 34#include "base/stringpiece.h" 35#include "base/timing_logger.h" 36#include "base/unix_file/fd_file.h" 37#include "class_linker.h" 38#include "compiler.h" 39#include "compiler_callbacks.h" 40#include "dex_file-inl.h" 41#include "dex/pass_driver_me_opts.h" 42#include "dex/verification_results.h" 43#include "dex/quick_compiler_callbacks.h" 44#include "dex/quick/dex_file_to_method_inliner_map.h" 45#include "driver/compiler_driver.h" 46#include "driver/compiler_options.h" 47#include "elf_fixup.h" 48#include "elf_stripper.h" 49#include "gc/space/image_space.h" 50#include "gc/space/space-inl.h" 51#include "image_writer.h" 52#include "implicit_check_options.h" 53#include "leb128.h" 54#include "mirror/art_method-inl.h" 55#include "mirror/class-inl.h" 56#include "mirror/class_loader.h" 57#include "mirror/object-inl.h" 58#include "mirror/object_array-inl.h" 59#include "oat_writer.h" 60#include "os.h" 61#include "runtime.h" 62#include "ScopedLocalRef.h" 63#include "scoped_thread_state_change.h" 64#include "utils.h" 65#include "vector_output_stream.h" 66#include "well_known_classes.h" 67#include "zip_archive.h" 68 69namespace art { 70 71static int original_argc; 72static char** original_argv; 73 74static std::string CommandLine() { 75 std::vector<std::string> command; 76 for (int i = 0; i < original_argc; ++i) { 77 command.push_back(original_argv[i]); 78 } 79 return Join(command, ' '); 80} 81 82static void UsageErrorV(const char* fmt, va_list ap) { 83 std::string error; 84 StringAppendV(&error, fmt, ap); 85 LOG(ERROR) << error; 86} 87 88static void UsageError(const char* fmt, ...) { 89 va_list ap; 90 va_start(ap, fmt); 91 UsageErrorV(fmt, ap); 92 va_end(ap); 93} 94 95static void Usage(const char* fmt, ...) { 96 va_list ap; 97 va_start(ap, fmt); 98 UsageErrorV(fmt, ap); 99 va_end(ap); 100 101 UsageError("Command: %s", CommandLine().c_str()); 102 103 UsageError("Usage: dex2oat [options]..."); 104 UsageError(""); 105 UsageError(" --dex-file=<dex-file>: specifies a .dex file to compile."); 106 UsageError(" Example: --dex-file=/system/framework/core.jar"); 107 UsageError(""); 108 UsageError(" --zip-fd=<file-descriptor>: specifies a file descriptor of a zip file"); 109 UsageError(" containing a classes.dex file to compile."); 110 UsageError(" Example: --zip-fd=5"); 111 UsageError(""); 112 UsageError(" --zip-location=<zip-location>: specifies a symbolic name for the file"); 113 UsageError(" corresponding to the file descriptor specified by --zip-fd."); 114 UsageError(" Example: --zip-location=/system/app/Calculator.apk"); 115 UsageError(""); 116 UsageError(" --oat-file=<file.oat>: specifies the oat output destination via a filename."); 117 UsageError(" Example: --oat-file=/system/framework/boot.oat"); 118 UsageError(""); 119 UsageError(" --oat-fd=<number>: specifies the oat output destination via a file descriptor."); 120 UsageError(" Example: --oat-fd=6"); 121 UsageError(""); 122 UsageError(" --oat-location=<oat-name>: specifies a symbolic name for the file corresponding"); 123 UsageError(" to the file descriptor specified by --oat-fd."); 124 UsageError(" Example: --oat-location=/data/dalvik-cache/system@app@Calculator.apk.oat"); 125 UsageError(""); 126 UsageError(" --oat-symbols=<file.oat>: specifies the oat output destination with full symbols."); 127 UsageError(" Example: --oat-symbols=/symbols/system/framework/boot.oat"); 128 UsageError(""); 129 UsageError(" --bitcode=<file.bc>: specifies the optional bitcode filename."); 130 UsageError(" Example: --bitcode=/system/framework/boot.bc"); 131 UsageError(""); 132 UsageError(" --image=<file.art>: specifies the output image filename."); 133 UsageError(" Example: --image=/system/framework/boot.art"); 134 UsageError(""); 135 UsageError(" --image-classes=<classname-file>: specifies classes to include in an image."); 136 UsageError(" Example: --image=frameworks/base/preloaded-classes"); 137 UsageError(""); 138 UsageError(" --base=<hex-address>: specifies the base address when creating a boot image."); 139 UsageError(" Example: --base=0x50000000"); 140 UsageError(""); 141 UsageError(" --boot-image=<file.art>: provide the image file for the boot class path."); 142 UsageError(" Example: --boot-image=/system/framework/boot.art"); 143 UsageError(" Default: $ANDROID_ROOT/system/framework/boot.art"); 144 UsageError(""); 145 UsageError(" --android-root=<path>: used to locate libraries for portable linking."); 146 UsageError(" Example: --android-root=out/host/linux-x86"); 147 UsageError(" Default: $ANDROID_ROOT"); 148 UsageError(""); 149 UsageError(" --instruction-set=(arm|arm64|mips|x86|x86_64): compile for a particular"); 150 UsageError(" instruction set."); 151 UsageError(" Example: --instruction-set=x86"); 152 UsageError(" Default: arm"); 153 UsageError(""); 154 UsageError(" --instruction-set-features=...,: Specify instruction set features"); 155 UsageError(" Example: --instruction-set-features=div"); 156 UsageError(" Default: default"); 157 UsageError(""); 158 UsageError(" --compiler-backend=(Quick|Optimizing|Portable): select compiler backend"); 159 UsageError(" set."); 160 UsageError(" Example: --compiler-backend=Portable"); 161 UsageError(" Default: Quick"); 162 UsageError(""); 163 UsageError(" --compiler-filter=(verify-none|interpret-only|space|balanced|speed|everything):"); 164 UsageError(" select compiler filter."); 165 UsageError(" Example: --compiler-filter=everything"); 166#if ART_SMALL_MODE 167 UsageError(" Default: interpret-only"); 168#else 169 UsageError(" Default: speed"); 170#endif 171 UsageError(""); 172 UsageError(" --huge-method-max=<method-instruction-count>: the threshold size for a huge"); 173 UsageError(" method for compiler filter tuning."); 174 UsageError(" Example: --huge-method-max=%d", CompilerOptions::kDefaultHugeMethodThreshold); 175 UsageError(" Default: %d", CompilerOptions::kDefaultHugeMethodThreshold); 176 UsageError(""); 177 UsageError(" --huge-method-max=<method-instruction-count>: threshold size for a huge"); 178 UsageError(" method for compiler filter tuning."); 179 UsageError(" Example: --huge-method-max=%d", CompilerOptions::kDefaultHugeMethodThreshold); 180 UsageError(" Default: %d", CompilerOptions::kDefaultHugeMethodThreshold); 181 UsageError(""); 182 UsageError(" --large-method-max=<method-instruction-count>: threshold size for a large"); 183 UsageError(" method for compiler filter tuning."); 184 UsageError(" Example: --large-method-max=%d", CompilerOptions::kDefaultLargeMethodThreshold); 185 UsageError(" Default: %d", CompilerOptions::kDefaultLargeMethodThreshold); 186 UsageError(""); 187 UsageError(" --small-method-max=<method-instruction-count>: threshold size for a small"); 188 UsageError(" method for compiler filter tuning."); 189 UsageError(" Example: --small-method-max=%d", CompilerOptions::kDefaultSmallMethodThreshold); 190 UsageError(" Default: %d", CompilerOptions::kDefaultSmallMethodThreshold); 191 UsageError(""); 192 UsageError(" --tiny-method-max=<method-instruction-count>: threshold size for a tiny"); 193 UsageError(" method for compiler filter tuning."); 194 UsageError(" Example: --tiny-method-max=%d", CompilerOptions::kDefaultTinyMethodThreshold); 195 UsageError(" Default: %d", CompilerOptions::kDefaultTinyMethodThreshold); 196 UsageError(""); 197 UsageError(" --num-dex-methods=<method-count>: threshold size for a small dex file for"); 198 UsageError(" compiler filter tuning. If the input has fewer than this many methods"); 199 UsageError(" and the filter is not interpret-only or verify-none, overrides the"); 200 UsageError(" filter to use speed"); 201 UsageError(" Example: --num-dex-method=%d", CompilerOptions::kDefaultNumDexMethodsThreshold); 202 UsageError(" Default: %d", CompilerOptions::kDefaultNumDexMethodsThreshold); 203 UsageError(""); 204 UsageError(" --host: used with Portable backend to link against host runtime libraries"); 205 UsageError(""); 206 UsageError(" --dump-timing: display a breakdown of where time was spent"); 207 UsageError(""); 208 UsageError(" --include-patch-information: Include patching information so the generated code"); 209 UsageError(" can have its base address moved without full recompilation."); 210 UsageError(""); 211 UsageError(" --no-include-patch-information: Do not include patching information."); 212 UsageError(""); 213 UsageError(" --include-debug-symbols: Include ELF symbols in this oat file"); 214 UsageError(""); 215 UsageError(" --no-include-debug-symbols: Do not include ELF symbols in this oat file"); 216 UsageError(""); 217 UsageError(" --runtime-arg <argument>: used to specify various arguments for the runtime,"); 218 UsageError(" such as initial heap size, maximum heap size, and verbose output."); 219 UsageError(" Use a separate --runtime-arg switch for each argument."); 220 UsageError(" Example: --runtime-arg -Xms256m"); 221 UsageError(""); 222 UsageError(" --profile-file=<filename>: specify profiler output file to use for compilation."); 223 UsageError(""); 224 UsageError(" --print-pass-names: print a list of pass names"); 225 UsageError(""); 226 UsageError(" --disable-passes=<pass-names>: disable one or more passes separated by comma."); 227 UsageError(" Example: --disable-passes=UseCount,BBOptimizations"); 228 UsageError(""); 229 std::cerr << "See log for usage error information\n"; 230 exit(EXIT_FAILURE); 231} 232 233class Dex2Oat { 234 public: 235 static bool Create(Dex2Oat** p_dex2oat, 236 const RuntimeOptions& runtime_options, 237 const CompilerOptions& compiler_options, 238 Compiler::Kind compiler_kind, 239 InstructionSet instruction_set, 240 InstructionSetFeatures instruction_set_features, 241 VerificationResults* verification_results, 242 DexFileToMethodInlinerMap* method_inliner_map, 243 size_t thread_count) 244 SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_) { 245 CHECK(verification_results != nullptr); 246 CHECK(method_inliner_map != nullptr); 247 std::unique_ptr<Dex2Oat> dex2oat(new Dex2Oat(&compiler_options, 248 compiler_kind, 249 instruction_set, 250 instruction_set_features, 251 verification_results, 252 method_inliner_map, 253 thread_count)); 254 if (!dex2oat->CreateRuntime(runtime_options, instruction_set)) { 255 *p_dex2oat = nullptr; 256 return false; 257 } 258 *p_dex2oat = dex2oat.release(); 259 return true; 260 } 261 262 ~Dex2Oat() { 263 delete runtime_; 264 LogCompletionTime(); 265 } 266 267 void LogCompletionTime() { 268 LOG(INFO) << "dex2oat took " << PrettyDuration(NanoTime() - start_ns_) 269 << " (threads: " << thread_count_ << ")"; 270 } 271 272 273 // Reads the class names (java.lang.Object) and returns a set of descriptors (Ljava/lang/Object;) 274 CompilerDriver::DescriptorSet* ReadImageClassesFromFile(const char* image_classes_filename) { 275 std::unique_ptr<std::ifstream> image_classes_file(new std::ifstream(image_classes_filename, 276 std::ifstream::in)); 277 if (image_classes_file.get() == nullptr) { 278 LOG(ERROR) << "Failed to open image classes file " << image_classes_filename; 279 return nullptr; 280 } 281 std::unique_ptr<CompilerDriver::DescriptorSet> result(ReadImageClasses(*image_classes_file)); 282 image_classes_file->close(); 283 return result.release(); 284 } 285 286 CompilerDriver::DescriptorSet* ReadImageClasses(std::istream& image_classes_stream) { 287 std::unique_ptr<CompilerDriver::DescriptorSet> image_classes(new CompilerDriver::DescriptorSet); 288 while (image_classes_stream.good()) { 289 std::string dot; 290 std::getline(image_classes_stream, dot); 291 if (StartsWith(dot, "#") || dot.empty()) { 292 continue; 293 } 294 std::string descriptor(DotToDescriptor(dot.c_str())); 295 image_classes->insert(descriptor); 296 } 297 return image_classes.release(); 298 } 299 300 // Reads the class names (java.lang.Object) and returns a set of descriptors (Ljava/lang/Object;) 301 CompilerDriver::DescriptorSet* ReadImageClassesFromZip(const char* zip_filename, 302 const char* image_classes_filename, 303 std::string* error_msg) { 304 std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(zip_filename, error_msg)); 305 if (zip_archive.get() == nullptr) { 306 return nullptr; 307 } 308 std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(image_classes_filename, error_msg)); 309 if (zip_entry.get() == nullptr) { 310 *error_msg = StringPrintf("Failed to find '%s' within '%s': %s", image_classes_filename, 311 zip_filename, error_msg->c_str()); 312 return nullptr; 313 } 314 std::unique_ptr<MemMap> image_classes_file(zip_entry->ExtractToMemMap(zip_filename, 315 image_classes_filename, 316 error_msg)); 317 if (image_classes_file.get() == nullptr) { 318 *error_msg = StringPrintf("Failed to extract '%s' from '%s': %s", image_classes_filename, 319 zip_filename, error_msg->c_str()); 320 return nullptr; 321 } 322 const std::string image_classes_string(reinterpret_cast<char*>(image_classes_file->Begin()), 323 image_classes_file->Size()); 324 std::istringstream image_classes_stream(image_classes_string); 325 return ReadImageClasses(image_classes_stream); 326 } 327 328 const CompilerDriver* CreateOatFile(const std::string& boot_image_option, 329 const std::string& android_root, 330 bool is_host, 331 const std::vector<const DexFile*>& dex_files, 332 File* oat_file, 333 const std::string& bitcode_filename, 334 bool image, 335 std::unique_ptr<CompilerDriver::DescriptorSet>& image_classes, 336 bool dump_stats, 337 bool dump_passes, 338 TimingLogger& timings, 339 CumulativeLogger& compiler_phases_timings, 340 std::string profile_file, 341 SafeMap<std::string, std::string>* key_value_store) { 342 CHECK(key_value_store != nullptr); 343 344 // Handle and ClassLoader creation needs to come after Runtime::Create 345 jobject class_loader = nullptr; 346 Thread* self = Thread::Current(); 347 if (!boot_image_option.empty()) { 348 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 349 std::vector<const DexFile*> class_path_files(dex_files); 350 OpenClassPathFiles(runtime_->GetClassPathString(), class_path_files); 351 ScopedObjectAccess soa(self); 352 for (size_t i = 0; i < class_path_files.size(); i++) { 353 class_linker->RegisterDexFile(*class_path_files[i]); 354 } 355 soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader); 356 ScopedLocalRef<jobject> class_loader_local(soa.Env(), 357 soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader)); 358 class_loader = soa.Env()->NewGlobalRef(class_loader_local.get()); 359 Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path_files); 360 } 361 362 std::unique_ptr<CompilerDriver> driver(new CompilerDriver(compiler_options_, 363 verification_results_, 364 method_inliner_map_, 365 compiler_kind_, 366 instruction_set_, 367 instruction_set_features_, 368 image, 369 image_classes.release(), 370 thread_count_, 371 dump_stats, 372 dump_passes, 373 &compiler_phases_timings, 374 profile_file)); 375 376 driver->GetCompiler()->SetBitcodeFileName(*driver.get(), bitcode_filename); 377 378 driver->CompileAll(class_loader, dex_files, &timings); 379 380 TimingLogger::ScopedTiming t2("dex2oat OatWriter", &timings); 381 std::string image_file_location; 382 uint32_t image_file_location_oat_checksum = 0; 383 uintptr_t image_file_location_oat_data_begin = 0; 384 if (!driver->IsImage()) { 385 TimingLogger::ScopedTiming t3("Loading image checksum", &timings); 386 gc::space::ImageSpace* image_space = Runtime::Current()->GetHeap()->GetImageSpace(); 387 image_file_location_oat_checksum = image_space->GetImageHeader().GetOatChecksum(); 388 image_file_location_oat_data_begin = 389 reinterpret_cast<uintptr_t>(image_space->GetImageHeader().GetOatDataBegin()); 390 image_file_location = image_space->GetImageFilename(); 391 } 392 393 if (!image_file_location.empty()) { 394 key_value_store->Put(OatHeader::kImageLocationKey, image_file_location); 395 } 396 397 OatWriter oat_writer(dex_files, image_file_location_oat_checksum, 398 image_file_location_oat_data_begin, 399 driver.get(), 400 &timings, 401 key_value_store); 402 403 t2.NewTiming("Writing ELF"); 404 if (!driver->WriteElf(android_root, is_host, dex_files, &oat_writer, oat_file)) { 405 LOG(ERROR) << "Failed to write ELF file " << oat_file->GetPath(); 406 return nullptr; 407 } 408 409 return driver.release(); 410 } 411 412 bool CreateImageFile(const std::string& image_filename, 413 uintptr_t image_base, 414 const std::string& oat_filename, 415 const std::string& oat_location, 416 const CompilerDriver& compiler) 417 LOCKS_EXCLUDED(Locks::mutator_lock_) { 418 uintptr_t oat_data_begin; 419 { 420 // ImageWriter is scoped so it can free memory before doing FixupElf 421 ImageWriter image_writer(compiler); 422 if (!image_writer.Write(image_filename, image_base, oat_filename, oat_location)) { 423 LOG(ERROR) << "Failed to create image file " << image_filename; 424 return false; 425 } 426 oat_data_begin = image_writer.GetOatDataBegin(); 427 } 428 429 std::unique_ptr<File> oat_file(OS::OpenFileReadWrite(oat_filename.c_str())); 430 if (oat_file.get() == nullptr) { 431 PLOG(ERROR) << "Failed to open ELF file: " << oat_filename; 432 return false; 433 } 434 if (!ElfFixup::Fixup(oat_file.get(), oat_data_begin)) { 435 LOG(ERROR) << "Failed to fixup ELF file " << oat_file->GetPath(); 436 return false; 437 } 438 return true; 439 } 440 441 private: 442 explicit Dex2Oat(const CompilerOptions* compiler_options, 443 Compiler::Kind compiler_kind, 444 InstructionSet instruction_set, 445 InstructionSetFeatures instruction_set_features, 446 VerificationResults* verification_results, 447 DexFileToMethodInlinerMap* method_inliner_map, 448 size_t thread_count) 449 : compiler_options_(compiler_options), 450 compiler_kind_(compiler_kind), 451 instruction_set_(instruction_set), 452 instruction_set_features_(instruction_set_features), 453 verification_results_(verification_results), 454 method_inliner_map_(method_inliner_map), 455 runtime_(nullptr), 456 thread_count_(thread_count), 457 start_ns_(NanoTime()) { 458 CHECK(compiler_options != nullptr); 459 CHECK(verification_results != nullptr); 460 CHECK(method_inliner_map != nullptr); 461 } 462 463 bool CreateRuntime(const RuntimeOptions& runtime_options, InstructionSet instruction_set) 464 SHARED_TRYLOCK_FUNCTION(true, Locks::mutator_lock_) { 465 if (!Runtime::Create(runtime_options, false)) { 466 LOG(ERROR) << "Failed to create runtime"; 467 return false; 468 } 469 Runtime* runtime = Runtime::Current(); 470 runtime->SetInstructionSet(instruction_set); 471 for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) { 472 Runtime::CalleeSaveType type = Runtime::CalleeSaveType(i); 473 if (!runtime->HasCalleeSaveMethod(type)) { 474 runtime->SetCalleeSaveMethod(runtime->CreateCalleeSaveMethod(type), type); 475 } 476 } 477 runtime->GetClassLinker()->FixupDexCaches(runtime->GetResolutionMethod()); 478 runtime->GetClassLinker()->RunRootClinits(); 479 runtime_ = runtime; 480 return true; 481 } 482 483 // Appends to dex_files any elements of class_path that it doesn't already 484 // contain. This will open those dex files as necessary. 485 static void OpenClassPathFiles(const std::string& class_path, 486 std::vector<const DexFile*>& dex_files) { 487 std::vector<std::string> parsed; 488 Split(class_path, ':', parsed); 489 // Take Locks::mutator_lock_ so that lock ordering on the ClassLinker::dex_lock_ is maintained. 490 ScopedObjectAccess soa(Thread::Current()); 491 for (size_t i = 0; i < parsed.size(); ++i) { 492 if (DexFilesContains(dex_files, parsed[i])) { 493 continue; 494 } 495 std::string error_msg; 496 if (!DexFile::Open(parsed[i].c_str(), parsed[i].c_str(), &error_msg, &dex_files)) { 497 LOG(WARNING) << "Failed to open dex file '" << parsed[i] << "': " << error_msg; 498 } 499 } 500 } 501 502 // Returns true if dex_files has a dex with the named location. 503 static bool DexFilesContains(const std::vector<const DexFile*>& dex_files, 504 const std::string& location) { 505 for (size_t i = 0; i < dex_files.size(); ++i) { 506 if (dex_files[i]->GetLocation() == location) { 507 return true; 508 } 509 } 510 return false; 511 } 512 513 const CompilerOptions* const compiler_options_; 514 const Compiler::Kind compiler_kind_; 515 516 const InstructionSet instruction_set_; 517 const InstructionSetFeatures instruction_set_features_; 518 519 VerificationResults* const verification_results_; 520 DexFileToMethodInlinerMap* const method_inliner_map_; 521 Runtime* runtime_; 522 size_t thread_count_; 523 uint64_t start_ns_; 524 525 DISALLOW_IMPLICIT_CONSTRUCTORS(Dex2Oat); 526}; 527 528static size_t OpenDexFiles(const std::vector<const char*>& dex_filenames, 529 const std::vector<const char*>& dex_locations, 530 std::vector<const DexFile*>& dex_files) { 531 size_t failure_count = 0; 532 for (size_t i = 0; i < dex_filenames.size(); i++) { 533 const char* dex_filename = dex_filenames[i]; 534 const char* dex_location = dex_locations[i]; 535 ATRACE_BEGIN(StringPrintf("Opening dex file '%s'", dex_filenames[i]).c_str()); 536 std::string error_msg; 537 if (!OS::FileExists(dex_filename)) { 538 LOG(WARNING) << "Skipping non-existent dex file '" << dex_filename << "'"; 539 continue; 540 } 541 if (!DexFile::Open(dex_filename, dex_location, &error_msg, &dex_files)) { 542 LOG(WARNING) << "Failed to open .dex from file '" << dex_filename << "': " << error_msg; 543 ++failure_count; 544 } 545 ATRACE_END(); 546 } 547 return failure_count; 548} 549 550// The primary goal of the watchdog is to prevent stuck build servers 551// during development when fatal aborts lead to a cascade of failures 552// that result in a deadlock. 553class WatchDog { 554// WatchDog defines its own CHECK_PTHREAD_CALL to avoid using Log which uses locks 555#undef CHECK_PTHREAD_CALL 556#define CHECK_WATCH_DOG_PTHREAD_CALL(call, args, what) \ 557 do { \ 558 int rc = call args; \ 559 if (rc != 0) { \ 560 errno = rc; \ 561 std::string message(# call); \ 562 message += " failed for "; \ 563 message += reason; \ 564 Fatal(message); \ 565 } \ 566 } while (false) 567 568 public: 569 explicit WatchDog(bool is_watch_dog_enabled) { 570 is_watch_dog_enabled_ = is_watch_dog_enabled; 571 if (!is_watch_dog_enabled_) { 572 return; 573 } 574 shutting_down_ = false; 575 const char* reason = "dex2oat watch dog thread startup"; 576 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_init, (&mutex_, nullptr), reason); 577 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_init, (&cond_, nullptr), reason); 578 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_init, (&attr_), reason); 579 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_create, (&pthread_, &attr_, &CallBack, this), reason); 580 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_attr_destroy, (&attr_), reason); 581 } 582 ~WatchDog() { 583 if (!is_watch_dog_enabled_) { 584 return; 585 } 586 const char* reason = "dex2oat watch dog thread shutdown"; 587 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason); 588 shutting_down_ = true; 589 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_signal, (&cond_), reason); 590 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason); 591 592 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_join, (pthread_, nullptr), reason); 593 594 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_cond_destroy, (&cond_), reason); 595 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_destroy, (&mutex_), reason); 596 } 597 598 private: 599 static void* CallBack(void* arg) { 600 WatchDog* self = reinterpret_cast<WatchDog*>(arg); 601 ::art::SetThreadName("dex2oat watch dog"); 602 self->Wait(); 603 return nullptr; 604 } 605 606 static void Message(char severity, const std::string& message) { 607 // TODO: Remove when we switch to LOG when we can guarantee it won't prevent shutdown in error 608 // cases. 609 fprintf(stderr, "dex2oat%s %c %d %d %s\n", 610 kIsDebugBuild ? "d" : "", 611 severity, 612 getpid(), 613 GetTid(), 614 message.c_str()); 615 } 616 617 static void Warn(const std::string& message) { 618 Message('W', message); 619 } 620 621 static void Fatal(const std::string& message) { 622 Message('F', message); 623 exit(1); 624 } 625 626 void Wait() { 627 bool warning = true; 628 CHECK_GT(kWatchDogTimeoutSeconds, kWatchDogWarningSeconds); 629 // TODO: tune the multiplier for GC verification, the following is just to make the timeout 630 // large. 631 int64_t multiplier = kVerifyObjectSupport > kVerifyObjectModeFast ? 100 : 1; 632 timespec warning_ts; 633 InitTimeSpec(true, CLOCK_REALTIME, multiplier * kWatchDogWarningSeconds * 1000, 0, &warning_ts); 634 timespec timeout_ts; 635 InitTimeSpec(true, CLOCK_REALTIME, multiplier * kWatchDogTimeoutSeconds * 1000, 0, &timeout_ts); 636 const char* reason = "dex2oat watch dog thread waiting"; 637 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_lock, (&mutex_), reason); 638 while (!shutting_down_) { 639 int rc = TEMP_FAILURE_RETRY(pthread_cond_timedwait(&cond_, &mutex_, 640 warning ? &warning_ts 641 : &timeout_ts)); 642 if (rc == ETIMEDOUT) { 643 std::string message(StringPrintf("dex2oat did not finish after %d seconds", 644 warning ? kWatchDogWarningSeconds 645 : kWatchDogTimeoutSeconds)); 646 if (warning) { 647 Warn(message.c_str()); 648 warning = false; 649 } else { 650 Fatal(message.c_str()); 651 } 652 } else if (rc != 0) { 653 std::string message(StringPrintf("pthread_cond_timedwait failed: %s", 654 strerror(errno))); 655 Fatal(message.c_str()); 656 } 657 } 658 CHECK_WATCH_DOG_PTHREAD_CALL(pthread_mutex_unlock, (&mutex_), reason); 659 } 660 661 // When setting timeouts, keep in mind that the build server may not be as fast as your desktop. 662#if ART_USE_PORTABLE_COMPILER 663 static const unsigned int kWatchDogWarningSeconds = 2 * 60; // 2 minutes. 664 static const unsigned int kWatchDogTimeoutSeconds = 30 * 60; // 25 minutes + buffer. 665#else 666 static const unsigned int kWatchDogWarningSeconds = 1 * 60; // 1 minute. 667 static const unsigned int kWatchDogTimeoutSeconds = 6 * 60; // 5 minutes + buffer. 668#endif 669 670 bool is_watch_dog_enabled_; 671 bool shutting_down_; 672 // TODO: Switch to Mutex when we can guarantee it won't prevent shutdown in error cases. 673 pthread_mutex_t mutex_; 674 pthread_cond_t cond_; 675 pthread_attr_t attr_; 676 pthread_t pthread_; 677}; 678const unsigned int WatchDog::kWatchDogWarningSeconds; 679const unsigned int WatchDog::kWatchDogTimeoutSeconds; 680 681// Given a set of instruction features from the build, parse it. The 682// input 'str' is a comma separated list of feature names. Parse it and 683// return the InstructionSetFeatures object. 684static InstructionSetFeatures ParseFeatureList(std::string str) { 685 InstructionSetFeatures result; 686 typedef std::vector<std::string> FeatureList; 687 FeatureList features; 688 Split(str, ',', features); 689 for (FeatureList::iterator i = features.begin(); i != features.end(); i++) { 690 std::string feature = Trim(*i); 691 if (feature == "default") { 692 // Nothing to do. 693 } else if (feature == "div") { 694 // Supports divide instruction. 695 result.SetHasDivideInstruction(true); 696 } else if (feature == "nodiv") { 697 // Turn off support for divide instruction. 698 result.SetHasDivideInstruction(false); 699 } else if (feature == "lpae") { 700 // Supports Large Physical Address Extension. 701 result.SetHasLpae(true); 702 } else if (feature == "nolpae") { 703 // Turn off support for Large Physical Address Extension. 704 result.SetHasLpae(false); 705 } else { 706 Usage("Unknown instruction set feature: '%s'", feature.c_str()); 707 } 708 } 709 // others... 710 return result; 711} 712 713void ParseStringAfterChar(const std::string& s, char c, std::string* parsed_value) { 714 std::string::size_type colon = s.find(c); 715 if (colon == std::string::npos) { 716 Usage("Missing char %c in option %s\n", c, s.c_str()); 717 } 718 // Add one to remove the char we were trimming until. 719 *parsed_value = s.substr(colon + 1); 720} 721 722void ParseDouble(const std::string& option, char after_char, 723 double min, double max, double* parsed_value) { 724 std::string substring; 725 ParseStringAfterChar(option, after_char, &substring); 726 bool sane_val = true; 727 double value; 728 if (false) { 729 // TODO: this doesn't seem to work on the emulator. b/15114595 730 std::stringstream iss(substring); 731 iss >> value; 732 // Ensure that we have a value, there was no cruft after it and it satisfies a sensible range. 733 sane_val = iss.eof() && (value >= min) && (value <= max); 734 } else { 735 char* end = nullptr; 736 value = strtod(substring.c_str(), &end); 737 sane_val = *end == '\0' && value >= min && value <= max; 738 } 739 if (!sane_val) { 740 Usage("Invalid double value %s for option %s\n", substring.c_str(), option.c_str()); 741 } 742 *parsed_value = value; 743} 744 745void CheckExplicitCheckOptions(InstructionSet isa, bool* explicit_null_checks, 746 bool* explicit_so_checks, bool* explicit_suspend_checks) { 747 switch (isa) { 748 case kArm: 749 case kThumb2: 750 break; // All checks implemented, leave as is. 751 752 default: // No checks implemented, reset all to explicit checks. 753 *explicit_null_checks = true; 754 *explicit_so_checks = true; 755 *explicit_suspend_checks = true; 756 } 757} 758 759static int dex2oat(int argc, char** argv) { 760#if defined(__linux__) && defined(__arm__) 761 int major, minor; 762 struct utsname uts; 763 if (uname(&uts) != -1 && 764 sscanf(uts.release, "%d.%d", &major, &minor) == 2 && 765 ((major < 3) || ((major == 3) && (minor < 4)))) { 766 // Kernels before 3.4 don't handle the ASLR well and we can run out of address 767 // space (http://b/13564922). Work around the issue by inhibiting further mmap() randomization. 768 int old_personality = personality(0xffffffff); 769 if ((old_personality & ADDR_NO_RANDOMIZE) == 0) { 770 int new_personality = personality(old_personality | ADDR_NO_RANDOMIZE); 771 if (new_personality == -1) { 772 LOG(WARNING) << "personality(. | ADDR_NO_RANDOMIZE) failed."; 773 } 774 } 775 } 776#endif 777 778 original_argc = argc; 779 original_argv = argv; 780 781 TimingLogger timings("compiler", false, false); 782 CumulativeLogger compiler_phases_timings("compilation times"); 783 784 InitLogging(argv); 785 786 // Skip over argv[0]. 787 argv++; 788 argc--; 789 790 if (argc == 0) { 791 Usage("No arguments specified"); 792 } 793 794 std::vector<const char*> dex_filenames; 795 std::vector<const char*> dex_locations; 796 int zip_fd = -1; 797 std::string zip_location; 798 std::string oat_filename; 799 std::string oat_symbols; 800 std::string oat_location; 801 int oat_fd = -1; 802 std::string bitcode_filename; 803 const char* image_classes_zip_filename = nullptr; 804 const char* image_classes_filename = nullptr; 805 std::string image_filename; 806 std::string boot_image_filename; 807 uintptr_t image_base = 0; 808 std::string android_root; 809 std::vector<const char*> runtime_args; 810 int thread_count = sysconf(_SC_NPROCESSORS_CONF); 811 Compiler::Kind compiler_kind = kUsePortableCompiler 812 ? Compiler::kPortable 813 : Compiler::kQuick; 814 const char* compiler_filter_string = nullptr; 815 int huge_method_threshold = CompilerOptions::kDefaultHugeMethodThreshold; 816 int large_method_threshold = CompilerOptions::kDefaultLargeMethodThreshold; 817 int small_method_threshold = CompilerOptions::kDefaultSmallMethodThreshold; 818 int tiny_method_threshold = CompilerOptions::kDefaultTinyMethodThreshold; 819 int num_dex_methods_threshold = CompilerOptions::kDefaultNumDexMethodsThreshold; 820 821 // Take the default set of instruction features from the build. 822 InstructionSetFeatures instruction_set_features = 823 ParseFeatureList(Runtime::GetDefaultInstructionSetFeatures()); 824 825 InstructionSet instruction_set = kRuntimeISA; 826 827 // Profile file to use 828 std::string profile_file; 829 double top_k_profile_threshold = CompilerOptions::kDefaultTopKProfileThreshold; 830 831 bool is_host = false; 832 bool dump_stats = false; 833 bool dump_timing = false; 834 bool dump_passes = false; 835 bool include_patch_information = CompilerOptions::kDefaultIncludePatchInformation; 836 bool explicit_include_patch_information = false; 837 bool include_debug_symbols = kIsDebugBuild; 838 bool dump_slow_timing = kIsDebugBuild; 839 bool watch_dog_enabled = !kIsTargetBuild; 840 bool generate_gdb_information = kIsDebugBuild; 841 842 bool explicit_null_checks = true; 843 bool explicit_so_checks = true; 844 bool explicit_suspend_checks = true; 845 bool has_explicit_checks_options = false; 846 847 for (int i = 0; i < argc; i++) { 848 const StringPiece option(argv[i]); 849 const bool log_options = false; 850 if (log_options) { 851 LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i]; 852 } 853 if (option.starts_with("--dex-file=")) { 854 dex_filenames.push_back(option.substr(strlen("--dex-file=")).data()); 855 } else if (option.starts_with("--dex-location=")) { 856 dex_locations.push_back(option.substr(strlen("--dex-location=")).data()); 857 } else if (option.starts_with("--zip-fd=")) { 858 const char* zip_fd_str = option.substr(strlen("--zip-fd=")).data(); 859 if (!ParseInt(zip_fd_str, &zip_fd)) { 860 Usage("Failed to parse --zip-fd argument '%s' as an integer", zip_fd_str); 861 } 862 if (zip_fd < 0) { 863 Usage("--zip-fd passed a negative value %d", zip_fd); 864 } 865 } else if (option.starts_with("--zip-location=")) { 866 zip_location = option.substr(strlen("--zip-location=")).data(); 867 } else if (option.starts_with("--oat-file=")) { 868 oat_filename = option.substr(strlen("--oat-file=")).data(); 869 } else if (option.starts_with("--oat-symbols=")) { 870 oat_symbols = option.substr(strlen("--oat-symbols=")).data(); 871 } else if (option.starts_with("--oat-fd=")) { 872 const char* oat_fd_str = option.substr(strlen("--oat-fd=")).data(); 873 if (!ParseInt(oat_fd_str, &oat_fd)) { 874 Usage("Failed to parse --oat-fd argument '%s' as an integer", oat_fd_str); 875 } 876 if (oat_fd < 0) { 877 Usage("--oat-fd passed a negative value %d", oat_fd); 878 } 879 } else if (option == "--watch-dog") { 880 watch_dog_enabled = true; 881 } else if (option == "--no-watch-dog") { 882 watch_dog_enabled = false; 883 } else if (option == "--gen-gdb-info") { 884 generate_gdb_information = true; 885 // Debug symbols are needed for gdb information. 886 include_debug_symbols = true; 887 } else if (option == "--no-gen-gdb-info") { 888 generate_gdb_information = false; 889 } else if (option.starts_with("-j")) { 890 const char* thread_count_str = option.substr(strlen("-j")).data(); 891 if (!ParseInt(thread_count_str, &thread_count)) { 892 Usage("Failed to parse -j argument '%s' as an integer", thread_count_str); 893 } 894 } else if (option.starts_with("--oat-location=")) { 895 oat_location = option.substr(strlen("--oat-location=")).data(); 896 } else if (option.starts_with("--bitcode=")) { 897 bitcode_filename = option.substr(strlen("--bitcode=")).data(); 898 } else if (option.starts_with("--image=")) { 899 image_filename = option.substr(strlen("--image=")).data(); 900 } else if (option.starts_with("--image-classes=")) { 901 image_classes_filename = option.substr(strlen("--image-classes=")).data(); 902 } else if (option.starts_with("--image-classes-zip=")) { 903 image_classes_zip_filename = option.substr(strlen("--image-classes-zip=")).data(); 904 } else if (option.starts_with("--base=")) { 905 const char* image_base_str = option.substr(strlen("--base=")).data(); 906 char* end; 907 image_base = strtoul(image_base_str, &end, 16); 908 if (end == image_base_str || *end != '\0') { 909 Usage("Failed to parse hexadecimal value for option %s", option.data()); 910 } 911 } else if (option.starts_with("--boot-image=")) { 912 boot_image_filename = option.substr(strlen("--boot-image=")).data(); 913 } else if (option.starts_with("--android-root=")) { 914 android_root = option.substr(strlen("--android-root=")).data(); 915 } else if (option.starts_with("--instruction-set=")) { 916 StringPiece instruction_set_str = option.substr(strlen("--instruction-set=")).data(); 917 if (instruction_set_str == "arm") { 918 instruction_set = kThumb2; 919 } else if (instruction_set_str == "arm64") { 920 instruction_set = kArm64; 921 } else if (instruction_set_str == "mips") { 922 instruction_set = kMips; 923 } else if (instruction_set_str == "x86") { 924 instruction_set = kX86; 925 } else if (instruction_set_str == "x86_64") { 926 instruction_set = kX86_64; 927 } 928 } else if (option.starts_with("--instruction-set-features=")) { 929 StringPiece str = option.substr(strlen("--instruction-set-features=")).data(); 930 instruction_set_features = ParseFeatureList(str.as_string()); 931 } else if (option.starts_with("--compiler-backend=")) { 932 StringPiece backend_str = option.substr(strlen("--compiler-backend=")).data(); 933 if (backend_str == "Quick") { 934 compiler_kind = Compiler::kQuick; 935 } else if (backend_str == "Optimizing") { 936 compiler_kind = Compiler::kOptimizing; 937 } else if (backend_str == "Portable") { 938 compiler_kind = Compiler::kPortable; 939 } 940 } else if (option.starts_with("--compiler-filter=")) { 941 compiler_filter_string = option.substr(strlen("--compiler-filter=")).data(); 942 } else if (option.starts_with("--huge-method-max=")) { 943 const char* threshold = option.substr(strlen("--huge-method-max=")).data(); 944 if (!ParseInt(threshold, &huge_method_threshold)) { 945 Usage("Failed to parse --huge-method-max '%s' as an integer", threshold); 946 } 947 if (huge_method_threshold < 0) { 948 Usage("--huge-method-max passed a negative value %s", huge_method_threshold); 949 } 950 } else if (option.starts_with("--large-method-max=")) { 951 const char* threshold = option.substr(strlen("--large-method-max=")).data(); 952 if (!ParseInt(threshold, &large_method_threshold)) { 953 Usage("Failed to parse --large-method-max '%s' as an integer", threshold); 954 } 955 if (large_method_threshold < 0) { 956 Usage("--large-method-max passed a negative value %s", large_method_threshold); 957 } 958 } else if (option.starts_with("--small-method-max=")) { 959 const char* threshold = option.substr(strlen("--small-method-max=")).data(); 960 if (!ParseInt(threshold, &small_method_threshold)) { 961 Usage("Failed to parse --small-method-max '%s' as an integer", threshold); 962 } 963 if (small_method_threshold < 0) { 964 Usage("--small-method-max passed a negative value %s", small_method_threshold); 965 } 966 } else if (option.starts_with("--tiny-method-max=")) { 967 const char* threshold = option.substr(strlen("--tiny-method-max=")).data(); 968 if (!ParseInt(threshold, &tiny_method_threshold)) { 969 Usage("Failed to parse --tiny-method-max '%s' as an integer", threshold); 970 } 971 if (tiny_method_threshold < 0) { 972 Usage("--tiny-method-max passed a negative value %s", tiny_method_threshold); 973 } 974 } else if (option.starts_with("--num-dex-methods=")) { 975 const char* threshold = option.substr(strlen("--num-dex-methods=")).data(); 976 if (!ParseInt(threshold, &num_dex_methods_threshold)) { 977 Usage("Failed to parse --num-dex-methods '%s' as an integer", threshold); 978 } 979 if (num_dex_methods_threshold < 0) { 980 Usage("--num-dex-methods passed a negative value %s", num_dex_methods_threshold); 981 } 982 } else if (option == "--host") { 983 is_host = true; 984 } else if (option == "--runtime-arg") { 985 if (++i >= argc) { 986 Usage("Missing required argument for --runtime-arg"); 987 } 988 if (log_options) { 989 LOG(INFO) << "dex2oat: option[" << i << "]=" << argv[i]; 990 } 991 runtime_args.push_back(argv[i]); 992 } else if (option == "--dump-timing") { 993 dump_timing = true; 994 } else if (option == "--dump-passes") { 995 dump_passes = true; 996 } else if (option == "--dump-stats") { 997 dump_stats = true; 998 } else if (option == "--include-debug-symbols" || option == "--no-strip-symbols") { 999 include_debug_symbols = true; 1000 } else if (option == "--no-include-debug-symbols" || option == "--strip-symbols") { 1001 include_debug_symbols = false; 1002 } else if (option.starts_with("--profile-file=")) { 1003 profile_file = option.substr(strlen("--profile-file=")).data(); 1004 VLOG(compiler) << "dex2oat: profile file is " << profile_file; 1005 } else if (option == "--no-profile-file") { 1006 // No profile 1007 } else if (option.starts_with("--top-k-profile-threshold=")) { 1008 ParseDouble(option.data(), '=', 0.0, 100.0, &top_k_profile_threshold); 1009 } else if (option == "--print-pass-names") { 1010 PassDriverMEOpts::PrintPassNames(); 1011 } else if (option.starts_with("--disable-passes=")) { 1012 std::string disable_passes = option.substr(strlen("--disable-passes=")).data(); 1013 PassDriverMEOpts::CreateDefaultPassList(disable_passes); 1014 } else if (option.starts_with("--print-passes=")) { 1015 std::string print_passes = option.substr(strlen("--print-passes=")).data(); 1016 PassDriverMEOpts::SetPrintPassList(print_passes); 1017 } else if (option == "--print-all-passes") { 1018 PassDriverMEOpts::SetPrintAllPasses(); 1019 } else if (option.starts_with("--dump-cfg-passes=")) { 1020 std::string dump_passes = option.substr(strlen("--dump-cfg-passes=")).data(); 1021 PassDriverMEOpts::SetDumpPassList(dump_passes); 1022 } else if (option.starts_with("--implicit-checks=")) { 1023 std::string checks = option.substr(strlen("--implicit-checks=")).data(); 1024 std::vector<std::string> checkvec; 1025 Split(checks, ',', checkvec); 1026 for (auto& str : checkvec) { 1027 std::string val = Trim(str); 1028 if (val == "none") { 1029 explicit_null_checks = true; 1030 explicit_so_checks = true; 1031 explicit_suspend_checks = true; 1032 } else if (val == "null") { 1033 explicit_null_checks = false; 1034 } else if (val == "suspend") { 1035 explicit_suspend_checks = false; 1036 } else if (val == "stack") { 1037 explicit_so_checks = false; 1038 } else if (val == "all") { 1039 explicit_null_checks = false; 1040 explicit_so_checks = false; 1041 explicit_suspend_checks = false; 1042 } else { 1043 Usage("--implicit-checks passed non-recognized value %s", val.c_str()); 1044 } 1045 } 1046 has_explicit_checks_options = true; 1047 } else if (option == "--include-patch-information") { 1048 include_patch_information = true; 1049 explicit_include_patch_information = true; 1050 } else if (option == "--no-include-patch-information") { 1051 include_patch_information = false; 1052 explicit_include_patch_information = true; 1053 } else { 1054 Usage("Unknown argument %s", option.data()); 1055 } 1056 } 1057 1058 if (oat_filename.empty() && oat_fd == -1) { 1059 Usage("Output must be supplied with either --oat-file or --oat-fd"); 1060 } 1061 1062 if (!oat_filename.empty() && oat_fd != -1) { 1063 Usage("--oat-file should not be used with --oat-fd"); 1064 } 1065 1066 if (!oat_symbols.empty() && oat_fd != -1) { 1067 Usage("--oat-symbols should not be used with --oat-fd"); 1068 } 1069 1070 if (!oat_symbols.empty() && is_host) { 1071 Usage("--oat-symbols should not be used with --host"); 1072 } 1073 1074 if (oat_fd != -1 && !image_filename.empty()) { 1075 Usage("--oat-fd should not be used with --image"); 1076 } 1077 1078 if (android_root.empty()) { 1079 const char* android_root_env_var = getenv("ANDROID_ROOT"); 1080 if (android_root_env_var == nullptr) { 1081 Usage("--android-root unspecified and ANDROID_ROOT not set"); 1082 } 1083 android_root += android_root_env_var; 1084 } 1085 1086 bool image = (!image_filename.empty()); 1087 if (!image && boot_image_filename.empty()) { 1088 boot_image_filename += android_root; 1089 boot_image_filename += "/framework/boot.art"; 1090 } 1091 std::string boot_image_option; 1092 if (!boot_image_filename.empty()) { 1093 boot_image_option += "-Ximage:"; 1094 boot_image_option += boot_image_filename; 1095 } 1096 1097 if (image_classes_filename != nullptr && !image) { 1098 Usage("--image-classes should only be used with --image"); 1099 } 1100 1101 if (image_classes_filename != nullptr && !boot_image_option.empty()) { 1102 Usage("--image-classes should not be used with --boot-image"); 1103 } 1104 1105 if (image_classes_zip_filename != nullptr && image_classes_filename == nullptr) { 1106 Usage("--image-classes-zip should be used with --image-classes"); 1107 } 1108 1109 if (dex_filenames.empty() && zip_fd == -1) { 1110 Usage("Input must be supplied with either --dex-file or --zip-fd"); 1111 } 1112 1113 if (!dex_filenames.empty() && zip_fd != -1) { 1114 Usage("--dex-file should not be used with --zip-fd"); 1115 } 1116 1117 if (!dex_filenames.empty() && !zip_location.empty()) { 1118 Usage("--dex-file should not be used with --zip-location"); 1119 } 1120 1121 if (dex_locations.empty()) { 1122 for (size_t i = 0; i < dex_filenames.size(); i++) { 1123 dex_locations.push_back(dex_filenames[i]); 1124 } 1125 } else if (dex_locations.size() != dex_filenames.size()) { 1126 Usage("--dex-location arguments do not match --dex-file arguments"); 1127 } 1128 1129 if (zip_fd != -1 && zip_location.empty()) { 1130 Usage("--zip-location should be supplied with --zip-fd"); 1131 } 1132 1133 if (boot_image_option.empty()) { 1134 if (image_base == 0) { 1135 Usage("Non-zero --base not specified"); 1136 } 1137 } 1138 1139 std::string oat_stripped(oat_filename); 1140 std::string oat_unstripped; 1141 if (!oat_symbols.empty()) { 1142 oat_unstripped += oat_symbols; 1143 } else { 1144 oat_unstripped += oat_filename; 1145 } 1146 1147 if (compiler_filter_string == nullptr) { 1148 if (instruction_set == kMips64) { 1149 // TODO: fix compiler for Mips64. 1150 compiler_filter_string = "interpret-only"; 1151 } else if (image) { 1152 compiler_filter_string = "speed"; 1153 } else { 1154#if ART_SMALL_MODE 1155 compiler_filter_string = "interpret-only"; 1156#else 1157 compiler_filter_string = "speed"; 1158#endif 1159 } 1160 } 1161 CHECK(compiler_filter_string != nullptr); 1162 CompilerOptions::CompilerFilter compiler_filter = CompilerOptions::kDefaultCompilerFilter; 1163 if (strcmp(compiler_filter_string, "verify-none") == 0) { 1164 compiler_filter = CompilerOptions::kVerifyNone; 1165 } else if (strcmp(compiler_filter_string, "interpret-only") == 0) { 1166 compiler_filter = CompilerOptions::kInterpretOnly; 1167 } else if (strcmp(compiler_filter_string, "space") == 0) { 1168 compiler_filter = CompilerOptions::kSpace; 1169 } else if (strcmp(compiler_filter_string, "balanced") == 0) { 1170 compiler_filter = CompilerOptions::kBalanced; 1171 } else if (strcmp(compiler_filter_string, "speed") == 0) { 1172 compiler_filter = CompilerOptions::kSpeed; 1173 } else if (strcmp(compiler_filter_string, "everything") == 0) { 1174 compiler_filter = CompilerOptions::kEverything; 1175 } else { 1176 Usage("Unknown --compiler-filter value %s", compiler_filter_string); 1177 } 1178 1179 ImplicitCheckOptions::CheckISASupport(instruction_set, &explicit_null_checks, &explicit_so_checks, 1180 &explicit_suspend_checks); 1181 1182 if (!explicit_include_patch_information) { 1183 include_patch_information = 1184 (compiler_kind == Compiler::kQuick && CompilerOptions::kDefaultIncludePatchInformation); 1185 } 1186 1187 std::unique_ptr<CompilerOptions> compiler_options(new CompilerOptions(compiler_filter, 1188 huge_method_threshold, 1189 large_method_threshold, 1190 small_method_threshold, 1191 tiny_method_threshold, 1192 num_dex_methods_threshold, 1193 generate_gdb_information, 1194 include_patch_information, 1195 top_k_profile_threshold, 1196 include_debug_symbols, 1197 explicit_null_checks, 1198 explicit_so_checks, 1199 explicit_suspend_checks 1200#ifdef ART_SEA_IR_MODE 1201 , compiler_options.sea_ir_ = 1202 true; 1203#endif 1204 )); // NOLINT(whitespace/parens) 1205 1206 // Done with usage checks, enable watchdog if requested 1207 WatchDog watch_dog(watch_dog_enabled); 1208 1209 // Check early that the result of compilation can be written 1210 std::unique_ptr<File> oat_file; 1211 bool create_file = !oat_unstripped.empty(); // as opposed to using open file descriptor 1212 if (create_file) { 1213 oat_file.reset(OS::CreateEmptyFile(oat_unstripped.c_str())); 1214 if (oat_location.empty()) { 1215 oat_location = oat_filename; 1216 } 1217 } else { 1218 oat_file.reset(new File(oat_fd, oat_location)); 1219 oat_file->DisableAutoClose(); 1220 } 1221 if (oat_file.get() == nullptr) { 1222 PLOG(ERROR) << "Failed to create oat file: " << oat_location; 1223 return EXIT_FAILURE; 1224 } 1225 if (create_file && fchmod(oat_file->Fd(), 0644) != 0) { 1226 PLOG(ERROR) << "Failed to make oat file world readable: " << oat_location; 1227 return EXIT_FAILURE; 1228 } 1229 1230 timings.StartTiming("dex2oat Setup"); 1231 LOG(INFO) << CommandLine(); 1232 1233 RuntimeOptions runtime_options; 1234 std::vector<const DexFile*> boot_class_path; 1235 if (boot_image_option.empty()) { 1236 size_t failure_count = OpenDexFiles(dex_filenames, dex_locations, boot_class_path); 1237 if (failure_count > 0) { 1238 LOG(ERROR) << "Failed to open some dex files: " << failure_count; 1239 return EXIT_FAILURE; 1240 } 1241 runtime_options.push_back(std::make_pair("bootclasspath", &boot_class_path)); 1242 } else { 1243 runtime_options.push_back(std::make_pair(boot_image_option.c_str(), nullptr)); 1244 } 1245 for (size_t i = 0; i < runtime_args.size(); i++) { 1246 runtime_options.push_back(std::make_pair(runtime_args[i], nullptr)); 1247 } 1248 1249 std::unique_ptr<VerificationResults> verification_results(new VerificationResults( 1250 compiler_options.get())); 1251 DexFileToMethodInlinerMap method_inliner_map; 1252 QuickCompilerCallbacks callbacks(verification_results.get(), &method_inliner_map); 1253 runtime_options.push_back(std::make_pair("compilercallbacks", &callbacks)); 1254 runtime_options.push_back( 1255 std::make_pair("imageinstructionset", 1256 reinterpret_cast<const void*>(GetInstructionSetString(instruction_set)))); 1257 1258 Dex2Oat* p_dex2oat; 1259 if (!Dex2Oat::Create(&p_dex2oat, 1260 runtime_options, 1261 *compiler_options, 1262 compiler_kind, 1263 instruction_set, 1264 instruction_set_features, 1265 verification_results.get(), 1266 &method_inliner_map, 1267 thread_count)) { 1268 LOG(ERROR) << "Failed to create dex2oat"; 1269 return EXIT_FAILURE; 1270 } 1271 std::unique_ptr<Dex2Oat> dex2oat(p_dex2oat); 1272 1273 // TODO: Not sure whether it's a good idea to allow anything else but the runtime option in 1274 // this case at all, as we'll have to throw away produced code for a mismatch. 1275 if (!has_explicit_checks_options) { 1276 if (ImplicitCheckOptions::CheckForCompiling(kRuntimeISA, instruction_set, &explicit_null_checks, 1277 &explicit_so_checks, &explicit_suspend_checks)) { 1278 compiler_options->SetExplicitNullChecks(explicit_null_checks); 1279 compiler_options->SetExplicitStackOverflowChecks(explicit_so_checks); 1280 compiler_options->SetExplicitSuspendChecks(explicit_suspend_checks); 1281 } 1282 } 1283 1284 1285 // Runtime::Create acquired the mutator_lock_ that is normally given away when we Runtime::Start, 1286 // give it away now so that we don't starve GC. 1287 Thread* self = Thread::Current(); 1288 self->TransitionFromRunnableToSuspended(kNative); 1289 // If we're doing the image, override the compiler filter to force full compilation. Must be 1290 // done ahead of WellKnownClasses::Init that causes verification. Note: doesn't force 1291 // compilation of class initializers. 1292 // Whilst we're in native take the opportunity to initialize well known classes. 1293 WellKnownClasses::Init(self->GetJniEnv()); 1294 1295 // If --image-classes was specified, calculate the full list of classes to include in the image 1296 std::unique_ptr<CompilerDriver::DescriptorSet> image_classes(nullptr); 1297 if (image_classes_filename != nullptr) { 1298 std::string error_msg; 1299 if (image_classes_zip_filename != nullptr) { 1300 image_classes.reset(dex2oat->ReadImageClassesFromZip(image_classes_zip_filename, 1301 image_classes_filename, 1302 &error_msg)); 1303 } else { 1304 image_classes.reset(dex2oat->ReadImageClassesFromFile(image_classes_filename)); 1305 } 1306 if (image_classes.get() == nullptr) { 1307 LOG(ERROR) << "Failed to create list of image classes from '" << image_classes_filename << 1308 "': " << error_msg; 1309 return EXIT_FAILURE; 1310 } 1311 } else if (image) { 1312 image_classes.reset(new CompilerDriver::DescriptorSet); 1313 } 1314 1315 std::vector<const DexFile*> dex_files; 1316 if (boot_image_option.empty()) { 1317 dex_files = Runtime::Current()->GetClassLinker()->GetBootClassPath(); 1318 } else { 1319 if (dex_filenames.empty()) { 1320 ATRACE_BEGIN("Opening zip archive from file descriptor"); 1321 std::string error_msg; 1322 std::unique_ptr<ZipArchive> zip_archive(ZipArchive::OpenFromFd(zip_fd, zip_location.c_str(), 1323 &error_msg)); 1324 if (zip_archive.get() == nullptr) { 1325 LOG(ERROR) << "Failed to open zip from file descriptor for '" << zip_location << "': " 1326 << error_msg; 1327 return EXIT_FAILURE; 1328 } 1329 if (!DexFile::OpenFromZip(*zip_archive.get(), zip_location, &error_msg, &dex_files)) { 1330 LOG(ERROR) << "Failed to open dex from file descriptor for zip file '" << zip_location 1331 << "': " << error_msg; 1332 return EXIT_FAILURE; 1333 } 1334 ATRACE_END(); 1335 } else { 1336 size_t failure_count = OpenDexFiles(dex_filenames, dex_locations, dex_files); 1337 if (failure_count > 0) { 1338 LOG(ERROR) << "Failed to open some dex files: " << failure_count; 1339 return EXIT_FAILURE; 1340 } 1341 } 1342 1343 const bool kSaveDexInput = false; 1344 if (kSaveDexInput) { 1345 for (size_t i = 0; i < dex_files.size(); ++i) { 1346 const DexFile* dex_file = dex_files[i]; 1347 std::string tmp_file_name(StringPrintf("/data/local/tmp/dex2oat.%d.%zd.dex", getpid(), i)); 1348 std::unique_ptr<File> tmp_file(OS::CreateEmptyFile(tmp_file_name.c_str())); 1349 if (tmp_file.get() == nullptr) { 1350 PLOG(ERROR) << "Failed to open file " << tmp_file_name 1351 << ". Try: adb shell chmod 777 /data/local/tmp"; 1352 continue; 1353 } 1354 tmp_file->WriteFully(dex_file->Begin(), dex_file->Size()); 1355 LOG(INFO) << "Wrote input to " << tmp_file_name; 1356 } 1357 } 1358 } 1359 // Ensure opened dex files are writable for dex-to-dex transformations. 1360 for (const auto& dex_file : dex_files) { 1361 if (!dex_file->EnableWrite()) { 1362 PLOG(ERROR) << "Failed to make .dex file writeable '" << dex_file->GetLocation() << "'\n"; 1363 } 1364 } 1365 1366 /* 1367 * If we're not in interpret-only or verify-none mode, go ahead and compile small applications. 1368 * Don't bother to check if we're doing the image. 1369 */ 1370 if (!image && compiler_options->IsCompilationEnabled()) { 1371 size_t num_methods = 0; 1372 for (size_t i = 0; i != dex_files.size(); ++i) { 1373 const DexFile* dex_file = dex_files[i]; 1374 CHECK(dex_file != nullptr); 1375 num_methods += dex_file->NumMethodIds(); 1376 } 1377 if (num_methods <= compiler_options->GetNumDexMethodsThreshold()) { 1378 compiler_options->SetCompilerFilter(CompilerOptions::kSpeed); 1379 VLOG(compiler) << "Below method threshold, compiling anyways"; 1380 } 1381 } 1382 1383 // Fill some values into the key-value store for the oat header. 1384 std::unique_ptr<SafeMap<std::string, std::string> > key_value_store( 1385 new SafeMap<std::string, std::string>()); 1386 1387 // Insert implicit check options. 1388 key_value_store->Put(ImplicitCheckOptions::kImplicitChecksOatHeaderKey, 1389 ImplicitCheckOptions::Serialize(compiler_options->GetExplicitNullChecks(), 1390 compiler_options-> 1391 GetExplicitStackOverflowChecks(), 1392 compiler_options-> 1393 GetExplicitSuspendChecks())); 1394 1395 // Insert some compiler things. 1396 std::ostringstream oss; 1397 for (int i = 0; i < argc; ++i) { 1398 if (i > 0) { 1399 oss << ' '; 1400 } 1401 oss << argv[i]; 1402 } 1403 key_value_store->Put(OatHeader::kDex2OatCmdLineKey, oss.str()); 1404 oss.str(""); // Reset. 1405 oss << kRuntimeISA; 1406 key_value_store->Put(OatHeader::kDex2OatHostKey, oss.str()); 1407 1408 std::unique_ptr<const CompilerDriver> compiler(dex2oat->CreateOatFile(boot_image_option, 1409 android_root, 1410 is_host, 1411 dex_files, 1412 oat_file.get(), 1413 bitcode_filename, 1414 image, 1415 image_classes, 1416 dump_stats, 1417 dump_passes, 1418 timings, 1419 compiler_phases_timings, 1420 profile_file, 1421 key_value_store.get())); 1422 1423 if (compiler.get() == nullptr) { 1424 LOG(ERROR) << "Failed to create oat file: " << oat_location; 1425 return EXIT_FAILURE; 1426 } 1427 1428 VLOG(compiler) << "Oat file written successfully (unstripped): " << oat_location; 1429 1430 // Notes on the interleaving of creating the image and oat file to 1431 // ensure the references between the two are correct. 1432 // 1433 // Currently we have a memory layout that looks something like this: 1434 // 1435 // +--------------+ 1436 // | image | 1437 // +--------------+ 1438 // | boot oat | 1439 // +--------------+ 1440 // | alloc spaces | 1441 // +--------------+ 1442 // 1443 // There are several constraints on the loading of the image and boot.oat. 1444 // 1445 // 1. The image is expected to be loaded at an absolute address and 1446 // contains Objects with absolute pointers within the image. 1447 // 1448 // 2. There are absolute pointers from Methods in the image to their 1449 // code in the oat. 1450 // 1451 // 3. There are absolute pointers from the code in the oat to Methods 1452 // in the image. 1453 // 1454 // 4. There are absolute pointers from code in the oat to other code 1455 // in the oat. 1456 // 1457 // To get this all correct, we go through several steps. 1458 // 1459 // 1. We have already created that oat file above with 1460 // CreateOatFile. Originally this was just our own proprietary file 1461 // but now it is contained within an ELF dynamic object (aka an .so 1462 // file). The Compiler returned by CreateOatFile provides 1463 // PatchInformation for references to oat code and Methods that need 1464 // to be update once we know where the oat file will be located 1465 // after the image. 1466 // 1467 // 2. We create the image file. It needs to know where the oat file 1468 // will be loaded after itself. Originally when oat file was simply 1469 // memory mapped so we could predict where its contents were based 1470 // on the file size. Now that it is an ELF file, we need to inspect 1471 // the ELF file to understand the in memory segment layout including 1472 // where the oat header is located within. ImageWriter's 1473 // PatchOatCodeAndMethods uses the PatchInformation from the 1474 // Compiler to touch up absolute references in the oat file. 1475 // 1476 // 3. We fixup the ELF program headers so that dlopen will try to 1477 // load the .so at the desired location at runtime by offsetting the 1478 // Elf32_Phdr.p_vaddr values by the desired base address. 1479 // 1480 if (image) { 1481 TimingLogger::ScopedTiming t("dex2oat ImageWriter", &timings); 1482 bool image_creation_success = dex2oat->CreateImageFile(image_filename, 1483 image_base, 1484 oat_unstripped, 1485 oat_location, 1486 *compiler.get()); 1487 if (!image_creation_success) { 1488 return EXIT_FAILURE; 1489 } 1490 VLOG(compiler) << "Image written successfully: " << image_filename; 1491 } 1492 1493 if (is_host) { 1494 timings.EndTiming(); 1495 if (dump_timing || (dump_slow_timing && timings.GetTotalNs() > MsToNs(1000))) { 1496 LOG(INFO) << Dumpable<TimingLogger>(timings); 1497 } 1498 if (dump_passes) { 1499 LOG(INFO) << Dumpable<CumulativeLogger>(*compiler.get()->GetTimingsLogger()); 1500 } 1501 return EXIT_SUCCESS; 1502 } 1503 1504 // If we don't want to strip in place, copy from unstripped location to stripped location. 1505 // We need to strip after image creation because FixupElf needs to use .strtab. 1506 if (oat_unstripped != oat_stripped) { 1507 TimingLogger::ScopedTiming t("dex2oat OatFile copy", &timings); 1508 oat_file.reset(); 1509 std::unique_ptr<File> in(OS::OpenFileForReading(oat_unstripped.c_str())); 1510 std::unique_ptr<File> out(OS::CreateEmptyFile(oat_stripped.c_str())); 1511 size_t buffer_size = 8192; 1512 std::unique_ptr<uint8_t> buffer(new uint8_t[buffer_size]); 1513 while (true) { 1514 int bytes_read = TEMP_FAILURE_RETRY(read(in->Fd(), buffer.get(), buffer_size)); 1515 if (bytes_read <= 0) { 1516 break; 1517 } 1518 bool write_ok = out->WriteFully(buffer.get(), bytes_read); 1519 CHECK(write_ok); 1520 } 1521 oat_file.reset(out.release()); 1522 VLOG(compiler) << "Oat file copied successfully (stripped): " << oat_stripped; 1523 } 1524 1525#if ART_USE_PORTABLE_COMPILER // We currently only generate symbols on Portable 1526 if (!compiler_options.GetIncludeDebugSymbols()) { 1527 timings.NewSplit("dex2oat ElfStripper"); 1528 // Strip unneeded sections for target 1529 off_t seek_actual = lseek(oat_file->Fd(), 0, SEEK_SET); 1530 CHECK_EQ(0, seek_actual); 1531 std::string error_msg; 1532 CHECK(ElfStripper::Strip(oat_file.get(), &error_msg)) << error_msg; 1533 1534 1535 // We wrote the oat file successfully, and want to keep it. 1536 VLOG(compiler) << "Oat file written successfully (stripped): " << oat_location; 1537 } else { 1538 VLOG(compiler) << "Oat file written successfully without stripping: " << oat_location; 1539 } 1540#endif // ART_USE_PORTABLE_COMPILER 1541 1542 timings.EndTiming(); 1543 1544 if (dump_timing || (dump_slow_timing && timings.GetTotalNs() > MsToNs(1000))) { 1545 LOG(INFO) << Dumpable<TimingLogger>(timings); 1546 } 1547 if (dump_passes) { 1548 LOG(INFO) << Dumpable<CumulativeLogger>(compiler_phases_timings); 1549 } 1550 1551 // Everything was successfully written, do an explicit exit here to avoid running Runtime 1552 // destructors that take time (bug 10645725) unless we're a debug build or running on valgrind. 1553 if (!kIsDebugBuild && (RUNNING_ON_VALGRIND == 0)) { 1554 dex2oat->LogCompletionTime(); 1555 exit(EXIT_SUCCESS); 1556 } 1557 1558 return EXIT_SUCCESS; 1559} // NOLINT(readability/fn_size) 1560} // namespace art 1561 1562int main(int argc, char** argv) { 1563 return art::dex2oat(argc, argv); 1564} 1565