| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/bitmap.h" | 5 #include "vm/bitmap.h" |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "vm/object.h" | 8 #include "vm/object.h" |
| 9 | 9 |
| 10 namespace dart { | 10 namespace dart { |
| 11 | 11 |
| 12 void BitmapBuilder::SetLength(intptr_t new_length) { |
| 13 // When this function is used to shorten the length, affected bits in the |
| 14 // backing store need to be cleared because the implementation assumes it. |
| 15 if (new_length < length_) { |
| 16 // Byte offset containing the first bit to be cleared. |
| 17 intptr_t byte_offset = new_length >> kBitsPerByteLog2; |
| 18 if (byte_offset < size_in_bytes_) { |
| 19 // First bit index (in the byte) to be cleared. |
| 20 intptr_t bit_index = new_length & (kBitsPerByte - 1); |
| 21 intptr_t mask = (1 << bit_index) - 1; |
| 22 bit_list_[byte_offset] &= mask; |
| 23 // Clear the rest. |
| 24 ++byte_offset; |
| 25 if (byte_offset < size_in_bytes_) { |
| 26 memset(&bit_list_[byte_offset], 0, size_in_bytes_ - byte_offset); |
| 27 } |
| 28 } |
| 29 } |
| 30 length_ = new_length; |
| 31 } |
| 32 |
| 33 |
| 12 bool BitmapBuilder::Get(intptr_t bit_offset) const { | 34 bool BitmapBuilder::Get(intptr_t bit_offset) const { |
| 13 if (!InRange(bit_offset)) { | 35 ASSERT(InRange(bit_offset)); |
| 14 return false; | 36 intptr_t byte_offset = bit_offset >> kBitsPerByteLog2; |
| 15 } | 37 // Bits not covered by the backing store are implicitly false. |
| 16 return GetBit(bit_offset); | 38 return (byte_offset < size_in_bytes_) && GetBit(bit_offset); |
| 17 } | 39 } |
| 18 | 40 |
| 19 | 41 |
| 20 void BitmapBuilder::Set(intptr_t bit_offset, bool value) { | 42 void BitmapBuilder::Set(intptr_t bit_offset, bool value) { |
| 21 while (!InRange(bit_offset)) { | 43 ASSERT(bit_offset >= 0); |
| 22 intptr_t new_size = size_in_bytes_ + kIncrementSizeInBytes; | 44 if (!InRange(bit_offset)) { |
| 23 ASSERT(new_size > 0); | 45 length_ = bit_offset + 1; |
| 24 uint8_t* new_bit_list = | 46 // Bits not covered by the backing store are implicitly false. |
| 25 Isolate::Current()->current_zone()->Alloc<uint8_t>(new_size); | 47 if (!value) return; |
| 26 ASSERT(new_bit_list != NULL); | 48 // Grow the backing store if necessary. |
| 27 ASSERT(bit_list_ != NULL); | 49 intptr_t byte_offset = bit_offset >> kBitsPerByteLog2; |
| 28 uint8_t* old_bit_list = bit_list_; | 50 if (byte_offset >= size_in_bytes_) { |
| 29 memmove(new_bit_list, old_bit_list, size_in_bytes_); | 51 intptr_t new_size = |
| 30 memset((new_bit_list + size_in_bytes_), 0, kIncrementSizeInBytes); | 52 Utils::RoundUp(byte_offset + 1, kIncrementSizeInBytes); |
| 31 size_in_bytes_ = new_size; | 53 ASSERT(new_size > 0); |
| 32 bit_list_ = new_bit_list; | 54 uint8_t* new_bit_list = |
| 55 Isolate::Current()->current_zone()->Alloc<uint8_t>(new_size); |
| 56 ASSERT(new_bit_list != NULL); |
| 57 ASSERT(bit_list_ != NULL); |
| 58 uint8_t* old_bit_list = bit_list_; |
| 59 memmove(new_bit_list, old_bit_list, size_in_bytes_); |
| 60 memset((new_bit_list + size_in_bytes_), 0, (new_size - size_in_bytes_)); |
| 61 size_in_bytes_ = new_size; |
| 62 bit_list_ = new_bit_list; |
| 63 } |
| 33 } | 64 } |
| 34 SetBit(bit_offset, value); | 65 SetBit(bit_offset, value); |
| 35 } | 66 } |
| 36 | 67 |
| 37 | 68 |
| 38 // Return the bit offset of the highest bit set. | |
| 39 intptr_t BitmapBuilder::Maximum() const { | |
| 40 intptr_t bound = SizeInBits(); | |
| 41 for (intptr_t i = (bound - 1); i >= 0; i--) { | |
| 42 if (Get(i)) return i; | |
| 43 } | |
| 44 return Stackmap::kNoMaximum; | |
| 45 } | |
| 46 | |
| 47 | |
| 48 // Return the bit offset of the lowest bit set. | |
| 49 intptr_t BitmapBuilder::Minimum() const { | |
| 50 intptr_t bound = SizeInBits(); | |
| 51 for (intptr_t i = 0; i < bound; i++) { | |
| 52 if (Get(i)) return i; | |
| 53 } | |
| 54 return Stackmap::kNoMinimum; | |
| 55 } | |
| 56 | |
| 57 | |
| 58 void BitmapBuilder::SetRange(intptr_t min, intptr_t max, bool value) { | 69 void BitmapBuilder::SetRange(intptr_t min, intptr_t max, bool value) { |
| 59 for (intptr_t i = min; i <= max; i++) { | 70 for (intptr_t i = min; i <= max; i++) { |
| 60 Set(i, value); | 71 Set(i, value); |
| 61 } | 72 } |
| 62 } | 73 } |
| 63 | 74 |
| 64 | 75 |
| 65 bool BitmapBuilder::GetBit(intptr_t bit_offset) const { | 76 bool BitmapBuilder::GetBit(intptr_t bit_offset) const { |
| 66 ASSERT(InRange(bit_offset)); | 77 ASSERT(InRange(bit_offset)); |
| 67 int byte_offset = bit_offset >> kBitsPerByteLog2; | 78 intptr_t byte_offset = bit_offset >> kBitsPerByteLog2; |
| 68 int bit_remainder = bit_offset & (kBitsPerByte - 1); | 79 ASSERT(byte_offset < size_in_bytes_); |
| 80 intptr_t bit_remainder = bit_offset & (kBitsPerByte - 1); |
| 69 uint8_t mask = 1U << bit_remainder; | 81 uint8_t mask = 1U << bit_remainder; |
| 70 ASSERT(bit_list_ != NULL); | 82 ASSERT(bit_list_ != NULL); |
| 71 return ((bit_list_[byte_offset] & mask) != 0); | 83 return ((bit_list_[byte_offset] & mask) != 0); |
| 72 } | 84 } |
| 73 | 85 |
| 74 | 86 |
| 75 void BitmapBuilder::SetBit(intptr_t bit_offset, bool value) { | 87 void BitmapBuilder::SetBit(intptr_t bit_offset, bool value) { |
| 76 ASSERT(InRange(bit_offset)); | 88 ASSERT(InRange(bit_offset)); |
| 77 int byte_offset = bit_offset >> kBitsPerByteLog2; | 89 int byte_offset = bit_offset >> kBitsPerByteLog2; |
| 90 ASSERT(byte_offset < size_in_bytes_); |
| 78 int bit_remainder = bit_offset & (kBitsPerByte - 1); | 91 int bit_remainder = bit_offset & (kBitsPerByte - 1); |
| 79 uint8_t mask = 1U << bit_remainder; | 92 uint8_t mask = 1U << bit_remainder; |
| 80 uint8_t* byte_addr; | |
| 81 ASSERT(bit_list_ != NULL); | 93 ASSERT(bit_list_ != NULL); |
| 82 byte_addr = &(bit_list_[byte_offset]); | |
| 83 if (value) { | 94 if (value) { |
| 84 *byte_addr |= mask; | 95 bit_list_[byte_offset] |= mask; |
| 85 } else { | 96 } else { |
| 86 *byte_addr &= ~mask; | 97 bit_list_[byte_offset] &= ~mask; |
| 87 } | 98 } |
| 88 } | 99 } |
| 89 | 100 |
| 90 } // namespace dart | 101 } // namespace dart |
| OLD | NEW |