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
3811d9f06a96a6909905c248ed684366190140095cNarayan Kamath  // Create a 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.
46507e6180ad271eb719c67ce7394852c731d975a5Alex Light  static ImageSpace* Create(const char* image, InstructionSet image_isa, std::string* error_msg)
4711d9f06a96a6909905c248ed684366190140095cNarayan Kamath      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
481d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
4952f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath  // Reads the image header from the specified image location for the
5095a935415d44903b28326424beb4db5c013ef089Brian Carlstrom  // instruction set image_isa or dies trying.
5152f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath  static ImageHeader* ReadImageHeaderOrDie(const char* image_location,
522afe49450f2e018f18b5de45428b9174bfd6f196Brian Carlstrom                                           InstructionSet image_isa);
5352f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath
5495a935415d44903b28326424beb4db5c013ef089Brian Carlstrom  // Reads the image header from the specified image location for the
5595a935415d44903b28326424beb4db5c013ef089Brian Carlstrom  // instruction set image_isa. Returns nullptr on failure, with
5695a935415d44903b28326424beb4db5c013ef089Brian Carlstrom  // reason in error_msg.
5795a935415d44903b28326424beb4db5c013ef089Brian Carlstrom  static ImageHeader* ReadImageHeader(const char* image_location,
5895a935415d44903b28326424beb4db5c013ef089Brian Carlstrom                                      InstructionSet image_isa,
5995a935415d44903b28326424beb4db5c013ef089Brian Carlstrom                                      std::string* error_msg);
6095a935415d44903b28326424beb4db5c013ef089Brian Carlstrom
6122f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  // Give access to the OatFile.
6222f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe  const OatFile* GetOatFile() const;
6322f8e5c82d12951be38cd893426e13bee33fd69dAndreas Gampe
6456d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom  // Releases the OatFile from the ImageSpace so it can be transfer to
6556d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom  // the caller, presumably the ClassLinker.
668d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers  OatFile* ReleaseOatFile()
6756d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
6856d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom
6931e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier  void VerifyImageAllocations()
7031e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
7131e8925781c2302f1d1a9b39e216ba415bfe0d7eMathieu Chartier
721d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  const ImageHeader& GetImageHeader() const {
731d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return *reinterpret_cast<ImageHeader*>(Begin());
741d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
751d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
7652f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath  // Actual filename where image was loaded from.
7752f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath  // For example: /data/dalvik-cache/arm/system@framework@boot.art
781d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  const std::string GetImageFilename() const {
791d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return GetName();
801d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
811d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
8252f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath  // Symbolic location for image.
8352f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath  // For example: /system/framework/boot.art
8452f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath  const std::string GetImageLocation() const {
8552f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath    return image_location_;
8652f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath  }
8752f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath
88a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  accounting::ContinuousSpaceBitmap* GetLiveBitmap() const OVERRIDE {
891d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return live_bitmap_.get();
901d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
911d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
92a8e8f9c0a8e259a807d7b99a148d14104c24209dMathieu Chartier  accounting::ContinuousSpaceBitmap* GetMarkBitmap() const OVERRIDE {
931d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    // ImageSpaces have the same bitmap for both live and marked. This helps reduce the number of
941d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    // special cases to test against.
951d54e73444e017d3a65234e0f193846f3e27472bIan Rogers    return live_bitmap_.get();
961d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  }
971d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
981d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  void Dump(std::ostream& os) const;
991d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
100a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  // Sweeping image spaces is a NOP.
101a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  void Sweep(bool /* swap_bitmaps */, size_t* /* freed_objects */, size_t* /* freed_bytes */) {
102a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier  }
103a1602f28c0e3127ad511712d4b08db89737ae901Mathieu Chartier
10431f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier  bool CanMoveObjects() const OVERRIDE {
10531f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier    return false;
10631f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier  }
10731f441464c0c8f840aba37e236ad133f30308d70Mathieu Chartier
108a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  // Returns the filename of the image corresponding to
109a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  // requested image_location, or the filename where a new image
110a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  // should be written if one doesn't exist. Looks for a generated
111a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  // image in the specified location and then in the dalvik-cache.
112a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  //
113a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  // Returns true if an image was found, false otherwise.
114a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light  static bool FindImageFilename(const char* image_location,
115a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                                InstructionSet image_isa,
116a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                                std::string* system_location,
117a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                                bool* has_system,
118a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                                std::string* data_location,
119a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light                                bool* dalvik_cache_exists,
12033c36d4f22ab6a5e61eb47b654deaf647c34e49cAndreas Gampe                                bool* has_data,
12133c36d4f22ab6a5e61eb47b654deaf647c34e49cAndreas Gampe                                bool *is_global_cache);
122a59dd80f9f48cb750d329d4d4af2d99d72b484d1Alex Light
1231d54e73444e017d3a65234e0f193846f3e27472bIan Rogers private:
12456d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom  // Tries to initialize an ImageSpace from the given image path,
12556d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom  // returning NULL on error.
12656d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom  //
12756d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom  // If validate_oat_file is false (for /system), do not verify that
12856d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom  // image's OatFile is up-to-date relative to its DexFile
12956d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom  // inputs. Otherwise (for /data), validate the inputs and generate
13056d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom  // the OatFile in /data/dalvik-cache if necessary.
13152f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath  static ImageSpace* Init(const char* image_filename, const char* image_location,
13252f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath                          bool validate_oat_file, std::string* error_msg)
13356d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
13456d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom
1359583fbcf597eff6d0b3c5359b8e8d5f70ed82c40Nicolas Geoffray  OatFile* OpenOatFile(const char* image, std::string* error_msg) const
13656d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
13756d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom
1388d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers  bool ValidateOatFile(std::string* error_msg) const
13956d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
14056d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom
1411d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  friend class Space;
1421d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
143ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  static Atomic<uint32_t> bitmap_index_;
1441d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
145700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<accounting::ContinuousSpaceBitmap> live_bitmap_;
1461d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
14752f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath  ImageSpace(const std::string& name, const char* image_location,
14852f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath             MemMap* mem_map, accounting::ContinuousSpaceBitmap* live_bitmap);
1491d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
15056d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom  // The OatFile associated with the image during early startup to
15156d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom  // reserve space contiguous to the image. It is later released to
15256d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom  // the ClassLinker during it's initialization.
153700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<OatFile> oat_file_;
15456d947fbc9bc2992e2f93112fafb73e50d2aaa7aBrian Carlstrom
15552f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath  const std::string image_location_;
15652f84884433f3875f4b1bc5595b8d5a2d6fb3d99Narayan Kamath
1571d54e73444e017d3a65234e0f193846f3e27472bIan Rogers  DISALLOW_COPY_AND_ASSIGN(ImageSpace);
1581d54e73444e017d3a65234e0f193846f3e27472bIan Rogers};
1591d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
1601d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace space
1611d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace gc
1621d54e73444e017d3a65234e0f193846f3e27472bIan Rogers}  // namespace art
1631d54e73444e017d3a65234e0f193846f3e27472bIan Rogers
164fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_GC_SPACE_IMAGE_SPACE_H_
165