blob: 0d6de60917a9da22d153a8841e947cdc00825295 [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
Elliott Hughes5e71b522011-10-20 13:12:32 -070015#ifndef ART_SRC_HEAP_BITMAP_H_
16#define ART_SRC_HEAP_BITMAP_H_
Carl Shapiro69759ea2011-07-21 18:13:35 -070017
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
Ian Rogers30fab402012-01-23 15:43:46 -080054 typedef void SweepCallback(size_t numPtrs, Object** ptrs, void* arg);
Carl Shapiro69759ea2011-07-21 18:13:35 -070055
Ian Rogers30fab402012-01-23 15:43:46 -080056 // Initialize a HeapBitmap so that it points to a bitmap large enough to cover a heap at
57 // heap_begin of heap_capacity bytes, where objects are guaranteed to be kAlignment-aligned.
58 static HeapBitmap* Create(const char* name, byte* heap_begin, size_t heap_capacity);
Carl Shapiro69759ea2011-07-21 18:13:35 -070059
60 ~HeapBitmap();
61
Elliott Hughesb0663112011-10-19 18:16:37 -070062 inline void Set(const Object* obj) {
Carl Shapiro69759ea2011-07-21 18:13:35 -070063 Modify(obj, true);
64 }
65
Elliott Hughesb0663112011-10-19 18:16:37 -070066 inline void Clear(const Object* obj) {
Carl Shapiro69759ea2011-07-21 18:13:35 -070067 Modify(obj, false);
68 }
69
70 void Clear();
71
Elliott Hughesb0663112011-10-19 18:16:37 -070072 inline bool Test(const Object* obj) {
73 uintptr_t addr = reinterpret_cast<uintptr_t>(obj);
74 DCHECK(HasAddress(obj)) << obj;
Ian Rogers30fab402012-01-23 15:43:46 -080075 DCHECK(bitmap_begin_ != NULL);
76 DCHECK_GE(addr, heap_begin_);
77 if (addr <= heap_end_) {
78 const uintptr_t offset = addr - heap_begin_;
79 return (bitmap_begin_[HB_OFFSET_TO_INDEX(offset)] & HB_OFFSET_TO_MASK(offset)) != 0;
Carl Shapiro69759ea2011-07-21 18:13:35 -070080 } else {
Elliott Hughesb0663112011-10-19 18:16:37 -070081 return false;
Carl Shapiro69759ea2011-07-21 18:13:35 -070082 }
83 }
84
85 bool HasAddress(const void* addr) const;
86
Ian Rogers5d76c432011-10-31 21:42:49 -070087 void VisitRange(uintptr_t base, uintptr_t max, Callback* visitor, void* arg) const;
88
Carl Shapiro69759ea2011-07-21 18:13:35 -070089 void Walk(Callback* callback, void* arg);
90
Ian Rogers5d76c432011-10-31 21:42:49 -070091 void ScanWalk(uintptr_t base, uintptr_t max, ScanCallback* thunk, void* arg);
Carl Shapiro69759ea2011-07-21 18:13:35 -070092
93 static void SweepWalk(const HeapBitmap& live,
94 const HeapBitmap& mark,
95 uintptr_t base, uintptr_t max,
96 SweepCallback* thunk, void* arg);
97
98 private:
Ian Rogers30fab402012-01-23 15:43:46 -080099 // TODO: heap_end_ is initialized so that the heap bitmap is empty, this doesn't require the -1,
100 // however, we document that this is expected on heap_end_
101 HeapBitmap(const char* name, MemMap* mem_map, word* bitmap_begin, size_t bitmap_size, const void* heap_begin)
102 : mem_map_(mem_map), bitmap_begin_(bitmap_begin), bitmap_size_(bitmap_size),
103 heap_begin_(reinterpret_cast<uintptr_t>(heap_begin)), heap_end_(heap_begin_ - 1),
104 name_(name) {}
Carl Shapiro69759ea2011-07-21 18:13:35 -0700105
Elliott Hughesb0663112011-10-19 18:16:37 -0700106 inline void Modify(const Object* obj, bool do_set) {
Carl Shapiro69759ea2011-07-21 18:13:35 -0700107 uintptr_t addr = reinterpret_cast<uintptr_t>(obj);
Ian Rogers30fab402012-01-23 15:43:46 -0800108 DCHECK_GE(addr, heap_begin_);
109 const uintptr_t offset = addr - heap_begin_;
Carl Shapiro69759ea2011-07-21 18:13:35 -0700110 const size_t index = HB_OFFSET_TO_INDEX(offset);
Elliott Hughesb0663112011-10-19 18:16:37 -0700111 const word mask = HB_OFFSET_TO_MASK(offset);
Ian Rogers30fab402012-01-23 15:43:46 -0800112 DCHECK_LT(index, bitmap_size_ / kWordSize);
Carl Shapiro69759ea2011-07-21 18:13:35 -0700113 if (do_set) {
Ian Rogers30fab402012-01-23 15:43:46 -0800114 if (addr > heap_end_) {
115 heap_end_ = addr;
Carl Shapiro69759ea2011-07-21 18:13:35 -0700116 }
Ian Rogers30fab402012-01-23 15:43:46 -0800117 bitmap_begin_[index] |= mask;
Carl Shapiro69759ea2011-07-21 18:13:35 -0700118 } else {
Ian Rogers30fab402012-01-23 15:43:46 -0800119 bitmap_begin_[index] &= ~mask;
Carl Shapiro69759ea2011-07-21 18:13:35 -0700120 }
121 }
122
Ian Rogers30fab402012-01-23 15:43:46 -0800123 // Backing storage for bitmap.
Elliott Hughes90a33692011-08-30 13:27:07 -0700124 UniquePtr<MemMap> mem_map_;
Brian Carlstromdb4d5402011-08-09 12:18:28 -0700125
Ian Rogers30fab402012-01-23 15:43:46 -0800126 // This bitmap itself, word sized for efficiency in scanning.
127 word* const bitmap_begin_;
Carl Shapiro69759ea2011-07-21 18:13:35 -0700128
Ian Rogers30fab402012-01-23 15:43:46 -0800129 // Size of this bitmap.
130 const size_t bitmap_size_;
Carl Shapiro69759ea2011-07-21 18:13:35 -0700131
Ian Rogers30fab402012-01-23 15:43:46 -0800132 // The base address of the heap, which corresponds to the word containing the first bit in the
133 // bitmap.
134 const uintptr_t heap_begin_;
Carl Shapiro69759ea2011-07-21 18:13:35 -0700135
136 // The highest pointer value ever returned by an allocation from
137 // this heap. I.e., the highest address that may correspond to a
Ian Rogers30fab402012-01-23 15:43:46 -0800138 // set bit. If there are no bits set, (heap_end_ < heap_begin_).
139 uintptr_t heap_end_;
Carl Shapiro69759ea2011-07-21 18:13:35 -0700140
Ian Rogers30fab402012-01-23 15:43:46 -0800141 // Name of this bitmap.
142 const char* const name_;
Carl Shapiro69759ea2011-07-21 18:13:35 -0700143};
144
145} // namespace art
146
Elliott Hughes5e71b522011-10-20 13:12:32 -0700147#endif // ART_SRC_HEAP_BITMAP_H_