Home | History | Annotate | Download | only in space
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "image_space.h"
     18 
     19 #include <sys/statvfs.h>
     20 #include <sys/types.h>
     21 #include <unistd.h>
     22 
     23 #include <random>
     24 
     25 #include "android-base/stringprintf.h"
     26 #include "android-base/strings.h"
     27 
     28 #include "arch/instruction_set.h"
     29 #include "art_field-inl.h"
     30 #include "art_method-inl.h"
     31 #include "base/array_ref.h"
     32 #include "base/bit_memory_region.h"
     33 #include "base/callee_save_type.h"
     34 #include "base/enums.h"
     35 #include "base/file_utils.h"
     36 #include "base/macros.h"
     37 #include "base/os.h"
     38 #include "base/scoped_flock.h"
     39 #include "base/stl_util.h"
     40 #include "base/systrace.h"
     41 #include "base/time_utils.h"
     42 #include "base/utils.h"
     43 #include "class_root.h"
     44 #include "dex/art_dex_file_loader.h"
     45 #include "dex/dex_file_loader.h"
     46 #include "exec_utils.h"
     47 #include "gc/accounting/space_bitmap-inl.h"
     48 #include "gc/task_processor.h"
     49 #include "image-inl.h"
     50 #include "image_space_fs.h"
     51 #include "intern_table-inl.h"
     52 #include "mirror/class-inl.h"
     53 #include "mirror/executable-inl.h"
     54 #include "mirror/object-inl.h"
     55 #include "mirror/object-refvisitor-inl.h"
     56 #include "oat_file.h"
     57 #include "runtime.h"
     58 #include "space-inl.h"
     59 
     60 namespace art {
     61 namespace gc {
     62 namespace space {
     63 
     64 using android::base::StringAppendF;
     65 using android::base::StringPrintf;
     66 
     67 Atomic<uint32_t> ImageSpace::bitmap_index_(0);
     68 
     69 ImageSpace::ImageSpace(const std::string& image_filename,
     70                        const char* image_location,
     71                        MemMap&& mem_map,
     72                        std::unique_ptr<accounting::ContinuousSpaceBitmap> live_bitmap,
     73                        uint8_t* end)
     74     : MemMapSpace(image_filename,
     75                   std::move(mem_map),
     76                   mem_map.Begin(),
     77                   end,
     78                   end,
     79                   kGcRetentionPolicyNeverCollect),
     80       live_bitmap_(std::move(live_bitmap)),
     81       oat_file_non_owned_(nullptr),
     82       image_location_(image_location) {
     83   DCHECK(live_bitmap_ != nullptr);
     84 }
     85 
     86 static int32_t ChooseRelocationOffsetDelta(int32_t min_delta, int32_t max_delta) {
     87   CHECK_ALIGNED(min_delta, kPageSize);
     88   CHECK_ALIGNED(max_delta, kPageSize);
     89   CHECK_LT(min_delta, max_delta);
     90 
     91   int32_t r = GetRandomNumber<int32_t>(min_delta, max_delta);
     92   if (r % 2 == 0) {
     93     r = RoundUp(r, kPageSize);
     94   } else {
     95     r = RoundDown(r, kPageSize);
     96   }
     97   CHECK_LE(min_delta, r);
     98   CHECK_GE(max_delta, r);
     99   CHECK_ALIGNED(r, kPageSize);
    100   return r;
    101 }
    102 
    103 static int32_t ChooseRelocationOffsetDelta() {
    104   return ChooseRelocationOffsetDelta(ART_BASE_ADDRESS_MIN_DELTA, ART_BASE_ADDRESS_MAX_DELTA);
    105 }
    106 
    107 static bool GenerateImage(const std::string& image_filename,
    108                           InstructionSet image_isa,
    109                           std::string* error_msg) {
    110   Runtime* runtime = Runtime::Current();
    111   const std::vector<std::string>& boot_class_path = runtime->GetBootClassPath();
    112   if (boot_class_path.empty()) {
    113     *error_msg = "Failed to generate image because no boot class path specified";
    114     return false;
    115   }
    116   // We should clean up so we are more likely to have room for the image.
    117   if (Runtime::Current()->IsZygote()) {
    118     LOG(INFO) << "Pruning dalvik-cache since we are generating an image and will need to recompile";
    119     PruneDalvikCache(image_isa);
    120   }
    121 
    122   std::vector<std::string> arg_vector;
    123 
    124   std::string dex2oat(Runtime::Current()->GetCompilerExecutable());
    125   arg_vector.push_back(dex2oat);
    126 
    127   char* dex2oat_bcp = getenv("DEX2OATBOOTCLASSPATH");
    128   std::vector<std::string> dex2oat_bcp_vector;
    129   if (dex2oat_bcp != nullptr) {
    130     arg_vector.push_back("--runtime-arg");
    131     arg_vector.push_back(StringPrintf("-Xbootclasspath:%s", dex2oat_bcp));
    132     Split(dex2oat_bcp, ':', &dex2oat_bcp_vector);
    133   }
    134 
    135   std::string image_option_string("--image=");
    136   image_option_string += image_filename;
    137   arg_vector.push_back(image_option_string);
    138 
    139   if (!dex2oat_bcp_vector.empty()) {
    140     for (size_t i = 0u; i < dex2oat_bcp_vector.size(); i++) {
    141       arg_vector.push_back(std::string("--dex-file=") + dex2oat_bcp_vector[i]);
    142       arg_vector.push_back(std::string("--dex-location=") + dex2oat_bcp_vector[i]);
    143     }
    144   } else {
    145     const std::vector<std::string>& boot_class_path_locations =
    146         runtime->GetBootClassPathLocations();
    147     DCHECK_EQ(boot_class_path.size(), boot_class_path_locations.size());
    148     for (size_t i = 0u; i < boot_class_path.size(); i++) {
    149       arg_vector.push_back(std::string("--dex-file=") + boot_class_path[i]);
    150       arg_vector.push_back(std::string("--dex-location=") + boot_class_path_locations[i]);
    151     }
    152   }
    153 
    154   std::string oat_file_option_string("--oat-file=");
    155   oat_file_option_string += ImageHeader::GetOatLocationFromImageLocation(image_filename);
    156   arg_vector.push_back(oat_file_option_string);
    157 
    158   // Note: we do not generate a fully debuggable boot image so we do not pass the
    159   // compiler flag --debuggable here.
    160 
    161   Runtime::Current()->AddCurrentRuntimeFeaturesAsDex2OatArguments(&arg_vector);
    162   CHECK_EQ(image_isa, kRuntimeISA)
    163       << "We should always be generating an image for the current isa.";
    164 
    165   int32_t base_offset = ChooseRelocationOffsetDelta();
    166   LOG(INFO) << "Using an offset of 0x" << std::hex << base_offset << " from default "
    167             << "art base address of 0x" << std::hex << ART_BASE_ADDRESS;
    168   arg_vector.push_back(StringPrintf("--base=0x%x", ART_BASE_ADDRESS + base_offset));
    169 
    170   if (!kIsTargetBuild) {
    171     arg_vector.push_back("--host");
    172   }
    173 
    174   const std::vector<std::string>& compiler_options = Runtime::Current()->GetImageCompilerOptions();
    175   for (size_t i = 0; i < compiler_options.size(); ++i) {
    176     arg_vector.push_back(compiler_options[i].c_str());
    177   }
    178 
    179   std::string command_line(android::base::Join(arg_vector, ' '));
    180   LOG(INFO) << "GenerateImage: " << command_line;
    181   return Exec(arg_vector, error_msg);
    182 }
    183 
    184 static bool FindImageFilenameImpl(const char* image_location,
    185                                   const InstructionSet image_isa,
    186                                   bool* has_system,
    187                                   std::string* system_filename,
    188                                   bool* dalvik_cache_exists,
    189                                   std::string* dalvik_cache,
    190                                   bool* is_global_cache,
    191                                   bool* has_cache,
    192                                   std::string* cache_filename) {
    193   DCHECK(dalvik_cache != nullptr);
    194 
    195   *has_system = false;
    196   *has_cache = false;
    197   // image_location = /system/framework/boot.art
    198   // system_image_location = /system/framework/<image_isa>/boot.art
    199   std::string system_image_filename(GetSystemImageFilename(image_location, image_isa));
    200   if (OS::FileExists(system_image_filename.c_str())) {
    201     *system_filename = system_image_filename;
    202     *has_system = true;
    203   }
    204 
    205   bool have_android_data = false;
    206   *dalvik_cache_exists = false;
    207   GetDalvikCache(GetInstructionSetString(image_isa),
    208                  /*create_if_absent=*/ true,
    209                  dalvik_cache,
    210                  &have_android_data,
    211                  dalvik_cache_exists,
    212                  is_global_cache);
    213 
    214   if (*dalvik_cache_exists) {
    215     DCHECK(have_android_data);
    216     // Always set output location even if it does not exist,
    217     // so that the caller knows where to create the image.
    218     //
    219     // image_location = /system/framework/boot.art
    220     // *image_filename = /data/dalvik-cache/<image_isa>/system@framework (at) boot.art
    221     std::string error_msg;
    222     if (!GetDalvikCacheFilename(image_location,
    223                                 dalvik_cache->c_str(),
    224                                 cache_filename,
    225                                 &error_msg)) {
    226       LOG(WARNING) << error_msg;
    227       return *has_system;
    228     }
    229     *has_cache = OS::FileExists(cache_filename->c_str());
    230   }
    231   return *has_system || *has_cache;
    232 }
    233 
    234 bool ImageSpace::FindImageFilename(const char* image_location,
    235                                    const InstructionSet image_isa,
    236                                    std::string* system_filename,
    237                                    bool* has_system,
    238                                    std::string* cache_filename,
    239                                    bool* dalvik_cache_exists,
    240                                    bool* has_cache,
    241                                    bool* is_global_cache) {
    242   std::string dalvik_cache_unused;
    243   return FindImageFilenameImpl(image_location,
    244                                image_isa,
    245                                has_system,
    246                                system_filename,
    247                                dalvik_cache_exists,
    248                                &dalvik_cache_unused,
    249                                is_global_cache,
    250                                has_cache,
    251                                cache_filename);
    252 }
    253 
    254 static bool ReadSpecificImageHeader(const char* filename, ImageHeader* image_header) {
    255     std::unique_ptr<File> image_file(OS::OpenFileForReading(filename));
    256     if (image_file.get() == nullptr) {
    257       return false;
    258     }
    259     const bool success = image_file->ReadFully(image_header, sizeof(ImageHeader));
    260     if (!success || !image_header->IsValid()) {
    261       return false;
    262     }
    263     return true;
    264 }
    265 
    266 static std::unique_ptr<ImageHeader> ReadSpecificImageHeader(const char* filename,
    267                                                             std::string* error_msg) {
    268   std::unique_ptr<ImageHeader> hdr(new ImageHeader);
    269   if (!ReadSpecificImageHeader(filename, hdr.get())) {
    270     *error_msg = StringPrintf("Unable to read image header for %s", filename);
    271     return nullptr;
    272   }
    273   return hdr;
    274 }
    275 
    276 std::unique_ptr<ImageHeader> ImageSpace::ReadImageHeader(const char* image_location,
    277                                                          const InstructionSet image_isa,
    278                                                          ImageSpaceLoadingOrder order,
    279                                                          std::string* error_msg) {
    280   std::string system_filename;
    281   bool has_system = false;
    282   std::string cache_filename;
    283   bool has_cache = false;
    284   bool dalvik_cache_exists = false;
    285   bool is_global_cache = false;
    286   if (FindImageFilename(image_location,
    287                         image_isa,
    288                         &system_filename,
    289                         &has_system,
    290                         &cache_filename,
    291                         &dalvik_cache_exists,
    292                         &has_cache,
    293                         &is_global_cache)) {
    294     if (order == ImageSpaceLoadingOrder::kSystemFirst) {
    295       if (has_system) {
    296         return ReadSpecificImageHeader(system_filename.c_str(), error_msg);
    297       }
    298       if (has_cache) {
    299         return ReadSpecificImageHeader(cache_filename.c_str(), error_msg);
    300       }
    301     } else {
    302       if (has_cache) {
    303         return ReadSpecificImageHeader(cache_filename.c_str(), error_msg);
    304       }
    305       if (has_system) {
    306         return ReadSpecificImageHeader(system_filename.c_str(), error_msg);
    307       }
    308     }
    309   }
    310 
    311   *error_msg = StringPrintf("Unable to find image file for %s", image_location);
    312   return nullptr;
    313 }
    314 
    315 static bool CanWriteToDalvikCache(const InstructionSet isa) {
    316   const std::string dalvik_cache = GetDalvikCache(GetInstructionSetString(isa));
    317   if (access(dalvik_cache.c_str(), O_RDWR) == 0) {
    318     return true;
    319   } else if (errno != EACCES) {
    320     PLOG(WARNING) << "CanWriteToDalvikCache returned error other than EACCES";
    321   }
    322   return false;
    323 }
    324 
    325 static bool ImageCreationAllowed(bool is_global_cache,
    326                                  const InstructionSet isa,
    327                                  bool is_zygote,
    328                                  std::string* error_msg) {
    329   // Anyone can write into a "local" cache.
    330   if (!is_global_cache) {
    331     return true;
    332   }
    333 
    334   // Only the zygote running as root is allowed to create the global boot image.
    335   // If the zygote is running as non-root (and cannot write to the dalvik-cache),
    336   // then image creation is not allowed..
    337   if (is_zygote) {
    338     return CanWriteToDalvikCache(isa);
    339   }
    340 
    341   *error_msg = "Only the zygote can create the global boot image.";
    342   return false;
    343 }
    344 
    345 void ImageSpace::VerifyImageAllocations() {
    346   uint8_t* current = Begin() + RoundUp(sizeof(ImageHeader), kObjectAlignment);
    347   while (current < End()) {
    348     CHECK_ALIGNED(current, kObjectAlignment);
    349     auto* obj = reinterpret_cast<mirror::Object*>(current);
    350     CHECK(obj->GetClass() != nullptr) << "Image object at address " << obj << " has null class";
    351     CHECK(live_bitmap_->Test(obj)) << obj->PrettyTypeOf();
    352     if (kUseBakerReadBarrier) {
    353       obj->AssertReadBarrierState();
    354     }
    355     current += RoundUp(obj->SizeOf(), kObjectAlignment);
    356   }
    357 }
    358 
    359 // Helper class for relocating from one range of memory to another.
    360 class RelocationRange {
    361  public:
    362   RelocationRange() = default;
    363   RelocationRange(const RelocationRange&) = default;
    364   RelocationRange(uintptr_t source, uintptr_t dest, uintptr_t length)
    365       : source_(source),
    366         dest_(dest),
    367         length_(length) {}
    368 
    369   bool InSource(uintptr_t address) const {
    370     return address - source_ < length_;
    371   }
    372 
    373   bool InDest(const void* dest) const {
    374     return InDest(reinterpret_cast<uintptr_t>(dest));
    375   }
    376 
    377   bool InDest(uintptr_t address) const {
    378     return address - dest_ < length_;
    379   }
    380 
    381   // Translate a source address to the destination space.
    382   uintptr_t ToDest(uintptr_t address) const {
    383     DCHECK(InSource(address));
    384     return address + Delta();
    385   }
    386 
    387   // Returns the delta between the dest from the source.
    388   uintptr_t Delta() const {
    389     return dest_ - source_;
    390   }
    391 
    392   uintptr_t Source() const {
    393     return source_;
    394   }
    395 
    396   uintptr_t Dest() const {
    397     return dest_;
    398   }
    399 
    400   uintptr_t Length() const {
    401     return length_;
    402   }
    403 
    404  private:
    405   const uintptr_t source_;
    406   const uintptr_t dest_;
    407   const uintptr_t length_;
    408 };
    409 
    410 std::ostream& operator<<(std::ostream& os, const RelocationRange& reloc) {
    411   return os << "(" << reinterpret_cast<const void*>(reloc.Source()) << "-"
    412             << reinterpret_cast<const void*>(reloc.Source() + reloc.Length()) << ")->("
    413             << reinterpret_cast<const void*>(reloc.Dest()) << "-"
    414             << reinterpret_cast<const void*>(reloc.Dest() + reloc.Length()) << ")";
    415 }
    416 
    417 template <PointerSize kPointerSize, typename HeapVisitor, typename NativeVisitor>
    418 class ImageSpace::PatchObjectVisitor final {
    419  public:
    420   explicit PatchObjectVisitor(HeapVisitor heap_visitor, NativeVisitor native_visitor)
    421       : heap_visitor_(heap_visitor), native_visitor_(native_visitor) {}
    422 
    423   void VisitClass(mirror::Class* klass) REQUIRES_SHARED(Locks::mutator_lock_) {
    424     // A mirror::Class object consists of
    425     //  - instance fields inherited from j.l.Object,
    426     //  - instance fields inherited from j.l.Class,
    427     //  - embedded tables (vtable, interface method table),
    428     //  - static fields of the class itself.
    429     // The reference fields are at the start of each field section (this is how the
    430     // ClassLinker orders fields; except when that would create a gap between superclass
    431     // fields and the first reference of the subclass due to alignment, it can be filled
    432     // with smaller fields - but that's not the case for j.l.Object and j.l.Class).
    433 
    434     DCHECK_ALIGNED(klass, kObjectAlignment);
    435     static_assert(IsAligned<kHeapReferenceSize>(kObjectAlignment), "Object alignment check.");
    436     // First, patch the `klass->klass_`, known to be a reference to the j.l.Class.class.
    437     // This should be the only reference field in j.l.Object and we assert that below.
    438     PatchReferenceField</*kMayBeNull=*/ false>(klass, mirror::Object::ClassOffset());
    439     // Then patch the reference instance fields described by j.l.Class.class.
    440     // Use the sizeof(Object) to determine where these reference fields start;
    441     // this is the same as `class_class->GetFirstReferenceInstanceFieldOffset()`
    442     // after patching but the j.l.Class may not have been patched yet.
    443     mirror::Class* class_class = klass->GetClass<kVerifyNone, kWithoutReadBarrier>();
    444     size_t num_reference_instance_fields = class_class->NumReferenceInstanceFields<kVerifyNone>();
    445     DCHECK_NE(num_reference_instance_fields, 0u);
    446     static_assert(IsAligned<kHeapReferenceSize>(sizeof(mirror::Object)), "Size alignment check.");
    447     MemberOffset instance_field_offset(sizeof(mirror::Object));
    448     for (size_t i = 0; i != num_reference_instance_fields; ++i) {
    449       PatchReferenceField(klass, instance_field_offset);
    450       static_assert(sizeof(mirror::HeapReference<mirror::Object>) == kHeapReferenceSize,
    451                     "Heap reference sizes equality check.");
    452       instance_field_offset =
    453           MemberOffset(instance_field_offset.Uint32Value() + kHeapReferenceSize);
    454     }
    455     // Now that we have patched the `super_class_`, if this is the j.l.Class.class,
    456     // we can get a reference to j.l.Object.class and assert that it has only one
    457     // reference instance field (the `klass_` patched above).
    458     if (kIsDebugBuild && klass == class_class) {
    459       ObjPtr<mirror::Class> object_class =
    460           klass->GetSuperClass<kVerifyNone, kWithoutReadBarrier>();
    461       CHECK_EQ(object_class->NumReferenceInstanceFields<kVerifyNone>(), 1u);
    462     }
    463     // Then patch static fields.
    464     size_t num_reference_static_fields = klass->NumReferenceStaticFields<kVerifyNone>();
    465     if (num_reference_static_fields != 0u) {
    466       MemberOffset static_field_offset =
    467           klass->GetFirstReferenceStaticFieldOffset<kVerifyNone>(kPointerSize);
    468       for (size_t i = 0; i != num_reference_static_fields; ++i) {
    469         PatchReferenceField(klass, static_field_offset);
    470         static_assert(sizeof(mirror::HeapReference<mirror::Object>) == kHeapReferenceSize,
    471                       "Heap reference sizes equality check.");
    472         static_field_offset =
    473             MemberOffset(static_field_offset.Uint32Value() + kHeapReferenceSize);
    474       }
    475     }
    476     // Then patch native pointers.
    477     klass->FixupNativePointers<kVerifyNone>(klass, kPointerSize, *this);
    478   }
    479 
    480   template <typename T>
    481   T* operator()(T* ptr, void** dest_addr ATTRIBUTE_UNUSED) const {
    482     return (ptr != nullptr) ? native_visitor_(ptr) : nullptr;
    483   }
    484 
    485   void VisitPointerArray(ObjPtr<mirror::PointerArray> pointer_array)
    486       REQUIRES_SHARED(Locks::mutator_lock_) {
    487     // Fully patch the pointer array, including the `klass_` field.
    488     PatchReferenceField</*kMayBeNull=*/ false>(pointer_array, mirror::Object::ClassOffset());
    489 
    490     int32_t length = pointer_array->GetLength<kVerifyNone>();
    491     for (int32_t i = 0; i != length; ++i) {
    492       ArtMethod** method_entry = reinterpret_cast<ArtMethod**>(
    493           pointer_array->ElementAddress<kVerifyNone>(i, kPointerSize));
    494       PatchNativePointer</*kMayBeNull=*/ false>(method_entry);
    495     }
    496   }
    497 
    498   void VisitObject(mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_) {
    499     // Visit all reference fields.
    500     object->VisitReferences</*kVisitNativeRoots=*/ false,
    501                             kVerifyNone,
    502                             kWithoutReadBarrier>(*this, *this);
    503     // This function should not be called for classes.
    504     DCHECK(!object->IsClass<kVerifyNone>());
    505   }
    506 
    507   // Visitor for VisitReferences().
    508   ALWAYS_INLINE void operator()(ObjPtr<mirror::Object> object,
    509                                 MemberOffset field_offset,
    510                                 bool is_static)
    511       const REQUIRES_SHARED(Locks::mutator_lock_) {
    512     DCHECK(!is_static);
    513     PatchReferenceField(object, field_offset);
    514   }
    515   // Visitor for VisitReferences(), java.lang.ref.Reference case.
    516   ALWAYS_INLINE void operator()(ObjPtr<mirror::Class> klass, ObjPtr<mirror::Reference> ref) const
    517       REQUIRES_SHARED(Locks::mutator_lock_) {
    518     DCHECK(klass->IsTypeOfReferenceClass());
    519     this->operator()(ref, mirror::Reference::ReferentOffset(), /*is_static=*/ false);
    520   }
    521   // Ignore class native roots; not called from VisitReferences() for kVisitNativeRoots == false.
    522   void VisitRootIfNonNull(mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED)
    523       const {}
    524   void VisitRoot(mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED) const {}
    525 
    526   void VisitDexCacheArrays(ObjPtr<mirror::DexCache> dex_cache)
    527       REQUIRES_SHARED(Locks::mutator_lock_) {
    528     FixupDexCacheArray<mirror::StringDexCacheType>(dex_cache,
    529                                                    mirror::DexCache::StringsOffset(),
    530                                                    dex_cache->NumStrings<kVerifyNone>());
    531     FixupDexCacheArray<mirror::TypeDexCacheType>(dex_cache,
    532                                                  mirror::DexCache::ResolvedTypesOffset(),
    533                                                  dex_cache->NumResolvedTypes<kVerifyNone>());
    534     FixupDexCacheArray<mirror::MethodDexCacheType>(dex_cache,
    535                                                    mirror::DexCache::ResolvedMethodsOffset(),
    536                                                    dex_cache->NumResolvedMethods<kVerifyNone>());
    537     FixupDexCacheArray<mirror::FieldDexCacheType>(dex_cache,
    538                                                   mirror::DexCache::ResolvedFieldsOffset(),
    539                                                   dex_cache->NumResolvedFields<kVerifyNone>());
    540     FixupDexCacheArray<mirror::MethodTypeDexCacheType>(
    541         dex_cache,
    542         mirror::DexCache::ResolvedMethodTypesOffset(),
    543         dex_cache->NumResolvedMethodTypes<kVerifyNone>());
    544     FixupDexCacheArray<GcRoot<mirror::CallSite>>(
    545         dex_cache,
    546         mirror::DexCache::ResolvedCallSitesOffset(),
    547         dex_cache->NumResolvedCallSites<kVerifyNone>());
    548     FixupDexCacheArray<GcRoot<mirror::String>>(
    549         dex_cache,
    550         mirror::DexCache::PreResolvedStringsOffset(),
    551         dex_cache->NumPreResolvedStrings<kVerifyNone>());
    552   }
    553 
    554   template <bool kMayBeNull = true, typename T>
    555   ALWAYS_INLINE void PatchGcRoot(/*inout*/GcRoot<T>* root) const
    556       REQUIRES_SHARED(Locks::mutator_lock_) {
    557     static_assert(sizeof(GcRoot<mirror::Class*>) == sizeof(uint32_t), "GcRoot size check");
    558     T* old_value = root->template Read<kWithoutReadBarrier>();
    559     DCHECK(kMayBeNull || old_value != nullptr);
    560     if (!kMayBeNull || old_value != nullptr) {
    561       *root = GcRoot<T>(heap_visitor_(old_value));
    562     }
    563   }
    564 
    565   template <bool kMayBeNull = true, typename T>
    566   ALWAYS_INLINE void PatchNativePointer(/*inout*/T** entry) const {
    567     if (kPointerSize == PointerSize::k64) {
    568       uint64_t* raw_entry = reinterpret_cast<uint64_t*>(entry);
    569       T* old_value = reinterpret_cast64<T*>(*raw_entry);
    570       DCHECK(kMayBeNull || old_value != nullptr);
    571       if (!kMayBeNull || old_value != nullptr) {
    572         T* new_value = native_visitor_(old_value);
    573         *raw_entry = reinterpret_cast64<uint64_t>(new_value);
    574       }
    575     } else {
    576       uint32_t* raw_entry = reinterpret_cast<uint32_t*>(entry);
    577       T* old_value = reinterpret_cast32<T*>(*raw_entry);
    578       DCHECK(kMayBeNull || old_value != nullptr);
    579       if (!kMayBeNull || old_value != nullptr) {
    580         T* new_value = native_visitor_(old_value);
    581         *raw_entry = reinterpret_cast32<uint32_t>(new_value);
    582       }
    583     }
    584   }
    585 
    586   template <bool kMayBeNull = true>
    587   ALWAYS_INLINE void PatchReferenceField(ObjPtr<mirror::Object> object, MemberOffset offset) const
    588       REQUIRES_SHARED(Locks::mutator_lock_) {
    589     ObjPtr<mirror::Object> old_value =
    590         object->GetFieldObject<mirror::Object, kVerifyNone, kWithoutReadBarrier>(offset);
    591     DCHECK(kMayBeNull || old_value != nullptr);
    592     if (!kMayBeNull || old_value != nullptr) {
    593       ObjPtr<mirror::Object> new_value = heap_visitor_(old_value.Ptr());
    594       object->SetFieldObjectWithoutWriteBarrier</*kTransactionActive=*/ false,
    595                                                 /*kCheckTransaction=*/ true,
    596                                                 kVerifyNone>(offset, new_value);
    597     }
    598   }
    599 
    600   template <typename T>
    601   void FixupDexCacheArrayEntry(std::atomic<mirror::DexCachePair<T>>* array, uint32_t index)
    602       REQUIRES_SHARED(Locks::mutator_lock_) {
    603     static_assert(sizeof(std::atomic<mirror::DexCachePair<T>>) == sizeof(mirror::DexCachePair<T>),
    604                   "Size check for removing std::atomic<>.");
    605     PatchGcRoot(&(reinterpret_cast<mirror::DexCachePair<T>*>(array)[index].object));
    606   }
    607 
    608   template <typename T>
    609   void FixupDexCacheArrayEntry(std::atomic<mirror::NativeDexCachePair<T>>* array, uint32_t index)
    610       REQUIRES_SHARED(Locks::mutator_lock_) {
    611     static_assert(sizeof(std::atomic<mirror::NativeDexCachePair<T>>) ==
    612                       sizeof(mirror::NativeDexCachePair<T>),
    613                   "Size check for removing std::atomic<>.");
    614     mirror::NativeDexCachePair<T> pair =
    615         mirror::DexCache::GetNativePairPtrSize(array, index, kPointerSize);
    616     if (pair.object != nullptr) {
    617       pair.object = native_visitor_(pair.object);
    618       mirror::DexCache::SetNativePairPtrSize(array, index, pair, kPointerSize);
    619     }
    620   }
    621 
    622   void FixupDexCacheArrayEntry(GcRoot<mirror::CallSite>* array, uint32_t index)
    623       REQUIRES_SHARED(Locks::mutator_lock_) {
    624     PatchGcRoot(&array[index]);
    625   }
    626 
    627   void FixupDexCacheArrayEntry(GcRoot<mirror::String>* array, uint32_t index)
    628       REQUIRES_SHARED(Locks::mutator_lock_) {
    629     PatchGcRoot(&array[index]);
    630   }
    631 
    632   template <typename EntryType>
    633   void FixupDexCacheArray(ObjPtr<mirror::DexCache> dex_cache,
    634                           MemberOffset array_offset,
    635                           uint32_t size) REQUIRES_SHARED(Locks::mutator_lock_) {
    636     EntryType* old_array =
    637         reinterpret_cast64<EntryType*>(dex_cache->GetField64<kVerifyNone>(array_offset));
    638     DCHECK_EQ(old_array != nullptr, size != 0u);
    639     if (old_array != nullptr) {
    640       EntryType* new_array = native_visitor_(old_array);
    641       dex_cache->SetField64<kVerifyNone>(array_offset, reinterpret_cast64<uint64_t>(new_array));
    642       for (uint32_t i = 0; i != size; ++i) {
    643         FixupDexCacheArrayEntry(new_array, i);
    644       }
    645     }
    646   }
    647 
    648  private:
    649   // Heap objects visitor.
    650   HeapVisitor heap_visitor_;
    651 
    652   // Native objects visitor.
    653   NativeVisitor native_visitor_;
    654 };
    655 
    656 template <typename ReferenceVisitor>
    657 class ImageSpace::ClassTableVisitor final {
    658  public:
    659   explicit ClassTableVisitor(const ReferenceVisitor& reference_visitor)
    660       : reference_visitor_(reference_visitor) {}
    661 
    662   void VisitRoot(mirror::CompressedReference<mirror::Object>* root) const
    663       REQUIRES_SHARED(Locks::mutator_lock_) {
    664     DCHECK(root->AsMirrorPtr() != nullptr);
    665     root->Assign(reference_visitor_(root->AsMirrorPtr()));
    666   }
    667 
    668  private:
    669   ReferenceVisitor reference_visitor_;
    670 };
    671 
    672 // Helper class encapsulating loading, so we can access private ImageSpace members (this is a
    673 // nested class), but not declare functions in the header.
    674 class ImageSpace::Loader {
    675  public:
    676   static std::unique_ptr<ImageSpace> InitAppImage(const char* image_filename,
    677                                                   const char* image_location,
    678                                                   const OatFile* oat_file,
    679                                                   /*inout*/MemMap* image_reservation,
    680                                                   /*out*/std::string* error_msg)
    681       REQUIRES_SHARED(Locks::mutator_lock_) {
    682     TimingLogger logger(__PRETTY_FUNCTION__, /*precise=*/ true, VLOG_IS_ON(image));
    683 
    684     std::unique_ptr<ImageSpace> space = Init(image_filename,
    685                                              image_location,
    686                                              oat_file,
    687                                              &logger,
    688                                              image_reservation,
    689                                              error_msg);
    690     if (space != nullptr) {
    691       uint32_t expected_reservation_size =
    692           RoundUp(space->GetImageHeader().GetImageSize(), kPageSize);
    693       if (!CheckImageReservationSize(*space, expected_reservation_size, error_msg) ||
    694           !CheckImageComponentCount(*space, /*expected_component_count=*/ 1u, error_msg)) {
    695         return nullptr;
    696       }
    697 
    698       TimingLogger::ScopedTiming timing("RelocateImage", &logger);
    699       ImageHeader* image_header = reinterpret_cast<ImageHeader*>(space->GetMemMap()->Begin());
    700       const PointerSize pointer_size = image_header->GetPointerSize();
    701       bool result;
    702       if (pointer_size == PointerSize::k64) {
    703         result = RelocateInPlace<PointerSize::k64>(*image_header,
    704                                                    space->GetMemMap()->Begin(),
    705                                                    space->GetLiveBitmap(),
    706                                                    oat_file,
    707                                                    error_msg);
    708       } else {
    709         result = RelocateInPlace<PointerSize::k32>(*image_header,
    710                                                    space->GetMemMap()->Begin(),
    711                                                    space->GetLiveBitmap(),
    712                                                    oat_file,
    713                                                    error_msg);
    714       }
    715       if (!result) {
    716         return nullptr;
    717       }
    718       Runtime* runtime = Runtime::Current();
    719       CHECK_EQ(runtime->GetResolutionMethod(),
    720                image_header->GetImageMethod(ImageHeader::kResolutionMethod));
    721       CHECK_EQ(runtime->GetImtConflictMethod(),
    722                image_header->GetImageMethod(ImageHeader::kImtConflictMethod));
    723       CHECK_EQ(runtime->GetImtUnimplementedMethod(),
    724                image_header->GetImageMethod(ImageHeader::kImtUnimplementedMethod));
    725       CHECK_EQ(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveAllCalleeSaves),
    726                image_header->GetImageMethod(ImageHeader::kSaveAllCalleeSavesMethod));
    727       CHECK_EQ(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveRefsOnly),
    728                image_header->GetImageMethod(ImageHeader::kSaveRefsOnlyMethod));
    729       CHECK_EQ(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveRefsAndArgs),
    730                image_header->GetImageMethod(ImageHeader::kSaveRefsAndArgsMethod));
    731       CHECK_EQ(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveEverything),
    732                image_header->GetImageMethod(ImageHeader::kSaveEverythingMethod));
    733       CHECK_EQ(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveEverythingForClinit),
    734                image_header->GetImageMethod(ImageHeader::kSaveEverythingMethodForClinit));
    735       CHECK_EQ(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveEverythingForSuspendCheck),
    736                image_header->GetImageMethod(ImageHeader::kSaveEverythingMethodForSuspendCheck));
    737 
    738       VLOG(image) << "ImageSpace::Loader::InitAppImage exiting " << *space.get();
    739     }
    740     if (VLOG_IS_ON(image)) {
    741       logger.Dump(LOG_STREAM(INFO));
    742     }
    743     return space;
    744   }
    745 
    746   static std::unique_ptr<ImageSpace> Init(const char* image_filename,
    747                                           const char* image_location,
    748                                           const OatFile* oat_file,
    749                                           TimingLogger* logger,
    750                                           /*inout*/MemMap* image_reservation,
    751                                           /*out*/std::string* error_msg)
    752       REQUIRES_SHARED(Locks::mutator_lock_) {
    753     CHECK(image_filename != nullptr);
    754     CHECK(image_location != nullptr);
    755 
    756     VLOG(image) << "ImageSpace::Init entering image_filename=" << image_filename;
    757 
    758     std::unique_ptr<File> file;
    759     {
    760       TimingLogger::ScopedTiming timing("OpenImageFile", logger);
    761       file.reset(OS::OpenFileForReading(image_filename));
    762       if (file == nullptr) {
    763         *error_msg = StringPrintf("Failed to open '%s'", image_filename);
    764         return nullptr;
    765       }
    766     }
    767     ImageHeader temp_image_header;
    768     ImageHeader* image_header = &temp_image_header;
    769     {
    770       TimingLogger::ScopedTiming timing("ReadImageHeader", logger);
    771       bool success = file->ReadFully(image_header, sizeof(*image_header));
    772       if (!success || !image_header->IsValid()) {
    773         *error_msg = StringPrintf("Invalid image header in '%s'", image_filename);
    774         return nullptr;
    775       }
    776     }
    777     // Check that the file is larger or equal to the header size + data size.
    778     const uint64_t image_file_size = static_cast<uint64_t>(file->GetLength());
    779     if (image_file_size < sizeof(ImageHeader) + image_header->GetDataSize()) {
    780       *error_msg = StringPrintf(
    781           "Image file truncated: %" PRIu64 " vs. %" PRIu64 ".",
    782            image_file_size,
    783            static_cast<uint64_t>(sizeof(ImageHeader) + image_header->GetDataSize()));
    784       return nullptr;
    785     }
    786 
    787     if (oat_file != nullptr) {
    788       // If we have an oat file (i.e. for app image), check the oat file checksum.
    789       // Otherwise, we open the oat file after the image and check the checksum there.
    790       const uint32_t oat_checksum = oat_file->GetOatHeader().GetChecksum();
    791       const uint32_t image_oat_checksum = image_header->GetOatChecksum();
    792       if (oat_checksum != image_oat_checksum) {
    793         *error_msg = StringPrintf("Oat checksum 0x%x does not match the image one 0x%x in image %s",
    794                                   oat_checksum,
    795                                   image_oat_checksum,
    796                                   image_filename);
    797         return nullptr;
    798       }
    799     }
    800 
    801     if (VLOG_IS_ON(startup)) {
    802       LOG(INFO) << "Dumping image sections";
    803       for (size_t i = 0; i < ImageHeader::kSectionCount; ++i) {
    804         const auto section_idx = static_cast<ImageHeader::ImageSections>(i);
    805         auto& section = image_header->GetImageSection(section_idx);
    806         LOG(INFO) << section_idx << " start="
    807             << reinterpret_cast<void*>(image_header->GetImageBegin() + section.Offset()) << " "
    808             << section;
    809       }
    810     }
    811 
    812     const auto& bitmap_section = image_header->GetImageBitmapSection();
    813     // The location we want to map from is the first aligned page after the end of the stored
    814     // (possibly compressed) data.
    815     const size_t image_bitmap_offset = RoundUp(sizeof(ImageHeader) + image_header->GetDataSize(),
    816                                                kPageSize);
    817     const size_t end_of_bitmap = image_bitmap_offset + bitmap_section.Size();
    818     if (end_of_bitmap != image_file_size) {
    819       *error_msg = StringPrintf(
    820           "Image file size does not equal end of bitmap: size=%" PRIu64 " vs. %zu.",
    821           image_file_size,
    822           end_of_bitmap);
    823       return nullptr;
    824     }
    825 
    826     // GetImageBegin is the preferred address to map the image. If we manage to map the
    827     // image at the image begin, the amount of fixup work required is minimized.
    828     // If it is pic we will retry with error_msg for the2 failure case. Pass a null error_msg to
    829     // avoid reading proc maps for a mapping failure and slowing everything down.
    830     // For the boot image, we have already reserved the memory and we load the image
    831     // into the `image_reservation`.
    832     MemMap map = LoadImageFile(
    833         image_filename,
    834         image_location,
    835         *image_header,
    836         file->Fd(),
    837         logger,
    838         image_reservation,
    839         error_msg);
    840     if (!map.IsValid()) {
    841       DCHECK(!error_msg->empty());
    842       return nullptr;
    843     }
    844     DCHECK_EQ(0, memcmp(image_header, map.Begin(), sizeof(ImageHeader)));
    845 
    846     MemMap image_bitmap_map = MemMap::MapFile(bitmap_section.Size(),
    847                                               PROT_READ,
    848                                               MAP_PRIVATE,
    849                                               file->Fd(),
    850                                               image_bitmap_offset,
    851                                               /*low_4gb=*/ false,
    852                                               image_filename,
    853                                               error_msg);
    854     if (!image_bitmap_map.IsValid()) {
    855       *error_msg = StringPrintf("Failed to map image bitmap: %s", error_msg->c_str());
    856       return nullptr;
    857     }
    858     // Loaded the map, use the image header from the file now in case we patch it with
    859     // RelocateInPlace.
    860     image_header = reinterpret_cast<ImageHeader*>(map.Begin());
    861     const uint32_t bitmap_index = ImageSpace::bitmap_index_.fetch_add(1);
    862     std::string bitmap_name(StringPrintf("imagespace %s live-bitmap %u",
    863                                          image_filename,
    864                                          bitmap_index));
    865     // Bitmap only needs to cover until the end of the mirror objects section.
    866     const ImageSection& image_objects = image_header->GetObjectsSection();
    867     // We only want the mirror object, not the ArtFields and ArtMethods.
    868     uint8_t* const image_end = map.Begin() + image_objects.End();
    869     std::unique_ptr<accounting::ContinuousSpaceBitmap> bitmap;
    870     {
    871       TimingLogger::ScopedTiming timing("CreateImageBitmap", logger);
    872       bitmap.reset(
    873           accounting::ContinuousSpaceBitmap::CreateFromMemMap(
    874               bitmap_name,
    875               std::move(image_bitmap_map),
    876               reinterpret_cast<uint8_t*>(map.Begin()),
    877               // Make sure the bitmap is aligned to card size instead of just bitmap word size.
    878               RoundUp(image_objects.End(), gc::accounting::CardTable::kCardSize)));
    879       if (bitmap == nullptr) {
    880         *error_msg = StringPrintf("Could not create bitmap '%s'", bitmap_name.c_str());
    881         return nullptr;
    882       }
    883     }
    884     // We only want the mirror object, not the ArtFields and ArtMethods.
    885     std::unique_ptr<ImageSpace> space(new ImageSpace(image_filename,
    886                                                      image_location,
    887                                                      std::move(map),
    888                                                      std::move(bitmap),
    889                                                      image_end));
    890     space->oat_file_non_owned_ = oat_file;
    891     return space;
    892   }
    893 
    894   static bool CheckImageComponentCount(const ImageSpace& space,
    895                                        uint32_t expected_component_count,
    896                                        /*out*/std::string* error_msg) {
    897     const ImageHeader& header = space.GetImageHeader();
    898     if (header.GetComponentCount() != expected_component_count) {
    899       *error_msg = StringPrintf("Unexpected component count in %s, received %u, expected %u",
    900                                 space.GetImageFilename().c_str(),
    901                                 header.GetComponentCount(),
    902                                 expected_component_count);
    903       return false;
    904     }
    905     return true;
    906   }
    907 
    908   static bool CheckImageReservationSize(const ImageSpace& space,
    909                                         uint32_t expected_reservation_size,
    910                                         /*out*/std::string* error_msg) {
    911     const ImageHeader& header = space.GetImageHeader();
    912     if (header.GetImageReservationSize() != expected_reservation_size) {
    913       *error_msg = StringPrintf("Unexpected reservation size in %s, received %u, expected %u",
    914                                 space.GetImageFilename().c_str(),
    915                                 header.GetImageReservationSize(),
    916                                 expected_reservation_size);
    917       return false;
    918     }
    919     return true;
    920   }
    921 
    922  private:
    923   static MemMap LoadImageFile(const char* image_filename,
    924                               const char* image_location,
    925                               const ImageHeader& image_header,
    926                               int fd,
    927                               TimingLogger* logger,
    928                               /*inout*/MemMap* image_reservation,
    929                               /*out*/std::string* error_msg)
    930         REQUIRES_SHARED(Locks::mutator_lock_) {
    931     TimingLogger::ScopedTiming timing("MapImageFile", logger);
    932     std::string temp_error_msg;
    933     const bool is_compressed = image_header.HasCompressedBlock();
    934     if (!is_compressed) {
    935       uint8_t* address = (image_reservation != nullptr) ? image_reservation->Begin() : nullptr;
    936       return MemMap::MapFileAtAddress(address,
    937                                       image_header.GetImageSize(),
    938                                       PROT_READ | PROT_WRITE,
    939                                       MAP_PRIVATE,
    940                                       fd,
    941                                       /*start=*/ 0,
    942                                       /*low_4gb=*/ true,
    943                                       image_filename,
    944                                       /*reuse=*/ false,
    945                                       image_reservation,
    946                                       error_msg);
    947     }
    948 
    949     // Reserve output and decompress into it.
    950     MemMap map = MemMap::MapAnonymous(image_location,
    951                                       image_header.GetImageSize(),
    952                                       PROT_READ | PROT_WRITE,
    953                                       /*low_4gb=*/ true,
    954                                       image_reservation,
    955                                       error_msg);
    956     if (map.IsValid()) {
    957       const size_t stored_size = image_header.GetDataSize();
    958       MemMap temp_map = MemMap::MapFile(sizeof(ImageHeader) + stored_size,
    959                                         PROT_READ,
    960                                         MAP_PRIVATE,
    961                                         fd,
    962                                         /*start=*/ 0,
    963                                         /*low_4gb=*/ false,
    964                                         image_filename,
    965                                         error_msg);
    966       if (!temp_map.IsValid()) {
    967         DCHECK(error_msg == nullptr || !error_msg->empty());
    968         return MemMap::Invalid();
    969       }
    970       memcpy(map.Begin(), &image_header, sizeof(ImageHeader));
    971 
    972       Runtime::ScopedThreadPoolUsage stpu;
    973       ThreadPool* const pool = stpu.GetThreadPool();
    974       const uint64_t start = NanoTime();
    975       Thread* const self = Thread::Current();
    976       static constexpr size_t kMinBlocks = 2u;
    977       const bool use_parallel = pool != nullptr && image_header.GetBlockCount() >= kMinBlocks;
    978       for (const ImageHeader::Block& block : image_header.GetBlocks(temp_map.Begin())) {
    979         auto function = [&](Thread*) {
    980           const uint64_t start2 = NanoTime();
    981           ScopedTrace trace("LZ4 decompress block");
    982           bool result = block.Decompress(/*out_ptr=*/map.Begin(),
    983                                          /*in_ptr=*/temp_map.Begin(),
    984                                          error_msg);
    985           if (!result && error_msg != nullptr) {
    986             *error_msg = "Failed to decompress image block " + *error_msg;
    987           }
    988           VLOG(image) << "Decompress block " << block.GetDataSize() << " -> "
    989                       << block.GetImageSize() << " in " << PrettyDuration(NanoTime() - start2);
    990         };
    991         if (use_parallel) {
    992           pool->AddTask(self, new FunctionTask(std::move(function)));
    993         } else {
    994           function(self);
    995         }
    996       }
    997       if (use_parallel) {
    998         ScopedTrace trace("Waiting for workers");
    999         // Go to native since we don't want to suspend while holding the mutator lock.
   1000         ScopedThreadSuspension sts(Thread::Current(), kNative);
   1001         pool->Wait(self, true, false);
   1002       }
   1003       const uint64_t time = NanoTime() - start;
   1004       // Add one 1 ns to prevent possible divide by 0.
   1005       VLOG(image) << "Decompressing image took " << PrettyDuration(time) << " ("
   1006                   << PrettySize(static_cast<uint64_t>(map.Size()) * MsToNs(1000) / (time + 1))
   1007                   << "/s)";
   1008     }
   1009 
   1010     return map;
   1011   }
   1012 
   1013   class EmptyRange {
   1014    public:
   1015     ALWAYS_INLINE bool InSource(uintptr_t) const { return false; }
   1016     ALWAYS_INLINE bool InDest(uintptr_t) const { return false; }
   1017     ALWAYS_INLINE uintptr_t ToDest(uintptr_t) const { UNREACHABLE(); }
   1018   };
   1019 
   1020   template <typename Range0, typename Range1 = EmptyRange, typename Range2 = EmptyRange>
   1021   class ForwardAddress {
   1022    public:
   1023     ForwardAddress(const Range0& range0 = Range0(),
   1024                    const Range1& range1 = Range1(),
   1025                    const Range2& range2 = Range2())
   1026         : range0_(range0), range1_(range1), range2_(range2) {}
   1027 
   1028     // Return the relocated address of a heap object.
   1029     // Null checks must be performed in the caller (for performance reasons).
   1030     template <typename T>
   1031     ALWAYS_INLINE T* operator()(T* src) const {
   1032       DCHECK(src != nullptr);
   1033       const uintptr_t uint_src = reinterpret_cast<uintptr_t>(src);
   1034       if (range2_.InSource(uint_src)) {
   1035         return reinterpret_cast<T*>(range2_.ToDest(uint_src));
   1036       }
   1037       if (range1_.InSource(uint_src)) {
   1038         return reinterpret_cast<T*>(range1_.ToDest(uint_src));
   1039       }
   1040       CHECK(range0_.InSource(uint_src))
   1041           << reinterpret_cast<const void*>(src) << " not in "
   1042           << reinterpret_cast<const void*>(range0_.Source()) << "-"
   1043           << reinterpret_cast<const void*>(range0_.Source() + range0_.Length());
   1044       return reinterpret_cast<T*>(range0_.ToDest(uint_src));
   1045     }
   1046 
   1047    private:
   1048     const Range0 range0_;
   1049     const Range1 range1_;
   1050     const Range2 range2_;
   1051   };
   1052 
   1053   template <typename Forward>
   1054   class FixupRootVisitor {
   1055    public:
   1056     template<typename... Args>
   1057     explicit FixupRootVisitor(Args... args) : forward_(args...) {}
   1058 
   1059     ALWAYS_INLINE void VisitRootIfNonNull(mirror::CompressedReference<mirror::Object>* root) const
   1060         REQUIRES_SHARED(Locks::mutator_lock_) {
   1061       if (!root->IsNull()) {
   1062         VisitRoot(root);
   1063       }
   1064     }
   1065 
   1066     ALWAYS_INLINE void VisitRoot(mirror::CompressedReference<mirror::Object>* root) const
   1067         REQUIRES_SHARED(Locks::mutator_lock_) {
   1068       mirror::Object* ref = root->AsMirrorPtr();
   1069       mirror::Object* new_ref = forward_(ref);
   1070       if (ref != new_ref) {
   1071         root->Assign(new_ref);
   1072       }
   1073     }
   1074 
   1075    private:
   1076     Forward forward_;
   1077   };
   1078 
   1079   template <typename Forward>
   1080   class FixupObjectVisitor {
   1081    public:
   1082     explicit FixupObjectVisitor(gc::accounting::ContinuousSpaceBitmap* visited,
   1083                                 const Forward& forward)
   1084         : visited_(visited), forward_(forward) {}
   1085 
   1086     // Fix up separately since we also need to fix up method entrypoints.
   1087     ALWAYS_INLINE void VisitRootIfNonNull(
   1088         mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED) const {}
   1089 
   1090     ALWAYS_INLINE void VisitRoot(mirror::CompressedReference<mirror::Object>* root ATTRIBUTE_UNUSED)
   1091         const {}
   1092 
   1093     ALWAYS_INLINE void operator()(ObjPtr<mirror::Object> obj,
   1094                                   MemberOffset offset,
   1095                                   bool is_static ATTRIBUTE_UNUSED) const
   1096         NO_THREAD_SAFETY_ANALYSIS {
   1097       // Space is not yet added to the heap, don't do a read barrier.
   1098       mirror::Object* ref = obj->GetFieldObject<mirror::Object, kVerifyNone, kWithoutReadBarrier>(
   1099           offset);
   1100       if (ref != nullptr) {
   1101         // Use SetFieldObjectWithoutWriteBarrier to avoid card marking since we are writing to the
   1102         // image.
   1103         obj->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(offset, forward_(ref));
   1104       }
   1105     }
   1106 
   1107     // java.lang.ref.Reference visitor.
   1108     void operator()(ObjPtr<mirror::Class> klass ATTRIBUTE_UNUSED,
   1109                     ObjPtr<mirror::Reference> ref) const
   1110         REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::heap_bitmap_lock_) {
   1111       mirror::Object* obj = ref->GetReferent<kWithoutReadBarrier>();
   1112       if (obj != nullptr) {
   1113         ref->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(
   1114             mirror::Reference::ReferentOffset(),
   1115             forward_(obj));
   1116       }
   1117     }
   1118 
   1119     void operator()(mirror::Object* obj) const
   1120         NO_THREAD_SAFETY_ANALYSIS {
   1121       if (!visited_->Set(obj)) {
   1122         // Not already visited.
   1123         obj->VisitReferences</*visit native roots*/false, kVerifyNone, kWithoutReadBarrier>(
   1124             *this,
   1125             *this);
   1126         CHECK(!obj->IsClass());
   1127       }
   1128     }
   1129 
   1130    private:
   1131     gc::accounting::ContinuousSpaceBitmap* const visited_;
   1132     Forward forward_;
   1133   };
   1134 
   1135   // Relocate an image space mapped at target_base which possibly used to be at a different base
   1136   // address. In place means modifying a single ImageSpace in place rather than relocating from
   1137   // one ImageSpace to another.
   1138   template <PointerSize kPointerSize>
   1139   static bool RelocateInPlace(ImageHeader& image_header,
   1140                               uint8_t* target_base,
   1141                               accounting::ContinuousSpaceBitmap* bitmap,
   1142                               const OatFile* app_oat_file,
   1143                               std::string* error_msg) {
   1144     DCHECK(error_msg != nullptr);
   1145     // Set up sections.
   1146     uint32_t boot_image_begin = 0;
   1147     uint32_t boot_image_end = 0;
   1148     uint32_t boot_oat_begin = 0;
   1149     uint32_t boot_oat_end = 0;
   1150     gc::Heap* const heap = Runtime::Current()->GetHeap();
   1151     heap->GetBootImagesSize(&boot_image_begin, &boot_image_end, &boot_oat_begin, &boot_oat_end);
   1152     if (boot_image_begin == boot_image_end) {
   1153       *error_msg = "Can not relocate app image without boot image space";
   1154       return false;
   1155     }
   1156     if (boot_oat_begin == boot_oat_end) {
   1157       *error_msg = "Can not relocate app image without boot oat file";
   1158       return false;
   1159     }
   1160     const uint32_t boot_image_size = boot_oat_end - boot_image_begin;
   1161     const uint32_t image_header_boot_image_size = image_header.GetBootImageSize();
   1162     if (boot_image_size != image_header_boot_image_size) {
   1163       *error_msg = StringPrintf("Boot image size %" PRIu64 " does not match expected size %"
   1164                                     PRIu64,
   1165                                 static_cast<uint64_t>(boot_image_size),
   1166                                 static_cast<uint64_t>(image_header_boot_image_size));
   1167       return false;
   1168     }
   1169     const ImageSection& objects_section = image_header.GetObjectsSection();
   1170     // Where the app image objects are mapped to.
   1171     uint8_t* objects_location = target_base + objects_section.Offset();
   1172     TimingLogger logger(__FUNCTION__, true, false);
   1173     RelocationRange boot_image(image_header.GetBootImageBegin(),
   1174                                boot_image_begin,
   1175                                boot_image_size);
   1176     // Metadata is everything after the objects section, use exclusion to be safe.
   1177     RelocationRange app_image_metadata(
   1178         reinterpret_cast<uintptr_t>(image_header.GetImageBegin()) + objects_section.End(),
   1179         reinterpret_cast<uintptr_t>(target_base) + objects_section.End(),
   1180         image_header.GetImageSize() - objects_section.End());
   1181     // App image heap objects, may be mapped in the heap.
   1182     RelocationRange app_image_objects(
   1183         reinterpret_cast<uintptr_t>(image_header.GetImageBegin()) + objects_section.Offset(),
   1184         reinterpret_cast<uintptr_t>(objects_location),
   1185         objects_section.Size());
   1186     // Use the oat data section since this is where the OatFile::Begin is.
   1187     RelocationRange app_oat(reinterpret_cast<uintptr_t>(image_header.GetOatDataBegin()),
   1188                             // Not necessarily in low 4GB.
   1189                             reinterpret_cast<uintptr_t>(app_oat_file->Begin()),
   1190                             image_header.GetOatDataEnd() - image_header.GetOatDataBegin());
   1191     VLOG(image) << "App image metadata " << app_image_metadata;
   1192     VLOG(image) << "App image objects " << app_image_objects;
   1193     VLOG(image) << "App oat " << app_oat;
   1194     VLOG(image) << "Boot image " << boot_image;
   1195     // True if we need to fixup any heap pointers.
   1196     const bool fixup_image = boot_image.Delta() != 0 || app_image_metadata.Delta() != 0 ||
   1197         app_image_objects.Delta() != 0;
   1198     if (!fixup_image) {
   1199       // Nothing to fix up.
   1200       return true;
   1201     }
   1202     ScopedDebugDisallowReadBarriers sddrb(Thread::Current());
   1203 
   1204     using ForwardObject = ForwardAddress<RelocationRange, RelocationRange>;
   1205     ForwardObject forward_object(boot_image, app_image_objects);
   1206     ForwardObject forward_metadata(boot_image, app_image_metadata);
   1207     using ForwardCode = ForwardAddress<RelocationRange, RelocationRange>;
   1208     ForwardCode forward_code(boot_image, app_oat);
   1209     PatchObjectVisitor<kPointerSize, ForwardObject, ForwardCode> patch_object_visitor(
   1210         forward_object,
   1211         forward_metadata);
   1212     if (fixup_image) {
   1213       // Two pass approach, fix up all classes first, then fix up non class-objects.
   1214       // The visited bitmap is used to ensure that pointer arrays are not forwarded twice.
   1215       std::unique_ptr<gc::accounting::ContinuousSpaceBitmap> visited_bitmap(
   1216           gc::accounting::ContinuousSpaceBitmap::Create("Relocate bitmap",
   1217                                                         target_base,
   1218                                                         image_header.GetImageSize()));
   1219       {
   1220         TimingLogger::ScopedTiming timing("Fixup classes", &logger);
   1221         const auto& class_table_section = image_header.GetClassTableSection();
   1222         if (class_table_section.Size() > 0u) {
   1223           ScopedObjectAccess soa(Thread::Current());
   1224           ClassTableVisitor class_table_visitor(forward_object);
   1225           size_t read_count = 0u;
   1226           const uint8_t* data = target_base + class_table_section.Offset();
   1227           // We avoid making a copy of the data since we want modifications to be propagated to the
   1228           // memory map.
   1229           ClassTable::ClassSet temp_set(data, /*make_copy_of_data=*/ false, &read_count);
   1230           for (ClassTable::TableSlot& slot : temp_set) {
   1231             slot.VisitRoot(class_table_visitor);
   1232             mirror::Class* klass = slot.Read<kWithoutReadBarrier>();
   1233             if (!app_image_objects.InDest(klass)) {
   1234               continue;
   1235             }
   1236             const bool already_marked = visited_bitmap->Set(klass);
   1237             CHECK(!already_marked) << "App image class already visited";
   1238             patch_object_visitor.VisitClass(klass);
   1239             // Then patch the non-embedded vtable and iftable.
   1240             ObjPtr<mirror::PointerArray> vtable =
   1241                 klass->GetVTable<kVerifyNone, kWithoutReadBarrier>();
   1242             if (vtable != nullptr &&
   1243                 app_image_objects.InDest(vtable.Ptr()) &&
   1244                 !visited_bitmap->Set(vtable.Ptr())) {
   1245               patch_object_visitor.VisitPointerArray(vtable);
   1246             }
   1247             ObjPtr<mirror::IfTable> iftable = klass->GetIfTable<kVerifyNone, kWithoutReadBarrier>();
   1248             if (iftable != nullptr && app_image_objects.InDest(iftable.Ptr())) {
   1249               // Avoid processing the fields of iftable since we will process them later anyways
   1250               // below.
   1251               int32_t ifcount = klass->GetIfTableCount<kVerifyNone>();
   1252               for (int32_t i = 0; i != ifcount; ++i) {
   1253                 ObjPtr<mirror::PointerArray> unpatched_ifarray =
   1254                     iftable->GetMethodArrayOrNull<kVerifyNone, kWithoutReadBarrier>(i);
   1255                 if (unpatched_ifarray != nullptr) {
   1256                   // The iftable has not been patched, so we need to explicitly adjust the pointer.
   1257                   ObjPtr<mirror::PointerArray> ifarray = forward_object(unpatched_ifarray.Ptr());
   1258                   if (app_image_objects.InDest(ifarray.Ptr()) &&
   1259                       !visited_bitmap->Set(ifarray.Ptr())) {
   1260                     patch_object_visitor.VisitPointerArray(ifarray);
   1261                   }
   1262                 }
   1263               }
   1264             }
   1265           }
   1266         }
   1267       }
   1268 
   1269       // Fixup objects may read fields in the boot image, use the mutator lock here for sanity.
   1270       // Though its probably not required.
   1271       TimingLogger::ScopedTiming timing("Fixup objects", &logger);
   1272       ScopedObjectAccess soa(Thread::Current());
   1273       // Need to update the image to be at the target base.
   1274       uintptr_t objects_begin = reinterpret_cast<uintptr_t>(target_base + objects_section.Offset());
   1275       uintptr_t objects_end = reinterpret_cast<uintptr_t>(target_base + objects_section.End());
   1276       FixupObjectVisitor<ForwardObject> fixup_object_visitor(visited_bitmap.get(), forward_object);
   1277       bitmap->VisitMarkedRange(objects_begin, objects_end, fixup_object_visitor);
   1278       // Fixup image roots.
   1279       CHECK(app_image_objects.InSource(reinterpret_cast<uintptr_t>(
   1280           image_header.GetImageRoots<kWithoutReadBarrier>().Ptr())));
   1281       image_header.RelocateImageObjects(app_image_objects.Delta());
   1282       CHECK_EQ(image_header.GetImageBegin(), target_base);
   1283       // Fix up dex cache DexFile pointers.
   1284       ObjPtr<mirror::ObjectArray<mirror::DexCache>> dex_caches =
   1285           image_header.GetImageRoot<kWithoutReadBarrier>(ImageHeader::kDexCaches)
   1286               ->AsObjectArray<mirror::DexCache, kVerifyNone>();
   1287       for (int32_t i = 0, count = dex_caches->GetLength(); i < count; ++i) {
   1288         ObjPtr<mirror::DexCache> dex_cache = dex_caches->Get<kVerifyNone, kWithoutReadBarrier>(i);
   1289         CHECK(dex_cache != nullptr);
   1290         patch_object_visitor.VisitDexCacheArrays(dex_cache);
   1291       }
   1292     }
   1293     {
   1294       // Only touches objects in the app image, no need for mutator lock.
   1295       TimingLogger::ScopedTiming timing("Fixup methods", &logger);
   1296       image_header.VisitPackedArtMethods([&](ArtMethod& method) NO_THREAD_SAFETY_ANALYSIS {
   1297         // TODO: Consider a separate visitor for runtime vs normal methods.
   1298         if (UNLIKELY(method.IsRuntimeMethod())) {
   1299           ImtConflictTable* table = method.GetImtConflictTable(kPointerSize);
   1300           if (table != nullptr) {
   1301             ImtConflictTable* new_table = forward_metadata(table);
   1302             if (table != new_table) {
   1303               method.SetImtConflictTable(new_table, kPointerSize);
   1304             }
   1305           }
   1306           const void* old_code = method.GetEntryPointFromQuickCompiledCodePtrSize(kPointerSize);
   1307           const void* new_code = forward_code(old_code);
   1308           if (old_code != new_code) {
   1309             method.SetEntryPointFromQuickCompiledCodePtrSize(new_code, kPointerSize);
   1310           }
   1311         } else {
   1312           method.UpdateObjectsForImageRelocation(forward_object);
   1313           method.UpdateEntrypoints(forward_code, kPointerSize);
   1314         }
   1315       }, target_base, kPointerSize);
   1316     }
   1317     if (fixup_image) {
   1318       {
   1319         // Only touches objects in the app image, no need for mutator lock.
   1320         TimingLogger::ScopedTiming timing("Fixup fields", &logger);
   1321         image_header.VisitPackedArtFields([&](ArtField& field) NO_THREAD_SAFETY_ANALYSIS {
   1322           field.UpdateObjects(forward_object);
   1323         }, target_base);
   1324       }
   1325       {
   1326         TimingLogger::ScopedTiming timing("Fixup imt", &logger);
   1327         image_header.VisitPackedImTables(forward_metadata, target_base, kPointerSize);
   1328       }
   1329       {
   1330         TimingLogger::ScopedTiming timing("Fixup conflict tables", &logger);
   1331         image_header.VisitPackedImtConflictTables(forward_metadata, target_base, kPointerSize);
   1332       }
   1333       // In the app image case, the image methods are actually in the boot image.
   1334       image_header.RelocateImageMethods(boot_image.Delta());
   1335       // Fix up the intern table.
   1336       const auto& intern_table_section = image_header.GetInternedStringsSection();
   1337       if (intern_table_section.Size() > 0u) {
   1338         TimingLogger::ScopedTiming timing("Fixup intern table", &logger);
   1339         ScopedObjectAccess soa(Thread::Current());
   1340         // Fixup the pointers in the newly written intern table to contain image addresses.
   1341         InternTable temp_intern_table;
   1342         // Note that we require that ReadFromMemory does not make an internal copy of the elements
   1343         // so that the VisitRoots() will update the memory directly rather than the copies.
   1344         temp_intern_table.AddTableFromMemory(target_base + intern_table_section.Offset(),
   1345                                              [&](InternTable::UnorderedSet& strings)
   1346             REQUIRES_SHARED(Locks::mutator_lock_) {
   1347           for (GcRoot<mirror::String>& root : strings) {
   1348             root = GcRoot<mirror::String>(forward_object(root.Read<kWithoutReadBarrier>()));
   1349           }
   1350         }, /*is_boot_image=*/ false);
   1351       }
   1352     }
   1353     if (VLOG_IS_ON(image)) {
   1354       logger.Dump(LOG_STREAM(INFO));
   1355     }
   1356     return true;
   1357   }
   1358 };
   1359 
   1360 class ImageSpace::BootImageLoader {
   1361  public:
   1362   BootImageLoader(const std::vector<std::string>& boot_class_path,
   1363                   const std::vector<std::string>& boot_class_path_locations,
   1364                   const std::string& image_location,
   1365                   InstructionSet image_isa,
   1366                   bool relocate,
   1367                   bool executable,
   1368                   bool is_zygote)
   1369       : boot_class_path_(boot_class_path),
   1370         boot_class_path_locations_(boot_class_path_locations),
   1371         image_location_(image_location),
   1372         image_isa_(image_isa),
   1373         relocate_(relocate),
   1374         executable_(executable),
   1375         is_zygote_(is_zygote),
   1376         has_system_(false),
   1377         has_cache_(false),
   1378         is_global_cache_(true),
   1379         dalvik_cache_exists_(false),
   1380         dalvik_cache_(),
   1381         cache_filename_() {
   1382   }
   1383 
   1384   bool IsZygote() const { return is_zygote_; }
   1385 
   1386   void FindImageFiles() {
   1387     std::string system_filename;
   1388     bool found_image = FindImageFilenameImpl(image_location_.c_str(),
   1389                                              image_isa_,
   1390                                              &has_system_,
   1391                                              &system_filename,
   1392                                              &dalvik_cache_exists_,
   1393                                              &dalvik_cache_,
   1394                                              &is_global_cache_,
   1395                                              &has_cache_,
   1396                                              &cache_filename_);
   1397     DCHECK(!dalvik_cache_exists_ || !dalvik_cache_.empty());
   1398     DCHECK_EQ(found_image, has_system_ || has_cache_);
   1399   }
   1400 
   1401   bool HasSystem() const { return has_system_; }
   1402   bool HasCache() const { return has_cache_; }
   1403 
   1404   bool DalvikCacheExists() const { return dalvik_cache_exists_; }
   1405   bool IsGlobalCache() const { return is_global_cache_; }
   1406 
   1407   const std::string& GetDalvikCache() const {
   1408     return dalvik_cache_;
   1409   }
   1410 
   1411   const std::string& GetCacheFilename() const {
   1412     return cache_filename_;
   1413   }
   1414 
   1415   bool LoadFromSystem(bool validate_oat_file,
   1416                       size_t extra_reservation_size,
   1417                       /*out*/std::vector<std::unique_ptr<space::ImageSpace>>* boot_image_spaces,
   1418                       /*out*/MemMap* extra_reservation,
   1419                       /*out*/std::string* error_msg) REQUIRES_SHARED(Locks::mutator_lock_) {
   1420     TimingLogger logger(__PRETTY_FUNCTION__, /*precise=*/ true, VLOG_IS_ON(image));
   1421     std::string filename = GetSystemImageFilename(image_location_.c_str(), image_isa_);
   1422 
   1423     if (!LoadFromFile(filename,
   1424                       validate_oat_file,
   1425                       extra_reservation_size,
   1426                       &logger,
   1427                       boot_image_spaces,
   1428                       extra_reservation,
   1429                       error_msg)) {
   1430       return false;
   1431     }
   1432 
   1433     if (VLOG_IS_ON(image)) {
   1434       LOG(INFO) << "ImageSpace::BootImageLoader::LoadFromSystem exiting "
   1435           << boot_image_spaces->front();
   1436       logger.Dump(LOG_STREAM(INFO));
   1437     }
   1438     return true;
   1439   }
   1440 
   1441   bool LoadFromDalvikCache(
   1442       bool validate_oat_file,
   1443       size_t extra_reservation_size,
   1444       /*out*/std::vector<std::unique_ptr<space::ImageSpace>>* boot_image_spaces,
   1445       /*out*/MemMap* extra_reservation,
   1446       /*out*/std::string* error_msg) REQUIRES_SHARED(Locks::mutator_lock_) {
   1447     TimingLogger logger(__PRETTY_FUNCTION__, /*precise=*/ true, VLOG_IS_ON(image));
   1448     DCHECK(DalvikCacheExists());
   1449 
   1450     if (!LoadFromFile(cache_filename_,
   1451                       validate_oat_file,
   1452                       extra_reservation_size,
   1453                       &logger,
   1454                       boot_image_spaces,
   1455                       extra_reservation,
   1456                       error_msg)) {
   1457       return false;
   1458     }
   1459 
   1460     if (VLOG_IS_ON(image)) {
   1461       LOG(INFO) << "ImageSpace::BootImageLoader::LoadFromDalvikCache exiting "
   1462           << boot_image_spaces->front();
   1463       logger.Dump(LOG_STREAM(INFO));
   1464     }
   1465     return true;
   1466   }
   1467 
   1468  private:
   1469   bool LoadFromFile(
   1470       const std::string& filename,
   1471       bool validate_oat_file,
   1472       size_t extra_reservation_size,
   1473       TimingLogger* logger,
   1474       /*out*/std::vector<std::unique_ptr<space::ImageSpace>>* boot_image_spaces,
   1475       /*out*/MemMap* extra_reservation,
   1476       /*out*/std::string* error_msg) REQUIRES_SHARED(Locks::mutator_lock_) {
   1477     ImageHeader system_hdr;
   1478     if (!ReadSpecificImageHeader(filename.c_str(), &system_hdr)) {
   1479       *error_msg = StringPrintf("Cannot read header of %s", filename.c_str());
   1480       return false;
   1481     }
   1482     if (system_hdr.GetComponentCount() == 0u ||
   1483         system_hdr.GetComponentCount() > boot_class_path_.size()) {
   1484       *error_msg = StringPrintf("Unexpected component count in %s, received %u, "
   1485                                     "expected non-zero and <= %zu",
   1486                                 filename.c_str(),
   1487                                 system_hdr.GetComponentCount(),
   1488                                 boot_class_path_.size());
   1489       return false;
   1490     }
   1491     MemMap image_reservation;
   1492     MemMap local_extra_reservation;
   1493     if (!ReserveBootImageMemory(system_hdr.GetImageReservationSize(),
   1494                                 reinterpret_cast32<uint32_t>(system_hdr.GetImageBegin()),
   1495                                 extra_reservation_size,
   1496                                 &image_reservation,
   1497                                 &local_extra_reservation,
   1498                                 error_msg)) {
   1499       return false;
   1500     }
   1501 
   1502     ArrayRef<const std::string> provided_locations(boot_class_path_locations_.data(),
   1503                                                    system_hdr.GetComponentCount());
   1504     std::vector<std::string> locations =
   1505         ExpandMultiImageLocations(provided_locations, image_location_);
   1506     std::vector<std::string> filenames =
   1507         ExpandMultiImageLocations(provided_locations, filename);
   1508     DCHECK_EQ(locations.size(), filenames.size());
   1509     std::vector<std::unique_ptr<ImageSpace>> spaces;
   1510     spaces.reserve(locations.size());
   1511     for (std::size_t i = 0u, size = locations.size(); i != size; ++i) {
   1512       spaces.push_back(Load(locations[i], filenames[i], logger, &image_reservation, error_msg));
   1513       const ImageSpace* space = spaces.back().get();
   1514       if (space == nullptr) {
   1515         return false;
   1516       }
   1517       uint32_t expected_component_count = (i == 0u) ? system_hdr.GetComponentCount() : 0u;
   1518       uint32_t expected_reservation_size = (i == 0u) ? system_hdr.GetImageReservationSize() : 0u;
   1519       if (!Loader::CheckImageReservationSize(*space, expected_reservation_size, error_msg) ||
   1520           !Loader::CheckImageComponentCount(*space, expected_component_count, error_msg)) {
   1521         return false;
   1522       }
   1523     }
   1524     for (size_t i = 0u, size = spaces.size(); i != size; ++i) {
   1525       std::string expected_boot_class_path =
   1526           (i == 0u) ? android::base::Join(provided_locations, ':') : std::string();
   1527       if (!OpenOatFile(spaces[i].get(),
   1528                        boot_class_path_[i],
   1529                        expected_boot_class_path,
   1530                        validate_oat_file,
   1531                        logger,
   1532                        &image_reservation,
   1533                        error_msg)) {
   1534         return false;
   1535       }
   1536     }
   1537     if (!CheckReservationExhausted(image_reservation, error_msg)) {
   1538       return false;
   1539     }
   1540 
   1541     MaybeRelocateSpaces(spaces, logger);
   1542     boot_image_spaces->swap(spaces);
   1543     *extra_reservation = std::move(local_extra_reservation);
   1544     return true;
   1545   }
   1546 
   1547  private:
   1548   class RelocateVisitor {
   1549    public:
   1550     explicit RelocateVisitor(uint32_t diff) : diff_(diff) {}
   1551 
   1552     template <typename T>
   1553     ALWAYS_INLINE T* operator()(T* src) const {
   1554       DCHECK(src != nullptr);
   1555       return reinterpret_cast32<T*>(reinterpret_cast32<uint32_t>(src) + diff_);
   1556     }
   1557 
   1558    private:
   1559     const uint32_t diff_;
   1560   };
   1561 
   1562   static void** PointerAddress(ArtMethod* method, MemberOffset offset) {
   1563     return reinterpret_cast<void**>(reinterpret_cast<uint8_t*>(method) + offset.Uint32Value());
   1564   }
   1565 
   1566   template <PointerSize kPointerSize>
   1567   static void DoRelocateSpaces(const std::vector<std::unique_ptr<ImageSpace>>& spaces,
   1568                                uint32_t diff) REQUIRES_SHARED(Locks::mutator_lock_) {
   1569     std::unique_ptr<gc::accounting::ContinuousSpaceBitmap> patched_objects(
   1570         gc::accounting::ContinuousSpaceBitmap::Create(
   1571             "Marked objects",
   1572             spaces.front()->Begin(),
   1573             spaces.back()->End() - spaces.front()->Begin()));
   1574     using PatchRelocateVisitor = PatchObjectVisitor<kPointerSize, RelocateVisitor, RelocateVisitor>;
   1575     RelocateVisitor relocate_visitor(diff);
   1576     PatchRelocateVisitor patch_object_visitor(relocate_visitor, relocate_visitor);
   1577 
   1578     mirror::Class* dcheck_class_class = nullptr;  // Used only for a DCHECK().
   1579     for (const std::unique_ptr<ImageSpace>& space : spaces) {
   1580       // First patch the image header. The `diff` is OK for patching 32-bit fields but
   1581       // the 64-bit method fields in the ImageHeader may need a negative `delta`.
   1582       reinterpret_cast<ImageHeader*>(space->Begin())->RelocateImage(
   1583           (reinterpret_cast32<uint32_t>(space->Begin()) >= -diff)  // Would `begin+diff` overflow?
   1584               ? -static_cast<int64_t>(-diff) : static_cast<int64_t>(diff));
   1585 
   1586       // Patch fields and methods.
   1587       const ImageHeader& image_header = space->GetImageHeader();
   1588       image_header.VisitPackedArtFields([&](ArtField& field) REQUIRES_SHARED(Locks::mutator_lock_) {
   1589         patch_object_visitor.template PatchGcRoot</*kMayBeNull=*/ false>(
   1590             &field.DeclaringClassRoot());
   1591       }, space->Begin());
   1592       image_header.VisitPackedArtMethods([&](ArtMethod& method)
   1593           REQUIRES_SHARED(Locks::mutator_lock_) {
   1594         patch_object_visitor.PatchGcRoot(&method.DeclaringClassRoot());
   1595         void** data_address = PointerAddress(&method, ArtMethod::DataOffset(kPointerSize));
   1596         patch_object_visitor.PatchNativePointer(data_address);
   1597         void** entrypoint_address =
   1598             PointerAddress(&method, ArtMethod::EntryPointFromQuickCompiledCodeOffset(kPointerSize));
   1599         patch_object_visitor.PatchNativePointer(entrypoint_address);
   1600       }, space->Begin(), kPointerSize);
   1601       auto method_table_visitor = [&](ArtMethod* method) {
   1602         DCHECK(method != nullptr);
   1603         return relocate_visitor(method);
   1604       };
   1605       image_header.VisitPackedImTables(method_table_visitor, space->Begin(), kPointerSize);
   1606       image_header.VisitPackedImtConflictTables(method_table_visitor, space->Begin(), kPointerSize);
   1607 
   1608       // Patch the intern table.
   1609       if (image_header.GetInternedStringsSection().Size() != 0u) {
   1610         const uint8_t* data = space->Begin() + image_header.GetInternedStringsSection().Offset();
   1611         size_t read_count;
   1612         InternTable::UnorderedSet temp_set(data, /*make_copy_of_data=*/ false, &read_count);
   1613         for (GcRoot<mirror::String>& slot : temp_set) {
   1614           patch_object_visitor.template PatchGcRoot</*kMayBeNull=*/ false>(&slot);
   1615         }
   1616       }
   1617 
   1618       // Patch the class table and classes, so that we can traverse class hierarchy to
   1619       // determine the types of other objects when we visit them later.
   1620       if (image_header.GetClassTableSection().Size() != 0u) {
   1621         uint8_t* data = space->Begin() + image_header.GetClassTableSection().Offset();
   1622         size_t read_count;
   1623         ClassTable::ClassSet temp_set(data, /*make_copy_of_data=*/ false, &read_count);
   1624         DCHECK(!temp_set.empty());
   1625         ClassTableVisitor class_table_visitor(relocate_visitor);
   1626         for (ClassTable::TableSlot& slot : temp_set) {
   1627           slot.VisitRoot(class_table_visitor);
   1628           mirror::Class* klass = slot.Read<kWithoutReadBarrier>();
   1629           DCHECK(klass != nullptr);
   1630           patched_objects->Set(klass);
   1631           patch_object_visitor.VisitClass(klass);
   1632           if (kIsDebugBuild) {
   1633             mirror::Class* class_class = klass->GetClass<kVerifyNone, kWithoutReadBarrier>();
   1634             if (dcheck_class_class == nullptr) {
   1635               dcheck_class_class = class_class;
   1636             } else {
   1637               CHECK_EQ(class_class, dcheck_class_class);
   1638             }
   1639           }
   1640           // Then patch the non-embedded vtable and iftable.
   1641           ObjPtr<mirror::PointerArray> vtable =
   1642               klass->GetVTable<kVerifyNone, kWithoutReadBarrier>();
   1643           if (vtable != nullptr && !patched_objects->Set(vtable.Ptr())) {
   1644             patch_object_visitor.VisitPointerArray(vtable);
   1645           }
   1646           ObjPtr<mirror::IfTable> iftable = klass->GetIfTable<kVerifyNone, kWithoutReadBarrier>();
   1647           if (iftable != nullptr) {
   1648             int32_t ifcount = klass->GetIfTableCount<kVerifyNone>();
   1649             for (int32_t i = 0; i != ifcount; ++i) {
   1650               ObjPtr<mirror::PointerArray> unpatched_ifarray =
   1651                   iftable->GetMethodArrayOrNull<kVerifyNone, kWithoutReadBarrier>(i);
   1652               if (unpatched_ifarray != nullptr) {
   1653                 // The iftable has not been patched, so we need to explicitly adjust the pointer.
   1654                 ObjPtr<mirror::PointerArray> ifarray = relocate_visitor(unpatched_ifarray.Ptr());
   1655                 if (!patched_objects->Set(ifarray.Ptr())) {
   1656                   patch_object_visitor.VisitPointerArray(ifarray);
   1657                 }
   1658               }
   1659             }
   1660           }
   1661         }
   1662       }
   1663     }
   1664 
   1665     // Patch class roots now, so that we can recognize mirror::Method and mirror::Constructor.
   1666     ObjPtr<mirror::Class> method_class;
   1667     ObjPtr<mirror::Class> constructor_class;
   1668     {
   1669       const ImageSpace* space = spaces.front().get();
   1670       const ImageHeader& image_header = space->GetImageHeader();
   1671 
   1672       ObjPtr<mirror::ObjectArray<mirror::Object>> image_roots =
   1673           image_header.GetImageRoots<kWithoutReadBarrier>();
   1674       patched_objects->Set(image_roots.Ptr());
   1675       patch_object_visitor.VisitObject(image_roots.Ptr());
   1676 
   1677       ObjPtr<mirror::ObjectArray<mirror::Class>> class_roots =
   1678           ObjPtr<mirror::ObjectArray<mirror::Class>>::DownCast(
   1679               image_header.GetImageRoot<kWithoutReadBarrier>(ImageHeader::kClassRoots));
   1680       patched_objects->Set(class_roots.Ptr());
   1681       patch_object_visitor.VisitObject(class_roots.Ptr());
   1682 
   1683       method_class = GetClassRoot<mirror::Method, kWithoutReadBarrier>(class_roots);
   1684       constructor_class = GetClassRoot<mirror::Constructor, kWithoutReadBarrier>(class_roots);
   1685     }
   1686 
   1687     for (size_t s = 0u, size = spaces.size(); s != size; ++s) {
   1688       const ImageSpace* space = spaces[s].get();
   1689       const ImageHeader& image_header = space->GetImageHeader();
   1690 
   1691       static_assert(IsAligned<kObjectAlignment>(sizeof(ImageHeader)), "Header alignment check");
   1692       uint32_t objects_end = image_header.GetObjectsSection().Size();
   1693       DCHECK_ALIGNED(objects_end, kObjectAlignment);
   1694       for (uint32_t pos = sizeof(ImageHeader); pos != objects_end; ) {
   1695         mirror::Object* object = reinterpret_cast<mirror::Object*>(space->Begin() + pos);
   1696         if (!patched_objects->Test(object)) {
   1697           // This is the last pass over objects, so we do not need to Set().
   1698           patch_object_visitor.VisitObject(object);
   1699           ObjPtr<mirror::Class> klass = object->GetClass<kVerifyNone, kWithoutReadBarrier>();
   1700           if (klass->IsDexCacheClass<kVerifyNone>()) {
   1701             // Patch dex cache array pointers and elements.
   1702             ObjPtr<mirror::DexCache> dex_cache =
   1703                 object->AsDexCache<kVerifyNone, kWithoutReadBarrier>();
   1704             patch_object_visitor.VisitDexCacheArrays(dex_cache);
   1705           } else if (klass == method_class || klass == constructor_class) {
   1706             // Patch the ArtMethod* in the mirror::Executable subobject.
   1707             ObjPtr<mirror::Executable> as_executable =
   1708                 ObjPtr<mirror::Executable>::DownCast(object);
   1709             ArtMethod* unpatched_method = as_executable->GetArtMethod<kVerifyNone>();
   1710             ArtMethod* patched_method = relocate_visitor(unpatched_method);
   1711             as_executable->SetArtMethod</*kTransactionActive=*/ false,
   1712                                         /*kCheckTransaction=*/ true,
   1713                                         kVerifyNone>(patched_method);
   1714           }
   1715         }
   1716         pos += RoundUp(object->SizeOf<kVerifyNone>(), kObjectAlignment);
   1717       }
   1718     }
   1719   }
   1720 
   1721   void MaybeRelocateSpaces(const std::vector<std::unique_ptr<ImageSpace>>& spaces,
   1722                            TimingLogger* logger)
   1723       REQUIRES_SHARED(Locks::mutator_lock_) {
   1724     TimingLogger::ScopedTiming timing("MaybeRelocateSpaces", logger);
   1725     ImageSpace* first_space = spaces.front().get();
   1726     const ImageHeader& first_space_header = first_space->GetImageHeader();
   1727     uint32_t diff =
   1728         static_cast<uint32_t>(first_space->Begin() - first_space_header.GetImageBegin());
   1729     if (!relocate_) {
   1730       DCHECK_EQ(diff, 0u);
   1731       return;
   1732     }
   1733 
   1734     PointerSize pointer_size = first_space_header.GetPointerSize();
   1735     if (pointer_size == PointerSize::k64) {
   1736       DoRelocateSpaces<PointerSize::k64>(spaces, diff);
   1737     } else {
   1738       DoRelocateSpaces<PointerSize::k32>(spaces, diff);
   1739     }
   1740   }
   1741 
   1742   std::unique_ptr<ImageSpace> Load(const std::string& image_location,
   1743                                    const std::string& image_filename,
   1744                                    TimingLogger* logger,
   1745                                    /*inout*/MemMap* image_reservation,
   1746                                    /*out*/std::string* error_msg)
   1747       REQUIRES_SHARED(Locks::mutator_lock_) {
   1748     // Should this be a RDWR lock? This is only a defensive measure, as at
   1749     // this point the image should exist.
   1750     // However, only the zygote can write into the global dalvik-cache, so
   1751     // restrict to zygote processes, or any process that isn't using
   1752     // /data/dalvik-cache (which we assume to be allowed to write there).
   1753     const bool rw_lock = is_zygote_ || !is_global_cache_;
   1754 
   1755     // Note that we must not use the file descriptor associated with
   1756     // ScopedFlock::GetFile to Init the image file. We want the file
   1757     // descriptor (and the associated exclusive lock) to be released when
   1758     // we leave Create.
   1759     ScopedFlock image = LockedFile::Open(image_filename.c_str(),
   1760                                          /*flags=*/ rw_lock ? (O_CREAT | O_RDWR) : O_RDONLY,
   1761                                          /*block=*/ true,
   1762                                          error_msg);
   1763 
   1764     VLOG(startup) << "Using image file " << image_filename.c_str() << " for image location "
   1765                   << image_location;
   1766     // If we are in /system we can assume the image is good. We can also
   1767     // assume this if we are using a relocated image (i.e. image checksum
   1768     // matches) since this is only different by the offset. We need this to
   1769     // make sure that host tests continue to work.
   1770     // Since we are the boot image, pass null since we load the oat file from the boot image oat
   1771     // file name.
   1772     return Loader::Init(image_filename.c_str(),
   1773                         image_location.c_str(),
   1774                         /*oat_file=*/ nullptr,
   1775                         logger,
   1776                         image_reservation,
   1777                         error_msg);
   1778   }
   1779 
   1780   bool OpenOatFile(ImageSpace* space,
   1781                    const std::string& dex_filename,
   1782                    const std::string& expected_boot_class_path,
   1783                    bool validate_oat_file,
   1784                    TimingLogger* logger,
   1785                    /*inout*/MemMap* image_reservation,
   1786                    /*out*/std::string* error_msg) {
   1787     // VerifyImageAllocations() will be called later in Runtime::Init()
   1788     // as some class roots like ArtMethod::java_lang_reflect_ArtMethod_
   1789     // and ArtField::java_lang_reflect_ArtField_, which are used from
   1790     // Object::SizeOf() which VerifyImageAllocations() calls, are not
   1791     // set yet at this point.
   1792     DCHECK(image_reservation != nullptr);
   1793     std::unique_ptr<OatFile> oat_file;
   1794     {
   1795       TimingLogger::ScopedTiming timing("OpenOatFile", logger);
   1796       std::string oat_filename =
   1797           ImageHeader::GetOatLocationFromImageLocation(space->GetImageFilename());
   1798       std::string oat_location =
   1799           ImageHeader::GetOatLocationFromImageLocation(space->GetImageLocation());
   1800 
   1801       oat_file.reset(OatFile::Open(/*zip_fd=*/ -1,
   1802                                    oat_filename,
   1803                                    oat_location,
   1804                                    executable_,
   1805                                    /*low_4gb=*/ false,
   1806                                    /*abs_dex_location=*/ dex_filename.c_str(),
   1807                                    image_reservation,
   1808                                    error_msg));
   1809       if (oat_file == nullptr) {
   1810         *error_msg = StringPrintf("Failed to open oat file '%s' referenced from image %s: %s",
   1811                                   oat_filename.c_str(),
   1812                                   space->GetName(),
   1813                                   error_msg->c_str());
   1814         return false;
   1815       }
   1816       const ImageHeader& image_header = space->GetImageHeader();
   1817       uint32_t oat_checksum = oat_file->GetOatHeader().GetChecksum();
   1818       uint32_t image_oat_checksum = image_header.GetOatChecksum();
   1819       if (oat_checksum != image_oat_checksum) {
   1820         *error_msg = StringPrintf("Failed to match oat file checksum 0x%x to expected oat checksum"
   1821                                   " 0x%x in image %s",
   1822                                   oat_checksum,
   1823                                   image_oat_checksum,
   1824                                   space->GetName());
   1825         return false;
   1826       }
   1827       const char* oat_boot_class_path =
   1828           oat_file->GetOatHeader().GetStoreValueByKey(OatHeader::kBootClassPathKey);
   1829       oat_boot_class_path = (oat_boot_class_path != nullptr) ? oat_boot_class_path : "";
   1830       if (expected_boot_class_path != oat_boot_class_path) {
   1831         *error_msg = StringPrintf("Failed to match oat boot class path %s to expected "
   1832                                   "boot class path %s in image %s",
   1833                                   oat_boot_class_path,
   1834                                   expected_boot_class_path.c_str(),
   1835                                   space->GetName());
   1836         return false;
   1837       }
   1838       ptrdiff_t relocation_diff = space->Begin() - image_header.GetImageBegin();
   1839       CHECK(image_header.GetOatDataBegin() != nullptr);
   1840       uint8_t* oat_data_begin = image_header.GetOatDataBegin() + relocation_diff;
   1841       if (oat_file->Begin() != oat_data_begin) {
   1842         *error_msg = StringPrintf("Oat file '%s' referenced from image %s has unexpected begin"
   1843                                       " %p v. %p",
   1844                                   oat_filename.c_str(),
   1845                                   space->GetName(),
   1846                                   oat_file->Begin(),
   1847                                   oat_data_begin);
   1848         return false;
   1849       }
   1850     }
   1851     if (validate_oat_file) {
   1852       TimingLogger::ScopedTiming timing("ValidateOatFile", logger);
   1853       if (!ImageSpace::ValidateOatFile(*oat_file, error_msg)) {
   1854         DCHECK(!error_msg->empty());
   1855         return false;
   1856       }
   1857     }
   1858     space->oat_file_ = std::move(oat_file);
   1859     space->oat_file_non_owned_ = space->oat_file_.get();
   1860     return true;
   1861   }
   1862 
   1863   bool ReserveBootImageMemory(uint32_t reservation_size,
   1864                               uint32_t image_start,
   1865                               size_t extra_reservation_size,
   1866                               /*out*/MemMap* image_reservation,
   1867                               /*out*/MemMap* extra_reservation,
   1868                               /*out*/std::string* error_msg) {
   1869     DCHECK_ALIGNED(reservation_size, kPageSize);
   1870     DCHECK_ALIGNED(image_start, kPageSize);
   1871     DCHECK(!image_reservation->IsValid());
   1872     DCHECK_LT(extra_reservation_size, std::numeric_limits<uint32_t>::max() - reservation_size);
   1873     size_t total_size = reservation_size + extra_reservation_size;
   1874     // If relocating, choose a random address for ALSR.
   1875     uint32_t addr = relocate_ ? ART_BASE_ADDRESS + ChooseRelocationOffsetDelta() : image_start;
   1876     *image_reservation =
   1877         MemMap::MapAnonymous("Boot image reservation",
   1878                              reinterpret_cast32<uint8_t*>(addr),
   1879                              total_size,
   1880                              PROT_NONE,
   1881                              /*low_4gb=*/ true,
   1882                              /*reuse=*/ false,
   1883                              /*reservation=*/ nullptr,
   1884                              error_msg);
   1885     if (!image_reservation->IsValid()) {
   1886       return false;
   1887     }
   1888     DCHECK(!extra_reservation->IsValid());
   1889     if (extra_reservation_size != 0u) {
   1890       DCHECK_ALIGNED(extra_reservation_size, kPageSize);
   1891       DCHECK_LT(extra_reservation_size, image_reservation->Size());
   1892       uint8_t* split = image_reservation->End() - extra_reservation_size;
   1893       *extra_reservation = image_reservation->RemapAtEnd(split,
   1894                                                          "Boot image extra reservation",
   1895                                                          PROT_NONE,
   1896                                                          error_msg);
   1897       if (!extra_reservation->IsValid()) {
   1898         return false;
   1899       }
   1900     }
   1901 
   1902     return true;
   1903   }
   1904 
   1905   bool CheckReservationExhausted(const MemMap& image_reservation, /*out*/std::string* error_msg) {
   1906     if (image_reservation.IsValid()) {
   1907       *error_msg = StringPrintf("Excessive image reservation after loading boot image: %p-%p",
   1908                                 image_reservation.Begin(),
   1909                                 image_reservation.End());
   1910       return false;
   1911     }
   1912     return true;
   1913   }
   1914 
   1915   const std::vector<std::string>& boot_class_path_;
   1916   const std::vector<std::string>& boot_class_path_locations_;
   1917   const std::string& image_location_;
   1918   InstructionSet image_isa_;
   1919   bool relocate_;
   1920   bool executable_;
   1921   bool is_zygote_;
   1922   bool has_system_;
   1923   bool has_cache_;
   1924   bool is_global_cache_;
   1925   bool dalvik_cache_exists_;
   1926   std::string dalvik_cache_;
   1927   std::string cache_filename_;
   1928 };
   1929 
   1930 static constexpr uint64_t kLowSpaceValue = 50 * MB;
   1931 static constexpr uint64_t kTmpFsSentinelValue = 384 * MB;
   1932 
   1933 // Read the free space of the cache partition and make a decision whether to keep the generated
   1934 // image. This is to try to mitigate situations where the system might run out of space later.
   1935 static bool CheckSpace(const std::string& cache_filename, std::string* error_msg) {
   1936   // Using statvfs vs statvfs64 because of b/18207376, and it is enough for all practical purposes.
   1937   struct statvfs buf;
   1938 
   1939   int res = TEMP_FAILURE_RETRY(statvfs(cache_filename.c_str(), &buf));
   1940   if (res != 0) {
   1941     // Could not stat. Conservatively tell the system to delete the image.
   1942     *error_msg = "Could not stat the filesystem, assuming low-memory situation.";
   1943     return false;
   1944   }
   1945 
   1946   uint64_t fs_overall_size = buf.f_bsize * static_cast<uint64_t>(buf.f_blocks);
   1947   // Zygote is privileged, but other things are not. Use bavail.
   1948   uint64_t fs_free_size = buf.f_bsize * static_cast<uint64_t>(buf.f_bavail);
   1949 
   1950   // Take the overall size as an indicator for a tmpfs, which is being used for the decryption
   1951   // environment. We do not want to fail quickening the boot image there, as it is beneficial
   1952   // for time-to-UI.
   1953   if (fs_overall_size > kTmpFsSentinelValue) {
   1954     if (fs_free_size < kLowSpaceValue) {
   1955       *error_msg = StringPrintf("Low-memory situation: only %4.2f megabytes available, need at "
   1956                                 "least %" PRIu64 ".",
   1957                                 static_cast<double>(fs_free_size) / MB,
   1958                                 kLowSpaceValue / MB);
   1959       return false;
   1960     }
   1961   }
   1962   return true;
   1963 }
   1964 
   1965 bool ImageSpace::LoadBootImage(
   1966     const std::vector<std::string>& boot_class_path,
   1967     const std::vector<std::string>& boot_class_path_locations,
   1968     const std::string& image_location,
   1969     const InstructionSet image_isa,
   1970     ImageSpaceLoadingOrder order,
   1971     bool relocate,
   1972     bool executable,
   1973     bool is_zygote,
   1974     size_t extra_reservation_size,
   1975     /*out*/std::vector<std::unique_ptr<space::ImageSpace>>* boot_image_spaces,
   1976     /*out*/MemMap* extra_reservation) {
   1977   ScopedTrace trace(__FUNCTION__);
   1978 
   1979   DCHECK(boot_image_spaces != nullptr);
   1980   DCHECK(boot_image_spaces->empty());
   1981   DCHECK_ALIGNED(extra_reservation_size, kPageSize);
   1982   DCHECK(extra_reservation != nullptr);
   1983   DCHECK_NE(image_isa, InstructionSet::kNone);
   1984 
   1985   if (image_location.empty()) {
   1986     return false;
   1987   }
   1988 
   1989   BootImageLoader loader(boot_class_path,
   1990                          boot_class_path_locations,
   1991                          image_location,
   1992                          image_isa,
   1993                          relocate,
   1994                          executable,
   1995                          is_zygote);
   1996 
   1997   // Step 0: Extra zygote work.
   1998 
   1999   // Step 0.a: If we're the zygote, mark boot.
   2000   if (loader.IsZygote() && CanWriteToDalvikCache(image_isa)) {
   2001     MarkZygoteStart(image_isa, Runtime::Current()->GetZygoteMaxFailedBoots());
   2002   }
   2003 
   2004   loader.FindImageFiles();
   2005 
   2006   // Step 0.b: If we're the zygote, check for free space, and prune the cache preemptively,
   2007   //           if necessary. While the runtime may be fine (it is pretty tolerant to
   2008   //           out-of-disk-space situations), other parts of the platform are not.
   2009   //
   2010   //           The advantage of doing this proactively is that the later steps are simplified,
   2011   //           i.e., we do not need to code retries.
   2012   bool low_space = false;
   2013   if (loader.IsZygote() && loader.DalvikCacheExists()) {
   2014     // Extra checks for the zygote. These only apply when loading the first image, explained below.
   2015     const std::string& dalvik_cache = loader.GetDalvikCache();
   2016     DCHECK(!dalvik_cache.empty());
   2017     std::string local_error_msg;
   2018     bool check_space = CheckSpace(dalvik_cache, &local_error_msg);
   2019     if (!check_space) {
   2020       LOG(WARNING) << local_error_msg << " Preemptively pruning the dalvik cache.";
   2021       PruneDalvikCache(image_isa);
   2022 
   2023       // Re-evaluate the image.
   2024       loader.FindImageFiles();
   2025 
   2026       // Disable compilation/patching - we do not want to fill up the space again.
   2027       low_space = true;
   2028     }
   2029   }
   2030 
   2031   // Collect all the errors.
   2032   std::vector<std::string> error_msgs;
   2033 
   2034   auto try_load_from = [&](auto has_fn, auto load_fn, bool validate_oat_file) {
   2035     if ((loader.*has_fn)()) {
   2036       std::string local_error_msg;
   2037       if ((loader.*load_fn)(validate_oat_file,
   2038                             extra_reservation_size,
   2039                             boot_image_spaces,
   2040                             extra_reservation,
   2041                             &local_error_msg)) {
   2042         return true;
   2043       }
   2044       error_msgs.push_back(local_error_msg);
   2045     }
   2046     return false;
   2047   };
   2048 
   2049   auto try_load_from_system = [&]() {
   2050     return try_load_from(&BootImageLoader::HasSystem, &BootImageLoader::LoadFromSystem, false);
   2051   };
   2052   auto try_load_from_cache = [&]() {
   2053     return try_load_from(&BootImageLoader::HasCache, &BootImageLoader::LoadFromDalvikCache, true);
   2054   };
   2055 
   2056   auto invoke_sequentially = [](auto first, auto second) {
   2057     return first() || second();
   2058   };
   2059 
   2060   // Step 1+2: Check system and cache images in the asked-for order.
   2061   if (order == ImageSpaceLoadingOrder::kSystemFirst) {
   2062     if (invoke_sequentially(try_load_from_system, try_load_from_cache)) {
   2063       return true;
   2064     }
   2065   } else {
   2066     if (invoke_sequentially(try_load_from_cache, try_load_from_system)) {
   2067       return true;
   2068     }
   2069   }
   2070 
   2071   // Step 3: We do not have an existing image in /system,
   2072   //         so generate an image into the dalvik cache.
   2073   if (!loader.HasSystem() && loader.DalvikCacheExists()) {
   2074     std::string local_error_msg;
   2075     if (low_space || !Runtime::Current()->IsImageDex2OatEnabled()) {
   2076       local_error_msg = "Image compilation disabled.";
   2077     } else if (ImageCreationAllowed(loader.IsGlobalCache(),
   2078                                     image_isa,
   2079                                     is_zygote,
   2080                                     &local_error_msg)) {
   2081       bool compilation_success =
   2082           GenerateImage(loader.GetCacheFilename(), image_isa, &local_error_msg);
   2083       if (compilation_success) {
   2084         if (loader.LoadFromDalvikCache(/*validate_oat_file=*/ false,
   2085                                        extra_reservation_size,
   2086                                        boot_image_spaces,
   2087                                        extra_reservation,
   2088                                        &local_error_msg)) {
   2089           return true;
   2090         }
   2091       }
   2092     }
   2093     error_msgs.push_back(StringPrintf("Cannot compile image to %s: %s",
   2094                                       loader.GetCacheFilename().c_str(),
   2095                                       local_error_msg.c_str()));
   2096   }
   2097 
   2098   // We failed. Prune the cache the free up space, create a compound error message
   2099   // and return false.
   2100   if (loader.DalvikCacheExists()) {
   2101     PruneDalvikCache(image_isa);
   2102   }
   2103 
   2104   std::ostringstream oss;
   2105   bool first = true;
   2106   for (const auto& msg : error_msgs) {
   2107     if (!first) {
   2108       oss << "\n    ";
   2109     }
   2110     oss << msg;
   2111   }
   2112 
   2113   LOG(ERROR) << "Could not create image space with image file '" << image_location << "'. "
   2114       << "Attempting to fall back to imageless running. Error was: " << oss.str();
   2115 
   2116   return false;
   2117 }
   2118 
   2119 ImageSpace::~ImageSpace() {
   2120   // Everything done by member destructors. Classes forward-declared in header are now defined.
   2121 }
   2122 
   2123 std::unique_ptr<ImageSpace> ImageSpace::CreateFromAppImage(const char* image,
   2124                                                            const OatFile* oat_file,
   2125                                                            std::string* error_msg) {
   2126   // Note: The oat file has already been validated.
   2127   return Loader::InitAppImage(image,
   2128                               image,
   2129                               oat_file,
   2130                               /*image_reservation=*/ nullptr,
   2131                               error_msg);
   2132 }
   2133 
   2134 const OatFile* ImageSpace::GetOatFile() const {
   2135   return oat_file_non_owned_;
   2136 }
   2137 
   2138 std::unique_ptr<const OatFile> ImageSpace::ReleaseOatFile() {
   2139   CHECK(oat_file_ != nullptr);
   2140   return std::move(oat_file_);
   2141 }
   2142 
   2143 void ImageSpace::Dump(std::ostream& os) const {
   2144   os << GetType()
   2145       << " begin=" << reinterpret_cast<void*>(Begin())
   2146       << ",end=" << reinterpret_cast<void*>(End())
   2147       << ",size=" << PrettySize(Size())
   2148       << ",name=\"" << GetName() << "\"]";
   2149 }
   2150 
   2151 bool ImageSpace::ValidateOatFile(const OatFile& oat_file, std::string* error_msg) {
   2152   const ArtDexFileLoader dex_file_loader;
   2153   for (const OatDexFile* oat_dex_file : oat_file.GetOatDexFiles()) {
   2154     const std::string& dex_file_location = oat_dex_file->GetDexFileLocation();
   2155 
   2156     // Skip multidex locations - These will be checked when we visit their
   2157     // corresponding primary non-multidex location.
   2158     if (DexFileLoader::IsMultiDexLocation(dex_file_location.c_str())) {
   2159       continue;
   2160     }
   2161 
   2162     std::vector<uint32_t> checksums;
   2163     if (!dex_file_loader.GetMultiDexChecksums(dex_file_location.c_str(), &checksums, error_msg)) {
   2164       *error_msg = StringPrintf("ValidateOatFile failed to get checksums of dex file '%s' "
   2165                                 "referenced by oat file %s: %s",
   2166                                 dex_file_location.c_str(),
   2167                                 oat_file.GetLocation().c_str(),
   2168                                 error_msg->c_str());
   2169       return false;
   2170     }
   2171     CHECK(!checksums.empty());
   2172     if (checksums[0] != oat_dex_file->GetDexFileLocationChecksum()) {
   2173       *error_msg = StringPrintf("ValidateOatFile found checksum mismatch between oat file "
   2174                                 "'%s' and dex file '%s' (0x%x != 0x%x)",
   2175                                 oat_file.GetLocation().c_str(),
   2176                                 dex_file_location.c_str(),
   2177                                 oat_dex_file->GetDexFileLocationChecksum(),
   2178                                 checksums[0]);
   2179       return false;
   2180     }
   2181 
   2182     // Verify checksums for any related multidex entries.
   2183     for (size_t i = 1; i < checksums.size(); i++) {
   2184       std::string multi_dex_location = DexFileLoader::GetMultiDexLocation(
   2185           i,
   2186           dex_file_location.c_str());
   2187       const OatDexFile* multi_dex = oat_file.GetOatDexFile(multi_dex_location.c_str(),
   2188                                                            nullptr,
   2189                                                            error_msg);
   2190       if (multi_dex == nullptr) {
   2191         *error_msg = StringPrintf("ValidateOatFile oat file '%s' is missing entry '%s'",
   2192                                   oat_file.GetLocation().c_str(),
   2193                                   multi_dex_location.c_str());
   2194         return false;
   2195       }
   2196 
   2197       if (checksums[i] != multi_dex->GetDexFileLocationChecksum()) {
   2198         *error_msg = StringPrintf("ValidateOatFile found checksum mismatch between oat file "
   2199                                   "'%s' and dex file '%s' (0x%x != 0x%x)",
   2200                                   oat_file.GetLocation().c_str(),
   2201                                   multi_dex_location.c_str(),
   2202                                   multi_dex->GetDexFileLocationChecksum(),
   2203                                   checksums[i]);
   2204         return false;
   2205       }
   2206     }
   2207   }
   2208   return true;
   2209 }
   2210 
   2211 std::string ImageSpace::GetBootClassPathChecksums(ArrayRef<const std::string> boot_class_path,
   2212                                                   const std::string& image_location,
   2213                                                   InstructionSet image_isa,
   2214                                                   ImageSpaceLoadingOrder order,
   2215                                                   /*out*/std::string* error_msg) {
   2216   std::string system_filename;
   2217   bool has_system = false;
   2218   std::string cache_filename;
   2219   bool has_cache = false;
   2220   bool dalvik_cache_exists = false;
   2221   bool is_global_cache = false;
   2222   if (!FindImageFilename(image_location.c_str(),
   2223                          image_isa,
   2224                          &system_filename,
   2225                          &has_system,
   2226                          &cache_filename,
   2227                          &dalvik_cache_exists,
   2228                          &has_cache,
   2229                          &is_global_cache)) {
   2230     *error_msg = StringPrintf("Unable to find image file for %s and %s",
   2231                               image_location.c_str(),
   2232                               GetInstructionSetString(image_isa));
   2233     return std::string();
   2234   }
   2235 
   2236   DCHECK(has_system || has_cache);
   2237   const std::string& filename = (order == ImageSpaceLoadingOrder::kSystemFirst)
   2238       ? (has_system ? system_filename : cache_filename)
   2239       : (has_cache ? cache_filename : system_filename);
   2240   std::unique_ptr<ImageHeader> header = ReadSpecificImageHeader(filename.c_str(), error_msg);
   2241   if (header == nullptr) {
   2242     return std::string();
   2243   }
   2244   if (header->GetComponentCount() == 0u || header->GetComponentCount() > boot_class_path.size()) {
   2245     *error_msg = StringPrintf("Unexpected component count in %s, received %u, "
   2246                                   "expected non-zero and <= %zu",
   2247                               filename.c_str(),
   2248                               header->GetComponentCount(),
   2249                               boot_class_path.size());
   2250     return std::string();
   2251   }
   2252 
   2253   std::string boot_image_checksum =
   2254       StringPrintf("i;%d/%08x", header->GetComponentCount(), header->GetImageChecksum());
   2255   ArrayRef<const std::string> boot_class_path_tail =
   2256       ArrayRef<const std::string>(boot_class_path).SubArray(header->GetComponentCount());
   2257   for (const std::string& bcp_filename : boot_class_path_tail) {
   2258     std::vector<std::unique_ptr<const DexFile>> dex_files;
   2259     const ArtDexFileLoader dex_file_loader;
   2260     if (!dex_file_loader.Open(bcp_filename.c_str(),
   2261                               bcp_filename,  // The location does not matter here.
   2262                               /*verify=*/ false,
   2263                               /*verify_checksum=*/ false,
   2264                               error_msg,
   2265                               &dex_files)) {
   2266       return std::string();
   2267     }
   2268     DCHECK(!dex_files.empty());
   2269     StringAppendF(&boot_image_checksum, ":d");
   2270     for (const std::unique_ptr<const DexFile>& dex_file : dex_files) {
   2271       StringAppendF(&boot_image_checksum, "/%08x", dex_file->GetLocationChecksum());
   2272     }
   2273   }
   2274   return boot_image_checksum;
   2275 }
   2276 
   2277 std::string ImageSpace::GetBootClassPathChecksums(
   2278     const std::vector<ImageSpace*>& image_spaces,
   2279     const std::vector<const DexFile*>& boot_class_path) {
   2280   size_t pos = 0u;
   2281   std::string boot_image_checksum;
   2282 
   2283   if (!image_spaces.empty()) {
   2284     const ImageHeader& primary_header = image_spaces.front()->GetImageHeader();
   2285     uint32_t component_count = primary_header.GetComponentCount();
   2286     DCHECK_EQ(component_count, image_spaces.size());
   2287     boot_image_checksum =
   2288         StringPrintf("i;%d/%08x", component_count, primary_header.GetImageChecksum());
   2289     for (const ImageSpace* space : image_spaces) {
   2290       size_t num_dex_files = space->oat_file_non_owned_->GetOatDexFiles().size();
   2291       if (kIsDebugBuild) {
   2292         CHECK_NE(num_dex_files, 0u);
   2293         CHECK_LE(space->oat_file_non_owned_->GetOatDexFiles().size(), boot_class_path.size() - pos);
   2294         for (size_t i = 0; i != num_dex_files; ++i) {
   2295           CHECK_EQ(space->oat_file_non_owned_->GetOatDexFiles()[i]->GetDexFileLocation(),
   2296                    boot_class_path[pos + i]->GetLocation());
   2297         }
   2298       }
   2299       pos += num_dex_files;
   2300     }
   2301   }
   2302 
   2303   ArrayRef<const DexFile* const> boot_class_path_tail =
   2304       ArrayRef<const DexFile* const>(boot_class_path).SubArray(pos);
   2305   DCHECK(boot_class_path_tail.empty() ||
   2306          !DexFileLoader::IsMultiDexLocation(boot_class_path_tail.front()->GetLocation().c_str()));
   2307   for (const DexFile* dex_file : boot_class_path_tail) {
   2308     if (!DexFileLoader::IsMultiDexLocation(dex_file->GetLocation().c_str())) {
   2309       StringAppendF(&boot_image_checksum, boot_image_checksum.empty() ? "d" : ":d");
   2310     }
   2311     StringAppendF(&boot_image_checksum, "/%08x", dex_file->GetLocationChecksum());
   2312   }
   2313   return boot_image_checksum;
   2314 }
   2315 
   2316 std::vector<std::string> ImageSpace::ExpandMultiImageLocations(
   2317     const std::vector<std::string>& dex_locations,
   2318     const std::string& image_location) {
   2319   return ExpandMultiImageLocations(ArrayRef<const std::string>(dex_locations), image_location);
   2320 }
   2321 
   2322 std::vector<std::string> ImageSpace::ExpandMultiImageLocations(
   2323     ArrayRef<const std::string> dex_locations,
   2324     const std::string& image_location) {
   2325   DCHECK(!dex_locations.empty());
   2326 
   2327   // Find the path.
   2328   size_t last_slash = image_location.rfind('/');
   2329   CHECK_NE(last_slash, std::string::npos);
   2330 
   2331   // We also need to honor path components that were encoded through '@'. Otherwise the loading
   2332   // code won't be able to find the images.
   2333   if (image_location.find('@', last_slash) != std::string::npos) {
   2334     last_slash = image_location.rfind('@');
   2335   }
   2336 
   2337   // Find the dot separating the primary image name from the extension.
   2338   size_t last_dot = image_location.rfind('.');
   2339   // Extract the extension and base (the path and primary image name).
   2340   std::string extension;
   2341   std::string base = image_location;
   2342   if (last_dot != std::string::npos && last_dot > last_slash) {
   2343     extension = image_location.substr(last_dot);  // Including the dot.
   2344     base.resize(last_dot);
   2345   }
   2346   // For non-empty primary image name, add '-' to the `base`.
   2347   if (last_slash + 1u != base.size()) {
   2348     base += '-';
   2349   }
   2350 
   2351   std::vector<std::string> locations;
   2352   locations.reserve(dex_locations.size());
   2353   locations.push_back(image_location);
   2354 
   2355   // Now create the other names. Use a counted loop to skip the first one.
   2356   for (size_t i = 1u; i < dex_locations.size(); ++i) {
   2357     // Replace path with `base` (i.e. image path and prefix) and replace the original
   2358     // extension (if any) with `extension`.
   2359     std::string name = dex_locations[i];
   2360     size_t last_dex_slash = name.rfind('/');
   2361     if (last_dex_slash != std::string::npos) {
   2362       name = name.substr(last_dex_slash + 1);
   2363     }
   2364     size_t last_dex_dot = name.rfind('.');
   2365     if (last_dex_dot != std::string::npos) {
   2366       name.resize(last_dex_dot);
   2367     }
   2368     locations.push_back(base + name + extension);
   2369   }
   2370   return locations;
   2371 }
   2372 
   2373 void ImageSpace::DumpSections(std::ostream& os) const {
   2374   const uint8_t* base = Begin();
   2375   const ImageHeader& header = GetImageHeader();
   2376   for (size_t i = 0; i < ImageHeader::kSectionCount; ++i) {
   2377     auto section_type = static_cast<ImageHeader::ImageSections>(i);
   2378     const ImageSection& section = header.GetImageSection(section_type);
   2379     os << section_type << " " << reinterpret_cast<const void*>(base + section.Offset())
   2380        << "-" << reinterpret_cast<const void*>(base + section.End()) << "\n";
   2381   }
   2382 }
   2383 
   2384 void ImageSpace::DisablePreResolvedStrings() {
   2385   // Clear dex cache pointers.
   2386   ObjPtr<mirror::ObjectArray<mirror::DexCache>> dex_caches =
   2387       GetImageHeader().GetImageRoot(ImageHeader::kDexCaches)->AsObjectArray<mirror::DexCache>();
   2388   for (size_t len = dex_caches->GetLength(), i = 0; i < len; ++i) {
   2389     ObjPtr<mirror::DexCache> dex_cache = dex_caches->Get(i);
   2390     dex_cache->ClearPreResolvedStrings();
   2391   }
   2392 }
   2393 
   2394 void ImageSpace::ReleaseMetadata() {
   2395   const ImageSection& metadata = GetImageHeader().GetMetadataSection();
   2396   VLOG(image) << "Releasing " << metadata.Size() << " image metadata bytes";
   2397   // In the case where new app images may have been added around the checkpoint, ensure that we
   2398   // don't madvise the cache for these.
   2399   ObjPtr<mirror::ObjectArray<mirror::DexCache>> dex_caches =
   2400       GetImageHeader().GetImageRoot(ImageHeader::kDexCaches)->AsObjectArray<mirror::DexCache>();
   2401   bool have_startup_cache = false;
   2402   for (size_t len = dex_caches->GetLength(), i = 0; i < len; ++i) {
   2403     ObjPtr<mirror::DexCache> dex_cache = dex_caches->Get(i);
   2404     if (dex_cache->NumPreResolvedStrings() != 0u) {
   2405       have_startup_cache = true;
   2406     }
   2407   }
   2408   // Only safe to do for images that have their preresolved strings caches disabled. This is because
   2409   // uncompressed images madvise to the original unrelocated image contents.
   2410   if (!have_startup_cache) {
   2411     // Avoid using ZeroAndReleasePages since the zero fill might not be word atomic.
   2412     uint8_t* const page_begin = AlignUp(Begin() + metadata.Offset(), kPageSize);
   2413     uint8_t* const page_end = AlignDown(Begin() + metadata.End(), kPageSize);
   2414     if (page_begin < page_end) {
   2415       CHECK_NE(madvise(page_begin, page_end - page_begin, MADV_DONTNEED), -1) << "madvise failed";
   2416     }
   2417   }
   2418 }
   2419 
   2420 }  // namespace space
   2421 }  // namespace gc
   2422 }  // namespace art
   2423