blob: d766a832cac5f22c4ea843d9ac372e8faa5601ca [file] [log] [blame]
Carl Shapiro69759ea2011-07-21 18:13:35 -07001// Copyright (C) 2008 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#ifndef ART_SRC_OBJECT_BITMAP_H_
16#define ART_SRC_OBJECT_BITMAP_H_
17
18#include <limits.h>
19#include <stdint.h>
20
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070021#include "globals.h"
22#include "logging.h"
Carl Shapiro69759ea2011-07-21 18:13:35 -070023
24namespace art {
25
26class Object;
27
28// <offset> is the difference from .base to a pointer address.
29// <index> is the index of .bits that contains the bit representing
30// <offset>.
31#define HB_OFFSET_TO_INDEX(offset_) \
32 ((offset_) / kAlignment / kBitsPerWord)
33#define HB_INDEX_TO_OFFSET(index_) \
34 ((index_) * kAlignment * kBitsPerWord)
35
36#define HB_OFFSET_TO_BYTE_INDEX(offset_) \
37 (HB_OFFSET_TO_INDEX(offset_) * sizeof(*((HeapBitmap *)0)->words_))
38
39// Pack the bits in backwards so they come out in address order
40// when using CLZ.
41#define HB_OFFSET_TO_MASK(offset_) \
42 (1 << \
43 (31-(((uintptr_t)(offset_) / kAlignment) % kBitsPerWord)))
44
45class HeapBitmap {
46 public:
47 static const size_t kAlignment = 8;
48
49 typedef void Callback(Object *obj, void *arg);
50
51 typedef void ScanCallback(Object *obj, void *finger, void *arg);
52
53 typedef void SweepCallback(size_t numPtrs, void **ptrs, void *arg);
54
55 static HeapBitmap* Create(byte* base, size_t length);
56
57 ~HeapBitmap();
58
59 void Set(const Object* obj) {
60 Modify(obj, true);
61 }
62
63 void Clear(const Object* obj) {
64 Modify(obj, false);
65 }
66
67 void Clear();
68
69 bool Test(const Object* obj) {
70 CHECK(HasAddress(obj));
71 CHECK(words_ != NULL);
72 CHECK_GE((uintptr_t)obj, base_);
73 if ((uintptr_t)obj <= max_) {
74 const uintptr_t offset = (uintptr_t)obj - base_;
75 unsigned long word = words_[HB_OFFSET_TO_INDEX(offset)];
76 return (word & HB_OFFSET_TO_MASK(offset)) != 0;
77 } else {
78 return false;
79 }
80 }
81
82 bool HasAddress(const void* addr) const;
83
84 void Walk(Callback* callback, void* arg);
85
86 void ScanWalk(uintptr_t base, uintptr_t max,
87 ScanCallback* thunk, void* arg);
88
89 static void SweepWalk(const HeapBitmap& live,
90 const HeapBitmap& mark,
91 uintptr_t base, uintptr_t max,
92 SweepCallback* thunk, void* arg);
93
94 private:
95 HeapBitmap(const void* base, size_t length)
96 : words_(NULL),
97 num_bytes_(length),
98 base_(reinterpret_cast<uintptr_t>(base)) {
99 };
100
101 void Modify(const Object* obj, bool do_set) {
102 uintptr_t addr = reinterpret_cast<uintptr_t>(obj);
103 CHECK_GE(addr, base_);
104 const uintptr_t offset = addr - base_;
105 const size_t index = HB_OFFSET_TO_INDEX(offset);
106 const unsigned long mask = HB_OFFSET_TO_MASK(offset);
107 CHECK_LT(index, num_bytes_ / kWordSize);
108 if (do_set) {
109 if (addr > max_) {
110 max_ = addr;
111 }
112 words_[index] |= mask;
113 } else {
114 words_[index] &= ~mask;
115 }
116 }
117
118 bool Init(const byte* base, size_t length);
119
120 unsigned long* words_;
121
122 size_t num_bytes_;
123
124 // The base address, which corresponds to the word containing the
125 // first bit in the bitmap.
126 uintptr_t base_;
127
128 // The highest pointer value ever returned by an allocation from
129 // this heap. I.e., the highest address that may correspond to a
130 // set bit. If there are no bits set, (max < base).
131 uintptr_t max_;
132
133 const char* name_;
134};
135
136} // namespace art
137
138#endif // ART_SRC_OBJECT_BITMAP_H_