Remove back-door bootclasspath option from Runtime

The 'bootclasspath' option allowed users of the Runtime to load their
own boot class path DexFiles and pass them directly to the Runtime as
an option. This obscures the fact that the Runtime must take ownership
of the boot class path DexFiles.

This change removes the use of the bootclasspath option by dex2oat and
the common runtime tests. For dex2oat, we use the existing
-Xbootclasspath option instead, and introduce a new
-Xbootclasspath-locations option to override the dex locations for the
loaded boot class path dex files. For the common runtime tests, we
simply use -Xbootclasspath.

Bug: 18809837
Change-Id: Idfcd4885390bf0f3dc350993756dd337220def73
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index a2c9f50..fb6034d 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -683,6 +683,7 @@
 
 
 static size_t OpenDexFiles(const std::vector<std::string>& dex_filenames,
+                           const std::vector<std::string>& dex_locations,
                            const std::string& image_location,
                            std::vector<const DexFile*>& dex_files) {
   size_t failure_count = 0;
@@ -692,12 +693,13 @@
   failure_count = 0;
   for (size_t i = 0; i < dex_filenames.size(); i++) {
     const char* dex_filename = dex_filenames[i].c_str();
+    const char* dex_location = dex_locations[i].c_str();
     std::string error_msg;
     if (!OS::FileExists(dex_filename)) {
       LOG(WARNING) << "Skipping non-existent dex file '" << dex_filename << "'";
       continue;
     }
-    if (!DexFile::Open(dex_filename, dex_filename, &error_msg, &dex_files)) {
+    if (!DexFile::Open(dex_filename, dex_location, &error_msg, &dex_files)) {
       LOG(WARNING) << "Failed to open .dex from file '" << dex_filename << "': " << error_msg;
       ++failure_count;
     }
@@ -858,17 +860,25 @@
 
   CHECK_GE(GetHeap()->GetContinuousSpaces().size(), 1U);
   class_linker_ = new ClassLinker(intern_table_);
-  bool options_class_path_used = false;
   if (GetHeap()->HasImageSpace()) {
     class_linker_->InitFromImage();
     if (kIsDebugBuild) {
       GetHeap()->GetImageSpace()->VerifyImageAllocations();
     }
-  } else if (!IsCompiler() || !image_dex2oat_enabled_) {
+  } else {
     std::vector<std::string> dex_filenames;
     Split(boot_class_path_string_, ':', &dex_filenames);
+
+    std::vector<std::string> dex_locations;
+    if (options->boot_class_path_locations_string_.empty()) {
+      dex_locations = dex_filenames;
+    } else {
+      Split(options->boot_class_path_locations_string_, ':', &dex_locations);
+      CHECK_EQ(dex_filenames.size(), dex_locations.size());
+    }
+
     std::vector<const DexFile*> boot_class_path;
-    OpenDexFiles(dex_filenames, options->image_, boot_class_path);
+    OpenDexFiles(dex_filenames, dex_locations, options->image_, boot_class_path);
     class_linker_->InitWithoutImage(boot_class_path);
     // TODO: Should we move the following to InitWithoutImage?
     SetInstructionSet(kRuntimeISA);
@@ -878,18 +888,6 @@
         SetCalleeSaveMethod(CreateCalleeSaveMethod(), type);
       }
     }
-  } else {
-    CHECK(options->boot_class_path_ != nullptr);
-    CHECK_NE(options->boot_class_path_->size(), 0U);
-    class_linker_->InitWithoutImage(*options->boot_class_path_);
-    options_class_path_used = true;
-  }
-
-  if (!options_class_path_used) {
-    // If the class linker does not take ownership of the boot class path, wipe it to prevent leaks.
-    auto boot_class_path_vector_ptr =
-        const_cast<std::vector<const DexFile*>*>(options->boot_class_path_);
-    STLDeleteElements(boot_class_path_vector_ptr);
   }
 
   CHECK(class_linker_ != nullptr);