summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mathieu Chartier <mathieuc@google.com> 2016-03-08 16:50:20 -0800
committer Mathieu Chartier <mathieuc@google.com> 2016-03-09 11:03:13 -0800
commit8b8f6d6e85f46718b6865c962614d3d34fd33db0 (patch)
treecf94cc6ada04966bd4bcbf072b3bd1555d6bdcbf
parent2048b01dfec8877d672a4da41a158f68b12b5337 (diff)
Use per character suffix for multi image
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
-rw-r--r--runtime/gc/space/image_space.cc63
1 files changed, 22 insertions, 41 deletions
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index a4e558728e..9ecd391e4d 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -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);
}
}