1 /* 2 * Copyright (C) 2012 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_HEAP_BITMAP_H_ 18 #define ART_RUNTIME_GC_ACCOUNTING_HEAP_BITMAP_H_ 19 20 #include "base/logging.h" 21 #include "gc_allocator.h" 22 #include "locks.h" 23 #include "space_bitmap.h" 24 25 namespace art { 26 namespace gc { 27 28 class Heap; 29 30 namespace accounting { 31 32 class HeapBitmap { 33 public: 34 typedef std::vector<SpaceBitmap*, GCAllocator<SpaceBitmap*> > SpaceBitmapVector; 35 typedef std::vector<SpaceSetMap*, GCAllocator<SpaceSetMap*> > SpaceSetMapVector; 36 37 bool Test(const mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) { 38 SpaceBitmap* bitmap = GetContinuousSpaceBitmap(obj); 39 if (LIKELY(bitmap != NULL)) { 40 return bitmap->Test(obj); 41 } else { 42 return GetDiscontinuousSpaceObjectSet(obj) != NULL; 43 } 44 } 45 46 void Clear(const mirror::Object* obj) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) { 47 SpaceBitmap* bitmap = GetContinuousSpaceBitmap(obj); 48 if (LIKELY(bitmap != NULL)) { 49 bitmap->Clear(obj); 50 } else { 51 SpaceSetMap* set = GetDiscontinuousSpaceObjectSet(obj); 52 DCHECK(set != NULL); 53 set->Clear(obj); 54 } 55 } 56 57 void Set(const mirror::Object* obj) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) { 58 SpaceBitmap* bitmap = GetContinuousSpaceBitmap(obj); 59 if (LIKELY(bitmap != NULL)) { 60 bitmap->Set(obj); 61 } else { 62 SpaceSetMap* set = GetDiscontinuousSpaceObjectSet(obj); 63 DCHECK(set != NULL); 64 set->Set(obj); 65 } 66 } 67 68 SpaceBitmap* GetContinuousSpaceBitmap(const mirror::Object* obj) { 69 for (const auto& bitmap : continuous_space_bitmaps_) { 70 if (bitmap->HasAddress(obj)) { 71 return bitmap; 72 } 73 } 74 return NULL; 75 } 76 77 SpaceSetMap* GetDiscontinuousSpaceObjectSet(const mirror::Object* obj) { 78 for (const auto& space_set : discontinuous_space_sets_) { 79 if (space_set->Test(obj)) { 80 return space_set; 81 } 82 } 83 return NULL; 84 } 85 86 void Walk(SpaceBitmap::Callback* callback, void* arg) 87 SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_); 88 89 template <typename Visitor> 90 void Visit(const Visitor& visitor) 91 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) 92 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 93 94 // Find and replace a bitmap pointer, this is used by for the bitmap swapping in the GC. 95 void ReplaceBitmap(SpaceBitmap* old_bitmap, SpaceBitmap* new_bitmap) 96 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_); 97 98 // Find and replace a object set pointer, this is used by for the bitmap swapping in the GC. 99 void ReplaceObjectSet(SpaceSetMap* old_set, SpaceSetMap* new_set) 100 EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_); 101 102 explicit HeapBitmap(Heap* heap) : heap_(heap) {} 103 104 private: 105 const Heap* const heap_; 106 107 void AddContinuousSpaceBitmap(SpaceBitmap* bitmap); 108 void AddDiscontinuousObjectSet(SpaceSetMap* set); 109 110 // Bitmaps covering continuous spaces. 111 SpaceBitmapVector continuous_space_bitmaps_; 112 113 // Sets covering discontinuous spaces. 114 SpaceSetMapVector discontinuous_space_sets_; 115 116 friend class art::gc::Heap; 117 }; 118 119 } // namespace accounting 120 } // namespace gc 121 } // namespace art 122 123 #endif // ART_RUNTIME_GC_ACCOUNTING_HEAP_BITMAP_H_ 124