Home | History | Annotate | Download | only in accounting
      1 /*
      2  * Copyright (C) 2008 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_ACCOUNTING_SPACE_BITMAP_H_
     18 #define ART_RUNTIME_GC_ACCOUNTING_SPACE_BITMAP_H_
     19 
     20 #include "locks.h"
     21 #include "gc_allocator.h"
     22 #include "globals.h"
     23 #include "mem_map.h"
     24 #include "UniquePtr.h"
     25 
     26 #include <limits.h>
     27 #include <set>
     28 #include <stdint.h>
     29 #include <vector>
     30 
     31 namespace art {
     32 
     33 namespace mirror {
     34   class Object;
     35 }  // namespace mirror
     36 
     37 namespace gc {
     38 namespace accounting {
     39 
     40 class SpaceBitmap {
     41  public:
     42   // Alignment of objects within spaces.
     43   static const size_t kAlignment = 8;
     44 
     45   typedef void Callback(mirror::Object* obj, void* arg);
     46 
     47   typedef void ScanCallback(mirror::Object* obj, void* finger, void* arg);
     48 
     49   typedef void SweepCallback(size_t ptr_count, mirror::Object** ptrs, void* arg);
     50 
     51   // Initialize a space bitmap so that it points to a bitmap large enough to cover a heap at
     52   // heap_begin of heap_capacity bytes, where objects are guaranteed to be kAlignment-aligned.
     53   static SpaceBitmap* Create(const std::string& name, byte* heap_begin, size_t heap_capacity);
     54 
     55   // Initialize a space bitmap using the provided mem_map as the live bits. Takes ownership of the
     56   // mem map. The address range covered starts at heap_begin and is of size equal to heap_capacity.
     57   // Objects are kAlignement-aligned.
     58   static SpaceBitmap* CreateFromMemMap(const std::string& name, MemMap* mem_map,
     59                                        byte* heap_begin, size_t heap_capacity);
     60 
     61   ~SpaceBitmap();
     62 
     63   // <offset> is the difference from .base to a pointer address.
     64   // <index> is the index of .bits that contains the bit representing
     65   //         <offset>.
     66   static size_t OffsetToIndex(size_t offset) {
     67     return offset / kAlignment / kBitsPerWord;
     68   }
     69 
     70   static uintptr_t IndexToOffset(size_t index) {
     71     return static_cast<uintptr_t>(index * kAlignment * kBitsPerWord);
     72   }
     73 
     74   // Pack the bits in backwards so they come out in address order when using CLZ.
     75   static word OffsetToMask(uintptr_t offset_) {
     76     return static_cast<uintptr_t>(kWordHighBitMask) >> ((offset_ / kAlignment) % kBitsPerWord);
     77   }
     78 
     79   inline bool Set(const mirror::Object* obj) {
     80     return Modify(obj, true);
     81   }
     82 
     83   inline bool Clear(const mirror::Object* obj) {
     84     return Modify(obj, false);
     85   }
     86 
     87   // Returns true if the object was previously marked.
     88   bool AtomicTestAndSet(const mirror::Object* obj);
     89 
     90   // Fill the bitmap with zeroes.  Returns the bitmap's memory to the system as a side-effect.
     91   void Clear();
     92 
     93   bool Test(const mirror::Object* obj) const;
     94 
     95   // Return true iff <obj> is within the range of pointers that this bitmap could potentially cover,
     96   // even if a bit has not been set for it.
     97   bool HasAddress(const void* obj) const {
     98     // If obj < heap_begin_ then offset underflows to some very large value past the end of the
     99     // bitmap.
    100     const uintptr_t offset = reinterpret_cast<uintptr_t>(obj) - heap_begin_;
    101     const size_t index = OffsetToIndex(offset);
    102     return index < bitmap_size_ / kWordSize;
    103   }
    104 
    105   void VisitRange(uintptr_t base, uintptr_t max, Callback* visitor, void* arg) const;
    106 
    107   class ClearVisitor {
    108    public:
    109     explicit ClearVisitor(SpaceBitmap* const bitmap)
    110         : bitmap_(bitmap) {
    111     }
    112 
    113     void operator()(mirror::Object* obj) const {
    114       bitmap_->Clear(obj);
    115     }
    116    private:
    117     SpaceBitmap* const bitmap_;
    118   };
    119 
    120   template <typename Visitor>
    121   void VisitRange(uintptr_t visit_begin, uintptr_t visit_end, const Visitor& visitor) const {
    122     for (; visit_begin < visit_end; visit_begin += kAlignment) {
    123       visitor(reinterpret_cast<mirror::Object*>(visit_begin));
    124     }
    125   }
    126 
    127   template <typename Visitor>
    128   void VisitMarkedRange(uintptr_t visit_begin, uintptr_t visit_end, const Visitor& visitor) const
    129       EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
    130       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    131 
    132   void Walk(Callback* callback, void* arg)
    133       SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
    134 
    135   void InOrderWalk(Callback* callback, void* arg)
    136       SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
    137 
    138   static void SweepWalk(const SpaceBitmap& live, const SpaceBitmap& mark, uintptr_t base,
    139                         uintptr_t max, SweepCallback* thunk, void* arg);
    140 
    141   void CopyFrom(SpaceBitmap* source_bitmap);
    142 
    143   // Starting address of our internal storage.
    144   word* Begin() {
    145     return bitmap_begin_;
    146   }
    147 
    148   // Size of our internal storage
    149   size_t Size() const {
    150     return bitmap_size_;
    151   }
    152 
    153   // Size in bytes of the memory that the bitmaps spans.
    154   size_t HeapSize() const {
    155     return IndexToOffset(Size() / kWordSize);
    156   }
    157 
    158   uintptr_t HeapBegin() const {
    159     return heap_begin_;
    160   }
    161 
    162   // The maximum address which the bitmap can span. (HeapBegin() <= object < HeapLimit()).
    163   uintptr_t HeapLimit() const {
    164     return HeapBegin() + static_cast<uintptr_t>(HeapSize());
    165   }
    166 
    167   // Set the max address which can covered by the bitmap.
    168   void SetHeapLimit(uintptr_t new_end);
    169 
    170   std::string GetName() const;
    171   void SetName(const std::string& name);
    172 
    173   std::string Dump() const;
    174 
    175   const void* GetObjectWordAddress(const mirror::Object* obj) const {
    176     uintptr_t addr = reinterpret_cast<uintptr_t>(obj);
    177     const uintptr_t offset = addr - heap_begin_;
    178     const size_t index = OffsetToIndex(offset);
    179     return &bitmap_begin_[index];
    180   }
    181 
    182  private:
    183   // TODO: heap_end_ is initialized so that the heap bitmap is empty, this doesn't require the -1,
    184   // however, we document that this is expected on heap_end_
    185   SpaceBitmap(const std::string& name, MemMap* mem_map, word* bitmap_begin, size_t bitmap_size,
    186               const void* heap_begin)
    187       : mem_map_(mem_map), bitmap_begin_(bitmap_begin), bitmap_size_(bitmap_size),
    188         heap_begin_(reinterpret_cast<uintptr_t>(heap_begin)),
    189         name_(name) {}
    190 
    191   bool Modify(const mirror::Object* obj, bool do_set);
    192 
    193   // Backing storage for bitmap.
    194   UniquePtr<MemMap> mem_map_;
    195 
    196   // This bitmap itself, word sized for efficiency in scanning.
    197   word* const bitmap_begin_;
    198 
    199   // Size of this bitmap.
    200   size_t bitmap_size_;
    201 
    202   // The base address of the heap, which corresponds to the word containing the first bit in the
    203   // bitmap.
    204   const uintptr_t heap_begin_;
    205 
    206   // Name of this bitmap.
    207   std::string name_;
    208 };
    209 
    210 // Like a bitmap except it keeps track of objects using sets.
    211 class SpaceSetMap {
    212  public:
    213   typedef std::set<
    214       const mirror::Object*, std::less<const mirror::Object*>,
    215       GCAllocator<const mirror::Object*> > Objects;
    216 
    217   bool IsEmpty() const {
    218     return contained_.empty();
    219   }
    220 
    221   inline void Set(const mirror::Object* obj) {
    222     contained_.insert(obj);
    223   }
    224 
    225   inline void Clear(const mirror::Object* obj) {
    226     Objects::iterator found = contained_.find(obj);
    227     if (found != contained_.end()) {
    228       contained_.erase(found);
    229     }
    230   }
    231 
    232   void Clear() {
    233     contained_.clear();
    234   }
    235 
    236   inline bool Test(const mirror::Object* obj) const {
    237     return contained_.find(obj) != contained_.end();
    238   }
    239 
    240   std::string GetName() const;
    241   void SetName(const std::string& name);
    242 
    243   void Walk(SpaceBitmap::Callback* callback, void* arg)
    244       SHARED_LOCKS_REQUIRED(GlobalSynchronization::heap_bitmap_lock_);
    245 
    246   void CopyFrom(const SpaceSetMap& space_set);
    247 
    248   template <typename Visitor>
    249   void Visit(const Visitor& visitor) NO_THREAD_SAFETY_ANALYSIS {
    250     for (Objects::iterator it = contained_.begin(); it != contained_.end(); ++it) {
    251       visitor(*it);
    252     }
    253   }
    254 
    255   explicit SpaceSetMap(const std::string& name) : name_(name) {}
    256   ~SpaceSetMap() {}
    257 
    258   Objects& GetObjects() {
    259     return contained_;
    260   }
    261 
    262  private:
    263   std::string name_;
    264   Objects contained_;
    265 };
    266 
    267 std::ostream& operator << (std::ostream& stream, const SpaceBitmap& bitmap);
    268 
    269 }  // namespace accounting
    270 }  // namespace gc
    271 }  // namespace art
    272 
    273 #endif  // ART_RUNTIME_GC_ACCOUNTING_SPACE_BITMAP_H_
    274