| 445 | static constexpr size_t kWarnOnManyDexFilesThreshold = 100; |
| 446 | |
| 447 | bool DexFileLoader::OpenAllDexFilesFromZip( |
| 448 | const DexZipArchive& zip_archive, |
| 449 | const std::string& location, |
| 450 | bool verify, |
| 451 | bool verify_checksum, |
| 452 | std::string* error_msg, |
| 453 | std::vector<std::unique_ptr<const DexFile>>* dex_files) const { |
| 454 | DCHECK(dex_files != nullptr) << "DexFile::OpenFromZip: out-param is nullptr"; |
| 455 | ZipOpenErrorCode error_code; |
| 456 | std::unique_ptr<const DexFile> dex_file(OpenOneDexFileFromZip(zip_archive, |
| 457 | kClassesDex, |
| 458 | location, |
| 459 | verify, |
| 460 | verify_checksum, |
| 461 | error_msg, |
| 462 | &error_code)); |
| 463 | if (dex_file.get() == nullptr) { |
| 464 | return false; |
| 465 | } else { |
| 466 | // Had at least classes.dex. |
| 467 | dex_files->push_back(std::move(dex_file)); |
| 468 | |
| 469 | // Now try some more. |
| 470 | |
| 471 | // We could try to avoid std::string allocations by working on a char array directly. As we |
| 472 | // do not expect a lot of iterations, this seems too involved and brittle. |
| 473 | |
| 474 | for (size_t i = 1; ; ++i) { |
| 475 | std::string name = GetMultiDexClassesDexName(i); |
| 476 | std::string fake_location = GetMultiDexLocation(i, location.c_str()); |
| 477 | std::unique_ptr<const DexFile> next_dex_file(OpenOneDexFileFromZip(zip_archive, |
| 478 | name.c_str(), |
| 479 | fake_location, |
| 480 | verify, |
| 481 | verify_checksum, |
| 482 | error_msg, |
| 483 | &error_code)); |
| 484 | if (next_dex_file.get() == nullptr) { |
| 485 | if (error_code != ZipOpenErrorCode::kEntryNotFound) { |
| 486 | LOG(WARNING) << "Zip open failed: " << *error_msg; |
| 487 | } |
| 488 | break; |
| 489 | } else { |
| 490 | dex_files->push_back(std::move(next_dex_file)); |
| 491 | } |
| 492 | |
| 493 | if (i == kWarnOnManyDexFilesThreshold) { |
| 494 | LOG(WARNING) << location << " has in excess of " << kWarnOnManyDexFilesThreshold |
| 495 | << " dex files. Please consider coalescing and shrinking the number to " |
| 496 | " avoid runtime overhead."; |
| 497 | } |
| 498 | |
| 499 | if (i == std::numeric_limits<size_t>::max()) { |
| 500 | LOG(ERROR) << "Overflow in number of dex files!"; |
| 501 | break; |
| 502 | } |
| 503 | } |
| 504 | |