summaryrefslogtreecommitdiff
path: root/src/space_bitmap.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/space_bitmap.cc')
-rw-r--r--src/space_bitmap.cc72
1 files changed, 37 insertions, 35 deletions
diff --git a/src/space_bitmap.cc b/src/space_bitmap.cc
index 28dee4505a..7da8146a14 100644
--- a/src/space_bitmap.cc
+++ b/src/space_bitmap.cc
@@ -38,6 +38,18 @@ SpaceBitmap* SpaceBitmap::Create(const std::string& name, byte* heap_begin, size
// Clean up any resources associated with the bitmap.
SpaceBitmap::~SpaceBitmap() {}
+void SpaceBitmap::SetHeapLimit(uintptr_t new_end) {
+ DCHECK(IsAligned<kBitsPerWord * kAlignment>(new_end));
+ size_t new_size = OffsetToIndex(new_end - heap_begin_) * kWordSize;
+ if (new_size < bitmap_size_) {
+ bitmap_size_ = new_size;
+ }
+ // Not sure if doing this trim is necessary, since nothing past the end of the heap capacity
+ // should be marked.
+ // TODO: Fix this code is, it broken and causes rare heap corruption!
+ // mem_map_->Trim(reinterpret_cast<byte*>(heap_begin_ + bitmap_size_));
+}
+
// Fill the bitmap with zeroes. Returns the bitmap's memory to the
// system as a side-effect.
void SpaceBitmap::Clear() {
@@ -61,24 +73,6 @@ bool SpaceBitmap::HasAddress(const void* obj) const {
return index < bitmap_size_ / kWordSize;
}
-void SpaceBitmap::VisitRange(uintptr_t visit_begin, uintptr_t visit_end, Callback* visitor, void* arg) const {
- size_t start = OffsetToIndex(visit_begin - heap_begin_);
- size_t end = OffsetToIndex(visit_end - heap_begin_ - 1);
- for (size_t i = start; i <= end; i++) {
- word w = bitmap_begin_[i];
- if (w != 0) {
- word high_bit = 1 << (kBitsPerWord - 1);
- uintptr_t ptr_base = IndexToOffset(i) + heap_begin_;
- while (w != 0) {
- const int shift = CLZ(w);
- Object* obj = reinterpret_cast<Object*>(ptr_base + shift * kAlignment);
- (*visitor)(obj, arg);
- w &= ~(high_bit >> shift);
- }
- }
- }
-}
-
// Visits set bits in address order. The callback is not permitted to
// change the bitmap bits or max during the traversal.
void SpaceBitmap::Walk(SpaceBitmap::Callback* callback, void* arg) {
@@ -91,13 +85,12 @@ void SpaceBitmap::Walk(SpaceBitmap::Callback* callback, void* arg) {
for (uintptr_t i = 0; i <= end; ++i) {
word w = bitmap_begin_[i];
if (UNLIKELY(w != 0)) {
- word high_bit = 1 << (kBitsPerWord - 1);
uintptr_t ptr_base = IndexToOffset(i) + heap_begin_;
while (w != 0) {
- const int shift = CLZ(w);
+ const size_t shift = CLZ(w);
Object* obj = reinterpret_cast<Object*>(ptr_base + shift * kAlignment);
(*callback)(obj, arg);
- w &= ~(high_bit >> shift);
+ w ^= static_cast<size_t>(kWordHighBitMask) >> shift;
}
}
}
@@ -116,22 +109,34 @@ void SpaceBitmap::ScanWalk(uintptr_t scan_begin, uintptr_t scan_end, ScanCallbac
CHECK(callback != NULL);
CHECK_LE(scan_begin, scan_end);
CHECK_GE(scan_begin, heap_begin_);
- size_t start = OffsetToIndex(scan_begin - heap_begin_);
+
+ // This function doesn't support unaligned boundaries yet.
+ size_t begin_offset = scan_begin - heap_begin_;
+ size_t end_offset = scan_end - heap_begin_;
+ DCHECK((begin_offset / kAlignment) % kBitsPerWord == 0)
+ << "scan begin " << reinterpret_cast<const void*>(scan_begin)
+ << " with offset " << begin_offset
+ << " not aligned to word boundary";
+ DCHECK((end_offset / kAlignment) % kBitsPerWord == 0)
+ << "scan end " << reinterpret_cast<const void*>(scan_end)
+ << " with offset " << end_offset
+ << " not aligned to word boundary";
+
+ size_t start = OffsetToIndex(begin_offset);
if (scan_end < heap_end_) {
// The end of the space we're looking at is before the current maximum bitmap PC, scan to that
// and don't recompute end on each iteration
- size_t end = OffsetToIndex(scan_end - heap_begin_ - 1);
+ size_t end = OffsetToIndex(end_offset - 1);
for (size_t i = start; i <= end; i++) {
word w = bitmap_begin_[i];
if (UNLIKELY(w != 0)) {
- word high_bit = 1 << (kBitsPerWord - 1);
uintptr_t ptr_base = IndexToOffset(i) + heap_begin_;
void* finger = reinterpret_cast<void*>(IndexToOffset(i + 1) + heap_begin_);
while (w != 0) {
- const int shift = CLZ(w);
+ const size_t shift = CLZ(w);
Object* obj = reinterpret_cast<Object*>(ptr_base + shift * kAlignment);
(*callback)(obj, finger, arg);
- w &= ~(high_bit >> shift);
+ w ^= static_cast<size_t>(kWordHighBitMask) >> shift;
}
}
}
@@ -140,14 +145,13 @@ void SpaceBitmap::ScanWalk(uintptr_t scan_begin, uintptr_t scan_end, ScanCallbac
for (size_t i = start; i <= end; i++) {
word w = bitmap_begin_[i];
if (UNLIKELY(w != 0)) {
- word high_bit = 1 << (kBitsPerWord - 1);
uintptr_t ptr_base = IndexToOffset(i) + heap_begin_;
void* finger = reinterpret_cast<void*>(IndexToOffset(i + 1) + heap_begin_);
while (w != 0) {
- const int shift = CLZ(w);
+ const size_t shift = CLZ(w);
Object* obj = reinterpret_cast<Object*>(ptr_base + shift * kAlignment);
(*callback)(obj, finger, arg);
- w &= ~(high_bit >> shift);
+ w ^= static_cast<size_t>(kWordHighBitMask) >> shift;
}
}
// update 'end' in case callback modified bitmap
@@ -188,11 +192,10 @@ void SpaceBitmap::SweepWalk(const SpaceBitmap& live_bitmap,
for (size_t i = start; i <= end; i++) {
word garbage = live[i] & ~mark[i];
if (UNLIKELY(garbage != 0)) {
- word high_bit = 1 << (kBitsPerWord - 1);
uintptr_t ptr_base = IndexToOffset(i) + live_bitmap.heap_begin_;
while (garbage != 0) {
- int shift = CLZ(garbage);
- garbage &= ~(high_bit >> shift);
+ const size_t shift = CLZ(garbage);
+ garbage ^= static_cast<size_t>(kWordHighBitMask) >> shift;
*pb++ = reinterpret_cast<Object*>(ptr_base + shift * kAlignment);
}
// Make sure that there are always enough slots available for an
@@ -296,13 +299,12 @@ void SpaceBitmap::InOrderWalk(SpaceBitmap::Callback* callback, void* arg) {
for (uintptr_t i = 0; i <= end; ++i) {
word w = bitmap_begin_[i];
if (UNLIKELY(w != 0)) {
- word high_bit = 1 << (kBitsPerWord - 1);
uintptr_t ptr_base = IndexToOffset(i) + heap_begin_;
while (w != 0) {
- const int shift = CLZ(w);
+ const size_t shift = CLZ(w);
Object* obj = reinterpret_cast<Object*>(ptr_base + shift * kAlignment);
WalkFieldsInOrder(visited.get(), callback, obj, arg);
- w &= ~(high_bit >> shift);
+ w ^= static_cast<size_t>(kWordHighBitMask) >> shift;
}
}
}