// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. #ifndef RUNTIME_VM_BIT_VECTOR_H_ #define RUNTIME_VM_BIT_VECTOR_H_ #include "vm/allocation.h" #include "vm/isolate.h" #include "vm/zone.h" namespace dart { // Bit vector implementation. class BitVector : public ZoneAllocated { public: // Iterator for the elements of this BitVector. class Iterator : public ValueObject { public: explicit Iterator(BitVector* target) : target_(target), bit_index_(-1), word_index_(0), current_word_(target->data_[0]) { ASSERT(target->data_length_ > 0); Advance(); } ~Iterator() {} bool Done() const { return word_index_ >= target_->data_length_; } void Advance(); intptr_t Current() const { ASSERT(!Done()); return bit_index_; } private: BitVector* target_; intptr_t bit_index_; intptr_t word_index_; uword current_word_; friend class BitVector; }; BitVector(Zone* zone, intptr_t length) : length_(length), data_length_(SizeFor(length)), data_(zone->Alloc(data_length_)) { Clear(); } void CopyFrom(const BitVector* other); static intptr_t SizeFor(intptr_t length) { return 1 + ((length - 1) / kBitsPerWord); } void Add(intptr_t i) { ASSERT(i >= 0 && i < length()); data_[i / kBitsPerWord] |= (static_cast(1) << (i % kBitsPerWord)); } void Remove(intptr_t i) { ASSERT(i >= 0 && i < length()); data_[i / kBitsPerWord] &= ~(static_cast(1) << (i % kBitsPerWord)); } void Set(intptr_t i, bool value) { value ? Add(i) : Remove(i); } bool Equals(const BitVector& other) const; // Add all elements that are in the bitvector from. bool AddAll(const BitVector* from); // Remove all elements that are in the bitvector from. bool RemoveAll(const BitVector* from); // From the bitvector gen add those elements that are not in the // bitvector kill. bool KillAndAdd(BitVector* kill, BitVector* gen); void Intersect(const BitVector* other); bool IsEmpty() const; bool Contains(intptr_t i) const { ASSERT(i >= 0 && i < length()); uword block = data_[i / kBitsPerWord]; return (block & (static_cast(1) << (i % kBitsPerWord))) != 0; } bool SubsetOf(const BitVector& other) { ASSERT(length_ == other.length_); for (intptr_t i = 0; i < data_length_; ++i) { if ((data_[i] & other.data_[i]) != data_[i]) return false; } return true; } void Clear() { for (intptr_t i = 0; i < data_length_; i++) { data_[i] = 0; } } void SetAll() { for (intptr_t i = 0; i < data_length_; i++) { data_[i] = static_cast(-1); } } intptr_t length() const { return length_; } void Print() const; private: intptr_t length_; intptr_t data_length_; uword* data_; DISALLOW_COPY_AND_ASSIGN(BitVector); }; } // namespace dart #endif // RUNTIME_VM_BIT_VECTOR_H_