diff options
Diffstat (limited to 'src/space_bitmap.cc')
| -rw-r--r-- | src/space_bitmap.cc | 72 | 
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;        }      }    }  |