Home | History | Annotate | Download | only in space
      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_SPACE_H_
     18 #define ART_RUNTIME_GC_SPACE_SPACE_H_
     19 
     20 #include <string>
     21 
     22 #include "UniquePtr.h"
     23 #include "base/macros.h"
     24 #include "base/mutex.h"
     25 #include "gc/accounting/space_bitmap.h"
     26 #include "globals.h"
     27 #include "image.h"
     28 #include "mem_map.h"
     29 
     30 namespace art {
     31 namespace mirror {
     32   class Object;
     33 }  // namespace mirror
     34 
     35 namespace gc {
     36 
     37 namespace accounting {
     38   class SpaceBitmap;
     39 }  // namespace accounting
     40 
     41 class Heap;
     42 
     43 namespace space {
     44 
     45 class DlMallocSpace;
     46 class ImageSpace;
     47 class LargeObjectSpace;
     48 
     49 static constexpr bool kDebugSpaces = kIsDebugBuild;
     50 
     51 // See Space::GetGcRetentionPolicy.
     52 enum GcRetentionPolicy {
     53   // Objects are retained forever with this policy for a space.
     54   kGcRetentionPolicyNeverCollect,
     55   // Every GC cycle will attempt to collect objects in this space.
     56   kGcRetentionPolicyAlwaysCollect,
     57   // Objects will be considered for collection only in "full" GC cycles, ie faster partial
     58   // collections won't scan these areas such as the Zygote.
     59   kGcRetentionPolicyFullCollect,
     60 };
     61 std::ostream& operator<<(std::ostream& os, const GcRetentionPolicy& policy);
     62 
     63 enum SpaceType {
     64   kSpaceTypeImageSpace,
     65   kSpaceTypeAllocSpace,
     66   kSpaceTypeZygoteSpace,
     67   kSpaceTypeLargeObjectSpace,
     68 };
     69 std::ostream& operator<<(std::ostream& os, const SpaceType& space_type);
     70 
     71 // A space contains memory allocated for managed objects.
     72 class Space {
     73  public:
     74   // Dump space. Also key method for C++ vtables.
     75   virtual void Dump(std::ostream& os) const;
     76 
     77   // Name of the space. May vary, for example before/after the Zygote fork.
     78   const char* GetName() const {
     79     return name_.c_str();
     80   }
     81 
     82   // The policy of when objects are collected associated with this space.
     83   GcRetentionPolicy GetGcRetentionPolicy() const {
     84     return gc_retention_policy_;
     85   }
     86 
     87   // Does the space support allocation?
     88   virtual bool CanAllocateInto() const {
     89     return true;
     90   }
     91 
     92   // Is the given object contained within this space?
     93   virtual bool Contains(const mirror::Object* obj) const = 0;
     94 
     95   // The kind of space this: image, alloc, zygote, large object.
     96   virtual SpaceType GetType() const = 0;
     97 
     98   // Is this an image space, ie one backed by a memory mapped image file.
     99   bool IsImageSpace() const {
    100     return GetType() == kSpaceTypeImageSpace;
    101   }
    102   ImageSpace* AsImageSpace();
    103 
    104   // Is this a dlmalloc backed allocation space?
    105   bool IsDlMallocSpace() const {
    106     SpaceType type = GetType();
    107     return type == kSpaceTypeAllocSpace || type == kSpaceTypeZygoteSpace;
    108   }
    109   DlMallocSpace* AsDlMallocSpace();
    110 
    111   // Is this the space allocated into by the Zygote and no-longer in use?
    112   bool IsZygoteSpace() const {
    113     return GetType() == kSpaceTypeZygoteSpace;
    114   }
    115 
    116   // Does this space hold large objects and implement the large object space abstraction?
    117   bool IsLargeObjectSpace() const {
    118     return GetType() == kSpaceTypeLargeObjectSpace;
    119   }
    120   LargeObjectSpace* AsLargeObjectSpace();
    121 
    122   virtual ~Space() {}
    123 
    124  protected:
    125   Space(const std::string& name, GcRetentionPolicy gc_retention_policy);
    126 
    127   void SetGcRetentionPolicy(GcRetentionPolicy gc_retention_policy) {
    128     gc_retention_policy_ = gc_retention_policy;
    129   }
    130 
    131   // Name of the space that may vary due to the Zygote fork.
    132   std::string name_;
    133 
    134  private:
    135   // When should objects within this space be reclaimed? Not constant as we vary it in the case
    136   // of Zygote forking.
    137   GcRetentionPolicy gc_retention_policy_;
    138 
    139   friend class art::gc::Heap;
    140 
    141   DISALLOW_COPY_AND_ASSIGN(Space);
    142 };
    143 std::ostream& operator<<(std::ostream& os, const Space& space);
    144 
    145 // AllocSpace interface.
    146 class AllocSpace {
    147  public:
    148   // Number of bytes currently allocated.
    149   virtual uint64_t GetBytesAllocated() const = 0;
    150   // Number of objects currently allocated.
    151   virtual uint64_t GetObjectsAllocated() const = 0;
    152   // Number of bytes allocated since the space was created.
    153   virtual uint64_t GetTotalBytesAllocated() const = 0;
    154   // Number of objects allocated since the space was created.
    155   virtual uint64_t GetTotalObjectsAllocated() const = 0;
    156 
    157   // Allocate num_bytes without allowing growth. If the allocation
    158   // succeeds, the output parameter bytes_allocated will be set to the
    159   // actually allocated bytes which is >= num_bytes.
    160   virtual mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated) = 0;
    161 
    162   // Return the storage space required by obj.
    163   virtual size_t AllocationSize(const mirror::Object* obj) = 0;
    164 
    165   // Returns how many bytes were freed.
    166   virtual size_t Free(Thread* self, mirror::Object* ptr) = 0;
    167 
    168   // Returns how many bytes were freed.
    169   virtual size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) = 0;
    170 
    171  protected:
    172   AllocSpace() {}
    173   virtual ~AllocSpace() {}
    174 
    175  private:
    176   DISALLOW_COPY_AND_ASSIGN(AllocSpace);
    177 };
    178 
    179 // Continuous spaces have bitmaps, and an address range. Although not required, objects within
    180 // continuous spaces can be marked in the card table.
    181 class ContinuousSpace : public Space {
    182  public:
    183   // Address at which the space begins
    184   byte* Begin() const {
    185     return begin_;
    186   }
    187 
    188   // Address at which the space ends, which may vary as the space is filled.
    189   byte* End() const {
    190     return end_;
    191   }
    192 
    193   // Current size of space
    194   size_t Size() const {
    195     return End() - Begin();
    196   }
    197 
    198   virtual accounting::SpaceBitmap* GetLiveBitmap() const = 0;
    199   virtual accounting::SpaceBitmap* GetMarkBitmap() const = 0;
    200 
    201   // Is object within this space? We check to see if the pointer is beyond the end first as
    202   // continuous spaces are iterated over from low to high.
    203   bool HasAddress(const mirror::Object* obj) const {
    204     const byte* byte_ptr = reinterpret_cast<const byte*>(obj);
    205     return byte_ptr < End() && byte_ptr >= Begin();
    206   }
    207 
    208   bool Contains(const mirror::Object* obj) const {
    209     return HasAddress(obj);
    210   }
    211 
    212   virtual ~ContinuousSpace() {}
    213 
    214  protected:
    215   ContinuousSpace(const std::string& name, GcRetentionPolicy gc_retention_policy,
    216                   byte* begin, byte* end) :
    217       Space(name, gc_retention_policy), begin_(begin), end_(end) {
    218   }
    219 
    220 
    221   // The beginning of the storage for fast access.
    222   byte* const begin_;
    223 
    224   // Current end of the space.
    225   byte* end_;
    226 
    227  private:
    228   DISALLOW_COPY_AND_ASSIGN(ContinuousSpace);
    229 };
    230 
    231 // A space where objects may be allocated higgledy-piggledy throughout virtual memory. Currently
    232 // the card table can't cover these objects and so the write barrier shouldn't be triggered. This
    233 // is suitable for use for large primitive arrays.
    234 class DiscontinuousSpace : public Space {
    235  public:
    236   accounting::SpaceSetMap* GetLiveObjects() const {
    237     return live_objects_.get();
    238   }
    239 
    240   accounting::SpaceSetMap* GetMarkObjects() const {
    241     return mark_objects_.get();
    242   }
    243 
    244   virtual ~DiscontinuousSpace() {}
    245 
    246  protected:
    247   DiscontinuousSpace(const std::string& name, GcRetentionPolicy gc_retention_policy);
    248 
    249   UniquePtr<accounting::SpaceSetMap> live_objects_;
    250   UniquePtr<accounting::SpaceSetMap> mark_objects_;
    251 
    252  private:
    253   DISALLOW_COPY_AND_ASSIGN(DiscontinuousSpace);
    254 };
    255 
    256 class MemMapSpace : public ContinuousSpace {
    257  public:
    258   // Maximum which the mapped space can grow to.
    259   virtual size_t Capacity() const {
    260     return mem_map_->Size();
    261   }
    262 
    263   // Size of the space without a limit on its growth. By default this is just the Capacity, but
    264   // for the allocation space we support starting with a small heap and then extending it.
    265   virtual size_t NonGrowthLimitCapacity() const {
    266     return Capacity();
    267   }
    268 
    269  protected:
    270   MemMapSpace(const std::string& name, MemMap* mem_map, size_t initial_size,
    271               GcRetentionPolicy gc_retention_policy)
    272       : ContinuousSpace(name, gc_retention_policy,
    273                         mem_map->Begin(), mem_map->Begin() + initial_size),
    274         mem_map_(mem_map) {
    275   }
    276 
    277   MemMap* GetMemMap() {
    278     return mem_map_.get();
    279   }
    280 
    281   const MemMap* GetMemMap() const {
    282     return mem_map_.get();
    283   }
    284 
    285  private:
    286   // Underlying storage of the space
    287   UniquePtr<MemMap> mem_map_;
    288 
    289   DISALLOW_COPY_AND_ASSIGN(MemMapSpace);
    290 };
    291 
    292 }  // namespace space
    293 }  // namespace gc
    294 }  // namespace art
    295 
    296 #endif  // ART_RUNTIME_GC_SPACE_SPACE_H_
    297