OSDN Git Service

Use per character suffix for multi image
authorMathieu Chartier <mathieuc@google.com>
Wed, 9 Mar 2016 00:50:20 +0000 (16:50 -0800)
committerMathieu Chartier <mathieuc@google.com>
Wed, 9 Mar 2016 19:03:13 +0000 (11:03 -0800)
E.g. if you pull the oat files from the device, you get oat files
with the following names:
system@framework@boot.art

But the name stored in the image header is:
boot.art

So we need to append system@framework@ as a file name prefix to each
image file to get the actual one.

Required for adding oatdump support for app images.

Bug: 22858531
Bug: 27408512

(cherry picked from commit 05752398db7f25d7892b62cb39615eee468f1db8)

Change-Id: Ia6fb34b137c5e285818d39c3b9794cd4ce6c3219

runtime/gc/space/image_space.cc

index a4e5587..9ecd391 100644 (file)
@@ -1535,50 +1535,31 @@ void ImageSpace::CreateMultiImageLocations(const std::string& input_image_file_n
   //              images[0] is          f/c/d/e.art
   // ----------------------------------------------
   //              images[1] is          g/h/i/j.art  -> /a/b/h/i/j.art
-
-  // Derive pattern.
-  std::vector<std::string> left;
-  Split(input_image_file_name, '/', &left);
-  std::vector<std::string> right;
-  Split(images[0], '/', &right);
-
-  size_t common = 1;
-  while (common < left.size() && common < right.size()) {
-    if (left[left.size() - common - 1] != right[right.size() - common - 1]) {
-      break;
-    }
-    common++;
-  }
-
-  std::vector<std::string> prefix_vector(left.begin(), left.end() - common);
-  std::string common_prefix = Join(prefix_vector, '/');
-  if (!common_prefix.empty() && common_prefix[0] != '/' && input_image_file_name[0] == '/') {
-    common_prefix = "/" + common_prefix;
-  }
+  const std::string& first_image = images[0];
+  // Length of common suffix.
+  size_t common = 0;
+  while (common < input_image_file_name.size() &&
+         common < first_image.size() &&
+         *(input_image_file_name.end() - common - 1) == *(first_image.end() - common - 1)) {
+    ++common;
+  }
+  // We want to replace the prefix of the input image with the prefix of the boot class path.
+  // This handles the case where the image file contains @ separators.
+  // Example image_file_name is oats/system@framework@boot.art
+  // images[0] is .../arm/boot.art
+  // means that the image name prefix will be oats/system@framework@
+  // so that the other images are openable.
+  const size_t old_prefix_length = first_image.size() - common;
+  const std::string new_prefix = input_image_file_name.substr(
+      0,
+      input_image_file_name.size() - common);
 
   // Apply pattern to images[1] .. images[n].
   for (size_t i = 1; i < images.size(); ++i) {
-    std::string image = images[i];
-
-    size_t rslash = std::string::npos;
-    for (size_t j = 0; j < common; ++j) {
-      if (rslash != std::string::npos) {
-        rslash--;
-      }
-
-      rslash = image.rfind('/', rslash);
-      if (rslash == std::string::npos) {
-        rslash = 0;
-      }
-      if (rslash == 0) {
-        break;
-      }
-    }
-    std::string image_part = image.substr(rslash);
-
-    std::string new_image = common_prefix + (StartsWith(image_part, "/") ? "" : "/") +
-        image_part;
-    image_file_names->push_back(new_image);
+    const std::string& image = images[i];
+    CHECK_GT(image.length(), old_prefix_length);
+    std::string suffix = image.substr(old_prefix_length);
+    image_file_names->push_back(new_prefix + suffix);
   }
 }