diff options
author | 2021-05-20 15:14:25 -0700 | |
---|---|---|
committer | 2021-05-24 20:05:49 +0000 | |
commit | 61ffd049d8d6946ba52884a8f679dde0e3a6654d (patch) | |
tree | 6ce3787caae6d00bfb30165786fe40d42a86e045 | |
parent | 6d8d68efbe2101e2d5fdf078556cbc1f286c37c7 (diff) |
Make the runtime option -Ximage a ParseStringList
Previously, the string spliting is done in multiple code locations,
including ImageSpace::BootImageLayout::LoadOrValidate and
GetPrimaryImageLocation (which may be called multiple times).
This change converts the -Ximage option from a string into a
ParseStringList<':'>.
It may be worth pointing out that this doesn't change the current code
expectation that each image can have a profile (e.g.
"/path/to/foo.art!/some/profile.prof").
There is a later plan to introduce new options of boot image fds with
ParseIntList<':'>. This change would make them more consistent.
Bug: 187327262
Test: boot looks normal
Test: dexopt looks normal
Test: TH
Change-Id: I82657cb725cda2d3b782cbe7a6e6d9a871e80ee7
-rw-r--r-- | dex2oat/dex2oat_image_test.cc | 2 | ||||
-rw-r--r-- | dexoptanalyzer/dexoptanalyzer.cc | 3 | ||||
-rw-r--r-- | runtime/dexopt_test.cc | 2 | ||||
-rw-r--r-- | runtime/gc/heap.cc | 4 | ||||
-rw-r--r-- | runtime/gc/heap.h | 2 | ||||
-rw-r--r-- | runtime/gc/space/image_space.cc | 65 | ||||
-rw-r--r-- | runtime/gc/space/image_space.h | 4 | ||||
-rw-r--r-- | runtime/gc/space/image_space_test.cc | 19 | ||||
-rw-r--r-- | runtime/oat_file_assistant.cc | 2 | ||||
-rw-r--r-- | runtime/parsed_options.cc | 6 | ||||
-rw-r--r-- | runtime/parsed_options_test.cc | 4 | ||||
-rw-r--r-- | runtime/runtime.cc | 11 | ||||
-rw-r--r-- | runtime/runtime.h | 6 | ||||
-rw-r--r-- | runtime/runtime_options.def | 2 |
14 files changed, 63 insertions, 69 deletions
diff --git a/dex2oat/dex2oat_image_test.cc b/dex2oat/dex2oat_image_test.cc index a44a3e4e55..cfb79e5f39 100644 --- a/dex2oat/dex2oat_image_test.cc +++ b/dex2oat/dex2oat_image_test.cc @@ -422,7 +422,7 @@ TEST_F(Dex2oatImageTest, TestExtension) { ScopedObjectAccess soa(Thread::Current()); return gc::space::ImageSpace::LoadBootImage(/*boot_class_path=*/ boot_class_path, /*boot_class_path_locations=*/ libcore_dex_files, - image_location, + android::base::Split(image_location, ":"), kRuntimeISA, relocate, /*executable=*/ true, diff --git a/dexoptanalyzer/dexoptanalyzer.cc b/dexoptanalyzer/dexoptanalyzer.cc index 998f41a935..5863e45cc3 100644 --- a/dexoptanalyzer/dexoptanalyzer.cc +++ b/dexoptanalyzer/dexoptanalyzer.cc @@ -368,10 +368,11 @@ class DexoptAnalyzer final { std::string error_msg; const std::vector<std::string>& bcp = runtime->GetBootClassPath(); const std::vector<std::string>& bcp_locations = runtime->GetBootClassPathLocations(); + const std::vector<std::string>& image_locations = runtime->GetImageLocations(); const std::string bcp_locations_path = android::base::Join(bcp_locations, ':'); if (!ImageSpace::VerifyBootClassPathChecksums(checksums, bcp_locations_path, - runtime->GetImageLocation(), + ArrayRef<const std::string>(image_locations), ArrayRef<const std::string>(bcp_locations), ArrayRef<const std::string>(bcp), runtime->GetInstructionSet(), diff --git a/runtime/dexopt_test.cc b/runtime/dexopt_test.cc index cfd7f9125f..9b5b473da0 100644 --- a/runtime/dexopt_test.cc +++ b/runtime/dexopt_test.cc @@ -152,7 +152,7 @@ void DexoptTest::GenerateOatForTest(const std::string& dex_location, bool match = gc::space::ImageSpace::VerifyBootClassPathChecksums( checksums, oat_bcp, - image_location, + ArrayRef<const std::string>(&image_location, 1), ArrayRef<const std::string>(Runtime::Current()->GetBootClassPathLocations()), ArrayRef<const std::string>(Runtime::Current()->GetBootClassPath()), kRuntimeISA, diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index a3dd3c7c9a..93a594e49f 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -262,7 +262,7 @@ Heap::Heap(size_t initial_size, size_t non_moving_space_capacity, const std::vector<std::string>& boot_class_path, const std::vector<std::string>& boot_class_path_locations, - const std::string& image_file_name, + const std::vector<std::string>& image_file_names, const InstructionSet image_instruction_set, CollectorType foreground_collector_type, CollectorType background_collector_type, @@ -462,7 +462,7 @@ Heap::Heap(size_t initial_size, MemMap heap_reservation; if (space::ImageSpace::LoadBootImage(boot_class_path, boot_class_path_locations, - image_file_name, + image_file_names, image_instruction_set, runtime->ShouldRelocate(), /*executable=*/ !runtime->IsAotCompiler(), diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h index 31075b1feb..bd899bc326 100644 --- a/runtime/gc/heap.h +++ b/runtime/gc/heap.h @@ -201,7 +201,7 @@ class Heap { size_t non_moving_space_capacity, const std::vector<std::string>& boot_class_path, const std::vector<std::string>& boot_class_path_locations, - const std::string& image_file_name, + const std::vector<std::string>& image_file_names, InstructionSet image_instruction_set, CollectorType foreground_collector_type, CollectorType background_collector_type, diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc index 1627d7857f..5ee126cc65 100644 --- a/runtime/gc/space/image_space.cc +++ b/runtime/gc/space/image_space.cc @@ -1411,10 +1411,10 @@ class ImageSpace::BootImageLayout { mutable android::base::unique_fd oat_fd; }; - BootImageLayout(const std::string& image_location, + BootImageLayout(ArrayRef<const std::string> image_locations, ArrayRef<const std::string> boot_class_path, ArrayRef<const std::string> boot_class_path_locations) - : image_location_(image_location), + : image_locations_(image_locations), boot_class_path_(boot_class_path), boot_class_path_locations_(boot_class_path_locations) {} @@ -1485,7 +1485,7 @@ class ImageSpace::BootImageLayout { return boot_class_path_[bcp_index].substr(0u, bcp_slash_pos + 1u); } - bool VerifyImageLocation(const std::vector<std::string>& components, + bool VerifyImageLocation(ArrayRef<const std::string> components, /*out*/size_t* named_components_count, /*out*/std::string* error_msg); @@ -1512,7 +1512,7 @@ class ImageSpace::BootImageLayout { const std::string& base_filename, size_t bcp_index, const std::string& profile_filename, - ArrayRef<std::string> dependencies, + ArrayRef<const std::string> dependencies, /*out*/std::string* error_msg); bool CheckAndRemoveLastChunkChecksum(/*inout*/std::string_view* oat_checksums, @@ -1527,7 +1527,7 @@ class ImageSpace::BootImageLayout { /*inout*/std::string_view* oat_checksums, /*out*/std::string* error_msg); - const std::string& image_location_; + ArrayRef<const std::string> image_locations_; ArrayRef<const std::string> boot_class_path_; ArrayRef<const std::string> boot_class_path_locations_; @@ -1539,15 +1539,8 @@ class ImageSpace::BootImageLayout { }; std::string ImageSpace::BootImageLayout::GetPrimaryImageLocation() { - size_t location_start = 0u; - size_t location_end = image_location_.find(kComponentSeparator); - while (location_end == location_start) { - ++location_start; - location_end = image_location_.find(location_start, kComponentSeparator); - } - std::string location = (location_end == std::string::npos) - ? image_location_.substr(location_start) - : image_location_.substr(location_start, location_end - location_start); + DCHECK(!image_locations_.empty()); + std::string location = image_locations_[0]; if (location.find('/') == std::string::npos) { // No path, so use the path from the first boot class path component. size_t slash_pos = boot_class_path_.empty() @@ -1562,7 +1555,7 @@ std::string ImageSpace::BootImageLayout::GetPrimaryImageLocation() { } bool ImageSpace::BootImageLayout::VerifyImageLocation( - const std::vector<std::string>& components, + ArrayRef<const std::string> components, /*out*/size_t* named_components_count, /*out*/std::string* error_msg) { DCHECK(named_components_count != nullptr); @@ -1853,7 +1846,7 @@ bool ImageSpace::BootImageLayout::CompileExtension(const std::string& base_locat const std::string& base_filename, size_t bcp_index, const std::string& profile_filename, - ArrayRef<std::string> dependencies, + ArrayRef<const std::string> dependencies, /*out*/std::string* error_msg) { DCHECK_LE(total_component_count_, next_bcp_index_); DCHECK_LE(next_bcp_index_, bcp_index); @@ -2080,8 +2073,7 @@ bool ImageSpace::BootImageLayout::LoadOrValidate(FilenameFn&& filename_fn, static_assert(ImageSpace::kImageChecksumPrefix == 'i', "Format prefix check."); DCHECK(!validate || StartsWith(*oat_checksums, "i")); - std::vector<std::string> components; - Split(image_location_, kComponentSeparator, &components); + ArrayRef<const std::string> components = image_locations_; size_t named_components_count = 0u; if (!VerifyImageLocation(components, &named_components_count, error_msg)) { return false; @@ -2099,7 +2091,7 @@ bool ImageSpace::BootImageLayout::LoadOrValidate(FilenameFn&& filename_fn, DCHECK_EQ(named_component_locations.size(), named_components.size()); const size_t bcp_component_count = boot_class_path_.size(); size_t bcp_pos = 0u; - ArrayRef<std::string> extension_dependencies; + ArrayRef<const std::string> extension_dependencies; for (size_t i = 0, size = named_components.size(); i != size; ++i) { const std::string& base_location = named_component_locations[i].base_location; size_t bcp_index = named_component_locations[i].bcp_index; @@ -2107,8 +2099,7 @@ bool ImageSpace::BootImageLayout::LoadOrValidate(FilenameFn&& filename_fn, if (extension_dependencies.empty() && !profile_filename.empty()) { // Each extension is compiled against the same dependencies, namely the leading // named components that were specified without providing the profile filename. - extension_dependencies = - ArrayRef<std::string>(components).SubArray(/*pos=*/ 0, /*length=*/ i); + extension_dependencies = components.SubArray(/*pos=*/ 0, /*length=*/ i); } if (bcp_index < bcp_pos) { DCHECK_NE(i, 0u); @@ -2158,8 +2149,7 @@ bool ImageSpace::BootImageLayout::LoadOrValidate(FilenameFn&& filename_fn, } // Look for remaining components if there are any wildcard specifications. - ArrayRef<const std::string> search_paths = - ArrayRef<const std::string>(components).SubArray(/*pos=*/ named_components_count); + ArrayRef<const std::string> search_paths = components.SubArray(/*pos=*/ named_components_count); if (!search_paths.empty()) { const std::string& primary_base_location = named_component_locations[0].base_location; size_t base_slash_pos = primary_base_location.rfind('/'); @@ -2229,13 +2219,13 @@ class ImageSpace::BootImageLoader { public: BootImageLoader(const std::vector<std::string>& boot_class_path, const std::vector<std::string>& boot_class_path_locations, - const std::string& image_location, + const std::vector<std::string>& image_locations, InstructionSet image_isa, bool relocate, bool executable) : boot_class_path_(boot_class_path), boot_class_path_locations_(boot_class_path_locations), - image_location_(image_location), + image_locations_(image_locations), image_isa_(image_isa), relocate_(relocate), executable_(executable), @@ -2243,7 +2233,7 @@ class ImageSpace::BootImageLoader { } void FindImageFiles() { - BootImageLayout layout(image_location_, boot_class_path_, boot_class_path_locations_); + BootImageLayout layout(image_locations_, boot_class_path_, boot_class_path_locations_); std::string image_location = layout.GetPrimaryImageLocation(); std::string system_filename; bool found_image = FindImageFilenameImpl(image_location.c_str(), @@ -3101,7 +3091,7 @@ class ImageSpace::BootImageLoader { const ArrayRef<const std::string> boot_class_path_; const ArrayRef<const std::string> boot_class_path_locations_; - const std::string image_location_; + const ArrayRef<const std::string> image_locations_; const InstructionSet image_isa_; const bool relocate_; const bool executable_; @@ -3115,7 +3105,7 @@ bool ImageSpace::BootImageLoader::LoadFromSystem( /*out*/std::string* error_msg) { TimingLogger logger(__PRETTY_FUNCTION__, /*precise=*/ true, VLOG_IS_ON(image)); - BootImageLayout layout(image_location_, boot_class_path_, boot_class_path_locations_); + BootImageLayout layout(image_locations_, boot_class_path_, boot_class_path_locations_); if (!layout.LoadFromSystem(image_isa_, error_msg)) { return false; } @@ -3140,7 +3130,7 @@ bool ImageSpace::BootImageLoader::LoadFromSystem( bool ImageSpace::IsBootClassPathOnDisk(InstructionSet image_isa) { Runtime* runtime = Runtime::Current(); - BootImageLayout layout(runtime->GetImageLocation(), + BootImageLayout layout(ArrayRef<const std::string>(runtime->GetImageLocations()), ArrayRef<const std::string>(runtime->GetBootClassPath()), ArrayRef<const std::string>(runtime->GetBootClassPathLocations())); const std::string image_location = layout.GetPrimaryImageLocation(); @@ -3164,7 +3154,7 @@ bool ImageSpace::IsBootClassPathOnDisk(InstructionSet image_isa) { bool ImageSpace::LoadBootImage( const std::vector<std::string>& boot_class_path, const std::vector<std::string>& boot_class_path_locations, - const std::string& image_location, + const std::vector<std::string>& image_locations, const InstructionSet image_isa, bool relocate, bool executable, @@ -3179,13 +3169,13 @@ bool ImageSpace::LoadBootImage( DCHECK(extra_reservation != nullptr); DCHECK_NE(image_isa, InstructionSet::kNone); - if (image_location.empty()) { + if (image_locations.empty()) { return false; } BootImageLoader loader(boot_class_path, boot_class_path_locations, - image_location, + image_locations, image_isa, relocate, executable); @@ -3216,8 +3206,9 @@ bool ImageSpace::LoadBootImage( oss << msg; } - LOG(ERROR) << "Could not create image space with image file '" << image_location << "'. " - << "Attempting to fall back to imageless running. Error was: " << oss.str(); + LOG(ERROR) << "Could not create image space with image file '" + << Join(image_locations, kComponentSeparator) << "'. Attempting to fall back to imageless " + << "running. Error was: " << oss.str(); return false; } @@ -3426,7 +3417,7 @@ static size_t CheckAndCountBCPComponents(std::string_view oat_boot_class_path, bool ImageSpace::VerifyBootClassPathChecksums(std::string_view oat_checksums, std::string_view oat_boot_class_path, - const std::string& image_location, + ArrayRef<const std::string> image_locations, ArrayRef<const std::string> boot_class_path_locations, ArrayRef<const std::string> boot_class_path, InstructionSet image_isa, @@ -3447,7 +3438,7 @@ bool ImageSpace::VerifyBootClassPathChecksums(std::string_view oat_checksums, size_t bcp_pos = 0u; if (StartsWith(oat_checksums, "i")) { // Use only the matching part of the BCP for validation. - BootImageLayout layout(image_location, + BootImageLayout layout(image_locations, boot_class_path.SubArray(/*pos=*/ 0u, bcp_size), boot_class_path_locations.SubArray(/*pos=*/ 0u, bcp_size)); std::string primary_image_location = layout.GetPrimaryImageLocation(); @@ -3458,7 +3449,7 @@ bool ImageSpace::VerifyBootClassPathChecksums(std::string_view oat_checksums, &system_filename, &has_system)) { *error_msg = StringPrintf("Unable to find image file for %s and %s", - image_location.c_str(), + android::base::Join(image_locations, kComponentSeparator).c_str(), GetInstructionSetString(image_isa)); return false; } diff --git a/runtime/gc/space/image_space.h b/runtime/gc/space/image_space.h index 545f659c68..aa93247880 100644 --- a/runtime/gc/space/image_space.h +++ b/runtime/gc/space/image_space.h @@ -124,7 +124,7 @@ class ImageSpace : public MemMapSpace { static bool LoadBootImage( const std::vector<std::string>& boot_class_path, const std::vector<std::string>& boot_class_path_locations, - const std::string& image_location, + const std::vector<std::string>& image_locations, const InstructionSet image_isa, bool relocate, bool executable, @@ -233,7 +233,7 @@ class ImageSpace : public MemMapSpace { // The boot image and dex files do not need to be loaded in memory. static bool VerifyBootClassPathChecksums(std::string_view oat_checksums, std::string_view oat_boot_class_path, - const std::string& image_location, + ArrayRef<const std::string> image_locations, ArrayRef<const std::string> boot_class_path_locations, ArrayRef<const std::string> boot_class_path, InstructionSet image_isa, diff --git a/runtime/gc/space/image_space_test.cc b/runtime/gc/space/image_space_test.cc index 885dd218de..1a53efae48 100644 --- a/runtime/gc/space/image_space_test.cc +++ b/runtime/gc/space/image_space_test.cc @@ -128,7 +128,7 @@ TEST_F(ImageSpaceTest, StringDeduplication) { ASSERT_TRUE(success) << error_msg; } - std::string full_image_locations; + std::vector<std::string> full_image_locations; std::vector<std::unique_ptr<gc::space::ImageSpace>> boot_image_spaces; MemMap extra_reservation; auto load_boot_image = [&]() REQUIRES_SHARED(Locks::mutator_lock_) { @@ -165,9 +165,9 @@ TEST_F(ImageSpaceTest, StringDeduplication) { // Load extensions and test for the presence of the test string. ScopedObjectAccess soa(Thread::Current()); ASSERT_EQ(2u, extension_image_locations.size()); - full_image_locations = base_image_location + - ImageSpace::kComponentSeparator + extension_image_locations[0] + - ImageSpace::kComponentSeparator + extension_image_locations[1]; + full_image_locations = { + base_image_location, extension_image_locations[0], extension_image_locations[1] + }; bool success = load_boot_image(); ASSERT_TRUE(success); ASSERT_EQ(bcp.size(), boot_image_spaces.size()); @@ -178,9 +178,9 @@ TEST_F(ImageSpaceTest, StringDeduplication) { // Reload extensions in reverse order and test for the presence of the test string. std::swap(bcp[bcp.size() - 2u], bcp[bcp.size() - 1u]); std::swap(bcp_locations[bcp_locations.size() - 2u], bcp_locations[bcp_locations.size() - 1u]); - full_image_locations = base_image_location + - ImageSpace::kComponentSeparator + extension_image_locations[1] + - ImageSpace::kComponentSeparator + extension_image_locations[0]; + full_image_locations = { + base_image_location, extension_image_locations[1], extension_image_locations[0] + }; success = load_boot_image(); ASSERT_TRUE(success); ASSERT_EQ(bcp.size(), boot_image_spaces.size()); @@ -191,8 +191,7 @@ TEST_F(ImageSpaceTest, StringDeduplication) { // Reload the image without the second extension. bcp.erase(bcp.end() - 2u); bcp_locations.erase(bcp_locations.end() - 2u); - full_image_locations = - base_image_location + ImageSpace::kComponentSeparator + extension_image_locations[0]; + full_image_locations = {base_image_location, extension_image_locations[0]}; success = load_boot_image(); ASSERT_TRUE(success); ASSERT_EQ(bcp.size(), boot_image_spaces.size()); @@ -334,7 +333,7 @@ TEST_F(DexoptTest, Checksums) { return gc::space::ImageSpace::VerifyBootClassPathChecksums( checksums, android::base::Join(bcp_locations, ':'), - runtime->GetImageLocation(), + ArrayRef<const std::string>(runtime->GetImageLocations()), ArrayRef<const std::string>(bcp_locations), ArrayRef<const std::string>(bcp), kRuntimeISA, diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc index c74f19bab5..a5ccb69b30 100644 --- a/runtime/oat_file_assistant.cc +++ b/runtime/oat_file_assistant.cc @@ -649,7 +649,7 @@ bool OatFileAssistant::ValidateBootClassPathChecksums(const OatFile& oat_file) { bool result = gc::space::ImageSpace::VerifyBootClassPathChecksums( oat_boot_class_path_checksums_view, oat_boot_class_path_view, - runtime->GetImageLocation(), + ArrayRef<const std::string>(runtime->GetImageLocations()), ArrayRef<const std::string>(runtime->GetBootClassPathLocations()), ArrayRef<const std::string>(runtime->GetBootClassPath()), isa_, diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc index f896511679..fec2587f3c 100644 --- a/runtime/parsed_options.cc +++ b/runtime/parsed_options.cc @@ -166,7 +166,7 @@ std::unique_ptr<RuntimeParser> ParsedOptions::MakeParser(bool ignore_unrecognize .IntoKey(M::JITCompileThreshold) .SetCategory("ART") .Define("-Ximage:_") - .WithType<std::string>() + .WithType<ParseStringList<':'>>() .IntoKey(M::Image) .Define("-Xprimaryzygote") .IntoKey(M::PrimaryZygote) @@ -733,8 +733,8 @@ bool ParsedOptions::DoParse(const RuntimeOptions& options, } if (!args.Exists(M::CompilerCallbacksPtr) && !args.Exists(M::Image)) { - std::string image = GetDefaultBootImageLocation(GetAndroidRoot()); - args.Set(M::Image, image); + std::string image_locations = GetDefaultBootImageLocation(GetAndroidRoot()); + args.Set(M::Image, ParseStringList<':'>::Split(image_locations)); } // 0 means no growth limit, and growth limit should be always <= heap size diff --git a/runtime/parsed_options_test.cc b/runtime/parsed_options_test.cc index 8873eb9c60..b9ca98883e 100644 --- a/runtime/parsed_options_test.cc +++ b/runtime/parsed_options_test.cc @@ -86,7 +86,9 @@ TEST_F(ParsedOptionsTest, ParsedOptions) { EXPECT_PARSED_EQ_AS_STRING_VECTOR(expected_boot_class_path, Opt::BootClassPath); EXPECT_PARSED_EQ(class_path, Opt::ClassPath); - EXPECT_PARSED_EQ(std::string("boot_image"), Opt::Image); + std::vector<std::string> boot_images = map.GetOrDefault(Opt::Image); + ASSERT_EQ(1U, boot_images.size()); + EXPECT_EQ(std::string("boot_image"), boot_images[0]); EXPECT_PARSED_EXISTS(Opt::CheckJni); EXPECT_PARSED_EQ(2048U, Opt::MemoryInitialSize); EXPECT_PARSED_EQ(4 * KB, Opt::MemoryMaximumSize); diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 38f8ce1039..97c1d6dea7 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -1342,7 +1342,7 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { Monitor::Init(runtime_options.GetOrDefault(Opt::LockProfThreshold), runtime_options.GetOrDefault(Opt::StackDumpLockProfThreshold)); - image_location_ = runtime_options.GetOrDefault(Opt::Image); + image_locations_ = runtime_options.ReleaseOrDefault(Opt::Image); SetInstructionSet(runtime_options.GetOrDefault(Opt::ImageInstructionSet)); boot_class_path_ = runtime_options.ReleaseOrDefault(Opt::BootClassPath); @@ -1351,13 +1351,14 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { boot_class_path_locations_.size() == boot_class_path_.size()); if (boot_class_path_.empty()) { // Try to extract the boot class path from the system boot image. - if (image_location_.empty()) { + if (image_locations_.empty()) { LOG(ERROR) << "Empty boot class path, cannot continue without image."; return false; } std::string system_oat_filename = ImageHeader::GetOatLocationFromImageLocation( - GetSystemImageFilename(image_location_.c_str(), instruction_set_)); - std::string system_oat_location = ImageHeader::GetOatLocationFromImageLocation(image_location_); + GetSystemImageFilename(image_locations_[0].c_str(), instruction_set_)); + std::string system_oat_location = ImageHeader::GetOatLocationFromImageLocation( + image_locations_[0]); std::string error_msg; std::unique_ptr<OatFile> oat_file(OatFile::Open(/*zip_fd=*/ -1, system_oat_filename, @@ -1503,7 +1504,7 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { runtime_options.GetOrDefault(Opt::NonMovingSpaceCapacity), GetBootClassPath(), GetBootClassPathLocations(), - image_location_, + image_locations_, instruction_set_, // Override the collector type to CC if the read barrier config. kUseReadBarrier ? gc::kCollectorTypeCC : xgc_option.collector_type_, diff --git a/runtime/runtime.h b/runtime/runtime.h index 88f7bc0240..9664977577 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -212,8 +212,8 @@ class Runtime { return image_compiler_options_; } - const std::string& GetImageLocation() const { - return image_location_; + const std::vector<std::string>& GetImageLocations() const { + return image_locations_; } // Starts a runtime, which may cause threads to be started and code to run. @@ -1089,7 +1089,7 @@ class Runtime { std::string compiler_executable_; std::vector<std::string> compiler_options_; std::vector<std::string> image_compiler_options_; - std::string image_location_; + std::vector<std::string> image_locations_; std::vector<std::string> boot_class_path_; std::vector<std::string> boot_class_path_locations_; diff --git a/runtime/runtime_options.def b/runtime/runtime_options.def index 3f0e3cca59..9667484fba 100644 --- a/runtime/runtime_options.def +++ b/runtime/runtime_options.def @@ -41,7 +41,7 @@ RUNTIME_OPTIONS_KEY (Unit, ShowVersion) RUNTIME_OPTIONS_KEY (ParseStringList<':'>,BootClassPath) // std::vector<std::string> RUNTIME_OPTIONS_KEY (ParseStringList<':'>,BootClassPathLocations) // std::vector<std::string> RUNTIME_OPTIONS_KEY (std::string, ClassPath) -RUNTIME_OPTIONS_KEY (std::string, Image) +RUNTIME_OPTIONS_KEY (ParseStringList<':'>,Image) RUNTIME_OPTIONS_KEY (Unit, CheckJni) RUNTIME_OPTIONS_KEY (Unit, JniOptsForceCopy) RUNTIME_OPTIONS_KEY (std::string, JdwpOptions, "suspend=n,server=y") |