blob: 1374563b0304623b6f01ee909368573b2de86e14 [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
Elliott Hughes90a33692011-08-30 13:27:07 -070021#include "UniquePtr.h"
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070022#include "globals.h"
23#include "logging.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070024#include "mem_map.h"
Carl Shapiro69759ea2011-07-21 18:13:35 -070025
26namespace art {
27
28class Object;
29
30// <offset> is the difference from .base to a pointer address.
31// <index> is the index of .bits that contains the bit representing
32// <offset>.
33#define HB_OFFSET_TO_INDEX(offset_) \
34 ((offset_) / kAlignment / kBitsPerWord)
35#define HB_INDEX_TO_OFFSET(index_) \
36 ((index_) * kAlignment * kBitsPerWord)
37
38#define HB_OFFSET_TO_BYTE_INDEX(offset_) \
Elliott Hughesb0663112011-10-19 18:16:37 -070039 (HB_OFFSET_TO_INDEX(offset_) * sizeof(*(reinterpret_cast<HeapBitmap*>(0))->words_))
Carl Shapiro69759ea2011-07-21 18:13:35 -070040
41// Pack the bits in backwards so they come out in address order
42// when using CLZ.
43#define HB_OFFSET_TO_MASK(offset_) \
Elliott Hughesb0663112011-10-19 18:16:37 -070044 (1 << (31-(((uintptr_t)(offset_) / kAlignment) % kBitsPerWord)))
Carl Shapiro69759ea2011-07-21 18:13:35 -070045
46class HeapBitmap {
47 public:
48 static const size_t kAlignment = 8;
49
Brian Carlstrom78128a62011-09-15 17:21:19 -070050 typedef void Callback(Object* obj, void* arg);
Carl Shapiro69759ea2011-07-21 18:13:35 -070051
Brian Carlstrom78128a62011-09-15 17:21:19 -070052 typedef void ScanCallback(Object* obj, void* finger, void* arg);
Carl Shapiro69759ea2011-07-21 18:13:35 -070053
Brian Carlstrom78128a62011-09-15 17:21:19 -070054 typedef void SweepCallback(size_t numPtrs, void** ptrs, void* arg);
Carl Shapiro69759ea2011-07-21 18:13:35 -070055
56 static HeapBitmap* Create(byte* base, size_t length);
57
58 ~HeapBitmap();
59
Elliott Hughesb0663112011-10-19 18:16:37 -070060 inline void Set(const Object* obj) {
Carl Shapiro69759ea2011-07-21 18:13:35 -070061 Modify(obj, true);
62 }
63
Elliott Hughesb0663112011-10-19 18:16:37 -070064 inline void Clear(const Object* obj) {
Carl Shapiro69759ea2011-07-21 18:13:35 -070065 Modify(obj, false);
66 }
67
68 void Clear();
69
Elliott Hughesb0663112011-10-19 18:16:37 -070070 inline bool Test(const Object* obj) {
71 uintptr_t addr = reinterpret_cast<uintptr_t>(obj);
72 DCHECK(HasAddress(obj)) << obj;
73 DCHECK(words_ != NULL);
74 DCHECK_GE(addr, base_);
75 if (addr <= max_) {
76 const uintptr_t offset = addr - base_;
77 return (words_[HB_OFFSET_TO_INDEX(offset)] & HB_OFFSET_TO_MASK(offset)) != 0;
Carl Shapiro69759ea2011-07-21 18:13:35 -070078 } else {
Elliott Hughesb0663112011-10-19 18:16:37 -070079 return false;
Carl Shapiro69759ea2011-07-21 18:13:35 -070080 }
81 }
82
83 bool HasAddress(const void* addr) const;
84
85 void Walk(Callback* callback, void* arg);
86
Brian Carlstrom1f870082011-08-23 16:02:11 -070087 void ScanWalk(uintptr_t base, ScanCallback* thunk, void* arg);
Carl Shapiro69759ea2011-07-21 18:13:35 -070088
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
Elliott Hughesb0663112011-10-19 18:16:37 -0700101 inline void Modify(const Object* obj, bool do_set) {
Carl Shapiro69759ea2011-07-21 18:13:35 -0700102 uintptr_t addr = reinterpret_cast<uintptr_t>(obj);
Elliott Hughesb0663112011-10-19 18:16:37 -0700103 DCHECK_GE(addr, base_);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700104 const uintptr_t offset = addr - base_;
105 const size_t index = HB_OFFSET_TO_INDEX(offset);
Elliott Hughesb0663112011-10-19 18:16:37 -0700106 const word mask = HB_OFFSET_TO_MASK(offset);
107 DCHECK_LT(index, num_bytes_ / kWordSize);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700108 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
Elliott Hughes90a33692011-08-30 13:27:07 -0700120 UniquePtr<MemMap> mem_map_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700121
122 word* words_;
Carl Shapiro69759ea2011-07-21 18:13:35 -0700123
124 size_t num_bytes_;
125
126 // The base address, which corresponds to the word containing the
127 // first bit in the bitmap.
128 uintptr_t base_;
129
130 // The highest pointer value ever returned by an allocation from
131 // this heap. I.e., the highest address that may correspond to a
Brian Carlstrom1f870082011-08-23 16:02:11 -0700132 // set bit. If there are no bits set, (max_ < base_).
Carl Shapiro69759ea2011-07-21 18:13:35 -0700133 uintptr_t max_;
134
135 const char* name_;
136};
137
138} // namespace art
139
140#endif // ART_SRC_OBJECT_BITMAP_H_