| Index: runtime/vm/bitmap.cc
|
| diff --git a/runtime/vm/bitmap.cc b/runtime/vm/bitmap.cc
|
| index 479c780546c495db9e288d449a92f310c0c7ad7c..ae114d8f74416b9ace72d2b6273690b00cd65fef 100644
|
| --- a/runtime/vm/bitmap.cc
|
| +++ b/runtime/vm/bitmap.cc
|
| @@ -9,49 +9,58 @@
|
|
|
| namespace dart {
|
|
|
| -bool BitmapBuilder::Get(intptr_t bit_offset) const {
|
| - if (!InRange(bit_offset)) {
|
| - return false;
|
| - }
|
| - return GetBit(bit_offset);
|
| -}
|
| -
|
| -
|
| -void BitmapBuilder::Set(intptr_t bit_offset, bool value) {
|
| - while (!InRange(bit_offset)) {
|
| - intptr_t new_size = size_in_bytes_ + kIncrementSizeInBytes;
|
| - ASSERT(new_size > 0);
|
| - uint8_t* new_bit_list =
|
| - Isolate::Current()->current_zone()->Alloc<uint8_t>(new_size);
|
| - ASSERT(new_bit_list != NULL);
|
| - ASSERT(bit_list_ != NULL);
|
| - uint8_t* old_bit_list = bit_list_;
|
| - memmove(new_bit_list, old_bit_list, size_in_bytes_);
|
| - memset((new_bit_list + size_in_bytes_), 0, kIncrementSizeInBytes);
|
| - size_in_bytes_ = new_size;
|
| - bit_list_ = new_bit_list;
|
| +void BitmapBuilder::SetLength(intptr_t new_length) {
|
| + // When this function is used to shorten the length, affected bits in the
|
| + // backing store need to be cleared because the implementation assumes it.
|
| + if (new_length < length_) {
|
| + // Byte offset containing the first bit to be cleared.
|
| + intptr_t byte_offset = new_length >> kBitsPerByteLog2;
|
| + if (byte_offset < data_size_in_bytes_) {
|
| + // First bit index (in the byte) to be cleared.
|
| + intptr_t bit_index = new_length & (kBitsPerByte - 1);
|
| + intptr_t mask = (1 << bit_index) - 1;
|
| + data_[byte_offset] &= mask;
|
| + // Clear the rest.
|
| + ++byte_offset;
|
| + if (byte_offset < data_size_in_bytes_) {
|
| + memset(&data_[byte_offset], 0, data_size_in_bytes_ - byte_offset);
|
| + }
|
| + }
|
| }
|
| - SetBit(bit_offset, value);
|
| + length_ = new_length;
|
| }
|
|
|
|
|
| -// Return the bit offset of the highest bit set.
|
| -intptr_t BitmapBuilder::Maximum() const {
|
| - intptr_t bound = SizeInBits();
|
| - for (intptr_t i = (bound - 1); i >= 0; i--) {
|
| - if (Get(i)) return i;
|
| - }
|
| - return Stackmap::kNoMaximum;
|
| +bool BitmapBuilder::Get(intptr_t bit_offset) const {
|
| + ASSERT(InRange(bit_offset));
|
| + intptr_t byte_offset = bit_offset >> kBitsPerByteLog2;
|
| + // Bits not covered by the backing store are implicitly false.
|
| + return (byte_offset < data_size_in_bytes_) && GetBit(bit_offset);
|
| }
|
|
|
|
|
| -// Return the bit offset of the lowest bit set.
|
| -intptr_t BitmapBuilder::Minimum() const {
|
| - intptr_t bound = SizeInBits();
|
| - for (intptr_t i = 0; i < bound; i++) {
|
| - if (Get(i)) return i;
|
| +void BitmapBuilder::Set(intptr_t bit_offset, bool value) {
|
| + ASSERT(bit_offset >= 0);
|
| + if (!InRange(bit_offset)) {
|
| + length_ = bit_offset + 1;
|
| + // Bits not covered by the backing store are implicitly false.
|
| + if (!value) return;
|
| + // Grow the backing store if necessary.
|
| + intptr_t byte_offset = bit_offset >> kBitsPerByteLog2;
|
| + if (byte_offset >= data_size_in_bytes_) {
|
| + uint8_t* old_data = data_;
|
| + intptr_t old_size = data_size_in_bytes_;
|
| + data_size_in_bytes_ =
|
| + Utils::RoundUp(byte_offset + 1, kIncrementSizeInBytes);
|
| + ASSERT(data_size_in_bytes_ > 0);
|
| + data_ = Isolate::Current()->current_zone()->Alloc<uint8_t>(
|
| + data_size_in_bytes_);
|
| + ASSERT(data_ != NULL);
|
| + memmove(data_, old_data, old_size);
|
| + memset(&data_[old_size], 0, (data_size_in_bytes_ - old_size));
|
| + }
|
| }
|
| - return Stackmap::kNoMinimum;
|
| + SetBit(bit_offset, value);
|
| }
|
|
|
|
|
| @@ -64,26 +73,26 @@ void BitmapBuilder::SetRange(intptr_t min, intptr_t max, bool value) {
|
|
|
| bool BitmapBuilder::GetBit(intptr_t bit_offset) const {
|
| ASSERT(InRange(bit_offset));
|
| - int byte_offset = bit_offset >> kBitsPerByteLog2;
|
| - int bit_remainder = bit_offset & (kBitsPerByte - 1);
|
| + intptr_t byte_offset = bit_offset >> kBitsPerByteLog2;
|
| + ASSERT(byte_offset < data_size_in_bytes_);
|
| + intptr_t bit_remainder = bit_offset & (kBitsPerByte - 1);
|
| uint8_t mask = 1U << bit_remainder;
|
| - ASSERT(bit_list_ != NULL);
|
| - return ((bit_list_[byte_offset] & mask) != 0);
|
| + ASSERT(data_ != NULL);
|
| + return ((data_[byte_offset] & mask) != 0);
|
| }
|
|
|
|
|
| void BitmapBuilder::SetBit(intptr_t bit_offset, bool value) {
|
| ASSERT(InRange(bit_offset));
|
| int byte_offset = bit_offset >> kBitsPerByteLog2;
|
| + ASSERT(byte_offset < data_size_in_bytes_);
|
| int bit_remainder = bit_offset & (kBitsPerByte - 1);
|
| uint8_t mask = 1U << bit_remainder;
|
| - uint8_t* byte_addr;
|
| - ASSERT(bit_list_ != NULL);
|
| - byte_addr = &(bit_list_[byte_offset]);
|
| + ASSERT(data_ != NULL);
|
| if (value) {
|
| - *byte_addr |= mask;
|
| + data_[byte_offset] |= mask;
|
| } else {
|
| - *byte_addr &= ~mask;
|
| + data_[byte_offset] &= ~mask;
|
| }
|
| }
|
|
|
|
|