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 |