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_INL_H_
18 #define ART_RUNTIME_GC_ACCOUNTING_HEAP_BITMAP_INL_H_
19 
20 #include "heap_bitmap.h"
21 
22 #include "space_bitmap-inl.h"
23 
24 namespace art {
25 namespace gc {
26 namespace accounting {
27 
28 template <typename Visitor>
Visit(Visitor && visitor)29 inline void HeapBitmap::Visit(Visitor&& visitor) {
30   for (const auto& bitmap : continuous_space_bitmaps_) {
31     bitmap->VisitMarkedRange(bitmap->HeapBegin(), bitmap->HeapLimit(), visitor);
32   }
33   for (const auto& bitmap : large_object_bitmaps_) {
34     bitmap->VisitMarkedRange(bitmap->HeapBegin(), bitmap->HeapLimit(), visitor);
35   }
36 }
37 
Test(const mirror::Object * obj)38 inline bool HeapBitmap::Test(const mirror::Object* obj) {
39   ContinuousSpaceBitmap* bitmap = GetContinuousSpaceBitmap(obj);
40   if (LIKELY(bitmap != nullptr)) {
41     return bitmap->Test(obj);
42   }
43   for (const auto& lo_bitmap : large_object_bitmaps_) {
44     if (LIKELY(lo_bitmap->HasAddress(obj))) {
45       return lo_bitmap->Test(obj);
46     }
47   }
48   LOG(FATAL) << "Invalid object " << obj;
49   return false;
50 }
51 
Clear(const mirror::Object * obj)52 inline void HeapBitmap::Clear(const mirror::Object* obj) {
53   ContinuousSpaceBitmap* bitmap = GetContinuousSpaceBitmap(obj);
54   if (LIKELY(bitmap != nullptr)) {
55     bitmap->Clear(obj);
56     return;
57   }
58   for (const auto& lo_bitmap : large_object_bitmaps_) {
59     if (LIKELY(lo_bitmap->HasAddress(obj))) {
60       lo_bitmap->Clear(obj);
61     }
62   }
63   LOG(FATAL) << "Invalid object " << obj;
64 }
65 
66 template<typename LargeObjectSetVisitor>
Set(const mirror::Object * obj,const LargeObjectSetVisitor & visitor)67 inline bool HeapBitmap::Set(const mirror::Object* obj, const LargeObjectSetVisitor& visitor) {
68   ContinuousSpaceBitmap* bitmap = GetContinuousSpaceBitmap(obj);
69   if (LIKELY(bitmap != nullptr)) {
70     return bitmap->Set(obj);
71   }
72   visitor(obj);
73   for (const auto& lo_bitmap : large_object_bitmaps_) {
74     if (LIKELY(lo_bitmap->HasAddress(obj))) {
75       return lo_bitmap->Set(obj);
76     }
77   }
78   LOG(FATAL) << "Invalid object " << obj;
79   return false;
80 }
81 
82 template<typename LargeObjectSetVisitor>
AtomicTestAndSet(const mirror::Object * obj,const LargeObjectSetVisitor & visitor)83 inline bool HeapBitmap::AtomicTestAndSet(const mirror::Object* obj,
84                                          const LargeObjectSetVisitor& visitor) {
85   ContinuousSpaceBitmap* bitmap = GetContinuousSpaceBitmap(obj);
86   if (LIKELY(bitmap != nullptr)) {
87     return bitmap->AtomicTestAndSet(obj);
88   }
89   visitor(obj);
90   for (const auto& lo_bitmap : large_object_bitmaps_) {
91     if (LIKELY(lo_bitmap->HasAddress(obj))) {
92       return lo_bitmap->AtomicTestAndSet(obj);
93     }
94   }
95   LOG(FATAL) << "Invalid object " << obj;
96   return false;
97 }
98 
GetContinuousSpaceBitmap(const mirror::Object * obj)99 inline ContinuousSpaceBitmap* HeapBitmap::GetContinuousSpaceBitmap(const mirror::Object* obj) const {
100   for (const auto& bitmap : continuous_space_bitmaps_) {
101     if (bitmap->HasAddress(obj)) {
102       return bitmap;
103     }
104   }
105   return nullptr;
106 }
107 
GetLargeObjectBitmap(const mirror::Object * obj)108 inline LargeObjectBitmap* HeapBitmap::GetLargeObjectBitmap(const mirror::Object* obj) const {
109   for (const auto& bitmap : large_object_bitmaps_) {
110     if (LIKELY(bitmap->HasAddress(obj))) {
111       return bitmap;
112     }
113   }
114   return nullptr;
115 }
116 
117 }  // namespace accounting
118 }  // namespace gc
119 }  // namespace art
120 
121 #endif  // ART_RUNTIME_GC_ACCOUNTING_HEAP_BITMAP_INL_H_
122