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 < data_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 data_[byte_offset] &= mask; |
| 23 // Clear the rest. |
| 24 ++byte_offset; |
| 25 if (byte_offset < data_size_in_bytes_) { |
| 26 memset(&data_[byte_offset], 0, data_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 < data_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 >= data_size_in_bytes_) { |
29 memmove(new_bit_list, old_bit_list, size_in_bytes_); | 51 uint8_t* old_data = data_; |
30 memset((new_bit_list + size_in_bytes_), 0, kIncrementSizeInBytes); | 52 intptr_t old_size = data_size_in_bytes_; |
31 size_in_bytes_ = new_size; | 53 data_size_in_bytes_ = |
32 bit_list_ = new_bit_list; | 54 Utils::RoundUp(byte_offset + 1, kIncrementSizeInBytes); |
| 55 ASSERT(data_size_in_bytes_ > 0); |
| 56 data_ = Isolate::Current()->current_zone()->Alloc<uint8_t>( |
| 57 data_size_in_bytes_); |
| 58 ASSERT(data_ != NULL); |
| 59 memmove(data_, old_data, old_size); |
| 60 memset(&data_[old_size], 0, (data_size_in_bytes_ - old_size)); |
| 61 } |
33 } | 62 } |
34 SetBit(bit_offset, value); | 63 SetBit(bit_offset, value); |
35 } | 64 } |
36 | 65 |
37 | 66 |
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) { | 67 void BitmapBuilder::SetRange(intptr_t min, intptr_t max, bool value) { |
59 for (intptr_t i = min; i <= max; i++) { | 68 for (intptr_t i = min; i <= max; i++) { |
60 Set(i, value); | 69 Set(i, value); |
61 } | 70 } |
62 } | 71 } |
63 | 72 |
64 | 73 |
65 bool BitmapBuilder::GetBit(intptr_t bit_offset) const { | 74 bool BitmapBuilder::GetBit(intptr_t bit_offset) const { |
66 ASSERT(InRange(bit_offset)); | 75 ASSERT(InRange(bit_offset)); |
67 int byte_offset = bit_offset >> kBitsPerByteLog2; | 76 intptr_t byte_offset = bit_offset >> kBitsPerByteLog2; |
68 int bit_remainder = bit_offset & (kBitsPerByte - 1); | 77 ASSERT(byte_offset < data_size_in_bytes_); |
| 78 intptr_t bit_remainder = bit_offset & (kBitsPerByte - 1); |
69 uint8_t mask = 1U << bit_remainder; | 79 uint8_t mask = 1U << bit_remainder; |
70 ASSERT(bit_list_ != NULL); | 80 ASSERT(data_ != NULL); |
71 return ((bit_list_[byte_offset] & mask) != 0); | 81 return ((data_[byte_offset] & mask) != 0); |
72 } | 82 } |
73 | 83 |
74 | 84 |
75 void BitmapBuilder::SetBit(intptr_t bit_offset, bool value) { | 85 void BitmapBuilder::SetBit(intptr_t bit_offset, bool value) { |
76 ASSERT(InRange(bit_offset)); | 86 ASSERT(InRange(bit_offset)); |
77 int byte_offset = bit_offset >> kBitsPerByteLog2; | 87 int byte_offset = bit_offset >> kBitsPerByteLog2; |
| 88 ASSERT(byte_offset < data_size_in_bytes_); |
78 int bit_remainder = bit_offset & (kBitsPerByte - 1); | 89 int bit_remainder = bit_offset & (kBitsPerByte - 1); |
79 uint8_t mask = 1U << bit_remainder; | 90 uint8_t mask = 1U << bit_remainder; |
80 uint8_t* byte_addr; | 91 ASSERT(data_ != NULL); |
81 ASSERT(bit_list_ != NULL); | |
82 byte_addr = &(bit_list_[byte_offset]); | |
83 if (value) { | 92 if (value) { |
84 *byte_addr |= mask; | 93 data_[byte_offset] |= mask; |
85 } else { | 94 } else { |
86 *byte_addr &= ~mask; | 95 data_[byte_offset] &= ~mask; |
87 } | 96 } |
88 } | 97 } |
89 | 98 |
90 } // namespace dart | 99 } // namespace dart |
OLD | NEW |