/* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ART_RUNTIME_GC_ACCOUNTING_HEAP_BITMAP_H_ #define ART_RUNTIME_GC_ACCOUNTING_HEAP_BITMAP_H_ #include "base/logging.h" #include "locks.h" #include "space_bitmap.h" namespace art { namespace gc { class Heap; namespace accounting { class HeapBitmap { public: bool Test(const mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) { SpaceBitmap* bitmap = GetContinuousSpaceBitmap(obj); if (LIKELY(bitmap != NULL)) { return bitmap->Test(obj); } else { return GetDiscontinuousSpaceObjectSet(obj) != NULL; } } void Clear(const mirror::Object* obj) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) { SpaceBitmap* bitmap = GetContinuousSpaceBitmap(obj); if (LIKELY(bitmap != NULL)) { bitmap->Clear(obj); } else { SpaceSetMap* set = GetDiscontinuousSpaceObjectSet(obj); DCHECK(set != NULL); set->Clear(obj); } } void Set(const mirror::Object* obj) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) { SpaceBitmap* bitmap = GetContinuousSpaceBitmap(obj); if (LIKELY(bitmap != NULL)) { bitmap->Set(obj); } else { SpaceSetMap* set = GetDiscontinuousSpaceObjectSet(obj); DCHECK(set != NULL); set->Set(obj); } } SpaceBitmap* GetContinuousSpaceBitmap(const mirror::Object* obj) { // TODO: C++0x auto typedef std::vector::iterator It; for (It it = continuous_space_bitmaps_.begin(), end = continuous_space_bitmaps_.end(); it != end; ++it) { SpaceBitmap* bitmap = *it; if (bitmap->HasAddress(obj)) { return bitmap; } } return NULL; } SpaceSetMap* GetDiscontinuousSpaceObjectSet(const mirror::Object* obj) { // TODO: C++0x auto typedef std::vector::iterator It; for (It it = discontinuous_space_sets_.begin(), end = discontinuous_space_sets_.end(); it != end; ++it) { SpaceSetMap* set = *it; if (set->Test(obj)) { return set; } } return NULL; } void Walk(SpaceBitmap::Callback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_); template void Visit(const Visitor& visitor) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Find and replace a bitmap pointer, this is used by for the bitmap swapping in the GC. void ReplaceBitmap(SpaceBitmap* old_bitmap, SpaceBitmap* new_bitmap) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_); // Find and replace a object set pointer, this is used by for the bitmap swapping in the GC. void ReplaceObjectSet(SpaceSetMap* old_set, SpaceSetMap* new_set) EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_); HeapBitmap(Heap* heap) : heap_(heap) { } private: const Heap* const heap_; void AddContinuousSpaceBitmap(SpaceBitmap* bitmap); void AddDiscontinuousObjectSet(SpaceSetMap* set); // Bitmaps covering continuous spaces. std::vector continuous_space_bitmaps_; // Sets covering discontinuous spaces. std::vector discontinuous_space_sets_; friend class art::gc::Heap; }; } // namespace accounting } // namespace gc } // namespace art #endif // ART_RUNTIME_GC_ACCOUNTING_HEAP_BITMAP_H_