11d54e73444e017d3a65234e0f193846f3e27472bIan Rogers/* 21d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * Copyright (C) 2011 The Android Open Source Project 31d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * 41d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 51d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * you may not use this file except in compliance with the License. 61d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * You may obtain a copy of the License at 71d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * 81d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * http://www.apache.org/licenses/LICENSE-2.0 91d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * 101d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * Unless required by applicable law or agreed to in writing, software 111d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * distributed under the License is distributed on an "AS IS" BASIS, 121d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * See the License for the specific language governing permissions and 141d54e73444e017d3a65234e0f193846f3e27472bIan Rogers * limitations under the License. 151d54e73444e017d3a65234e0f193846f3e27472bIan Rogers */ 161d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_GC_SPACE_IMAGE_SPACE_H_ 18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_GC_SPACE_IMAGE_SPACE_H_ 191d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 20a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier#include "gc/accounting/space_bitmap.h" 2111d9f06a96a6909905c248ed684366190140095cNarayan Kamath#include "runtime.h" 221d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "space.h" 231d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 241d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace art { 2556d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom 2656d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstromclass OatFile; 2756d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom 281d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace gc { 291d54e73444e017d3a65234e0f193846f3e27472bIan Rogersnamespace space { 301d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 311d54e73444e017d3a65234e0f193846f3e27472bIan Rogers// An image space is a space backed with a memory mapped image. 321d54e73444e017d3a65234e0f193846f3e27472bIan Rogersclass ImageSpace : public MemMapSpace { 331d54e73444e017d3a65234e0f193846f3e27472bIan Rogers public: 341d54e73444e017d3a65234e0f193846f3e27472bIan Rogers SpaceType GetType() const { 351d54e73444e017d3a65234e0f193846f3e27472bIan Rogers return kSpaceTypeImageSpace; 361d54e73444e017d3a65234e0f193846f3e27472bIan Rogers } 371d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 38fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier // Create a boot image space from an image file for a specified instruction 3911d9f06a96a6909905c248ed684366190140095cNarayan Kamath // set. Cannot be used for future allocation or collected. 4056d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom // 4156d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom // Create also opens the OatFile associated with the image file so 4256d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom // that it be contiguously allocated with the image before the 4356d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom // creation of the alloc space. The ReleaseOatFile will later be 4456d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom // used to transfer ownership of the OatFile to the ClassLinker when 4556d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom // it is initialized. 46fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier static ImageSpace* CreateBootImage(const char* image, 47fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier InstructionSet image_isa, 48fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier bool secondary_image, 49fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier std::string* error_msg) 50fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 51fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier 52fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier // Try to open an existing app image space. 53fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier static ImageSpace* CreateFromAppImage(const char* image, 54fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier const OatFile* oat_file, 55fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier std::string* error_msg) 5690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 571d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 5852f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath // Reads the image header from the specified image location for the 5931d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom // instruction set image_isa or dies trying. 6052f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath static ImageHeader* ReadImageHeaderOrDie(const char* image_location, 612afe49450f2e018f18b5de45428b9174bfd6f196Brian Carlstrom InstructionSet image_isa); 6252f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath 6331d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom // Reads the image header from the specified image location for the 642cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // instruction set image_isa. Returns null on failure, with 6531d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom // reason in error_msg. 6631d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom static ImageHeader* ReadImageHeader(const char* image_location, 6731d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom InstructionSet image_isa, 6831d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom std::string* error_msg); 6931d8f5295c24730a57cb36cbc41197f0b7e8397cBrian Carlstrom 7022f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe // Give access to the OatFile. 7122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe const OatFile* GetOatFile() const; 7222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe 7356d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom // Releases the OatFile from the ImageSpace so it can be transfer to 74f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier // the caller, presumably the OatFileManager. 75f9c6fc610b27887f832e453a0da1789187293408Mathieu Chartier std::unique_ptr<const OatFile> ReleaseOatFile(); 7656d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom 7731e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier void VerifyImageAllocations() 7890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 7931e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier 801d54e73444e017d3a65234e0f193846f3e27472bIan Rogers const ImageHeader& GetImageHeader() const { 811d54e73444e017d3a65234e0f193846f3e27472bIan Rogers return *reinterpret_cast<ImageHeader*>(Begin()); 821d54e73444e017d3a65234e0f193846f3e27472bIan Rogers } 831d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 8452f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath // Actual filename where image was loaded from. 8552f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath // For example: /data/dalvik-cache/arm/system@framework@boot.art 861d54e73444e017d3a65234e0f193846f3e27472bIan Rogers const std::string GetImageFilename() const { 871d54e73444e017d3a65234e0f193846f3e27472bIan Rogers return GetName(); 881d54e73444e017d3a65234e0f193846f3e27472bIan Rogers } 891d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 9052f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath // Symbolic location for image. 9152f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath // For example: /system/framework/boot.art 9252f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath const std::string GetImageLocation() const { 9352f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath return image_location_; 9452f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath } 9552f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath 96a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier accounting::ContinuousSpaceBitmap* GetLiveBitmap() const OVERRIDE { 971d54e73444e017d3a65234e0f193846f3e27472bIan Rogers return live_bitmap_.get(); 981d54e73444e017d3a65234e0f193846f3e27472bIan Rogers } 991d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 100a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier accounting::ContinuousSpaceBitmap* GetMarkBitmap() const OVERRIDE { 1011d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // ImageSpaces have the same bitmap for both live and marked. This helps reduce the number of 1021d54e73444e017d3a65234e0f193846f3e27472bIan Rogers // special cases to test against. 1031d54e73444e017d3a65234e0f193846f3e27472bIan Rogers return live_bitmap_.get(); 1041d54e73444e017d3a65234e0f193846f3e27472bIan Rogers } 1051d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 1061d54e73444e017d3a65234e0f193846f3e27472bIan Rogers void Dump(std::ostream& os) const; 1071d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 108a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier // Sweeping image spaces is a NOP. 109a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier void Sweep(bool /* swap_bitmaps */, size_t* /* freed_objects */, size_t* /* freed_bytes */) { 110a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier } 111a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier 11231f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier bool CanMoveObjects() const OVERRIDE { 11331f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier return false; 11431f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier } 11531f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier 116a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light // Returns the filename of the image corresponding to 117a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light // requested image_location, or the filename where a new image 118a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light // should be written if one doesn't exist. Looks for a generated 119a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light // image in the specified location and then in the dalvik-cache. 120a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light // 121a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light // Returns true if an image was found, false otherwise. 122a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light static bool FindImageFilename(const char* image_location, 123a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light InstructionSet image_isa, 124a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light std::string* system_location, 125a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light bool* has_system, 126a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light std::string* data_location, 127a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light bool* dalvik_cache_exists, 1283c13a794845e0cf7887e33b2ec20de7e6ba85f8fAndreas Gampe bool* has_data, 1293c13a794845e0cf7887e33b2ec20de7e6ba85f8fAndreas Gampe bool *is_global_cache); 130a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light 1318994a04162a92759f8ec531d18ee8901145dfda0Andreas Gampe // Use the input image filename to adapt the names in the given boot classpath to establish 1328994a04162a92759f8ec531d18ee8901145dfda0Andreas Gampe // complete locations for secondary images. 13325adcfb7dc81131add3a0a681ae18bced6f7a0e0Mathieu Chartier static void ExtractMultiImageLocations(const std::string& input_image_file_name, 1348994a04162a92759f8ec531d18ee8901145dfda0Andreas Gampe const std::string& boot_classpath, 1358994a04162a92759f8ec531d18ee8901145dfda0Andreas Gampe std::vector<std::string>* image_filenames); 1368994a04162a92759f8ec531d18ee8901145dfda0Andreas Gampe 13725adcfb7dc81131add3a0a681ae18bced6f7a0e0Mathieu Chartier static std::string GetMultiImageBootClassPath(const std::vector<const char*>& dex_locations, 13825adcfb7dc81131add3a0a681ae18bced6f7a0e0Mathieu Chartier const std::vector<const char*>& oat_filenames, 13925adcfb7dc81131add3a0a681ae18bced6f7a0e0Mathieu Chartier const std::vector<const char*>& image_filenames); 14025adcfb7dc81131add3a0a681ae18bced6f7a0e0Mathieu Chartier 141763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // Return the end of the image which includes non-heap objects such as ArtMethods and ArtFields. 142763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier uint8_t* GetImageEnd() const { 143763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier return Begin() + GetImageHeader().GetImageSize(); 144763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } 145763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 146763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // Return the start of the associated oat file. 147763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier uint8_t* GetOatFileBegin() const { 148763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier return GetImageHeader().GetOatFileBegin(); 149763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } 150763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 151763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier // Return the end of the associated oat file. 152763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier uint8_t* GetOatFileEnd() const { 153763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier return GetImageHeader().GetOatFileEnd(); 154763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier } 155763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier 156b33b1dc78d178060ff0f4327d448fd3a89df51deMathieu Chartier void DumpSections(std::ostream& os) const; 157b33b1dc78d178060ff0f4327d448fd3a89df51deMathieu Chartier 158763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier protected: 159fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier // Tries to initialize an ImageSpace from the given image path, returning null on error. 16056d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom // 161fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier // If validate_oat_file is false (for /system), do not verify that image's OatFile is up-to-date 162fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier // relative to its DexFile inputs. Otherwise (for /data), validate the inputs and generate the 163fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier // OatFile in /data/dalvik-cache if necessary. If the oat_file is null, it uses the oat file from 164fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier // the image. 165fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier static ImageSpace* Init(const char* image_filename, 166fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier const char* image_location, 167fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier bool validate_oat_file, 168fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier const OatFile* oat_file, 169fbc31087932a65e036a153afab3049dc5298656aMathieu Chartier std::string* error_msg) 17090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 17156d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom 1729583fbcf597eff6d0b3c5359b8e8d5f70ed82c40Nicolas Geoffray OatFile* OpenOatFile(const char* image, std::string* error_msg) const 17390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 17456d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom 1758d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers bool ValidateOatFile(std::string* error_msg) const 17690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 17756d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom 1781d54e73444e017d3a65234e0f193846f3e27472bIan Rogers friend class Space; 1791d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 180ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers static Atomic<uint32_t> bitmap_index_; 1811d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 182700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<accounting::ContinuousSpaceBitmap> live_bitmap_; 1831d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 184dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao ImageSpace(const std::string& name, 185dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao const char* image_location, 186dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao MemMap* mem_map, 187dcdc85bbd569f0ee66c331b4219c19304a616214Jeff Hao accounting::ContinuousSpaceBitmap* live_bitmap, 1882d124ec869430789b51dc624db8ac655971c3a97Mathieu Chartier uint8_t* end); 1891d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 19056d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom // The OatFile associated with the image during early startup to 19156d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom // reserve space contiguous to the image. It is later released to 19256d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom // the ClassLinker during it's initialization. 193700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<OatFile> oat_file_; 19456d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom 19588da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe // There are times when we need to find the boot image oat file. As 19688da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe // we release ownership during startup, keep a non-owned reference. 19788da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe const OatFile* oat_file_non_owned_; 19888da3b0d2f76b1d6b9749315ac0c5b0367e92262Andreas Gampe 19952f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath const std::string image_location_; 20052f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath 201763a31ed7a2bfad22a9cb07f5301a71c0f97ca49Mathieu Chartier private: 2021d54e73444e017d3a65234e0f193846f3e27472bIan Rogers DISALLOW_COPY_AND_ASSIGN(ImageSpace); 2031d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}; 2041d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 2051d54e73444e017d3a65234e0f193846f3e27472bIan Rogers} // namespace space 2061d54e73444e017d3a65234e0f193846f3e27472bIan Rogers} // namespace gc 2071d54e73444e017d3a65234e0f193846f3e27472bIan Rogers} // namespace art 2081d54e73444e017d3a65234e0f193846f3e27472bIan Rogers 209fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_GC_SPACE_IMAGE_SPACE_H_ 210