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_DLMALLOC_SPACE_H_
     18 #define ART_RUNTIME_GC_SPACE_DLMALLOC_SPACE_H_
     19 
     20 #include "gc/allocator/dlmalloc.h"
     21 #include "space.h"
     22 
     23 namespace art {
     24 namespace gc {
     25 
     26 namespace collector {
     27   class MarkSweep;
     28 }  // namespace collector
     29 
     30 namespace space {
     31 
     32 // An alloc space is a space where objects may be allocated and garbage collected.
     33 class DlMallocSpace : public MemMapSpace, public AllocSpace {
     34  public:
     35   typedef void(*WalkCallback)(void *start, void *end, size_t num_bytes, void* callback_arg);
     36 
     37   SpaceType GetType() const {
     38     if (GetGcRetentionPolicy() == kGcRetentionPolicyFullCollect) {
     39       return kSpaceTypeZygoteSpace;
     40     } else {
     41       return kSpaceTypeAllocSpace;
     42     }
     43   }
     44 
     45   // Create a AllocSpace with the requested sizes. The requested
     46   // base address is not guaranteed to be granted, if it is required,
     47   // the caller should call Begin on the returned space to confirm
     48   // the request was granted.
     49   static DlMallocSpace* Create(const std::string& name, size_t initial_size, size_t growth_limit,
     50                                size_t capacity, byte* requested_begin);
     51 
     52   // Allocate num_bytes without allowing the underlying mspace to grow.
     53   virtual mirror::Object* AllocWithGrowth(Thread* self, size_t num_bytes,
     54                                           size_t* bytes_allocated) LOCKS_EXCLUDED(lock_);
     55 
     56   // Allocate num_bytes allowing the underlying mspace to grow.
     57   virtual mirror::Object* Alloc(Thread* self, size_t num_bytes, size_t* bytes_allocated);
     58 
     59   // Return the storage space required by obj.
     60   virtual size_t AllocationSize(const mirror::Object* obj);
     61   virtual size_t Free(Thread* self, mirror::Object* ptr);
     62   virtual size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs);
     63 
     64   mirror::Object* AllocNonvirtual(Thread* self, size_t num_bytes, size_t* bytes_allocated);
     65 
     66   size_t AllocationSizeNonvirtual(const mirror::Object* obj) {
     67     return mspace_usable_size(const_cast<void*>(reinterpret_cast<const void*>(obj))) +
     68         kChunkOverhead;
     69   }
     70 
     71   void* MoreCore(intptr_t increment);
     72 
     73   void* GetMspace() const {
     74     return mspace_;
     75   }
     76 
     77   // Hands unused pages back to the system.
     78   size_t Trim();
     79 
     80   // Perform a mspace_inspect_all which calls back for each allocation chunk. The chunk may not be
     81   // in use, indicated by num_bytes equaling zero.
     82   void Walk(WalkCallback callback, void* arg) LOCKS_EXCLUDED(lock_);
     83 
     84   // Returns the number of bytes that the space has currently obtained from the system. This is
     85   // greater or equal to the amount of live data in the space.
     86   size_t GetFootprint();
     87 
     88   // Returns the number of bytes that the heap is allowed to obtain from the system via MoreCore.
     89   size_t GetFootprintLimit();
     90 
     91   // Set the maximum number of bytes that the heap is allowed to obtain from the system via
     92   // MoreCore. Note this is used to stop the mspace growing beyond the limit to Capacity. When
     93   // allocations fail we GC before increasing the footprint limit and allowing the mspace to grow.
     94   void SetFootprintLimit(size_t limit);
     95 
     96   // Removes the fork time growth limit on capacity, allowing the application to allocate up to the
     97   // maximum reserved size of the heap.
     98   void ClearGrowthLimit() {
     99     growth_limit_ = NonGrowthLimitCapacity();
    100   }
    101 
    102   // Override capacity so that we only return the possibly limited capacity
    103   size_t Capacity() const {
    104     return growth_limit_;
    105   }
    106 
    107   // The total amount of memory reserved for the alloc space.
    108   size_t NonGrowthLimitCapacity() const {
    109     return GetMemMap()->Size();
    110   }
    111 
    112   accounting::SpaceBitmap* GetLiveBitmap() const {
    113     return live_bitmap_.get();
    114   }
    115 
    116   accounting::SpaceBitmap* GetMarkBitmap() const {
    117     return mark_bitmap_.get();
    118   }
    119 
    120   void Dump(std::ostream& os) const;
    121 
    122   void SetGrowthLimit(size_t growth_limit);
    123 
    124   // Swap the live and mark bitmaps of this space. This is used by the GC for concurrent sweeping.
    125   void SwapBitmaps();
    126 
    127   // Turn ourself into a zygote space and return a new alloc space which has our unused memory.
    128   DlMallocSpace* CreateZygoteSpace(const char* alloc_space_name);
    129 
    130   uint64_t GetBytesAllocated() const {
    131     return num_bytes_allocated_;
    132   }
    133 
    134   uint64_t GetObjectsAllocated() const {
    135     return num_objects_allocated_;
    136   }
    137 
    138   uint64_t GetTotalBytesAllocated() const {
    139     return total_bytes_allocated_;
    140   }
    141 
    142   uint64_t GetTotalObjectsAllocated() const {
    143     return total_objects_allocated_;
    144   }
    145 
    146   // Returns the class of a recently freed object.
    147   mirror::Class* FindRecentFreedObject(const mirror::Object* obj);
    148 
    149  protected:
    150   DlMallocSpace(const std::string& name, MemMap* mem_map, void* mspace, byte* begin, byte* end,
    151                 size_t growth_limit);
    152 
    153  private:
    154   size_t InternalAllocationSize(const mirror::Object* obj);
    155   mirror::Object* AllocWithoutGrowthLocked(size_t num_bytes, size_t* bytes_allocated)
    156       EXCLUSIVE_LOCKS_REQUIRED(lock_);
    157   bool Init(size_t initial_size, size_t maximum_size, size_t growth_size, byte* requested_base);
    158   void RegisterRecentFree(mirror::Object* ptr);
    159   static void* CreateMallocSpace(void* base, size_t morecore_start, size_t initial_size);
    160 
    161   UniquePtr<accounting::SpaceBitmap> live_bitmap_;
    162   UniquePtr<accounting::SpaceBitmap> mark_bitmap_;
    163   UniquePtr<accounting::SpaceBitmap> temp_bitmap_;
    164 
    165   // Recent allocation buffer.
    166   static constexpr size_t kRecentFreeCount = kDebugSpaces ? (1 << 16) : 0;
    167   static constexpr size_t kRecentFreeMask = kRecentFreeCount - 1;
    168   std::pair<const mirror::Object*, mirror::Class*> recent_freed_objects_[kRecentFreeCount];
    169   size_t recent_free_pos_;
    170 
    171   // Approximate number of bytes which have been allocated into the space.
    172   size_t num_bytes_allocated_;
    173   size_t num_objects_allocated_;
    174   size_t total_bytes_allocated_;
    175   size_t total_objects_allocated_;
    176 
    177   static size_t bitmap_index_;
    178 
    179   // The boundary tag overhead.
    180   static const size_t kChunkOverhead = kWordSize;
    181 
    182   // Used to ensure mutual exclusion when the allocation spaces data structures are being modified.
    183   Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
    184 
    185   // Underlying malloc space
    186   void* const mspace_;
    187 
    188   // The capacity of the alloc space until such time that ClearGrowthLimit is called.
    189   // The underlying mem_map_ controls the maximum size we allow the heap to grow to. The growth
    190   // limit is a value <= to the mem_map_ capacity used for ergonomic reasons because of the zygote.
    191   // Prior to forking the zygote the heap will have a maximally sized mem_map_ but the growth_limit_
    192   // will be set to a lower value. The growth_limit_ is used as the capacity of the alloc_space_,
    193   // however, capacity normally can't vary. In the case of the growth_limit_ it can be cleared
    194   // one time by a call to ClearGrowthLimit.
    195   size_t growth_limit_;
    196 
    197   friend class collector::MarkSweep;
    198 
    199   DISALLOW_COPY_AND_ASSIGN(DlMallocSpace);
    200 };
    201 
    202 }  // namespace space
    203 }  // namespace gc
    204 }  // namespace art
    205 
    206 #endif  // ART_RUNTIME_GC_SPACE_DLMALLOC_SPACE_H_
    207