| 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 |
| 3 | // BSD-style license that can be found in the LICENSE file. |
| 4 | |
| 5 | #ifndef RUNTIME_VM_BIT_VECTOR_H_ |
| 6 | #define RUNTIME_VM_BIT_VECTOR_H_ |
| 7 | |
| 8 | #include "vm/allocation.h" |
| 9 | #include "vm/isolate.h" |
| 10 | #include "vm/zone.h" |
| 11 | |
| 12 | namespace dart { |
| 13 | |
| 14 | // Bit vector implementation. |
| 15 | class BitVector : public ZoneAllocated { |
| 16 | public: |
| 17 | // Iterator for the elements of this BitVector. |
| 18 | class Iterator : public ValueObject { |
| 19 | public: |
| 20 | explicit Iterator(BitVector* target) |
| 21 | : target_(target), |
| 22 | bit_index_(-1), |
| 23 | word_index_(0), |
| 24 | current_word_(target->data_[0]) { |
| 25 | ASSERT(target->data_length_ > 0); |
| 26 | Advance(); |
| 27 | } |
| 28 | ~Iterator() {} |
| 29 | |
| 30 | bool Done() const { return word_index_ >= target_->data_length_; } |
| 31 | void Advance(); |
| 32 | |
| 33 | intptr_t Current() const { |
| 34 | ASSERT(!Done()); |
| 35 | return bit_index_; |
| 36 | } |
| 37 | |
| 38 | private: |
| 39 | BitVector* target_; |
| 40 | intptr_t bit_index_; |
| 41 | intptr_t word_index_; |
| 42 | uword current_word_; |
| 43 | |
| 44 | friend class BitVector; |
| 45 | }; |
| 46 | |
| 47 | BitVector(Zone* zone, intptr_t length) |
| 48 | : length_(length), |
| 49 | data_length_(SizeFor(length)), |
| 50 | data_(zone->Alloc<uword>(data_length_)) { |
| 51 | Clear(); |
| 52 | } |
| 53 | |
| 54 | void CopyFrom(const BitVector* other) { |
| 55 | Clear(); |
| 56 | AddAll(other); |
| 57 | } |
| 58 | |
| 59 | static intptr_t SizeFor(intptr_t length) { |
| 60 | return 1 + ((length - 1) / kBitsPerWord); |
| 61 | } |
| 62 | |
| 63 | void Add(intptr_t i) { |
| 64 | ASSERT(i >= 0 && i < length()); |
| 65 | data_[i / kBitsPerWord] |= (static_cast<uword>(1) << (i % kBitsPerWord)); |
| 66 | } |
| 67 | |
| 68 | void Remove(intptr_t i) { |
| 69 | ASSERT(i >= 0 && i < length()); |
| 70 | data_[i / kBitsPerWord] &= ~(static_cast<uword>(1) << (i % kBitsPerWord)); |
| 71 | } |
| 72 | |
| 73 | void Set(intptr_t i, bool value) { value ? Add(i) : Remove(i); } |
| 74 | |
| 75 | bool Equals(const BitVector& other) const; |
| 76 | |
| 77 | // Add all elements that are in the bitvector from. |
| 78 | bool AddAll(const BitVector* from); |
| 79 | |
| 80 | // Remove all elements that are in the bitvector from. |
| 81 | bool RemoveAll(const BitVector* from); |
| 82 | |
| 83 | // From the bitvector gen add those elements that are not in the |
| 84 | // bitvector kill. |
| 85 | bool KillAndAdd(BitVector* kill, BitVector* gen); |
| 86 | |
| 87 | void Intersect(const BitVector* other); |
| 88 | |
| 89 | bool IsEmpty() const; |
| 90 | |
| 91 | bool Contains(intptr_t i) const { |
| 92 | ASSERT(i >= 0 && i < length()); |
| 93 | uword block = data_[i / kBitsPerWord]; |
| 94 | return (block & (static_cast<uword>(1) << (i % kBitsPerWord))) != 0; |
| 95 | } |
| 96 | |
| 97 | bool SubsetOf(const BitVector& other) { |
| 98 | ASSERT(length_ == other.length_); |
| 99 | for (intptr_t i = 0; i < data_length_; ++i) { |
| 100 | if ((data_[i] & other.data_[i]) != data_[i]) return false; |
| 101 | } |
| 102 | return true; |
| 103 | } |
| 104 | |
| 105 | void Clear() { |
| 106 | for (intptr_t i = 0; i < data_length_; i++) { |
| 107 | data_[i] = 0; |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | void SetAll() { |
| 112 | for (intptr_t i = 0; i < data_length_; i++) { |
| 113 | data_[i] = static_cast<uword>(-1); |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | intptr_t length() const { return length_; } |
| 118 | |
| 119 | void Print() const; |
| 120 | |
| 121 | private: |
| 122 | intptr_t length_; |
| 123 | intptr_t data_length_; |
| 124 | uword* data_; |
| 125 | |
| 126 | DISALLOW_COPY_AND_ASSIGN(BitVector); |
| 127 | }; |
| 128 | |
| 129 | } // namespace dart |
| 130 | |
| 131 | #endif // RUNTIME_VM_BIT_VECTOR_H_ |
| 132 |