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