• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 "runtime_image.h"
18 
19 #include <lz4.h>
20 #include <unistd.h>
21 
22 #include "android-base/file.h"
23 #include "android-base/stringprintf.h"
24 #include "android-base/strings.h"
25 #include "arch/instruction_set.h"
26 #include "arch/instruction_set_features.h"
27 #include "base/arena_allocator.h"
28 #include "base/arena_containers.h"
29 #include "base/bit_utils.h"
30 #include "base/file_utils.h"
31 #include "base/length_prefixed_array.h"
32 #include "base/scoped_flock.h"
33 #include "base/stl_util.h"
34 #include "base/systrace.h"
35 #include "base/unix_file/fd_file.h"
36 #include "base/utils.h"
37 #include "class_loader_context.h"
38 #include "class_loader_utils.h"
39 #include "class_root-inl.h"
40 #include "dex/class_accessor-inl.h"
41 #include "gc/space/image_space.h"
42 #include "mirror/object-inl.h"
43 #include "mirror/object-refvisitor-inl.h"
44 #include "mirror/object_array-alloc-inl.h"
45 #include "mirror/object_array-inl.h"
46 #include "mirror/object_array.h"
47 #include "mirror/string-inl.h"
48 #include "nterp_helpers.h"
49 #include "oat/image.h"
50 #include "oat/oat.h"
51 #include "profile/profile_compilation_info.h"
52 #include "scoped_thread_state_change-inl.h"
53 #include "vdex_file.h"
54 
55 namespace art HIDDEN {
56 
57 using android::base::StringPrintf;
58 
59 /**
60  * The native data structures that we store in the image.
61  */
62 enum class NativeRelocationKind {
63   kArtFieldArray,
64   kArtMethodArray,
65   kArtMethod,
66   kImTable,
67   // For dex cache arrays which can stay in memory even after startup. Those are
68   // dex cache arrays whose size is below a given threshold, defined by
69   // DexCache::ShouldAllocateFullArray.
70   kFullNativeDexCacheArray,
71   // For dex cache arrays which we will want to release after app startup.
72   kStartupNativeDexCacheArray,
73 };
74 
75 /**
76  * Helper class to generate an app image at runtime.
77  */
78 class RuntimeImageHelper {
79  public:
RuntimeImageHelper(gc::Heap * heap)80   explicit RuntimeImageHelper(gc::Heap* heap) :
81     allocator_(Runtime::Current()->GetArenaPool()),
82     objects_(allocator_.Adapter()),
83     art_fields_(allocator_.Adapter()),
84     art_methods_(allocator_.Adapter()),
85     im_tables_(allocator_.Adapter()),
86     metadata_(allocator_.Adapter()),
87     dex_cache_arrays_(allocator_.Adapter()),
88     string_reference_offsets_(allocator_.Adapter()),
89     sections_(ImageHeader::kSectionCount, allocator_.Adapter()),
90     object_offsets_(allocator_.Adapter()),
91     classes_(allocator_.Adapter()),
92     array_classes_(allocator_.Adapter()),
93     dex_caches_(allocator_.Adapter()),
94     class_hashes_(allocator_.Adapter()),
95     native_relocations_(allocator_.Adapter()),
96     boot_image_begin_(heap->GetBootImagesStartAddress()),
97     boot_image_size_(heap->GetBootImagesSize()),
98     image_begin_(boot_image_begin_ + boot_image_size_),
99     // Note: image relocation considers the image header in the bitmap.
100     object_section_size_(sizeof(ImageHeader)),
101     intern_table_(InternStringHash(this), InternStringEquals(this)),
102     class_table_(ClassDescriptorHash(this), ClassDescriptorEquals()) {}
103 
Generate(std::string * error_msg)104   bool Generate(std::string* error_msg) {
105     if (!WriteObjects(error_msg)) {
106       return false;
107     }
108 
109     // Generate the sections information stored in the header.
110     CreateImageSections();
111 
112     // Now that all sections have been created and we know their offset and
113     // size, relocate native pointers inside classes and ImTables.
114     RelocateNativePointers();
115 
116     // Generate the bitmap section, stored kElfSegmentAlignment-aligned after the sections data and
117     // of size `object_section_size_` rounded up to kCardSize to match the bitmap size expected by
118     // Loader::Init at art::gc::space::ImageSpace.
119     size_t sections_end = sections_[ImageHeader::kSectionMetadata].End();
120     image_bitmap_ = gc::accounting::ContinuousSpaceBitmap::Create(
121         "image bitmap",
122         reinterpret_cast<uint8_t*>(image_begin_),
123         RoundUp(object_section_size_, gc::accounting::CardTable::kCardSize));
124     for (uint32_t offset : object_offsets_) {
125       DCHECK(IsAligned<kObjectAlignment>(image_begin_ + sizeof(ImageHeader) + offset));
126       image_bitmap_.Set(
127           reinterpret_cast<mirror::Object*>(image_begin_ + sizeof(ImageHeader) + offset));
128     }
129     const size_t bitmap_bytes = image_bitmap_.Size();
130     auto* bitmap_section = &sections_[ImageHeader::kSectionImageBitmap];
131     // The offset of the bitmap section should be aligned to kElfSegmentAlignment to enable mapping
132     // the section from file to memory. However the section size doesn't have to be rounded up as
133     // it is located at the end of the file. When mapping file contents to memory, if the last page
134     // of the mapping is only partially filled with data, the rest will be zero-filled.
135     *bitmap_section = ImageSection(RoundUp(sections_end, kElfSegmentAlignment), bitmap_bytes);
136 
137     // Compute boot image checksum and boot image components, to be stored in
138     // the header.
139     gc::Heap* const heap = Runtime::Current()->GetHeap();
140     uint32_t boot_image_components = 0u;
141     uint32_t boot_image_checksums = 0u;
142     const std::vector<gc::space::ImageSpace*>& image_spaces = heap->GetBootImageSpaces();
143     for (size_t i = 0u, size = image_spaces.size(); i != size; ) {
144       const ImageHeader& header = image_spaces[i]->GetImageHeader();
145       boot_image_components += header.GetComponentCount();
146       boot_image_checksums ^= header.GetImageChecksum();
147       DCHECK_LE(header.GetImageSpaceCount(), size - i);
148       i += header.GetImageSpaceCount();
149     }
150 
151     header_ = ImageHeader(
152         /* image_reservation_size= */ RoundUp(sections_end, kElfSegmentAlignment),
153         /* component_count= */ 1,
154         image_begin_,
155         sections_end,
156         sections_.data(),
157         /* image_roots= */ image_begin_ + sizeof(ImageHeader),
158         /* oat_checksum= */ 0,
159         /* oat_file_begin= */ 0,
160         /* oat_data_begin= */ 0,
161         /* oat_data_end= */ 0,
162         /* oat_file_end= */ 0,
163         heap->GetBootImagesStartAddress(),
164         heap->GetBootImagesSize(),
165         boot_image_components,
166         boot_image_checksums,
167         kRuntimePointerSize);
168 
169     // Data size includes everything except the bitmap and the header.
170     header_.data_size_ = sections_end - sizeof(ImageHeader);
171 
172     // Write image methods - needs to happen after creation of the header.
173     WriteImageMethods();
174 
175     return true;
176   }
177 
FillData(std::vector<uint8_t> & data)178   void FillData(std::vector<uint8_t>& data) {
179     // Note we don't put the header, we only have it reserved in `data` as
180     // Image::WriteData expects the object section to contain the image header.
181     auto compute_dest = [&](const ImageSection& section) {
182       return data.data() + section.Offset();
183     };
184 
185     auto objects_section = header_.GetImageSection(ImageHeader::kSectionObjects);
186     memcpy(compute_dest(objects_section) + sizeof(ImageHeader), objects_.data(), objects_.size());
187 
188     auto fields_section = header_.GetImageSection(ImageHeader::kSectionArtFields);
189     memcpy(compute_dest(fields_section), art_fields_.data(), fields_section.Size());
190 
191     auto methods_section = header_.GetImageSection(ImageHeader::kSectionArtMethods);
192     memcpy(compute_dest(methods_section), art_methods_.data(), methods_section.Size());
193 
194     auto im_tables_section = header_.GetImageSection(ImageHeader::kSectionImTables);
195     memcpy(compute_dest(im_tables_section), im_tables_.data(), im_tables_section.Size());
196 
197     auto intern_section = header_.GetImageSection(ImageHeader::kSectionInternedStrings);
198     intern_table_.WriteToMemory(compute_dest(intern_section));
199 
200     auto class_table_section = header_.GetImageSection(ImageHeader::kSectionClassTable);
201     class_table_.WriteToMemory(compute_dest(class_table_section));
202 
203     auto string_offsets_section =
204         header_.GetImageSection(ImageHeader::kSectionStringReferenceOffsets);
205     memcpy(compute_dest(string_offsets_section),
206            string_reference_offsets_.data(),
207            string_offsets_section.Size());
208 
209     auto dex_cache_section = header_.GetImageSection(ImageHeader::kSectionDexCacheArrays);
210     memcpy(compute_dest(dex_cache_section), dex_cache_arrays_.data(), dex_cache_section.Size());
211 
212     auto metadata_section = header_.GetImageSection(ImageHeader::kSectionMetadata);
213     memcpy(compute_dest(metadata_section), metadata_.data(), metadata_section.Size());
214 
215     DCHECK_EQ(metadata_section.Offset() + metadata_section.Size(), data.size());
216   }
217 
218 
GetHeader()219   ImageHeader* GetHeader() {
220     return &header_;
221   }
222 
GetImageBitmap() const223   const gc::accounting::ContinuousSpaceBitmap& GetImageBitmap() const {
224     return image_bitmap_;
225   }
226 
GetDexLocation() const227   const std::string& GetDexLocation() const {
228     return dex_location_;
229   }
230 
231  private:
IsInBootImage(const void * obj) const232   bool IsInBootImage(const void* obj) const {
233     return reinterpret_cast<uintptr_t>(obj) - boot_image_begin_ < boot_image_size_;
234   }
235 
236   // Returns the image contents for `cls`. If `cls` is in the boot image, the
237   // method just returns it.
GetClassContent(ObjPtr<mirror::Class> cls)238   mirror::Class* GetClassContent(ObjPtr<mirror::Class> cls) REQUIRES_SHARED(Locks::mutator_lock_) {
239     if (cls == nullptr || IsInBootImage(cls.Ptr())) {
240       return cls.Ptr();
241     }
242     const dex::ClassDef* class_def = cls->GetClassDef();
243     DCHECK(class_def != nullptr) << cls->PrettyClass();
244     auto it = classes_.find(class_def);
245     DCHECK(it != classes_.end()) << cls->PrettyClass();
246     mirror::Class* result = reinterpret_cast<mirror::Class*>(objects_.data() + it->second);
247     DCHECK(result->GetClass()->IsClass());
248     return result;
249   }
250 
251   // Returns a pointer that can be stored in `objects_`:
252   // - The pointer itself for boot image objects,
253   // - The offset in the image for all other objects.
GetOrComputeImageAddress(ObjPtr<T> object)254   template <typename T> T* GetOrComputeImageAddress(ObjPtr<T> object)
255       REQUIRES_SHARED(Locks::mutator_lock_) {
256     if (object == nullptr || IsInBootImage(object.Ptr())) {
257       DCHECK(object == nullptr || Runtime::Current()->GetHeap()->ObjectIsInBootImageSpace(object));
258       return object.Ptr();
259     }
260 
261     if (object->IsClassLoader()) {
262       // DexCache and Class point to class loaders. For runtime-generated app
263       // images, we don't encode the class loader. It will be set when the
264       // runtime is loading the image.
265       return nullptr;
266     }
267 
268     if (object->GetClass() == GetClassRoot<mirror::ClassExt>()) {
269       // No need to encode `ClassExt`. If needed, it will be reconstructed at
270       // runtime.
271       return nullptr;
272     }
273 
274     uint32_t offset = 0u;
275     if (object->IsClass()) {
276       offset = CopyClass(object->AsClass());
277     } else if (object->IsDexCache()) {
278       offset = CopyDexCache(object->AsDexCache());
279     } else {
280       offset = CopyObject(object);
281     }
282     return reinterpret_cast<T*>(image_begin_ + sizeof(ImageHeader) + offset);
283   }
284 
CreateImageSections()285   void CreateImageSections() {
286     sections_[ImageHeader::kSectionObjects] = ImageSection(0u, object_section_size_);
287     sections_[ImageHeader::kSectionArtFields] =
288         ImageSection(sections_[ImageHeader::kSectionObjects].End(), art_fields_.size());
289 
290     // Round up to the alignment for ArtMethod.
291     static_assert(IsAligned<sizeof(void*)>(ArtMethod::Size(kRuntimePointerSize)));
292     size_t cur_pos = RoundUp(sections_[ImageHeader::kSectionArtFields].End(), sizeof(void*));
293     sections_[ImageHeader::kSectionArtMethods] = ImageSection(cur_pos, art_methods_.size());
294 
295     // Round up to the alignment for ImTables.
296     cur_pos = RoundUp(sections_[ImageHeader::kSectionArtMethods].End(), sizeof(void*));
297     sections_[ImageHeader::kSectionImTables] = ImageSection(cur_pos, im_tables_.size());
298 
299     // Round up to the alignment for conflict tables.
300     cur_pos = RoundUp(sections_[ImageHeader::kSectionImTables].End(), sizeof(void*));
301     sections_[ImageHeader::kSectionIMTConflictTables] = ImageSection(cur_pos, 0u);
302 
303     sections_[ImageHeader::kSectionRuntimeMethods] =
304         ImageSection(sections_[ImageHeader::kSectionIMTConflictTables].End(), 0u);
305 
306     // Round up to the alignment the string table expects. See HashSet::WriteToMemory.
307     cur_pos = RoundUp(sections_[ImageHeader::kSectionRuntimeMethods].End(), sizeof(uint64_t));
308 
309     size_t intern_table_bytes = intern_table_.WriteToMemory(nullptr);
310     sections_[ImageHeader::kSectionInternedStrings] = ImageSection(cur_pos, intern_table_bytes);
311 
312     // Obtain the new position and round it up to the appropriate alignment.
313     cur_pos = RoundUp(sections_[ImageHeader::kSectionInternedStrings].End(), sizeof(uint64_t));
314 
315     size_t class_table_bytes = class_table_.WriteToMemory(nullptr);
316     sections_[ImageHeader::kSectionClassTable] = ImageSection(cur_pos, class_table_bytes);
317 
318     // Round up to the alignment of the offsets we are going to store.
319     cur_pos = RoundUp(sections_[ImageHeader::kSectionClassTable].End(), sizeof(uint32_t));
320     sections_[ImageHeader::kSectionStringReferenceOffsets] = ImageSection(
321         cur_pos, string_reference_offsets_.size() * sizeof(string_reference_offsets_[0]));
322 
323     // Round up to the alignment dex caches arrays expects.
324     cur_pos =
325         RoundUp(sections_[ImageHeader::kSectionStringReferenceOffsets].End(), sizeof(void*));
326     sections_[ImageHeader::kSectionDexCacheArrays] =
327         ImageSection(cur_pos, dex_cache_arrays_.size());
328 
329     // Round up to the alignment expected for the metadata, which holds dex
330     // cache arrays.
331     cur_pos = RoundUp(sections_[ImageHeader::kSectionDexCacheArrays].End(), sizeof(void*));
332     sections_[ImageHeader::kSectionMetadata] = ImageSection(cur_pos, metadata_.size());
333   }
334 
335   // Returns the copied mirror Object if in the image, or the object directly if
336   // in the boot image. For the copy, this is really its content, it should not
337   // be returned as an `ObjPtr` (as it's not a GC object), nor stored anywhere.
FromImageOffsetToRuntimeContent(uint32_t offset)338   template<typename T> T* FromImageOffsetToRuntimeContent(uint32_t offset) {
339     if (offset == 0u || IsInBootImage(reinterpret_cast<const void*>(offset))) {
340       return reinterpret_cast<T*>(offset);
341     }
342     uint32_t vector_data_offset = FromImageOffsetToVectorOffset(offset);
343     return reinterpret_cast<T*>(objects_.data() + vector_data_offset);
344   }
345 
FromImageOffsetToVectorOffset(uint32_t offset) const346   uint32_t FromImageOffsetToVectorOffset(uint32_t offset) const {
347     DCHECK(!IsInBootImage(reinterpret_cast<const void*>(offset)));
348     return offset - sizeof(ImageHeader) - image_begin_;
349   }
350 
351   class InternStringHash {
352    public:
InternStringHash(RuntimeImageHelper * helper)353     explicit InternStringHash(RuntimeImageHelper* helper) : helper_(helper) {}
354 
355     // NO_THREAD_SAFETY_ANALYSIS as these helpers get passed to `HashSet`.
operator ()(mirror::String * str) const356     size_t operator()(mirror::String* str) const NO_THREAD_SAFETY_ANALYSIS {
357       int32_t hash = str->GetStoredHashCode();
358       DCHECK_EQ(hash, str->ComputeHashCode());
359       // An additional cast to prevent undesired sign extension.
360       return static_cast<uint32_t>(hash);
361     }
362 
operator ()(uint32_t entry) const363     size_t operator()(uint32_t entry) const NO_THREAD_SAFETY_ANALYSIS {
364       return (*this)(helper_->FromImageOffsetToRuntimeContent<mirror::String>(entry));
365     }
366 
367    private:
368     RuntimeImageHelper* helper_;
369   };
370 
371   class InternStringEquals {
372    public:
InternStringEquals(RuntimeImageHelper * helper)373     explicit InternStringEquals(RuntimeImageHelper* helper) : helper_(helper) {}
374 
375     // NO_THREAD_SAFETY_ANALYSIS as these helpers get passed to `HashSet`.
operator ()(uint32_t entry,mirror::String * other) const376     bool operator()(uint32_t entry, mirror::String* other) const NO_THREAD_SAFETY_ANALYSIS {
377       if (kIsDebugBuild) {
378         Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
379       }
380       return other->Equals(helper_->FromImageOffsetToRuntimeContent<mirror::String>(entry));
381     }
382 
operator ()(uint32_t entry,uint32_t other) const383     bool operator()(uint32_t entry, uint32_t other) const NO_THREAD_SAFETY_ANALYSIS {
384       return (*this)(entry, helper_->FromImageOffsetToRuntimeContent<mirror::String>(other));
385     }
386 
387    private:
388     RuntimeImageHelper* helper_;
389   };
390 
391   using InternTableSet =
392         HashSet<uint32_t, DefaultEmptyFn<uint32_t>, InternStringHash, InternStringEquals>;
393 
394   class ClassDescriptorHash {
395    public:
ClassDescriptorHash(RuntimeImageHelper * helper)396     explicit ClassDescriptorHash(RuntimeImageHelper* helper) : helper_(helper) {}
397 
operator ()(const ClassTable::TableSlot & slot) const398     uint32_t operator()(const ClassTable::TableSlot& slot) const NO_THREAD_SAFETY_ANALYSIS {
399       uint32_t ptr = slot.NonHashData();
400       if (helper_->IsInBootImage(reinterpret_cast32<const void*>(ptr))) {
401         return reinterpret_cast32<mirror::Class*>(ptr)->DescriptorHash();
402       }
403       return helper_->class_hashes_.Get(helper_->FromImageOffsetToVectorOffset(ptr));
404     }
405 
406    private:
407     RuntimeImageHelper* helper_;
408   };
409 
410   class ClassDescriptorEquals {
411    public:
ClassDescriptorEquals()412     ClassDescriptorEquals() {}
413 
operator ()(const ClassTable::TableSlot & a,const ClassTable::TableSlot & b) const414     bool operator()(const ClassTable::TableSlot& a, const ClassTable::TableSlot& b)
415         const NO_THREAD_SAFETY_ANALYSIS {
416       // No need to fetch the descriptor: we know the classes we are inserting
417       // in the ClassTable are unique.
418       return a.Data() == b.Data();
419     }
420   };
421 
422   using ClassTableSet = HashSet<ClassTable::TableSlot,
423                                 ClassTable::TableSlotEmptyFn,
424                                 ClassDescriptorHash,
425                                 ClassDescriptorEquals>;
426 
427   // Helper class to collect classes that we will generate in the image.
428   class ClassTableVisitor {
429    public:
ClassTableVisitor(Handle<mirror::ClassLoader> loader,VariableSizedHandleScope & handles)430     ClassTableVisitor(Handle<mirror::ClassLoader> loader, VariableSizedHandleScope& handles)
431         : loader_(loader), handles_(handles) {}
432 
operator ()(ObjPtr<mirror::Class> klass)433     bool operator()(ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_) {
434       // Record app classes and boot classpath classes: app classes will be
435       // generated in the image and put in the class table, boot classpath
436       // classes will be put in the class table.
437       ObjPtr<mirror::ClassLoader> class_loader = klass->GetClassLoader();
438       if (klass->IsResolved() && (class_loader == loader_.Get() || class_loader == nullptr)) {
439         handles_.NewHandle(klass);
440       }
441       return true;
442     }
443 
444    private:
445     Handle<mirror::ClassLoader> loader_;
446     VariableSizedHandleScope& handles_;
447   };
448 
449   // Helper class visitor to filter out classes we cannot emit.
450   class PruneVisitor {
451    public:
PruneVisitor(Thread * self,RuntimeImageHelper * helper,const ArenaSet<const DexFile * > & dex_files,ArenaVector<Handle<mirror::Class>> & classes,ArenaAllocator & allocator)452     PruneVisitor(Thread* self,
453                  RuntimeImageHelper* helper,
454                  const ArenaSet<const DexFile*>& dex_files,
455                  ArenaVector<Handle<mirror::Class>>& classes,
456                  ArenaAllocator& allocator)
457         : self_(self),
458           helper_(helper),
459           dex_files_(dex_files),
460           visited_(allocator.Adapter()),
461           classes_to_write_(classes) {}
462 
CanEmitHelper(Handle<mirror::Class> cls)463     bool CanEmitHelper(Handle<mirror::Class> cls) REQUIRES_SHARED(Locks::mutator_lock_) {
464       // If the class comes from a dex file which is not part of the primary
465       // APK, don't encode it.
466       if (!ContainsElement(dex_files_, &cls->GetDexFile())) {
467         return false;
468       }
469 
470       // Ensure pointers to classes in `cls` can also be emitted.
471       StackHandleScope<1> hs(self_);
472       MutableHandle<mirror::Class> other_class = hs.NewHandle(cls->GetSuperClass());
473       if (!CanEmit(other_class)) {
474         return false;
475       }
476 
477       other_class.Assign(cls->GetComponentType());
478       if (!CanEmit(other_class)) {
479         return false;
480       }
481 
482       for (size_t i = 0, num_interfaces = cls->NumDirectInterfaces(); i < num_interfaces; ++i) {
483         other_class.Assign(cls->GetDirectInterface(i));
484         DCHECK(other_class != nullptr);
485         if (!CanEmit(other_class)) {
486           return false;
487         }
488       }
489       return true;
490     }
491 
CanEmit(Handle<mirror::Class> cls)492     bool CanEmit(Handle<mirror::Class> cls) REQUIRES_SHARED(Locks::mutator_lock_) {
493       if (cls == nullptr) {
494         return true;
495       }
496       DCHECK(cls->IsResolved());
497       // Only emit classes that are resolved and not erroneous.
498       if (cls->IsErroneous()) {
499         return false;
500       }
501 
502       // Proxy classes are generated at runtime, so don't emit them.
503       if (cls->IsProxyClass()) {
504         return false;
505       }
506 
507       // Classes in the boot image can be trivially encoded directly.
508       if (helper_->IsInBootImage(cls.Get())) {
509         return true;
510       }
511 
512       if (cls->IsBootStrapClassLoaded()) {
513         // We cannot encode classes that are part of the boot classpath.
514         return false;
515       }
516 
517       DCHECK(!cls->IsPrimitive());
518 
519       if (cls->IsArrayClass()) {
520         if (cls->IsBootStrapClassLoaded()) {
521           // For boot classpath arrays, we can only emit them if they are
522           // in the boot image already.
523           return helper_->IsInBootImage(cls.Get());
524         }
525         ObjPtr<mirror::Class> temp = cls.Get();
526         while ((temp = temp->GetComponentType())->IsArrayClass()) {}
527         StackHandleScope<1> hs(self_);
528         Handle<mirror::Class> other_class = hs.NewHandle(temp);
529         return CanEmit(other_class);
530       }
531       const dex::ClassDef* class_def = cls->GetClassDef();
532       DCHECK_NE(class_def, nullptr);
533       auto existing = visited_.find(class_def);
534       if (existing != visited_.end()) {
535         // Already processed;
536         return existing->second == VisitState::kCanEmit;
537       }
538 
539       visited_.Put(class_def, VisitState::kVisiting);
540       if (CanEmitHelper(cls)) {
541         visited_.Overwrite(class_def, VisitState::kCanEmit);
542         return true;
543       } else {
544         visited_.Overwrite(class_def, VisitState::kCannotEmit);
545         return false;
546       }
547     }
548 
Visit(Handle<mirror::Object> obj)549     void Visit(Handle<mirror::Object> obj) REQUIRES_SHARED(Locks::mutator_lock_) {
550       MutableHandle<mirror::Class> cls(obj.GetReference());
551       if (CanEmit(cls)) {
552         if (cls->IsBootStrapClassLoaded()) {
553           DCHECK(helper_->IsInBootImage(cls.Get()));
554           // Insert the bootclasspath class in the class table.
555           uint32_t hash = cls->DescriptorHash();
556           helper_->class_table_.InsertWithHash(ClassTable::TableSlot(cls.Get(), hash), hash);
557         } else {
558           classes_to_write_.push_back(cls);
559         }
560       }
561     }
562 
563    private:
564     enum class VisitState {
565       kVisiting,
566       kCanEmit,
567       kCannotEmit,
568     };
569 
570     Thread* const self_;
571     RuntimeImageHelper* const helper_;
572     const ArenaSet<const DexFile*>& dex_files_;
573     ArenaSafeMap<const dex::ClassDef*, VisitState> visited_;
574     ArenaVector<Handle<mirror::Class>>& classes_to_write_;
575   };
576 
EmitClasses(Thread * self,Handle<mirror::ObjectArray<mirror::Object>> dex_cache_array)577   void EmitClasses(Thread* self, Handle<mirror::ObjectArray<mirror::Object>> dex_cache_array)
578       REQUIRES_SHARED(Locks::mutator_lock_) {
579     ScopedTrace trace("Emit strings and classes");
580     ArenaSet<const DexFile*> dex_files(allocator_.Adapter());
581     for (int32_t i = 0; i < dex_cache_array->GetLength(); ++i) {
582       dex_files.insert(dex_cache_array->Get(i)->AsDexCache()->GetDexFile());
583     }
584 
585     StackHandleScope<1> hs(self);
586     Handle<mirror::ClassLoader> loader = hs.NewHandle(
587         dex_cache_array->Get(0)->AsDexCache()->GetClassLoader());
588     ClassTable* const class_table = loader->GetClassTable();
589     if (class_table == nullptr) {
590       return;
591     }
592 
593     VariableSizedHandleScope handles(self);
594     {
595       ClassTableVisitor class_table_visitor(loader, handles);
596       class_table->Visit(class_table_visitor);
597     }
598 
599     ArenaVector<Handle<mirror::Class>> classes_to_write(allocator_.Adapter());
600     classes_to_write.reserve(class_table->Size());
601     {
602       PruneVisitor prune_visitor(self, this, dex_files, classes_to_write, allocator_);
603       handles.VisitHandles(prune_visitor);
604     }
605 
606     for (Handle<mirror::Class> cls : classes_to_write) {
607       {
608         ScopedAssertNoThreadSuspension sants("Writing class");
609         CopyClass(cls.Get());
610       }
611       self->AllowThreadSuspension();
612     }
613 
614     // Relocate the type array entries. We do this now before creating image
615     // sections because we may add new boot image classes into our
616     // `class_table`_.
617     for (auto entry : dex_caches_) {
618       const DexFile& dex_file = *entry.first;
619       mirror::DexCache* cache = reinterpret_cast<mirror::DexCache*>(&objects_[entry.second]);
620       mirror::GcRootArray<mirror::Class>* old_types_array = cache->GetResolvedTypesArray();
621       if (HasNativeRelocation(old_types_array)) {
622         auto reloc_it = native_relocations_.find(old_types_array);
623         DCHECK(reloc_it != native_relocations_.end());
624         ArenaVector<uint8_t>& data =
625             (reloc_it->second.first == NativeRelocationKind::kFullNativeDexCacheArray)
626                 ? dex_cache_arrays_ : metadata_;
627         mirror::GcRootArray<mirror::Class>* content_array =
628             reinterpret_cast<mirror::GcRootArray<mirror::Class>*>(
629                 data.data() + reloc_it->second.second);
630         for (uint32_t i = 0; i < dex_file.NumTypeIds(); ++i) {
631           ObjPtr<mirror::Class> cls = old_types_array->Get(i);
632           if (cls == nullptr) {
633             content_array->Set(i, nullptr);
634           } else if (IsInBootImage(cls.Ptr())) {
635             if (!cls->IsPrimitive()) {
636               // The dex cache is concurrently updated by the app. If the class
637               // collection logic in `PruneVisitor` did not see this class, insert it now.
638               // Note that application class tables do not contain primitive
639               // classes.
640               uint32_t hash = cls->DescriptorHash();
641               class_table_.InsertWithHash(ClassTable::TableSlot(cls.Ptr(), hash), hash);
642             }
643             content_array->Set(i, cls.Ptr());
644           } else if (cls->IsArrayClass()) {
645             std::string class_name;
646             cls->GetDescriptor(&class_name);
647             auto class_it = array_classes_.find(class_name);
648             if (class_it == array_classes_.end()) {
649               content_array->Set(i, nullptr);
650             } else {
651               mirror::Class* ptr = reinterpret_cast<mirror::Class*>(
652                   image_begin_ + sizeof(ImageHeader) + class_it->second);
653               content_array->Set(i, ptr);
654             }
655           } else {
656             DCHECK(!cls->IsPrimitive());
657             DCHECK(!cls->IsProxyClass());
658             const dex::ClassDef* class_def = cls->GetClassDef();
659             DCHECK_NE(class_def, nullptr);
660             auto class_it = classes_.find(class_def);
661             if (class_it == classes_.end()) {
662               content_array->Set(i, nullptr);
663             } else {
664               mirror::Class* ptr = reinterpret_cast<mirror::Class*>(
665                   image_begin_ + sizeof(ImageHeader) + class_it->second);
666               content_array->Set(i, ptr);
667             }
668           }
669         }
670       }
671     }
672   }
673 
674   // Helper visitor returning the location of a native pointer in the image.
675   class NativePointerVisitor {
676    public:
NativePointerVisitor(RuntimeImageHelper * helper)677     explicit NativePointerVisitor(RuntimeImageHelper* helper) : helper_(helper) {}
678 
679     template <typename T>
operator ()(T * ptr,void ** dest_addr) const680     T* operator()(T* ptr, [[maybe_unused]] void** dest_addr) const {
681       return helper_->NativeLocationInImage(ptr, /* must_have_relocation= */ true);
682     }
683 
operator ()(T * ptr,bool must_have_relocation=true) const684     template <typename T> T* operator()(T* ptr, bool must_have_relocation = true) const {
685       return helper_->NativeLocationInImage(ptr, must_have_relocation);
686     }
687 
688    private:
689     RuntimeImageHelper* helper_;
690   };
691 
NativeLocationInImage(T * ptr,bool must_have_relocation) const692   template <typename T> T* NativeLocationInImage(T* ptr, bool must_have_relocation) const {
693     if (ptr == nullptr || IsInBootImage(ptr)) {
694       return ptr;
695     }
696 
697     auto it = native_relocations_.find(ptr);
698     if (it == native_relocations_.end()) {
699       DCHECK(!must_have_relocation);
700       return nullptr;
701     }
702     switch (it->second.first) {
703       case NativeRelocationKind::kArtMethod:
704       case NativeRelocationKind::kArtMethodArray: {
705         uint32_t offset = sections_[ImageHeader::kSectionArtMethods].Offset();
706         return reinterpret_cast<T*>(image_begin_ + offset + it->second.second);
707       }
708       case NativeRelocationKind::kArtFieldArray: {
709         uint32_t offset = sections_[ImageHeader::kSectionArtFields].Offset();
710         return reinterpret_cast<T*>(image_begin_ + offset + it->second.second);
711       }
712       case NativeRelocationKind::kImTable: {
713         uint32_t offset = sections_[ImageHeader::kSectionImTables].Offset();
714         return reinterpret_cast<T*>(image_begin_ + offset + it->second.second);
715       }
716       case NativeRelocationKind::kStartupNativeDexCacheArray: {
717         uint32_t offset = sections_[ImageHeader::kSectionMetadata].Offset();
718         return reinterpret_cast<T*>(image_begin_ + offset + it->second.second);
719       }
720       case NativeRelocationKind::kFullNativeDexCacheArray: {
721         uint32_t offset = sections_[ImageHeader::kSectionDexCacheArrays].Offset();
722         return reinterpret_cast<T*>(image_begin_ + offset + it->second.second);
723       }
724     }
725   }
726 
727   template <typename Visitor>
RelocateMethodPointerArrays(mirror::Class * klass,const Visitor & visitor)728   void RelocateMethodPointerArrays(mirror::Class* klass, const Visitor& visitor)
729       REQUIRES_SHARED(Locks::mutator_lock_) {
730     // A bit of magic here: we cast contents from our buffer to mirror::Class,
731     // and do pointer comparison between 1) these classes, and 2) boot image objects.
732     // Both kinds do not move.
733 
734     // See if we need to fixup the vtable field.
735     mirror::Class* super = FromImageOffsetToRuntimeContent<mirror::Class>(
736         reinterpret_cast32<uint32_t>(
737             klass->GetSuperClass<kVerifyNone, kWithoutReadBarrier>().Ptr()));
738     DCHECK(super != nullptr) << "j.l.Object should never be in an app runtime image";
739     mirror::PointerArray* vtable = FromImageOffsetToRuntimeContent<mirror::PointerArray>(
740         reinterpret_cast32<uint32_t>(klass->GetVTable<kVerifyNone, kWithoutReadBarrier>().Ptr()));
741     mirror::PointerArray* super_vtable = FromImageOffsetToRuntimeContent<mirror::PointerArray>(
742         reinterpret_cast32<uint32_t>(super->GetVTable<kVerifyNone, kWithoutReadBarrier>().Ptr()));
743     if (vtable != nullptr && vtable != super_vtable) {
744       DCHECK(!IsInBootImage(vtable));
745       vtable->Fixup(vtable, kRuntimePointerSize, visitor);
746     }
747 
748     // See if we need to fixup entries in the IfTable.
749     mirror::IfTable* iftable = FromImageOffsetToRuntimeContent<mirror::IfTable>(
750         reinterpret_cast32<uint32_t>(
751             klass->GetIfTable<kVerifyNone, kWithoutReadBarrier>().Ptr()));
752     mirror::IfTable* super_iftable = FromImageOffsetToRuntimeContent<mirror::IfTable>(
753         reinterpret_cast32<uint32_t>(
754             super->GetIfTable<kVerifyNone, kWithoutReadBarrier>().Ptr()));
755     int32_t iftable_count = iftable->Count();
756     int32_t super_iftable_count = super_iftable->Count();
757     for (int32_t i = 0; i < iftable_count; ++i) {
758       mirror::PointerArray* methods = FromImageOffsetToRuntimeContent<mirror::PointerArray>(
759           reinterpret_cast32<uint32_t>(
760               iftable->GetMethodArrayOrNull<kVerifyNone, kWithoutReadBarrier>(i).Ptr()));
761       mirror::PointerArray* super_methods = (i < super_iftable_count)
762           ? FromImageOffsetToRuntimeContent<mirror::PointerArray>(
763                 reinterpret_cast32<uint32_t>(
764                     super_iftable->GetMethodArrayOrNull<kVerifyNone, kWithoutReadBarrier>(i).Ptr()))
765           : nullptr;
766       if (methods != super_methods) {
767         DCHECK(!IsInBootImage(methods));
768         methods->Fixup(methods, kRuntimePointerSize, visitor);
769       }
770     }
771   }
772 
773   template <typename Visitor, typename T>
RelocateNativeDexCacheArray(mirror::NativeArray<T> * old_method_array,uint32_t num_ids,const Visitor & visitor)774   void RelocateNativeDexCacheArray(mirror::NativeArray<T>* old_method_array,
775                                    uint32_t num_ids,
776                                    const Visitor& visitor)
777       REQUIRES_SHARED(Locks::mutator_lock_) {
778     if (old_method_array == nullptr) {
779       return;
780     }
781 
782     auto it = native_relocations_.find(old_method_array);
783     DCHECK(it != native_relocations_.end());
784     ArenaVector<uint8_t>& data =
785         (it->second.first == NativeRelocationKind::kFullNativeDexCacheArray)
786             ? dex_cache_arrays_ : metadata_;
787 
788     mirror::NativeArray<T>* content_array =
789         reinterpret_cast<mirror::NativeArray<T>*>(data.data() + it->second.second);
790     for (uint32_t i = 0; i < num_ids; ++i) {
791       // We may not have relocations for some entries, in which case we'll
792       // just store null.
793       content_array->Set(i, visitor(content_array->Get(i), /* must_have_relocation= */ false));
794     }
795   }
796 
797   template <typename Visitor>
RelocateDexCacheArrays(mirror::DexCache * cache,const DexFile & dex_file,const Visitor & visitor)798   void RelocateDexCacheArrays(mirror::DexCache* cache,
799                               const DexFile& dex_file,
800                               const Visitor& visitor)
801       REQUIRES_SHARED(Locks::mutator_lock_) {
802     mirror::NativeArray<ArtMethod>* old_method_array = cache->GetResolvedMethodsArray();
803     cache->SetResolvedMethodsArray(visitor(old_method_array));
804     RelocateNativeDexCacheArray(old_method_array, dex_file.NumMethodIds(), visitor);
805 
806     mirror::NativeArray<ArtField>* old_field_array = cache->GetResolvedFieldsArray();
807     cache->SetResolvedFieldsArray(visitor(old_field_array));
808     RelocateNativeDexCacheArray(old_field_array, dex_file.NumFieldIds(), visitor);
809 
810     mirror::GcRootArray<mirror::String>* old_strings_array = cache->GetStringsArray();
811     cache->SetStringsArray(visitor(old_strings_array));
812 
813     mirror::GcRootArray<mirror::Class>* old_types_array = cache->GetResolvedTypesArray();
814     cache->SetResolvedTypesArray(visitor(old_types_array));
815   }
816 
RelocateNativePointers()817   void RelocateNativePointers() {
818     ScopedTrace relocate_native_pointers("Relocate native pointers");
819     ScopedObjectAccess soa(Thread::Current());
820     NativePointerVisitor visitor(this);
821     for (auto&& entry : classes_) {
822       mirror::Class* cls = reinterpret_cast<mirror::Class*>(&objects_[entry.second]);
823       cls->FixupNativePointers(cls, kRuntimePointerSize, visitor);
824       RelocateMethodPointerArrays(cls, visitor);
825     }
826     for (auto&& entry : array_classes_) {
827       mirror::Class* cls = reinterpret_cast<mirror::Class*>(&objects_[entry.second]);
828       cls->FixupNativePointers(cls, kRuntimePointerSize, visitor);
829       RelocateMethodPointerArrays(cls, visitor);
830     }
831     for (auto&& entry : native_relocations_) {
832       if (entry.second.first == NativeRelocationKind::kImTable) {
833         ImTable* im_table = reinterpret_cast<ImTable*>(im_tables_.data() + entry.second.second);
834         RelocateImTable(im_table, visitor);
835       }
836     }
837     for (auto&& entry : dex_caches_) {
838       mirror::DexCache* cache = reinterpret_cast<mirror::DexCache*>(&objects_[entry.second]);
839       RelocateDexCacheArrays(cache, *entry.first, visitor);
840     }
841   }
842 
RelocateImTable(ImTable * im_table,const NativePointerVisitor & visitor)843   void RelocateImTable(ImTable* im_table, const NativePointerVisitor& visitor) {
844     for (size_t i = 0; i < ImTable::kSize; ++i) {
845       ArtMethod* method = im_table->Get(i, kRuntimePointerSize);
846       ArtMethod* new_method = nullptr;
847       if (method->IsRuntimeMethod() && !IsInBootImage(method)) {
848         // New IMT conflict method: just use the boot image version.
849         // TODO: Consider copying the new IMT conflict method.
850         new_method = Runtime::Current()->GetImtConflictMethod();
851         DCHECK(IsInBootImage(new_method));
852       } else {
853         new_method = visitor(method);
854       }
855       if (method != new_method) {
856         im_table->Set(i, new_method, kRuntimePointerSize);
857       }
858     }
859   }
860 
CopyFieldArrays(ObjPtr<mirror::Class> cls,uint32_t class_image_address)861   void CopyFieldArrays(ObjPtr<mirror::Class> cls, uint32_t class_image_address)
862       REQUIRES_SHARED(Locks::mutator_lock_) {
863     LengthPrefixedArray<ArtField>* cur_fields = cls->GetFieldsPtr();
864     if (cur_fields != nullptr) {
865       // Copy the array.
866       size_t number_of_fields = cur_fields->size();
867       size_t size = LengthPrefixedArray<ArtField>::ComputeSize(number_of_fields);
868       size_t offset = art_fields_.size();
869       art_fields_.resize(offset + size);
870       auto* dest_array =
871           reinterpret_cast<LengthPrefixedArray<ArtField>*>(art_fields_.data() + offset);
872       memcpy(dest_array, cur_fields, size);
873       native_relocations_.Put(cur_fields,
874                               std::make_pair(NativeRelocationKind::kArtFieldArray, offset));
875 
876       // Update the class pointer of individual fields.
877       for (size_t i = 0; i != number_of_fields; ++i) {
878         dest_array->At(i).GetDeclaringClassAddressWithoutBarrier()->Assign(
879             reinterpret_cast<mirror::Class*>(class_image_address));
880       }
881     }
882   }
883 
CopyMethodArrays(ObjPtr<mirror::Class> cls,uint32_t class_image_address,bool is_class_initialized)884   void CopyMethodArrays(ObjPtr<mirror::Class> cls,
885                         uint32_t class_image_address,
886                         bool is_class_initialized)
887       REQUIRES_SHARED(Locks::mutator_lock_) {
888     size_t number_of_methods = cls->NumMethods();
889     if (number_of_methods == 0) {
890       return;
891     }
892 
893     size_t size = LengthPrefixedArray<ArtMethod>::ComputeSize(number_of_methods);
894     size_t offset = art_methods_.size();
895     art_methods_.resize(offset + size);
896     auto* dest_array =
897         reinterpret_cast<LengthPrefixedArray<ArtMethod>*>(art_methods_.data() + offset);
898     memcpy(dest_array, cls->GetMethodsPtr(), size);
899     native_relocations_.Put(cls->GetMethodsPtr(),
900                             std::make_pair(NativeRelocationKind::kArtMethodArray, offset));
901 
902     for (size_t i = 0; i != number_of_methods; ++i) {
903       ArtMethod* method = &cls->GetMethodsPtr()->At(i);
904       ArtMethod* copy = &dest_array->At(i);
905 
906       // Update the class pointer.
907       ObjPtr<mirror::Class> declaring_class = method->GetDeclaringClass();
908       if (declaring_class == cls) {
909         copy->GetDeclaringClassAddressWithoutBarrier()->Assign(
910             reinterpret_cast<mirror::Class*>(class_image_address));
911       } else {
912         DCHECK(method->IsCopied());
913         if (!IsInBootImage(declaring_class.Ptr())) {
914           DCHECK(classes_.find(declaring_class->GetClassDef()) != classes_.end());
915           copy->GetDeclaringClassAddressWithoutBarrier()->Assign(
916               reinterpret_cast<mirror::Class*>(
917                   image_begin_ +
918                   sizeof(ImageHeader) +
919                   classes_.Get(declaring_class->GetClassDef())));
920         }
921       }
922 
923       // Record the native relocation of the method.
924       uintptr_t copy_offset =
925           reinterpret_cast<uintptr_t>(copy) - reinterpret_cast<uintptr_t>(art_methods_.data());
926       native_relocations_.Put(method,
927                               std::make_pair(NativeRelocationKind::kArtMethod, copy_offset));
928 
929       // Ignore the single-implementation info for abstract method.
930       if (method->IsAbstract()) {
931         copy->SetHasSingleImplementation(false);
932         copy->SetSingleImplementation(nullptr, kRuntimePointerSize);
933       }
934 
935       // Set the entrypoint and data pointer of the method.
936       StubType stub;
937       if (method->IsNative()) {
938         stub = StubType::kQuickGenericJNITrampoline;
939       } else if (!cls->IsVerified()) {
940         stub = StubType::kQuickToInterpreterBridge;
941       } else if (!is_class_initialized && method->NeedsClinitCheckBeforeCall()) {
942         stub = StubType::kQuickResolutionTrampoline;
943       } else if (interpreter::IsNterpSupported() && CanMethodUseNterp(method)) {
944         stub = StubType::kNterpTrampoline;
945       } else {
946         stub = StubType::kQuickToInterpreterBridge;
947       }
948       const std::vector<gc::space::ImageSpace*>& image_spaces =
949           Runtime::Current()->GetHeap()->GetBootImageSpaces();
950       DCHECK(!image_spaces.empty());
951       const OatFile* oat_file = image_spaces[0]->GetOatFile();
952       DCHECK(oat_file != nullptr);
953       const OatHeader& header = oat_file->GetOatHeader();
954       const void* entrypoint = header.GetOatAddress(stub);
955       if (method->IsNative() && (is_class_initialized || !method->NeedsClinitCheckBeforeCall())) {
956         // Use boot JNI stub if found.
957         ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
958         const void* boot_jni_stub = class_linker->FindBootJniStub(method);
959         if (boot_jni_stub != nullptr) {
960           entrypoint = boot_jni_stub;
961         }
962       }
963       copy->SetEntryPointFromQuickCompiledCode(entrypoint);
964 
965       if (method->IsNative()) {
966         StubType stub_type = method->IsCriticalNative()
967             ? StubType::kJNIDlsymLookupCriticalTrampoline
968             : StubType::kJNIDlsymLookupTrampoline;
969         copy->SetEntryPointFromJni(header.GetOatAddress(stub_type));
970       } else if (method->HasCodeItem()) {
971         const uint8_t* code_item = reinterpret_cast<const uint8_t*>(method->GetCodeItem());
972         DCHECK_GE(code_item, method->GetDexFile()->DataBegin());
973         uint32_t code_item_offset = dchecked_integral_cast<uint32_t>(
974             code_item - method->GetDexFile()->DataBegin());;
975         copy->SetDataPtrSize(
976             reinterpret_cast<const void*>(code_item_offset), kRuntimePointerSize);
977       }
978     }
979   }
980 
CopyImTable(ObjPtr<mirror::Class> cls)981   void CopyImTable(ObjPtr<mirror::Class> cls) REQUIRES_SHARED(Locks::mutator_lock_) {
982     ImTable* table = cls->GetImt(kRuntimePointerSize);
983 
984     // If the table is null or shared and/or already emitted, we can skip.
985     if (table == nullptr || IsInBootImage(table) || HasNativeRelocation(table)) {
986       return;
987     }
988     const size_t size = ImTable::SizeInBytes(kRuntimePointerSize);
989     size_t offset = im_tables_.size();
990     im_tables_.resize(offset + size);
991     uint8_t* dest = im_tables_.data() + offset;
992     memcpy(dest, table, size);
993     native_relocations_.Put(table, std::make_pair(NativeRelocationKind::kImTable, offset));
994   }
995 
HasNativeRelocation(void * ptr) const996   bool HasNativeRelocation(void* ptr) const {
997     return native_relocations_.find(ptr) != native_relocations_.end();
998   }
999 
1000 
LoadClassesFromReferenceProfile(Thread * self,const dchecked_vector<Handle<mirror::DexCache>> & dex_caches)1001   static void LoadClassesFromReferenceProfile(
1002       Thread* self,
1003       const dchecked_vector<Handle<mirror::DexCache>>& dex_caches)
1004           REQUIRES_SHARED(Locks::mutator_lock_) {
1005     AppInfo* app_info = Runtime::Current()->GetAppInfo();
1006     std::string profile_file = app_info->GetPrimaryApkReferenceProfile();
1007 
1008     if (profile_file.empty()) {
1009       return;
1010     }
1011 
1012     // Lock the file, it could be concurrently updated by the system. Don't block
1013     // as this is app startup sensitive.
1014     std::string error;
1015     ScopedFlock profile =
1016         LockedFile::Open(profile_file.c_str(), O_RDONLY, /*block=*/false, &error);
1017 
1018     if (profile == nullptr) {
1019       LOG(DEBUG) << "Couldn't lock the profile file " << profile_file << ": " << error;
1020       return;
1021     }
1022 
1023     ProfileCompilationInfo profile_info(/* for_boot_image= */ false);
1024 
1025     if (!profile_info.Load(profile->Fd())) {
1026       LOG(DEBUG) << "Could not load profile file";
1027       return;
1028     }
1029 
1030     StackHandleScope<1> hs(self);
1031     Handle<mirror::ClassLoader> class_loader =
1032         hs.NewHandle<mirror::ClassLoader>(dex_caches[0]->GetClassLoader());
1033     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1034     ScopedTrace loading_classes("Loading classes from profile");
1035     for (auto dex_cache : dex_caches) {
1036       const DexFile* dex_file = dex_cache->GetDexFile();
1037       const ArenaSet<dex::TypeIndex>* class_types = profile_info.GetClasses(*dex_file);
1038       if (class_types == nullptr) {
1039         // This means the profile file did not reference the dex file, which is the case
1040         // if there's no classes and methods of that dex file in the profile.
1041         continue;
1042       }
1043 
1044       for (dex::TypeIndex idx : *class_types) {
1045         // The index is greater or equal to NumTypeIds if the type is an extra
1046         // descriptor, not referenced by the dex file.
1047         if (idx.index_ < dex_file->NumTypeIds()) {
1048           ObjPtr<mirror::Class> klass = class_linker->ResolveType(idx, dex_cache, class_loader);
1049           if (klass == nullptr) {
1050             self->ClearException();
1051             LOG(DEBUG) << "Failed to preload " << dex_file->PrettyType(idx);
1052             continue;
1053           }
1054         }
1055       }
1056     }
1057   }
1058 
WriteObjects(std::string * error_msg)1059   bool WriteObjects(std::string* error_msg) {
1060     ScopedTrace write_objects("Writing objects");
1061     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1062     ScopedObjectAccess soa(Thread::Current());
1063     VariableSizedHandleScope handles(soa.Self());
1064 
1065     Handle<mirror::Class> object_array_class = handles.NewHandle(
1066         GetClassRoot<mirror::ObjectArray<mirror::Object>>(class_linker));
1067 
1068     Handle<mirror::ObjectArray<mirror::Object>> image_roots = handles.NewHandle(
1069         mirror::ObjectArray<mirror::Object>::Alloc(
1070             soa.Self(), object_array_class.Get(), ImageHeader::kImageRootsMax));
1071 
1072     if (image_roots == nullptr) {
1073       DCHECK(soa.Self()->IsExceptionPending());
1074       soa.Self()->ClearException();
1075       *error_msg = "Out of memory when trying to generate a runtime app image";
1076       return false;
1077     }
1078 
1079     // Find the dex files that will be used for generating the app image.
1080     dchecked_vector<Handle<mirror::DexCache>> dex_caches;
1081     FindDexCaches(soa.Self(), dex_caches, handles);
1082 
1083     if (dex_caches.size() == 0) {
1084       *error_msg = "Did not find dex caches to generate an app image";
1085       return false;
1086     }
1087     const OatDexFile* oat_dex_file = dex_caches[0]->GetDexFile()->GetOatDexFile();
1088     VdexFile* vdex_file = oat_dex_file->GetOatFile()->GetVdexFile();
1089     // The first entry in `dex_caches` contains the location of the primary APK.
1090     dex_location_ = oat_dex_file->GetDexFileLocation();
1091 
1092     size_t number_of_dex_files = vdex_file->GetNumberOfDexFiles();
1093     if (number_of_dex_files != dex_caches.size()) {
1094       // This means some dex files haven't been executed. For simplicity, just
1095       // register them and recollect dex caches.
1096       Handle<mirror::ClassLoader> loader = handles.NewHandle(dex_caches[0]->GetClassLoader());
1097       VisitClassLoaderDexFiles(soa.Self(), loader, [&](const art::DexFile* dex_file)
1098           REQUIRES_SHARED(Locks::mutator_lock_) {
1099         class_linker->RegisterDexFile(*dex_file, dex_caches[0]->GetClassLoader());
1100         return true;  // Continue with other dex files.
1101       });
1102       dex_caches.clear();
1103       FindDexCaches(soa.Self(), dex_caches, handles);
1104       if (number_of_dex_files != dex_caches.size()) {
1105         *error_msg = "Number of dex caches does not match number of dex files in the primary APK";
1106         return false;
1107       }
1108     }
1109 
1110     // If classes referenced in the reference profile are not loaded, preload
1111     // them. This makes sure we generate a good runtime app image, even if this
1112     // current app run did not load all startup classes.
1113     LoadClassesFromReferenceProfile(soa.Self(), dex_caches);
1114 
1115     // We store the checksums of the dex files used at runtime. These can be
1116     // different compared to the vdex checksums due to compact dex.
1117     std::vector<uint32_t> checksums(number_of_dex_files);
1118     uint32_t checksum_index = 0;
1119     for (const OatDexFile* current_oat_dex_file : oat_dex_file->GetOatFile()->GetOatDexFiles()) {
1120       const DexFile::Header* header =
1121           reinterpret_cast<const DexFile::Header*>(current_oat_dex_file->GetDexFilePointer());
1122       checksums[checksum_index++] = header->checksum_;
1123     }
1124     DCHECK_EQ(checksum_index, number_of_dex_files);
1125 
1126     // Create the fake OatHeader to store the dependencies of the image.
1127     SafeMap<std::string, std::string> key_value_store;
1128     Runtime* runtime = Runtime::Current();
1129     key_value_store.Put(OatHeader::kApexVersionsKey, runtime->GetApexVersions());
1130     key_value_store.Put(OatHeader::kBootClassPathKey,
1131                         android::base::Join(runtime->GetBootClassPathLocations(), ':'));
1132     key_value_store.Put(OatHeader::kBootClassPathChecksumsKey,
1133                         runtime->GetBootClassPathChecksums());
1134     key_value_store.Put(OatHeader::kClassPathKey,
1135                         oat_dex_file->GetOatFile()->GetClassLoaderContext());
1136     key_value_store.Put(OatHeader::kConcurrentCopying,
1137                         gUseReadBarrier ? OatHeader::kTrueValue : OatHeader::kFalseValue);
1138 
1139     std::unique_ptr<const InstructionSetFeatures> isa_features =
1140         InstructionSetFeatures::FromCppDefines();
1141     std::unique_ptr<OatHeader, decltype(&OatHeader::Delete)> oat_header(
1142         OatHeader::Create(kRuntimeQuickCodeISA,
1143                           isa_features.get(),
1144                           number_of_dex_files,
1145                           &key_value_store),
1146         &OatHeader::Delete);
1147 
1148     // Create the byte array containing the oat header and dex checksums.
1149     uint32_t checksums_size = checksums.size() * sizeof(uint32_t);
1150     Handle<mirror::ByteArray> header_data = handles.NewHandle(
1151         mirror::ByteArray::Alloc(soa.Self(), oat_header->GetHeaderSize() + checksums_size));
1152 
1153     if (header_data == nullptr) {
1154       DCHECK(soa.Self()->IsExceptionPending());
1155       soa.Self()->ClearException();
1156       *error_msg = "Out of memory when trying to generate a runtime app image";
1157       return false;
1158     }
1159 
1160     memcpy(header_data->GetData(), oat_header.get(), oat_header->GetHeaderSize());
1161     memcpy(header_data->GetData() + oat_header->GetHeaderSize(), checksums.data(), checksums_size);
1162 
1163     // Create and populate the dex caches aray.
1164     Handle<mirror::ObjectArray<mirror::Object>> dex_cache_array = handles.NewHandle(
1165         mirror::ObjectArray<mirror::Object>::Alloc(
1166             soa.Self(), object_array_class.Get(), dex_caches.size()));
1167 
1168     if (dex_cache_array == nullptr) {
1169       DCHECK(soa.Self()->IsExceptionPending());
1170       soa.Self()->ClearException();
1171       *error_msg = "Out of memory when trying to generate a runtime app image";
1172       return false;
1173     }
1174 
1175     for (uint32_t i = 0; i < dex_caches.size(); ++i) {
1176       dex_cache_array->Set(i, dex_caches[i].Get());
1177     }
1178 
1179     image_roots->Set(ImageHeader::kDexCaches, dex_cache_array.Get());
1180     image_roots->Set(ImageHeader::kClassRoots, class_linker->GetClassRoots());
1181     image_roots->Set(ImageHeader::kAppImageOatHeader, header_data.Get());
1182 
1183     {
1184       // Now that we have created all objects needed for the `image_roots`, copy
1185       // it into the buffer. Note that this will recursively copy all objects
1186       // contained in `image_roots`. That's acceptable as we don't have cycles,
1187       // nor a deep graph.
1188       ScopedAssertNoThreadSuspension sants("Writing runtime app image");
1189       CopyObject(image_roots.Get());
1190     }
1191 
1192     // Emit classes defined in the app class loader (which will also indirectly
1193     // emit dex caches and their arrays).
1194     EmitClasses(soa.Self(), dex_cache_array);
1195 
1196     return true;
1197   }
1198 
1199   class FixupVisitor {
1200    public:
FixupVisitor(RuntimeImageHelper * image,size_t copy_offset)1201     FixupVisitor(RuntimeImageHelper* image, size_t copy_offset)
1202         : image_(image), copy_offset_(copy_offset) {}
1203 
1204     // We do not visit native roots. These are handled with other logic.
VisitRootIfNonNull(mirror::CompressedReference<mirror::Object> * root) const1205     void VisitRootIfNonNull(
1206         [[maybe_unused]] mirror::CompressedReference<mirror::Object>* root) const {
1207       LOG(FATAL) << "UNREACHABLE";
1208     }
VisitRoot(mirror::CompressedReference<mirror::Object> * root) const1209     void VisitRoot([[maybe_unused]] mirror::CompressedReference<mirror::Object>* root) const {
1210       LOG(FATAL) << "UNREACHABLE";
1211     }
1212 
operator ()(ObjPtr<mirror::Object> obj,MemberOffset offset,bool is_static) const1213     void operator()(ObjPtr<mirror::Object> obj,
1214                     MemberOffset offset,
1215                     bool is_static) const
1216         REQUIRES_SHARED(Locks::mutator_lock_) {
1217       // We don't copy static fields, they are being handled when we try to
1218       // initialize the class.
1219       ObjPtr<mirror::Object> ref =
1220           is_static ? nullptr : obj->GetFieldObject<mirror::Object>(offset);
1221       mirror::Object* address = image_->GetOrComputeImageAddress(ref);
1222       mirror::Object* copy =
1223           reinterpret_cast<mirror::Object*>(image_->objects_.data() + copy_offset_);
1224       copy->GetFieldObjectReferenceAddr<kVerifyNone>(offset)->Assign(address);
1225     }
1226 
1227     // java.lang.ref.Reference visitor.
operator ()(ObjPtr<mirror::Class> klass,ObjPtr<mirror::Reference> ref) const1228     void operator()([[maybe_unused]] ObjPtr<mirror::Class> klass,
1229                     ObjPtr<mirror::Reference> ref) const REQUIRES_SHARED(Locks::mutator_lock_) {
1230       operator()(ref, mirror::Reference::ReferentOffset(), /* is_static */ false);
1231     }
1232 
1233    private:
1234     RuntimeImageHelper* image_;
1235     size_t copy_offset_;
1236   };
1237 
1238   template <typename T>
CopyNativeDexCacheArray(uint32_t num_entries,uint32_t max_entries,mirror::NativeArray<T> * array)1239   void CopyNativeDexCacheArray(uint32_t num_entries,
1240                                uint32_t max_entries,
1241                                mirror::NativeArray<T>* array) {
1242     if (array == nullptr) {
1243       return;
1244     }
1245 
1246     bool only_startup = !mirror::DexCache::ShouldAllocateFullArray(num_entries, max_entries);
1247     ArenaVector<uint8_t>& data = only_startup ? metadata_ : dex_cache_arrays_;
1248     NativeRelocationKind relocation_kind = only_startup
1249         ? NativeRelocationKind::kStartupNativeDexCacheArray
1250         : NativeRelocationKind::kFullNativeDexCacheArray;
1251 
1252     size_t size = num_entries * sizeof(void*);
1253     // We need to reserve space to store `num_entries` because ImageSpace doesn't have
1254     // access to the dex files when relocating dex caches.
1255     size_t offset = RoundUp(data.size(), sizeof(void*)) + sizeof(uintptr_t);
1256     data.resize(RoundUp(data.size(), sizeof(void*)) + sizeof(uintptr_t) + size);
1257     reinterpret_cast<uintptr_t*>(data.data() + offset)[-1] = num_entries;
1258 
1259     // Copy each entry individually. We cannot use memcpy, as the entries may be
1260     // updated concurrently by other mutator threads.
1261     mirror::NativeArray<T>* copy = reinterpret_cast<mirror::NativeArray<T>*>(data.data() + offset);
1262     for (uint32_t i = 0; i < num_entries; ++i) {
1263       copy->Set(i, array->Get(i));
1264     }
1265     native_relocations_.Put(array, std::make_pair(relocation_kind, offset));
1266   }
1267 
1268   template <typename T>
CreateGcRootDexCacheArray(uint32_t num_entries,uint32_t max_entries,mirror::GcRootArray<T> * array)1269   mirror::GcRootArray<T>* CreateGcRootDexCacheArray(uint32_t num_entries,
1270                                                     uint32_t max_entries,
1271                                                     mirror::GcRootArray<T>* array) {
1272     if (array == nullptr) {
1273       return nullptr;
1274     }
1275     bool only_startup = !mirror::DexCache::ShouldAllocateFullArray(num_entries, max_entries);
1276     ArenaVector<uint8_t>& data = only_startup ? metadata_ : dex_cache_arrays_;
1277     NativeRelocationKind relocation_kind = only_startup
1278         ? NativeRelocationKind::kStartupNativeDexCacheArray
1279         : NativeRelocationKind::kFullNativeDexCacheArray;
1280     size_t size = num_entries * sizeof(GcRoot<T>);
1281     // We need to reserve space to store `num_entries` because ImageSpace doesn't have
1282     // access to the dex files when relocating dex caches.
1283     static_assert(sizeof(GcRoot<T>) == sizeof(uint32_t));
1284     size_t offset = data.size() + sizeof(uint32_t);
1285     data.resize(data.size() + sizeof(uint32_t) + size);
1286     reinterpret_cast<uint32_t*>(data.data() + offset)[-1] = num_entries;
1287     native_relocations_.Put(array, std::make_pair(relocation_kind, offset));
1288 
1289     return reinterpret_cast<mirror::GcRootArray<T>*>(data.data() + offset);
1290   }
EmitDexCacheArrays()1291   static bool EmitDexCacheArrays() {
1292     // We need to treat dex cache arrays specially in an image for userfaultfd.
1293     // Disable for now. See b/270936884.
1294     return !gUseUserfaultfd;
1295   }
1296 
CopyDexCache(ObjPtr<mirror::DexCache> cache)1297   uint32_t CopyDexCache(ObjPtr<mirror::DexCache> cache) REQUIRES_SHARED(Locks::mutator_lock_) {
1298     auto it = dex_caches_.find(cache->GetDexFile());
1299     if (it != dex_caches_.end()) {
1300       return it->second;
1301     }
1302     uint32_t offset = CopyObject(cache);
1303     dex_caches_.Put(cache->GetDexFile(), offset);
1304     // For dex caches, clear pointers to data that will be set at runtime.
1305     mirror::Object* copy = reinterpret_cast<mirror::Object*>(objects_.data() + offset);
1306     reinterpret_cast<mirror::DexCache*>(copy)->ResetNativeArrays();
1307     reinterpret_cast<mirror::DexCache*>(copy)->SetDexFile(nullptr);
1308 
1309     if (!EmitDexCacheArrays()) {
1310       return offset;
1311     }
1312 
1313     // Copy the ArtMethod array.
1314     mirror::NativeArray<ArtMethod>* resolved_methods = cache->GetResolvedMethodsArray();
1315     CopyNativeDexCacheArray(cache->GetDexFile()->NumMethodIds(),
1316                             mirror::DexCache::kDexCacheMethodCacheSize,
1317                             resolved_methods);
1318     // Store the array pointer in the dex cache, which will be relocated at the end.
1319     reinterpret_cast<mirror::DexCache*>(copy)->SetResolvedMethodsArray(resolved_methods);
1320 
1321     // Copy the ArtField array.
1322     mirror::NativeArray<ArtField>* resolved_fields = cache->GetResolvedFieldsArray();
1323     CopyNativeDexCacheArray(cache->GetDexFile()->NumFieldIds(),
1324                             mirror::DexCache::kDexCacheFieldCacheSize,
1325                             resolved_fields);
1326     // Store the array pointer in the dex cache, which will be relocated at the end.
1327     reinterpret_cast<mirror::DexCache*>(copy)->SetResolvedFieldsArray(resolved_fields);
1328 
1329     // Copy the type array.
1330     mirror::GcRootArray<mirror::Class>* resolved_types = cache->GetResolvedTypesArray();
1331     CreateGcRootDexCacheArray(cache->GetDexFile()->NumTypeIds(),
1332                               mirror::DexCache::kDexCacheTypeCacheSize,
1333                               resolved_types);
1334     // Store the array pointer in the dex cache, which will be relocated at the end.
1335     reinterpret_cast<mirror::DexCache*>(copy)->SetResolvedTypesArray(resolved_types);
1336 
1337     // Copy the string array.
1338     mirror::GcRootArray<mirror::String>* strings = cache->GetStringsArray();
1339     // Note: `new_strings` points to temporary data, and is only valid here.
1340     mirror::GcRootArray<mirror::String>* new_strings =
1341         CreateGcRootDexCacheArray(cache->GetDexFile()->NumStringIds(),
1342                                   mirror::DexCache::kDexCacheStringCacheSize,
1343                                   strings);
1344     // Store the array pointer in the dex cache, which will be relocated at the end.
1345     reinterpret_cast<mirror::DexCache*>(copy)->SetStringsArray(strings);
1346 
1347     // The code below copies new objects, so invalidate the address we have for
1348     // `copy`.
1349     copy = nullptr;
1350     if (strings != nullptr) {
1351       for (uint32_t i = 0; i < cache->GetDexFile()->NumStringIds(); ++i) {
1352         ObjPtr<mirror::String> str = strings->Get(i);
1353         if (str == nullptr || IsInBootImage(str.Ptr())) {
1354           new_strings->Set(i, str.Ptr());
1355         } else {
1356           uint32_t hash = static_cast<uint32_t>(str->GetStoredHashCode());
1357           DCHECK_EQ(hash, static_cast<uint32_t>(str->ComputeHashCode()))
1358               << "Dex cache strings should be interned";
1359           auto it2 = intern_table_.FindWithHash(str.Ptr(), hash);
1360           if (it2 == intern_table_.end()) {
1361             uint32_t string_offset = CopyObject(str);
1362             uint32_t address = image_begin_ + string_offset + sizeof(ImageHeader);
1363             intern_table_.InsertWithHash(address, hash);
1364             new_strings->Set(i, reinterpret_cast<mirror::String*>(address));
1365           } else {
1366             new_strings->Set(i, reinterpret_cast<mirror::String*>(*it2));
1367           }
1368           // To not confuse string references from the dex cache object and
1369           // string references from the array, we put an offset bigger than the
1370           // size of a DexCache object. ClassLinker::VisitInternedStringReferences
1371           // knows how to decode this offset.
1372           string_reference_offsets_.emplace_back(
1373               sizeof(ImageHeader) + offset, sizeof(mirror::DexCache) + i);
1374         }
1375       }
1376     }
1377 
1378     return offset;
1379   }
1380 
IsInitialized(mirror::Class * cls)1381   bool IsInitialized(mirror::Class* cls) REQUIRES_SHARED(Locks::mutator_lock_) {
1382     if (IsInBootImage(cls)) {
1383       const OatDexFile* oat_dex_file = cls->GetDexFile().GetOatDexFile();
1384       DCHECK(oat_dex_file != nullptr) << "We should always have an .oat file for a boot image";
1385       uint16_t class_def_index = cls->GetDexClassDefIndex();
1386       ClassStatus oat_file_class_status = oat_dex_file->GetOatClass(class_def_index).GetStatus();
1387       return oat_file_class_status == ClassStatus::kVisiblyInitialized;
1388     } else {
1389       return cls->IsVisiblyInitialized<kVerifyNone>();
1390     }
1391   }
1392   // Try to initialize `copy`. Note that `cls` may not be initialized.
1393   // This is called after the image generation logic has visited super classes
1394   // and super interfaces, so we can just check those directly.
TryInitializeClass(mirror::Class * copy,ObjPtr<mirror::Class> cls,uint32_t class_offset)1395   bool TryInitializeClass(mirror::Class* copy, ObjPtr<mirror::Class> cls, uint32_t class_offset)
1396       REQUIRES_SHARED(Locks::mutator_lock_) {
1397     if (!cls->IsVerified()) {
1398       return false;
1399     }
1400     if (cls->IsArrayClass()) {
1401       return true;
1402     }
1403 
1404     // Check if we have been able to initialize the super class.
1405     mirror::Class* super = GetClassContent(cls->GetSuperClass());
1406     DCHECK(super != nullptr)
1407         << "App image classes should always have a super class: " << cls->PrettyClass();
1408     if (!IsInitialized(super)) {
1409       return false;
1410     }
1411 
1412     // We won't initialize class with class initializers.
1413     if (cls->FindClassInitializer(kRuntimePointerSize) != nullptr) {
1414       return false;
1415     }
1416 
1417     // For non-interface classes, we require all implemented interfaces to be
1418     // initialized.
1419     if (!cls->IsInterface()) {
1420       for (size_t i = 0; i < cls->NumDirectInterfaces(); i++) {
1421         mirror::Class* itf = GetClassContent(cls->GetDirectInterface(i));
1422         if (!IsInitialized(itf)) {
1423           return false;
1424         }
1425       }
1426     }
1427 
1428     // Trivial case: no static fields.
1429     if (!cls->HasStaticFields()) {
1430       return true;
1431     }
1432 
1433     // Go over all static fields and try to initialize them.
1434     EncodedStaticFieldValueIterator it(cls->GetDexFile(), *cls->GetClassDef());
1435     if (!it.HasNext()) {
1436       return true;
1437     }
1438 
1439     // Temporary string offsets in case we failed to initialize the class. We
1440     // will add the offsets at the end of this method if we are successful.
1441     ArenaVector<AppImageReferenceOffsetInfo> string_offsets(allocator_.Adapter());
1442     ClassLinker* linker = Runtime::Current()->GetClassLinker();
1443     ClassAccessor accessor(cls->GetDexFile(), *cls->GetClassDef());
1444     for (const ClassAccessor::Field& field : accessor.GetStaticFields()) {
1445       if (!it.HasNext()) {
1446         break;
1447       }
1448       ArtField* art_field = linker->LookupResolvedField(field.GetIndex(),
1449                                                         cls->GetDexCache(),
1450                                                         cls->GetClassLoader(),
1451                                                         /* is_static= */ true);
1452       DCHECK_NE(art_field, nullptr);
1453       MemberOffset offset(art_field->GetOffset());
1454       switch (it.GetValueType()) {
1455         case EncodedArrayValueIterator::ValueType::kBoolean:
1456           copy->SetFieldBoolean<false>(offset, it.GetJavaValue().z);
1457           break;
1458         case EncodedArrayValueIterator::ValueType::kByte:
1459           copy->SetFieldByte<false>(offset, it.GetJavaValue().b);
1460           break;
1461         case EncodedArrayValueIterator::ValueType::kShort:
1462           copy->SetFieldShort<false>(offset, it.GetJavaValue().s);
1463           break;
1464         case EncodedArrayValueIterator::ValueType::kChar:
1465           copy->SetFieldChar<false>(offset, it.GetJavaValue().c);
1466           break;
1467         case EncodedArrayValueIterator::ValueType::kInt:
1468           copy->SetField32<false>(offset, it.GetJavaValue().i);
1469           break;
1470         case EncodedArrayValueIterator::ValueType::kLong:
1471           copy->SetField64<false>(offset, it.GetJavaValue().j);
1472           break;
1473         case EncodedArrayValueIterator::ValueType::kFloat:
1474           copy->SetField32<false>(offset, it.GetJavaValue().i);
1475           break;
1476         case EncodedArrayValueIterator::ValueType::kDouble:
1477           copy->SetField64<false>(offset, it.GetJavaValue().j);
1478           break;
1479         case EncodedArrayValueIterator::ValueType::kNull:
1480           copy->SetFieldObject<false>(offset, nullptr);
1481           break;
1482         case EncodedArrayValueIterator::ValueType::kString: {
1483           ObjPtr<mirror::String> str =
1484               linker->LookupString(dex::StringIndex(it.GetJavaValue().i), cls->GetDexCache());
1485           mirror::String* str_copy = nullptr;
1486           if (str == nullptr) {
1487             // String wasn't created yet.
1488             return false;
1489           } else if (IsInBootImage(str.Ptr())) {
1490             str_copy = str.Ptr();
1491           } else {
1492             uint32_t hash = static_cast<uint32_t>(str->GetStoredHashCode());
1493             DCHECK_EQ(hash, static_cast<uint32_t>(str->ComputeHashCode()))
1494                 << "Dex cache strings should be interned";
1495             auto string_it = intern_table_.FindWithHash(str.Ptr(), hash);
1496             if (string_it == intern_table_.end()) {
1497               // The string must be interned.
1498               uint32_t string_offset = CopyObject(str);
1499               // Reload the class copy after having copied the string.
1500               copy = reinterpret_cast<mirror::Class*>(objects_.data() + class_offset);
1501               uint32_t address = image_begin_ + string_offset + sizeof(ImageHeader);
1502               intern_table_.InsertWithHash(address, hash);
1503               str_copy = reinterpret_cast<mirror::String*>(address);
1504             } else {
1505               str_copy = reinterpret_cast<mirror::String*>(*string_it);
1506             }
1507             string_offsets.emplace_back(sizeof(ImageHeader) + class_offset, offset.Int32Value());
1508           }
1509           uint8_t* raw_addr = reinterpret_cast<uint8_t*>(copy) + offset.Int32Value();
1510           mirror::HeapReference<mirror::Object>* objref_addr =
1511               reinterpret_cast<mirror::HeapReference<mirror::Object>*>(raw_addr);
1512           objref_addr->Assign</* kIsVolatile= */ false>(str_copy);
1513           break;
1514         }
1515         case EncodedArrayValueIterator::ValueType::kType: {
1516           // Note that it may be that the referenced type hasn't been processed
1517           // yet by the image generation logic. In this case we bail out for
1518           // simplicity.
1519           ObjPtr<mirror::Class> type =
1520               linker->LookupResolvedType(dex::TypeIndex(it.GetJavaValue().i), cls);
1521           mirror::Class* type_copy = nullptr;
1522           if (type == nullptr) {
1523             // Class wasn't resolved yet.
1524             return false;
1525           } else if (IsInBootImage(type.Ptr())) {
1526             // Make sure the type is in our class table.
1527             uint32_t hash = type->DescriptorHash();
1528             class_table_.InsertWithHash(ClassTable::TableSlot(type.Ptr(), hash), hash);
1529             type_copy = type.Ptr();
1530           } else if (type->IsArrayClass()) {
1531             std::string class_name;
1532             type->GetDescriptor(&class_name);
1533             auto class_it = array_classes_.find(class_name);
1534             if (class_it == array_classes_.end()) {
1535               return false;
1536             }
1537             type_copy = reinterpret_cast<mirror::Class*>(
1538                 image_begin_ + sizeof(ImageHeader) + class_it->second);
1539           } else {
1540             const dex::ClassDef* class_def = type->GetClassDef();
1541             DCHECK_NE(class_def, nullptr);
1542             auto class_it = classes_.find(class_def);
1543             if (class_it == classes_.end()) {
1544               return false;
1545             }
1546             type_copy = reinterpret_cast<mirror::Class*>(
1547                 image_begin_ + sizeof(ImageHeader) + class_it->second);
1548           }
1549           uint8_t* raw_addr = reinterpret_cast<uint8_t*>(copy) + offset.Int32Value();
1550           mirror::HeapReference<mirror::Object>* objref_addr =
1551               reinterpret_cast<mirror::HeapReference<mirror::Object>*>(raw_addr);
1552           objref_addr->Assign</* kIsVolatile= */ false>(type_copy);
1553           break;
1554         }
1555         default:
1556           LOG(FATAL) << "Unreachable";
1557       }
1558       it.Next();
1559     }
1560     // We have successfully initialized the class, we can now record the string
1561     // offsets.
1562     string_reference_offsets_.insert(
1563         string_reference_offsets_.end(), string_offsets.begin(), string_offsets.end());
1564     return true;
1565   }
1566 
CopyClass(ObjPtr<mirror::Class> cls)1567   uint32_t CopyClass(ObjPtr<mirror::Class> cls) REQUIRES_SHARED(Locks::mutator_lock_) {
1568     DCHECK(!cls->IsBootStrapClassLoaded());
1569     uint32_t offset = 0u;
1570     if (cls->IsArrayClass()) {
1571       std::string class_name;
1572       cls->GetDescriptor(&class_name);
1573       auto it = array_classes_.find(class_name);
1574       if (it != array_classes_.end()) {
1575         return it->second;
1576       }
1577       offset = CopyObject(cls);
1578       array_classes_.Put(class_name, offset);
1579     } else {
1580       const dex::ClassDef* class_def = cls->GetClassDef();
1581       auto it = classes_.find(class_def);
1582       if (it != classes_.end()) {
1583         return it->second;
1584       }
1585       offset = CopyObject(cls);
1586       classes_.Put(class_def, offset);
1587     }
1588 
1589     uint32_t hash = cls->DescriptorHash();
1590     // Save the hash, the `HashSet` implementation requires to find it.
1591     class_hashes_.Put(offset, hash);
1592     uint32_t class_image_address = image_begin_ + sizeof(ImageHeader) + offset;
1593     bool inserted =
1594         class_table_.InsertWithHash(ClassTable::TableSlot(class_image_address, hash), hash).second;
1595     DCHECK(inserted) << "Class " << cls->PrettyDescriptor()
1596                      << " (" << cls.Ptr() << ") already inserted";
1597 
1598     // Clear internal state.
1599     mirror::Class* copy = reinterpret_cast<mirror::Class*>(objects_.data() + offset);
1600     copy->SetClinitThreadId(static_cast<pid_t>(0u));
1601     if (cls->IsArrayClass()) {
1602       DCHECK(copy->IsVisiblyInitialized());
1603     } else {
1604       copy->SetStatusInternal(cls->IsVerified() ? ClassStatus::kVerified : ClassStatus::kResolved);
1605     }
1606 
1607     // Clear static field values.
1608     auto clear_class = [&] () REQUIRES_SHARED(Locks::mutator_lock_) {
1609       MemberOffset static_offset = cls->GetFirstReferenceStaticFieldOffset(kRuntimePointerSize);
1610       uint32_t ref_offsets = cls->GetReferenceInstanceOffsets();
1611       size_t size = cls->GetClassSize() - static_offset.Uint32Value();
1612       // Adjust for overflow instance-offset bitmap, which is after the static
1613       // fields.
1614       if ((ref_offsets & mirror::Class::kVisitReferencesSlowpathMask) != 0) {
1615         ref_offsets &= ~mirror::Class::kVisitReferencesSlowpathMask;
1616         size -= ref_offsets * sizeof(uint32_t);
1617       }
1618       memset(objects_.data() + offset + static_offset.Uint32Value(), 0, size);
1619     };
1620     clear_class();
1621 
1622     bool is_class_initialized = TryInitializeClass(copy, cls, offset);
1623     // Reload the copy, it may have moved after `TryInitializeClass`.
1624     copy = reinterpret_cast<mirror::Class*>(objects_.data() + offset);
1625     if (is_class_initialized) {
1626       copy->SetStatusInternal(ClassStatus::kVisiblyInitialized);
1627       if (!cls->IsArrayClass() && !cls->IsFinalizable()) {
1628         copy->SetObjectSizeAllocFastPath(RoundUp(cls->GetObjectSize(), kObjectAlignment));
1629       }
1630       if (cls->IsInterface()) {
1631         copy->SetAccessFlags(copy->GetAccessFlags() | kAccRecursivelyInitialized);
1632       }
1633     } else {
1634       // If we fail to initialize, remove initialization related flags and
1635       // clear again.
1636       copy->SetObjectSizeAllocFastPath(std::numeric_limits<uint32_t>::max());
1637       copy->SetAccessFlags(copy->GetAccessFlags() & ~kAccRecursivelyInitialized);
1638       clear_class();
1639     }
1640 
1641     CopyFieldArrays(cls, class_image_address);
1642     CopyMethodArrays(cls, class_image_address, is_class_initialized);
1643     if (cls->ShouldHaveImt()) {
1644       CopyImTable(cls);
1645     }
1646 
1647     return offset;
1648   }
1649 
1650   // Copy `obj` in `objects_` and relocate references. Returns the offset
1651   // within our buffer.
CopyObject(ObjPtr<mirror::Object> obj)1652   uint32_t CopyObject(ObjPtr<mirror::Object> obj) REQUIRES_SHARED(Locks::mutator_lock_) {
1653     // Copy the object in `objects_`.
1654     size_t object_size = obj->SizeOf();
1655     size_t offset = objects_.size();
1656     DCHECK(IsAligned<kObjectAlignment>(offset));
1657     object_offsets_.push_back(offset);
1658     objects_.resize(RoundUp(offset + object_size, kObjectAlignment));
1659 
1660     mirror::Object* copy = reinterpret_cast<mirror::Object*>(objects_.data() + offset);
1661     mirror::Object::CopyRawObjectData(
1662         reinterpret_cast<uint8_t*>(copy), obj, object_size - sizeof(mirror::Object));
1663     // Clear any lockword data.
1664     copy->SetLockWord(LockWord::Default(), /* as_volatile= */ false);
1665     copy->SetClass(obj->GetClass());
1666 
1667     // Fixup reference pointers.
1668     FixupVisitor visitor(this, offset);
1669     obj->VisitReferences</*kVisitNativeRoots=*/ false>(visitor, visitor);
1670 
1671     if (obj->IsString()) {
1672       // Ensure a string always has a hashcode stored. This is checked at
1673       // runtime because boot images don't want strings dirtied due to hashcode.
1674       reinterpret_cast<mirror::String*>(copy)->GetHashCode();
1675     }
1676 
1677     object_section_size_ += RoundUp(object_size, kObjectAlignment);
1678     return offset;
1679   }
1680 
1681   class CollectDexCacheVisitor : public DexCacheVisitor {
1682    public:
CollectDexCacheVisitor(VariableSizedHandleScope & handles)1683     explicit CollectDexCacheVisitor(VariableSizedHandleScope& handles) : handles_(handles) {}
1684 
Visit(ObjPtr<mirror::DexCache> dex_cache)1685     void Visit(ObjPtr<mirror::DexCache> dex_cache)
1686         REQUIRES_SHARED(Locks::dex_lock_, Locks::mutator_lock_) override {
1687       dex_caches_.push_back(handles_.NewHandle(dex_cache));
1688     }
GetDexCaches() const1689     const std::vector<Handle<mirror::DexCache>>& GetDexCaches() const {
1690       return dex_caches_;
1691     }
1692    private:
1693     VariableSizedHandleScope& handles_;
1694     std::vector<Handle<mirror::DexCache>> dex_caches_;
1695   };
1696 
1697   // Find dex caches corresponding to the primary APK.
FindDexCaches(Thread * self,dchecked_vector<Handle<mirror::DexCache>> & dex_caches,VariableSizedHandleScope & handles)1698   void FindDexCaches(Thread* self,
1699                      dchecked_vector<Handle<mirror::DexCache>>& dex_caches,
1700                      VariableSizedHandleScope& handles)
1701       REQUIRES_SHARED(Locks::mutator_lock_) {
1702     ScopedTrace trace("Find dex caches");
1703     DCHECK(dex_caches.empty());
1704     // Collect all dex caches.
1705     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1706     CollectDexCacheVisitor visitor(handles);
1707     {
1708       ReaderMutexLock mu(self, *Locks::dex_lock_);
1709       class_linker->VisitDexCaches(&visitor);
1710     }
1711 
1712     // Find the primary APK.
1713     AppInfo* app_info = Runtime::Current()->GetAppInfo();
1714     for (Handle<mirror::DexCache> cache : visitor.GetDexCaches()) {
1715       if (app_info->GetRegisteredCodeType(cache->GetDexFile()->GetLocation()) ==
1716               AppInfo::CodeType::kPrimaryApk) {
1717         dex_caches.push_back(handles.NewHandle(cache.Get()));
1718         break;
1719       }
1720     }
1721 
1722     if (dex_caches.empty()) {
1723       return;
1724     }
1725 
1726     const OatDexFile* oat_dex_file = dex_caches[0]->GetDexFile()->GetOatDexFile();
1727     if (oat_dex_file == nullptr) {
1728       // We need a .oat file for loading an app image;
1729       dex_caches.clear();
1730       return;
1731     }
1732 
1733     // Store the dex caches in the order in which their corresponding dex files
1734     // are stored in the oat file. When we check for checksums at the point of
1735     // loading the image, we rely on this order.
1736     for (const OatDexFile* current : oat_dex_file->GetOatFile()->GetOatDexFiles()) {
1737       if (current != oat_dex_file) {
1738         for (Handle<mirror::DexCache> cache : visitor.GetDexCaches()) {
1739           if (cache->GetDexFile()->GetOatDexFile() == current) {
1740             dex_caches.push_back(handles.NewHandle(cache.Get()));
1741           }
1742         }
1743       }
1744     }
1745   }
1746 
PointerToUint64(void * ptr)1747   static uint64_t PointerToUint64(void* ptr) {
1748     return reinterpret_cast64<uint64_t>(ptr);
1749   }
1750 
WriteImageMethods()1751   void WriteImageMethods() {
1752     ScopedObjectAccess soa(Thread::Current());
1753     // We can just use plain runtime pointers.
1754     Runtime* runtime = Runtime::Current();
1755     header_.image_methods_[ImageHeader::kResolutionMethod] =
1756         PointerToUint64(runtime->GetResolutionMethod());
1757     header_.image_methods_[ImageHeader::kImtConflictMethod] =
1758         PointerToUint64(runtime->GetImtConflictMethod());
1759     header_.image_methods_[ImageHeader::kImtUnimplementedMethod] =
1760         PointerToUint64(runtime->GetImtUnimplementedMethod());
1761     header_.image_methods_[ImageHeader::kSaveAllCalleeSavesMethod] =
1762         PointerToUint64(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveAllCalleeSaves));
1763     header_.image_methods_[ImageHeader::kSaveRefsOnlyMethod] =
1764         PointerToUint64(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveRefsOnly));
1765     header_.image_methods_[ImageHeader::kSaveRefsAndArgsMethod] =
1766         PointerToUint64(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveRefsAndArgs));
1767     header_.image_methods_[ImageHeader::kSaveEverythingMethod] =
1768         PointerToUint64(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveEverything));
1769     header_.image_methods_[ImageHeader::kSaveEverythingMethodForClinit] =
1770         PointerToUint64(runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveEverythingForClinit));
1771     header_.image_methods_[ImageHeader::kSaveEverythingMethodForSuspendCheck] =
1772         PointerToUint64(
1773             runtime->GetCalleeSaveMethod(CalleeSaveType::kSaveEverythingForSuspendCheck));
1774   }
1775 
1776   // Header for the image, created at the end once we know the size of all
1777   // sections.
1778   ImageHeader header_;
1779 
1780   // Allocator for the various data structures to allocate while generating the
1781   // image.
1782   ArenaAllocator allocator_;
1783 
1784   // Contents of the various sections.
1785   ArenaVector<uint8_t> objects_;
1786   ArenaVector<uint8_t> art_fields_;
1787   ArenaVector<uint8_t> art_methods_;
1788   ArenaVector<uint8_t> im_tables_;
1789   ArenaVector<uint8_t> metadata_;
1790   ArenaVector<uint8_t> dex_cache_arrays_;
1791 
1792   ArenaVector<AppImageReferenceOffsetInfo> string_reference_offsets_;
1793 
1794   // Bitmap of live objects in `objects_`. Populated from `object_offsets_`
1795   // once we know `object_section_size`.
1796   gc::accounting::ContinuousSpaceBitmap image_bitmap_;
1797 
1798   // Sections stored in the header.
1799   ArenaVector<ImageSection> sections_;
1800 
1801   // A list of offsets in `objects_` where objects begin.
1802   ArenaVector<uint32_t> object_offsets_;
1803 
1804   ArenaSafeMap<const dex::ClassDef*, uint32_t> classes_;
1805   ArenaSafeMap<std::string, uint32_t> array_classes_;
1806   ArenaSafeMap<const DexFile*, uint32_t> dex_caches_;
1807   ArenaSafeMap<uint32_t, uint32_t> class_hashes_;
1808 
1809   ArenaSafeMap<void*, std::pair<NativeRelocationKind, uint32_t>> native_relocations_;
1810 
1811   // Cached values of boot image information.
1812   const uint32_t boot_image_begin_;
1813   const uint32_t boot_image_size_;
1814 
1815   // Where the image begins: just after the boot image.
1816   const uint32_t image_begin_;
1817 
1818   // Size of the `kSectionObjects` section.
1819   size_t object_section_size_;
1820 
1821   // The location of the primary APK / dex file.
1822   std::string dex_location_;
1823 
1824   // The intern table for strings that we will write to disk.
1825   InternTableSet intern_table_;
1826 
1827   // The class table holding classes that we will write to disk.
1828   ClassTableSet class_table_;
1829 
1830   friend class ClassDescriptorHash;
1831   friend class PruneVisitor;
1832   friend class NativePointerVisitor;
1833 };
1834 
GetRuntimeImageDir(const std::string & app_data_dir)1835 std::string RuntimeImage::GetRuntimeImageDir(const std::string& app_data_dir) {
1836   if (app_data_dir.empty()) {
1837     // The data directory is empty for tests.
1838     return "";
1839   }
1840   return app_data_dir + "/cache/oat_primary/";
1841 }
1842 
1843 // Note: this may return a relative path for tests.
GetRuntimeImagePath(const std::string & app_data_dir,const std::string & dex_location,const std::string & isa)1844 std::string RuntimeImage::GetRuntimeImagePath(const std::string& app_data_dir,
1845                                               const std::string& dex_location,
1846                                               const std::string& isa) {
1847   std::string basename = android::base::Basename(dex_location);
1848   std::string filename = ReplaceFileExtension(basename, kArtExtension);
1849 
1850   return GetRuntimeImageDir(app_data_dir) + isa + "/" + filename;
1851 }
1852 
GetRuntimeImagePath(const std::string & dex_location)1853 std::string RuntimeImage::GetRuntimeImagePath(const std::string& dex_location) {
1854   return GetRuntimeImagePath(Runtime::Current()->GetProcessDataDirectory(),
1855                              dex_location,
1856                              GetInstructionSetString(kRuntimeQuickCodeISA));
1857 }
1858 
EnsureDirectoryExists(const std::string & directory,std::string * error_msg)1859 static bool EnsureDirectoryExists(const std::string& directory, std::string* error_msg) {
1860   if (!OS::DirectoryExists(directory.c_str())) {
1861     static constexpr mode_t kDirectoryMode = S_IRWXU | S_IRGRP | S_IXGRP| S_IROTH | S_IXOTH;
1862     if (mkdir(directory.c_str(), kDirectoryMode) != 0) {
1863       *error_msg =
1864           StringPrintf("Could not create directory %s: %s", directory.c_str(), strerror(errno));
1865       return false;
1866     }
1867   }
1868   return true;
1869 }
1870 
WriteImageToDisk(std::string * error_msg)1871 bool RuntimeImage::WriteImageToDisk(std::string* error_msg) {
1872   gc::Heap* heap = Runtime::Current()->GetHeap();
1873   if (!heap->HasBootImageSpace()) {
1874     *error_msg = "Cannot generate an app image without a boot image";
1875     return false;
1876   }
1877   std::string oat_path = GetRuntimeImageDir(Runtime::Current()->GetProcessDataDirectory());
1878   if (!oat_path.empty() && !EnsureDirectoryExists(oat_path, error_msg)) {
1879     return false;
1880   }
1881 
1882   ScopedTrace generate_image_trace("Generating runtime image");
1883   std::unique_ptr<RuntimeImageHelper> image(new RuntimeImageHelper(heap));
1884   if (!image->Generate(error_msg)) {
1885     return false;
1886   }
1887 
1888   ScopedTrace write_image_trace("Writing runtime image to disk");
1889 
1890   const std::string path = GetRuntimeImagePath(image->GetDexLocation());
1891   if (!EnsureDirectoryExists(android::base::Dirname(path), error_msg)) {
1892     return false;
1893   }
1894 
1895   // We first generate the app image in a temporary file, which we will then
1896   // move to `path`.
1897   const std::string temp_path = ReplaceFileExtension(path, std::to_string(getpid()) + ".tmp");
1898   ImageFileGuard image_file;
1899   image_file.reset(OS::CreateEmptyFileWriteOnly(temp_path.c_str()));
1900 
1901   if (image_file == nullptr) {
1902     *error_msg = "Could not open " + temp_path + " for writing";
1903     return false;
1904   }
1905 
1906   std::vector<uint8_t> full_data(image->GetHeader()->GetImageSize());
1907   image->FillData(full_data);
1908 
1909   // Specify default block size of 512K to enable parallel image decompression.
1910   static constexpr size_t kMaxImageBlockSize = 524288;
1911   // Use LZ4 as good compromise between CPU time and compression. LZ4HC
1912   // empirically takes 10x more time compressing.
1913   static constexpr ImageHeader::StorageMode kImageStorageMode = ImageHeader::kStorageModeLZ4;
1914   // Note: no need to update the checksum of the runtime app image: we have no
1915   // use for it, and computing it takes CPU time.
1916   if (!image->GetHeader()->WriteData(
1917           image_file,
1918           full_data.data(),
1919           reinterpret_cast<const uint8_t*>(image->GetImageBitmap().Begin()),
1920           kImageStorageMode,
1921           kMaxImageBlockSize,
1922           /* update_checksum= */ false,
1923           error_msg)) {
1924     return false;
1925   }
1926 
1927   if (!image_file.WriteHeaderAndClose(temp_path, image->GetHeader(), error_msg)) {
1928     return false;
1929   }
1930 
1931   if (rename(temp_path.c_str(), path.c_str()) != 0) {
1932     *error_msg =
1933         "Failed to move runtime app image to " + path + ": " + std::string(strerror(errno));
1934     // Unlink directly: we cannot use `out` as we have closed it.
1935     unlink(temp_path.c_str());
1936     return false;
1937   }
1938 
1939   return true;
1940 }
1941 
1942 }  // namespace art
1943