1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_DEX2OAT_LINKER_IMAGE_WRITER_H_ 18 #define ART_DEX2OAT_LINKER_IMAGE_WRITER_H_ 19 20 #include <stdint.h> 21 #include "base/memory_tool.h" 22 23 #include <cstddef> 24 #include <memory> 25 #include <ostream> 26 #include <set> 27 #include <stack> 28 #include <string> 29 30 #include "art_method.h" 31 #include "base/bit_utils.h" 32 #include "base/dchecked_vector.h" 33 #include "base/unix_file/fd_file.h" 34 #include "base/hash_map.h" 35 #include "base/hash_set.h" 36 #include "base/length_prefixed_array.h" 37 #include "base/macros.h" 38 #include "base/mem_map.h" 39 #include "base/os.h" 40 #include "base/pointer_size.h" 41 #include "base/utils.h" 42 #include "class_table.h" 43 #include "gc/accounting/space_bitmap.h" 44 #include "intern_table.h" 45 #include "lock_word.h" 46 #include "mirror/dex_cache.h" 47 #include "oat/image.h" 48 #include "oat/jni_stub_hash_map.h" 49 #include "oat/oat.h" 50 #include "oat/oat_file.h" 51 #include "obj_ptr.h" 52 53 namespace art { 54 namespace gc { 55 namespace accounting { 56 template <size_t kAlignment> class SpaceBitmap; 57 using ContinuousSpaceBitmap = SpaceBitmap<kObjectAlignment>; 58 } // namespace accounting 59 namespace space { 60 class ImageSpace; 61 } // namespace space 62 } // namespace gc 63 64 namespace mirror { 65 class ClassLoader; 66 } // namespace mirror 67 68 class ClassLoaderVisitor; 69 class CompilerOptions; 70 template<class T> class Handle; 71 class ImTable; 72 class ImtConflictTable; 73 class JavaVMExt; 74 class TimingLogger; 75 76 namespace linker { 77 78 // Write a Space built during compilation for use during execution. 79 class ImageWriter final { 80 public: 81 ImageWriter(const CompilerOptions& compiler_options, 82 uintptr_t image_begin, 83 ImageHeader::StorageMode image_storage_mode, 84 const std::vector<std::string>& oat_filenames, 85 const HashMap<const DexFile*, size_t>& dex_file_oat_index_map, 86 jobject class_loader, 87 const std::vector<std::string>* dirty_image_objects); 88 ~ImageWriter(); 89 90 /* 91 * Modifies the heap and collects information about objects and code so that 92 * they can be written to the boot or app image later. 93 * 94 * First, unneeded classes are removed from the managed heap. Next, we 95 * remove cached values and calculate necessary metadata for later in the 96 * process. Optionally some debugging information is collected and used to 97 * verify the state of the heap at this point. Next, metadata from earlier 98 * is used to calculate offsets of references to strings to speed up string 99 * interning when the image is loaded. Lastly, we allocate enough memory to 100 * fit all image data minus the bitmap and relocation sections. 101 * 102 * This function should only be called when all objects to be included in the 103 * image have been initialized and all native methods have been generated. In 104 * addition, no other thread should be modifying the heap. 105 */ 106 bool PrepareImageAddressSpace(TimingLogger* timings); 107 IsImageAddressSpaceReady()108 bool IsImageAddressSpaceReady() const { 109 DCHECK(!image_infos_.empty()); 110 for (const ImageInfo& image_info : image_infos_) { 111 if (image_info.image_roots_address_ == 0u) { 112 return false; 113 } 114 } 115 return true; 116 } 117 118 ObjPtr<mirror::ClassLoader> GetAppClassLoader() const REQUIRES_SHARED(Locks::mutator_lock_); 119 120 template <typename T> GetImageAddress(T * object)121 T* GetImageAddress(T* object) const REQUIRES_SHARED(Locks::mutator_lock_) { 122 if (object == nullptr || IsInBootImage(object)) { 123 return object; 124 } else { 125 size_t oat_index = GetOatIndex(object); 126 const ImageInfo& image_info = GetImageInfo(oat_index); 127 return reinterpret_cast<T*>(image_info.image_begin_ + GetImageOffset(object, oat_index)); 128 } 129 } 130 GetGlobalImageOffset(mirror::Object * object)131 uint32_t GetGlobalImageOffset(mirror::Object* object) const REQUIRES_SHARED(Locks::mutator_lock_) { 132 DCHECK(object != nullptr); 133 DCHECK(!IsInBootImage(object)); 134 size_t oat_index = GetOatIndex(object); 135 const ImageInfo& image_info = GetImageInfo(oat_index); 136 return dchecked_integral_cast<uint32_t>( 137 image_info.image_begin_ + GetImageOffset(object, oat_index) - global_image_begin_); 138 } 139 140 ArtMethod* GetImageMethodAddress(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_); 141 const void* GetIntrinsicReferenceAddress(uint32_t intrinsic_data) 142 REQUIRES_SHARED(Locks::mutator_lock_); 143 GetOatFileOffset(size_t oat_index)144 size_t GetOatFileOffset(size_t oat_index) const { 145 return GetImageInfo(oat_index).oat_offset_; 146 } 147 GetOatFileBegin(size_t oat_index)148 const uint8_t* GetOatFileBegin(size_t oat_index) const { 149 return GetImageInfo(oat_index).oat_file_begin_; 150 } 151 152 // If image_fd is not File::kInvalidFd, then we use that for the image file. Otherwise we open 153 // the names in image_filenames. 154 // If oat_fd is not File::kInvalidFd, then we use that for the oat file. Otherwise we open 155 // the names in oat_filenames. 156 bool Write(int image_fd, 157 const std::vector<std::string>& image_filenames, 158 size_t component_count) 159 REQUIRES(!Locks::mutator_lock_); 160 GetOatDataBegin(size_t oat_index)161 uintptr_t GetOatDataBegin(size_t oat_index) { 162 return reinterpret_cast<uintptr_t>(GetImageInfo(oat_index).oat_data_begin_); 163 } 164 165 // Get the index of the oat file containing the dex file. 166 // 167 // This "oat_index" is used to retrieve information about the the memory layout 168 // of the oat file and its associated image file, needed for link-time patching 169 // of references to the image or across oat files. 170 size_t GetOatIndexForDexFile(const DexFile* dex_file) const; 171 172 // Get the index of the oat file containing the definition of the class. 173 size_t GetOatIndexForClass(ObjPtr<mirror::Class> klass) const 174 REQUIRES_SHARED(Locks::mutator_lock_); 175 176 // Update the oat layout for the given oat file. 177 // This will make the oat_offset for the next oat file valid. 178 void UpdateOatFileLayout(size_t oat_index, 179 size_t oat_loaded_size, 180 size_t oat_data_offset, 181 size_t oat_data_size); 182 // Update information about the oat header, i.e. checksum and trampoline offsets. 183 void UpdateOatFileHeader(size_t oat_index, const OatHeader& oat_header); 184 185 private: 186 bool AllocMemory(); 187 188 // Mark the objects defined in this space in the given live bitmap. 189 void RecordImageAllocations() REQUIRES_SHARED(Locks::mutator_lock_); 190 191 // Classify different kinds of bins that objects end up getting packed into during image writing. 192 // Ordered from dirtiest to cleanest (until ArtMethods). 193 enum class Bin { 194 kKnownDirty, // Known dirty objects from --dirty-image-objects list 195 kMiscDirty, // Dex caches, object locks, etc... 196 kClassVerified, // Class verified, but initializers haven't been run 197 // Unknown mix of clean/dirty: 198 kRegular, 199 kClassInitialized, // Class initializers have been run 200 // All classes get their own bins since their fields often dirty 201 kClassInitializedFinalStatics, // Class initializers have been run, no non-final statics 202 // Likely-clean: 203 kString, // [String] Almost always immutable (except for obj header). 204 // Definitely clean: 205 kInternalClean, // ART internal: image roots, boot image live objects, vtables 206 // and interface tables, Object[]/int[]/long[]. 207 // Add more bins here if we add more segregation code. 208 // Non mirror fields must be below. 209 // ArtFields should be always clean. 210 kArtField, 211 // If the class is initialized, then the ArtMethods are probably clean. 212 kArtMethodClean, 213 // ArtMethods may be dirty if the class has native methods or a declaring class that isn't 214 // initialized. 215 kArtMethodDirty, 216 // IMT (clean) 217 kImTable, 218 // Conflict tables (clean). 219 kIMTConflictTable, 220 // Runtime methods (always clean, do not have a length prefix array). 221 kRuntimeMethod, 222 // Methods with unique JNI stubs. 223 kJniStubMethod, 224 // Metadata bin for data that is temporary during image lifetime. 225 kMetadata, 226 kLast = kMetadata, 227 // Number of bins which are for mirror objects. 228 kMirrorCount = kArtField, 229 }; 230 friend std::ostream& operator<<(std::ostream& stream, Bin bin); 231 232 enum class NativeObjectRelocationType { 233 kArtFieldArray, 234 kArtMethodClean, 235 kArtMethodArrayClean, 236 kArtMethodDirty, 237 kArtMethodArrayDirty, 238 kGcRootPointer, 239 kRuntimeMethod, 240 kIMTable, 241 kIMTConflictTable, 242 }; 243 friend std::ostream& operator<<(std::ostream& stream, NativeObjectRelocationType type); 244 245 static constexpr size_t kBinBits = 246 MinimumBitsToStore<uint32_t>(static_cast<size_t>(Bin::kMirrorCount) - 1); 247 // uint32 = typeof(lockword_) 248 // Subtract read barrier bits since we want these to remain 0, or else it may result in DCHECK 249 // failures due to invalid read barrier bits during object field reads. 250 static const size_t kBinShift = BitSizeOf<uint32_t>() - kBinBits - LockWord::kGCStateSize; 251 // 111000.....0 252 static const size_t kBinMask = ((static_cast<size_t>(1) << kBinBits) - 1) << kBinShift; 253 254 // Number of bins, including non-mirror bins. 255 static constexpr size_t kNumberOfBins = static_cast<size_t>(Bin::kLast) + 1u; 256 257 // Number of stub types. 258 static constexpr size_t kNumberOfStubTypes = static_cast<size_t>(StubType::kLast) + 1u; 259 260 // We use the lock word to store the bin # and bin index of the object in the image. 261 // 262 // The struct size must be exactly sizeof(LockWord), currently 32-bits, since this will end up 263 // stored in the lock word bit-for-bit when object forwarding addresses are being calculated. 264 struct BinSlot { 265 explicit BinSlot(uint32_t lockword); 266 BinSlot(Bin bin, uint32_t index); 267 268 // The bin an object belongs to, i.e. regular, class/verified, class/initialized, etc. 269 Bin GetBin() const; 270 // The offset in bytes from the beginning of the bin. Aligned to object size. 271 uint32_t GetOffset() const; 272 // Pack into a single uint32_t, for storing into a lock word. Uint32ValueBinSlot273 uint32_t Uint32Value() const { return lockword_; } 274 // Comparison operator for map support 275 bool operator<(const BinSlot& other) const { return lockword_ < other.lockword_; } 276 277 private: 278 // Must be the same size as LockWord, any larger and we would truncate the data. 279 uint32_t lockword_; 280 }; 281 282 struct ImageInfo { 283 ImageInfo(); 284 ImageInfo(ImageInfo&&) = default; 285 286 /* 287 * Creates ImageSection objects that describe most of the sections of a 288 * boot or AppImage. The following sections are not included: 289 * - ImageHeader::kSectionImageBitmap 290 * 291 * In addition, the ImageHeader is not covered here. 292 * 293 * This function will return the total size of the covered sections as well 294 * as a vector containing the individual ImageSection objects. 295 */ 296 std::pair<size_t, dchecked_vector<ImageSection>> CreateImageSections() const; 297 GetStubOffsetImageInfo298 size_t GetStubOffset(StubType stub_type) const { 299 DCHECK_LT(static_cast<size_t>(stub_type), kNumberOfStubTypes); 300 return stub_offsets_[static_cast<size_t>(stub_type)]; 301 } 302 SetStubOffsetImageInfo303 void SetStubOffset(StubType stub_type, size_t offset) { 304 DCHECK_LT(static_cast<size_t>(stub_type), kNumberOfStubTypes); 305 stub_offsets_[static_cast<size_t>(stub_type)] = offset; 306 } 307 GetBinSlotOffsetImageInfo308 size_t GetBinSlotOffset(Bin bin) const { 309 DCHECK_LT(static_cast<size_t>(bin), kNumberOfBins); 310 return bin_slot_offsets_[static_cast<size_t>(bin)]; 311 } 312 IncrementBinSlotSizeImageInfo313 void IncrementBinSlotSize(Bin bin, size_t size_to_add) { 314 DCHECK_LT(static_cast<size_t>(bin), kNumberOfBins); 315 bin_slot_sizes_[static_cast<size_t>(bin)] += size_to_add; 316 } 317 GetBinSlotSizeImageInfo318 size_t GetBinSlotSize(Bin bin) const { 319 DCHECK_LT(static_cast<size_t>(bin), kNumberOfBins); 320 return bin_slot_sizes_[static_cast<size_t>(bin)]; 321 } 322 IncrementBinSlotCountImageInfo323 void IncrementBinSlotCount(Bin bin, size_t count_to_add) { 324 DCHECK_LT(static_cast<size_t>(bin), kNumberOfBins); 325 bin_slot_count_[static_cast<size_t>(bin)] += count_to_add; 326 } 327 328 // Calculate the sum total of the bin slot sizes in [0, up_to). Defaults to all bins. 329 size_t GetBinSizeSum(Bin up_to) const; 330 331 MemMap image_; // Memory mapped for generating the image. 332 333 // Target begin of this image. Notes: It is not valid to write here, this is the address 334 // of the target image, not necessarily where image_ is mapped. The address is only valid 335 // after layouting (otherwise null). 336 uint8_t* image_begin_ = nullptr; 337 338 // Offset to the free space in image_, initially size of image header. 339 size_t image_end_ = RoundUp(sizeof(ImageHeader), kObjectAlignment); 340 uint32_t image_roots_address_ = 0; // The image roots address in the image. 341 size_t image_offset_ = 0; // Offset of this image from the start of the first image. 342 343 // Image size is the *address space* covered by this image. As the live bitmap is aligned 344 // to the page size, the live bitmap will cover more address space than necessary. But live 345 // bitmaps may not overlap, so an image has a "shadow," which is accounted for in the size. 346 // The next image may only start at image_begin_ + image_size_ (which is guaranteed to be 347 // page-aligned). 348 size_t image_size_ = 0; 349 350 // Oat data. 351 // Offset of the oat file for this image from start of oat files. This is 352 // valid when the previous oat file has been written. 353 size_t oat_offset_ = 0; 354 // Layout of the loaded ELF file containing the oat file, valid after UpdateOatFileLayout(). 355 const uint8_t* oat_file_begin_ = nullptr; 356 size_t oat_loaded_size_ = 0; 357 const uint8_t* oat_data_begin_ = nullptr; 358 size_t oat_size_ = 0; // Size of the corresponding oat data. 359 // The oat header checksum, valid after UpdateOatFileHeader(). 360 uint32_t oat_checksum_ = 0u; 361 362 // Image bitmap which lets us know where the objects inside of the image reside. 363 gc::accounting::ContinuousSpaceBitmap image_bitmap_; 364 365 // Offset from oat_data_begin_ to the stubs. 366 uint32_t stub_offsets_[kNumberOfStubTypes] = {}; 367 368 // Bin slot tracking for dirty object packing. 369 size_t bin_slot_sizes_[kNumberOfBins] = {}; // Number of bytes in a bin. 370 size_t bin_slot_offsets_[kNumberOfBins] = {}; // Number of bytes in previous bins. 371 size_t bin_slot_count_[kNumberOfBins] = {}; // Number of objects in a bin. 372 373 // Cached size of the intern table for when we allocate memory. 374 size_t intern_table_bytes_ = 0; 375 376 // Number of image class table bytes. 377 size_t class_table_bytes_ = 0; 378 379 // Number of object fixup bytes. 380 size_t object_fixup_bytes_ = 0; 381 382 // Number of pointer fixup bytes. 383 size_t pointer_fixup_bytes_ = 0; 384 385 // Number of offsets to string references that will be written to the 386 // StringFieldOffsets section. 387 size_t num_string_references_ = 0; 388 389 // Offsets into the image that indicate where string references are recorded. 390 dchecked_vector<AppImageReferenceOffsetInfo> string_reference_offsets_; 391 392 // Intern table associated with this image for serialization. 393 size_t intern_table_size_ = 0; 394 std::unique_ptr<GcRoot<mirror::String>[]> intern_table_buffer_; 395 std::optional<InternTable::UnorderedSet> intern_table_; 396 397 // Class table associated with this image for serialization. 398 size_t class_table_size_ = 0; 399 std::unique_ptr<ClassTable::ClassSet::value_type[]> class_table_buffer_; 400 std::optional<ClassTable::ClassSet> class_table_; 401 402 // Padding offsets to ensure region alignment (if required). 403 // Objects need to be added from the recorded offset until the end of the region. 404 dchecked_vector<size_t> padding_offsets_; 405 }; 406 407 // We use the lock word to store the offset of the object in the image. 408 size_t GetImageOffset(mirror::Object* object, size_t oat_index) const 409 REQUIRES_SHARED(Locks::mutator_lock_); 410 411 Bin GetImageBin(mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_); 412 void AssignImageBinSlot(mirror::Object* object, size_t oat_index, Bin bin) 413 REQUIRES_SHARED(Locks::mutator_lock_); 414 void RecordNativeRelocations(ObjPtr<mirror::Class> klass, size_t oat_index) 415 REQUIRES_SHARED(Locks::mutator_lock_); 416 void SetImageBinSlot(mirror::Object* object, BinSlot bin_slot) 417 REQUIRES_SHARED(Locks::mutator_lock_); 418 bool IsImageBinSlotAssigned(mirror::Object* object) const 419 REQUIRES_SHARED(Locks::mutator_lock_); 420 BinSlot GetImageBinSlot(mirror::Object* object, size_t oat_index) const 421 REQUIRES_SHARED(Locks::mutator_lock_); 422 void UpdateImageBinSlotOffset(mirror::Object* object, size_t oat_index, size_t new_offset) 423 REQUIRES_SHARED(Locks::mutator_lock_); 424 425 // Returns the address in the boot image if we are compiling the app image. 426 const uint8_t* GetOatAddress(StubType type) const; 427 GetOatAddressForOffset(uint32_t offset,const ImageInfo & image_info)428 const uint8_t* GetOatAddressForOffset(uint32_t offset, const ImageInfo& image_info) const { 429 // With Quick, code is within the OatFile, as there are all in one 430 // .o ELF object. But interpret it as signed. 431 DCHECK_LE(static_cast<int32_t>(offset), static_cast<int32_t>(image_info.oat_size_)); 432 DCHECK(image_info.oat_data_begin_ != nullptr); 433 return offset == 0u ? nullptr : image_info.oat_data_begin_ + static_cast<int32_t>(offset); 434 } 435 436 // Returns true if the class was in the original requested image classes list. 437 bool KeepClass(ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_); 438 439 // Debug aid that list of requested image classes. 440 void DumpImageClasses(); 441 442 // Visit all class loaders. 443 void VisitClassLoaders(ClassLoaderVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_); 444 445 // Remove unwanted classes from various roots. 446 void PruneNonImageClasses() REQUIRES_SHARED(Locks::mutator_lock_); 447 448 // Find dex caches for pruning or preloading. 449 dchecked_vector<ObjPtr<mirror::DexCache>> FindDexCaches(Thread* self) 450 REQUIRES_SHARED(Locks::mutator_lock_) 451 REQUIRES(!Locks::classlinker_classes_lock_); 452 453 // Verify unwanted classes removed. 454 void CheckNonImageClassesRemoved() REQUIRES_SHARED(Locks::mutator_lock_); 455 456 // Lays out where the image objects will be at runtime. 457 void CalculateNewObjectOffsets() 458 REQUIRES_SHARED(Locks::mutator_lock_); 459 void CreateHeader(size_t oat_index, size_t component_count) 460 REQUIRES_SHARED(Locks::mutator_lock_); 461 bool CreateImageRoots() REQUIRES_SHARED(Locks::mutator_lock_); 462 463 // Creates the contiguous image in memory and adjusts pointers. 464 void CopyAndFixupNativeData(size_t oat_index) REQUIRES_SHARED(Locks::mutator_lock_); 465 void CopyAndFixupJniStubMethods(size_t oat_index) REQUIRES_SHARED(Locks::mutator_lock_); 466 void CopyAndFixupObjects() REQUIRES_SHARED(Locks::mutator_lock_); 467 void CopyAndFixupObject(mirror::Object* obj) REQUIRES_SHARED(Locks::mutator_lock_); 468 template <bool kCheckIfDone> 469 mirror::Object* CopyObject(mirror::Object* obj) REQUIRES_SHARED(Locks::mutator_lock_); 470 void CopyAndFixupMethodPointerArray(mirror::PointerArray* arr) 471 REQUIRES_SHARED(Locks::mutator_lock_); 472 void CopyAndFixupMethod(ArtMethod* orig, ArtMethod* copy, size_t oat_index) 473 REQUIRES_SHARED(Locks::mutator_lock_); 474 void CopyAndFixupImTable(ImTable* orig, ImTable* copy) 475 REQUIRES_SHARED(Locks::mutator_lock_); 476 void CopyAndFixupImtConflictTable(ImtConflictTable* orig, ImtConflictTable* copy) 477 REQUIRES_SHARED(Locks::mutator_lock_); 478 479 /* 480 * Copies metadata from the heap into a buffer that will be compressed and 481 * written to the image. 482 * 483 * This function copies the string offset metadata from a local vector to an 484 * offset inside the image_ field of an ImageInfo struct. The offset into the 485 * memory pointed to by the image_ field is obtained from the ImageSection 486 * object for the String Offsets section. 487 * 488 * All data for the image, besides the object bitmap and the relocation data, 489 * will also be copied into the memory region pointed to by image_. 490 */ 491 void CopyMetadata(); 492 493 void FixupClass(mirror::Class* orig, mirror::Class* copy) 494 REQUIRES_SHARED(Locks::mutator_lock_); 495 void FixupObject(mirror::Object* orig, mirror::Object* copy) 496 REQUIRES_SHARED(Locks::mutator_lock_); 497 498 // Get quick code for non-resolution/imt_conflict/abstract method. 499 const uint8_t* GetQuickCode(ArtMethod* method, const ImageInfo& image_info) 500 REQUIRES_SHARED(Locks::mutator_lock_); 501 502 // Return true if a method is likely to be dirtied at runtime. 503 bool WillMethodBeDirty(ArtMethod* m) const REQUIRES_SHARED(Locks::mutator_lock_); 504 505 // Assign the offset for an ArtMethod. 506 void AssignMethodOffset(ArtMethod* method, 507 NativeObjectRelocationType type, 508 size_t oat_index) 509 REQUIRES_SHARED(Locks::mutator_lock_); 510 511 // Assign the offset for a method with unique JNI stub. 512 void AssignJniStubMethodOffset(ArtMethod* method, size_t oat_index) 513 REQUIRES_SHARED(Locks::mutator_lock_); 514 515 // Return true if imt was newly inserted. 516 bool TryAssignImTableOffset(ImTable* imt, size_t oat_index) REQUIRES_SHARED(Locks::mutator_lock_); 517 518 // Assign the offset for an IMT conflict table. Does nothing if the table already has a native 519 // relocation. 520 void TryAssignConflictTableOffset(ImtConflictTable* table, size_t oat_index) 521 REQUIRES_SHARED(Locks::mutator_lock_); 522 523 // Return true if `klass` depends on a class defined by the boot class path 524 // we're compiling against but not present in the boot image spaces. We want 525 // to prune these classes since we cannot guarantee that they will not be 526 // already loaded at run time when loading this image. This means that we 527 // also cannot have any classes which refer to these non image classes. 528 bool PruneImageClass(ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_); 529 530 // early_exit is true if we had a cyclic dependency anywhere down the chain. 531 bool PruneImageClassInternal(ObjPtr<mirror::Class> klass, 532 bool* early_exit, 533 HashSet<mirror::Object*>* visited) 534 REQUIRES_SHARED(Locks::mutator_lock_); 535 536 void PromoteWeakInternsToStrong(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_); 537 IsMultiImage()538 bool IsMultiImage() const { 539 return image_infos_.size() > 1; 540 } 541 542 static Bin BinTypeForNativeRelocationType(NativeObjectRelocationType type); 543 544 struct NativeObjectRelocation { 545 size_t oat_index; 546 uintptr_t offset; 547 NativeObjectRelocationType type; 548 }; 549 550 struct JniStubMethodRelocation { 551 size_t oat_index; 552 uintptr_t offset; 553 }; 554 555 NativeObjectRelocation GetNativeRelocation(void* obj) REQUIRES_SHARED(Locks::mutator_lock_); 556 557 // Location of where the object will be when the image is loaded at runtime. 558 template <typename T> 559 T* NativeLocationInImage(T* obj) REQUIRES_SHARED(Locks::mutator_lock_); 560 ArtField* NativeLocationInImage(ArtField* src_field) REQUIRES_SHARED(Locks::mutator_lock_); 561 562 // Return true if `dex_cache` belongs to the image we're writing. 563 // For a boot image, this is true for all dex caches. 564 // For an app image, boot class path dex caches are excluded. 565 bool IsImageDexCache(ObjPtr<mirror::DexCache> dex_cache) const 566 REQUIRES_SHARED(Locks::mutator_lock_); 567 568 // Return true if `obj` is inside of a boot image space that we're compiling against. 569 // (Always false when compiling the boot image.) IsInBootImage(const void * obj)570 ALWAYS_INLINE bool IsInBootImage(const void* obj) const { 571 return reinterpret_cast<uintptr_t>(obj) - boot_image_begin_ < boot_image_size_; 572 } 573 574 template <typename MirrorType> 575 static ObjPtr<MirrorType> DecodeGlobalWithoutRB(JavaVMExt* vm, jobject obj) 576 REQUIRES_SHARED(Locks::mutator_lock_); 577 578 template <typename MirrorType> 579 static ObjPtr<MirrorType> DecodeWeakGlobalWithoutRB( 580 JavaVMExt* vm, Thread* self, jobject obj) REQUIRES_SHARED(Locks::mutator_lock_); 581 582 // Get the index of the oat file associated with the object. 583 size_t GetOatIndex(mirror::Object* object) const REQUIRES_SHARED(Locks::mutator_lock_); 584 585 // The oat index for shared data in multi-image and all data in single-image compilation. GetDefaultOatIndex()586 static constexpr size_t GetDefaultOatIndex() { 587 return 0u; 588 } 589 GetImageInfo(size_t oat_index)590 ImageInfo& GetImageInfo(size_t oat_index) { 591 return image_infos_[oat_index]; 592 } 593 GetImageInfo(size_t oat_index)594 const ImageInfo& GetImageInfo(size_t oat_index) const { 595 return image_infos_[oat_index]; 596 } 597 598 // Return true if there already exists a native allocation for an object. 599 bool NativeRelocationAssigned(void* ptr) const; 600 601 // Copy a reference, translating source pointer to the target pointer. 602 template <typename DestType> 603 void CopyAndFixupReference(DestType* dest, ObjPtr<mirror::Object> src) 604 REQUIRES_SHARED(Locks::mutator_lock_); 605 606 // Translate a native pointer to the destination value and store in the target location. 607 template <typename ValueType> 608 void CopyAndFixupPointer(void** target, ValueType src_value, PointerSize pointer_size) 609 REQUIRES_SHARED(Locks::mutator_lock_); 610 template <typename ValueType> 611 void CopyAndFixupPointer(void** target, ValueType src_value) 612 REQUIRES_SHARED(Locks::mutator_lock_); 613 template <typename ValueType> 614 void CopyAndFixupPointer( 615 void* object, MemberOffset offset, ValueType src_value, PointerSize pointer_size) 616 REQUIRES_SHARED(Locks::mutator_lock_); 617 template <typename ValueType> 618 void CopyAndFixupPointer(void* object, MemberOffset offset, ValueType src_value) 619 REQUIRES_SHARED(Locks::mutator_lock_); 620 621 ALWAYS_INLINE 622 static bool IsStronglyInternedString(ObjPtr<mirror::String> str) 623 REQUIRES_SHARED(Locks::mutator_lock_); 624 625 /* 626 * Tests an object to see if it will be contained in an AppImage. 627 * 628 * An object reference is considered to be a AppImage String reference iff: 629 * - It isn't null 630 * - The referred-object isn't in the boot image 631 * - The referred-object is a Java String 632 */ 633 ALWAYS_INLINE 634 bool IsInternedAppImageStringReference(ObjPtr<mirror::Object> referred_obj) const 635 REQUIRES_SHARED(Locks::mutator_lock_); 636 637 const CompilerOptions& compiler_options_; 638 639 // Size of pointers on the target architecture. 640 PointerSize target_ptr_size_; 641 642 // Whether to mark non-abstract, non-intrinsic methods as "memory shared methods". 643 bool mark_memory_shared_methods_; 644 645 // Cached boot image begin and size. This includes heap, native objects and oat files. 646 const uint32_t boot_image_begin_; 647 const uint32_t boot_image_size_; 648 649 // Beginning target image address for the first image. 650 uint8_t* global_image_begin_; 651 652 // Offset from image_begin_ to where the first object is in image_. 653 size_t image_objects_offset_begin_; 654 655 // Saved hash codes. We use these to restore lockwords which were temporarily used to have 656 // forwarding addresses as well as copying over hash codes. 657 HashMap<mirror::Object*, uint32_t> saved_hashcode_map_; 658 659 // Oat index map for objects. 660 HashMap<mirror::Object*, uint32_t> oat_index_map_; 661 662 // Image data indexed by the oat file index. 663 dchecked_vector<ImageInfo> image_infos_; 664 665 // ArtField, ArtMethod relocating map. These are allocated as array of structs but we want to 666 // have one entry per art field for convenience. ArtFields are placed right after the end of the 667 // image objects (aka sum of bin_slot_sizes_). ArtMethods are placed right after the ArtFields. 668 HashMap<void*, NativeObjectRelocation> native_object_relocations_; 669 670 // HashMap used for generating JniStubMethodsSection. 671 JniStubHashMap<std::pair<ArtMethod*, JniStubMethodRelocation>> jni_stub_map_; 672 673 // Runtime ArtMethods which aren't reachable from any Class but need to be copied into the image. 674 ArtMethod* image_methods_[ImageHeader::kImageMethodsCount]; 675 676 // Counters for measurements, used for logging only. 677 uint64_t dirty_methods_; 678 uint64_t clean_methods_; 679 680 // Prune class memoization table to speed up ContainsBootClassLoaderNonImageClass. 681 HashMap<mirror::Class*, bool> prune_class_memo_; 682 683 // The application class loader. Null for boot image. 684 jobject app_class_loader_; 685 686 // Boot image live objects, invalid for app image. 687 mirror::ObjectArray<mirror::Object>* boot_image_live_objects_; 688 689 // Image roots corresponding to individual image files. 690 dchecked_vector<jobject> image_roots_; 691 692 // Which mode the image is stored as, see image.h 693 const ImageHeader::StorageMode image_storage_mode_; 694 695 // The file names of oat files. 696 const std::vector<std::string>& oat_filenames_; 697 698 // Map of dex files to the indexes of oat files that they were compiled into. 699 const HashMap<const DexFile*, size_t>& dex_file_oat_index_map_; 700 701 // Set of classes/objects known to be dirty in the image. Can be nullptr if there are none. 702 // Each entry contains a class descriptor with zero or more reference fields, which denote a path 703 // to the dirty object. 704 const std::vector<std::string>* dirty_image_objects_; 705 706 // Dirty object instances and their sort keys parsed from dirty_image_object_ 707 HashMap<mirror::Object*, uint32_t> dirty_objects_; 708 709 // Objects are guaranteed to not cross the region size boundary. 710 size_t region_size_ = 0u; 711 712 // Region alignment bytes wasted. 713 size_t region_alignment_wasted_ = 0u; 714 715 class FixupClassVisitor; 716 class FixupRootVisitor; 717 class FixupVisitor; 718 class LayoutHelper; 719 class NativeLocationVisitor; 720 class PruneClassesVisitor; 721 class PruneClassLoaderClassesVisitor; 722 class PruneObjectReferenceVisitor; 723 724 // A visitor used by the VerifyNativeGCRootInvariants() function. 725 class NativeGCRootInvariantVisitor; 726 727 DISALLOW_COPY_AND_ASSIGN(ImageWriter); 728 }; 729 730 std::ostream& operator<<(std::ostream& stream, ImageWriter::Bin bin); 731 std::ostream& operator<<(std::ostream& stream, ImageWriter::NativeObjectRelocationType type); 732 733 } // namespace linker 734 } // namespace art 735 736 #endif // ART_DEX2OAT_LINKER_IMAGE_WRITER_H_ 737