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_RUNTIME_GC_SPACE_IMAGE_SPACE_H_ 18 #define ART_RUNTIME_GC_SPACE_IMAGE_SPACE_H_ 19 20 #include "arch/instruction_set.h" 21 #include "gc/accounting/space_bitmap.h" 22 #include "image.h" 23 #include "space.h" 24 25 namespace art { 26 27 class OatFile; 28 29 namespace gc { 30 namespace space { 31 32 // An image space is a space backed with a memory mapped image. 33 class ImageSpace : public MemMapSpace { 34 public: GetType()35 SpaceType GetType() const { 36 return kSpaceTypeImageSpace; 37 } 38 39 // Load boot image spaces from a primary image file for a specified instruction set. 40 // 41 // On successful return, the loaded spaces are added to boot_image_spaces (which must be 42 // empty on entry) and oat_file_end is updated with the (page-aligned) end of the last 43 // oat file. 44 static bool LoadBootImage(const std::string& image_file_name, 45 const InstructionSet image_instruction_set, 46 std::vector<space::ImageSpace*>* boot_image_spaces, 47 uint8_t** oat_file_end) 48 REQUIRES_SHARED(Locks::mutator_lock_); 49 50 // Try to open an existing app image space. 51 static std::unique_ptr<ImageSpace> CreateFromAppImage(const char* image, 52 const OatFile* oat_file, 53 std::string* error_msg) 54 REQUIRES_SHARED(Locks::mutator_lock_); 55 56 // Reads the image header from the specified image location for the 57 // instruction set image_isa. Returns null on failure, with 58 // reason in error_msg. 59 static ImageHeader* ReadImageHeader(const char* image_location, 60 InstructionSet image_isa, 61 std::string* error_msg); 62 63 // Give access to the OatFile. 64 const OatFile* GetOatFile() const; 65 66 // Releases the OatFile from the ImageSpace so it can be transfer to 67 // the caller, presumably the OatFileManager. 68 std::unique_ptr<const OatFile> ReleaseOatFile(); 69 70 void VerifyImageAllocations() 71 REQUIRES_SHARED(Locks::mutator_lock_); 72 GetImageHeader()73 const ImageHeader& GetImageHeader() const { 74 return *reinterpret_cast<ImageHeader*>(Begin()); 75 } 76 77 // Actual filename where image was loaded from. 78 // For example: /data/dalvik-cache/arm/system@framework@boot.art GetImageFilename()79 const std::string GetImageFilename() const { 80 return GetName(); 81 } 82 83 // Symbolic location for image. 84 // For example: /system/framework/boot.art GetImageLocation()85 const std::string GetImageLocation() const { 86 return image_location_; 87 } 88 GetLiveBitmap()89 accounting::ContinuousSpaceBitmap* GetLiveBitmap() const OVERRIDE { 90 return live_bitmap_.get(); 91 } 92 GetMarkBitmap()93 accounting::ContinuousSpaceBitmap* GetMarkBitmap() const OVERRIDE { 94 // ImageSpaces have the same bitmap for both live and marked. This helps reduce the number of 95 // special cases to test against. 96 return live_bitmap_.get(); 97 } 98 99 void Dump(std::ostream& os) const; 100 101 // Sweeping image spaces is a NOP. Sweep(bool,size_t *,size_t *)102 void Sweep(bool /* swap_bitmaps */, size_t* /* freed_objects */, size_t* /* freed_bytes */) { 103 } 104 CanMoveObjects()105 bool CanMoveObjects() const OVERRIDE { 106 return false; 107 } 108 109 // Returns the filename of the image corresponding to 110 // requested image_location, or the filename where a new image 111 // should be written if one doesn't exist. Looks for a generated 112 // image in the specified location and then in the dalvik-cache. 113 // 114 // Returns true if an image was found, false otherwise. 115 static bool FindImageFilename(const char* image_location, 116 InstructionSet image_isa, 117 std::string* system_location, 118 bool* has_system, 119 std::string* data_location, 120 bool* dalvik_cache_exists, 121 bool* has_data, 122 bool *is_global_cache); 123 124 // Use the input image filename to adapt the names in the given boot classpath to establish 125 // complete locations for secondary images. 126 static void ExtractMultiImageLocations(const std::string& input_image_file_name, 127 const std::string& boot_classpath, 128 std::vector<std::string>* image_filenames); 129 130 static std::string GetMultiImageBootClassPath(const std::vector<const char*>& dex_locations, 131 const std::vector<const char*>& oat_filenames, 132 const std::vector<const char*>& image_filenames); 133 134 // Returns true if the dex checksums in the given oat file match the 135 // checksums of the original dex files on disk. This is intended to be used 136 // to validate the boot image oat file, which may contain dex entries from 137 // multiple different (possibly multidex) dex files on disk. Prefer the 138 // OatFileAssistant for validating regular app oat files because the 139 // OatFileAssistant caches dex checksums that are reused to check both the 140 // oat and odex file. 141 // 142 // This function is exposed for testing purposes. 143 static bool ValidateOatFile(const OatFile& oat_file, std::string* error_msg); 144 145 // Return the end of the image which includes non-heap objects such as ArtMethods and ArtFields. GetImageEnd()146 uint8_t* GetImageEnd() const { 147 return Begin() + GetImageHeader().GetImageSize(); 148 } 149 150 // Return the start of the associated oat file. GetOatFileBegin()151 uint8_t* GetOatFileBegin() const { 152 return GetImageHeader().GetOatFileBegin(); 153 } 154 155 // Return the end of the associated oat file. GetOatFileEnd()156 uint8_t* GetOatFileEnd() const { 157 return GetImageHeader().GetOatFileEnd(); 158 } 159 160 void DumpSections(std::ostream& os) const; 161 162 // De-initialize the image-space by undoing the effects in Init(). 163 virtual ~ImageSpace(); 164 165 protected: 166 // Tries to initialize an ImageSpace from the given image path, returning null on error. 167 // 168 // If validate_oat_file is false (for /system), do not verify that image's OatFile is up-to-date 169 // relative to its DexFile inputs. Otherwise (for /data), validate the inputs and generate the 170 // OatFile in /data/dalvik-cache if necessary. If the oat_file is null, it uses the oat file from 171 // the image. 172 static std::unique_ptr<ImageSpace> Init(const char* image_filename, 173 const char* image_location, 174 bool validate_oat_file, 175 const OatFile* oat_file, 176 std::string* error_msg) 177 REQUIRES_SHARED(Locks::mutator_lock_); 178 179 static Atomic<uint32_t> bitmap_index_; 180 181 std::unique_ptr<accounting::ContinuousSpaceBitmap> live_bitmap_; 182 183 ImageSpace(const std::string& name, 184 const char* image_location, 185 MemMap* mem_map, 186 accounting::ContinuousSpaceBitmap* live_bitmap, 187 uint8_t* end); 188 189 // The OatFile associated with the image during early startup to 190 // reserve space contiguous to the image. It is later released to 191 // the ClassLinker during it's initialization. 192 std::unique_ptr<OatFile> oat_file_; 193 194 // There are times when we need to find the boot image oat file. As 195 // we release ownership during startup, keep a non-owned reference. 196 const OatFile* oat_file_non_owned_; 197 198 const std::string image_location_; 199 200 friend class ImageSpaceLoader; 201 friend class Space; 202 203 private: 204 // Create a boot image space from an image file for a specified instruction 205 // set. Cannot be used for future allocation or collected. 206 // 207 // Create also opens the OatFile associated with the image file so 208 // that it be contiguously allocated with the image before the 209 // creation of the alloc space. The ReleaseOatFile will later be 210 // used to transfer ownership of the OatFile to the ClassLinker when 211 // it is initialized. 212 static std::unique_ptr<ImageSpace> CreateBootImage(const char* image, 213 InstructionSet image_isa, 214 bool secondary_image, 215 std::string* error_msg) 216 REQUIRES_SHARED(Locks::mutator_lock_); 217 218 DISALLOW_COPY_AND_ASSIGN(ImageSpace); 219 }; 220 221 } // namespace space 222 } // namespace gc 223 } // namespace art 224 225 #endif // ART_RUNTIME_GC_SPACE_IMAGE_SPACE_H_ 226