| // 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. | |
| #include "vm/bit_vector.h" | |
| #include "vm/log.h" | |
| #include "vm/os.h" | |
| namespace dart { | |
| void BitVector::Iterator::Advance() { | |
| ++bit_index_; | |
| // Skip zero words. | |
| if (current_word_ == 0) { | |
| do { | |
| ++word_index_; | |
| if (Done()) return; | |
| current_word_ = target_->data_[word_index_]; | |
| } while (current_word_ == 0); | |
| bit_index_ = word_index_ * kBitsPerWord; | |
| } | |
| // Skip zero bytes. | |
| while ((current_word_ & 0xff) == 0) { | |
| current_word_ >>= 8; | |
| bit_index_ += 8; | |
| } | |
| // Skip zero bits. | |
| while ((current_word_ & 0x1) == 0) { | |
| current_word_ >>= 1; | |
| ++bit_index_; | |
| } | |
| current_word_ = current_word_ >> 1; | |
| } | |
| bool BitVector::Equals(const BitVector& other) const { | |
| if (length_ != other.length_) return false; | |
| intptr_t i = 0; | |
| for (; i < data_length_ - 1; i++) { | |
| if (data_[i] != other.data_[i]) return false; | |
| } | |
| if (i < data_length_) { | |
| if (length_ % kBitsPerWord == 0) return data_[i] == other.data_[i]; | |
| // Don't compare bits beyond length_. | |
| const intptr_t shift_size = kBitsPerWord - (length_ % kBitsPerWord); | |
| const uword mask = static_cast<uword>(-1) >> shift_size; | |
| if ((data_[i] & mask) != (other.data_[i] & mask)) return false; | |
| } | |
| return true; | |
| } | |
| void BitVector::CopyFrom(const BitVector* from) { | |
| ASSERT(data_length_ == from->data_length_); | |
| memmove(data_, from->data_, data_length_ * sizeof(uword)); | |
| } | |
| bool BitVector::AddAll(const BitVector* from) { | |
| ASSERT(data_length_ == from->data_length_); | |
| bool changed = false; | |
| for (intptr_t i = 0; i < data_length_; i++) { | |
| const uword before = data_[i]; | |
| const uword after = data_[i] | from->data_[i]; | |
| if (before != after) { | |
| changed = true; | |
| data_[i] = after; | |
| } | |
| } | |
| return changed; | |
| } | |
| bool BitVector::RemoveAll(const BitVector* from) { | |
| ASSERT(data_length_ == from->data_length_); | |
| bool changed = false; | |
| for (intptr_t i = 0; i < data_length_; i++) { | |
| const uword before = data_[i]; | |
| const uword after = data_[i] & ~from->data_[i]; | |
| if (before != after) { | |
| changed = true; | |
| data_[i] = after; | |
| } | |
| } | |
| return changed; | |
| } | |
| bool BitVector::KillAndAdd(BitVector* kill, BitVector* gen) { | |
| ASSERT(data_length_ == kill->data_length_); | |
| ASSERT(data_length_ == gen->data_length_); | |
| bool changed = false; | |
| for (intptr_t i = 0; i < data_length_; i++) { | |
| const uword before = data_[i]; | |
| const uword after = data_[i] | (gen->data_[i] & ~kill->data_[i]); | |
| if (before != after) changed = true; | |
| data_[i] = after; | |
| } | |
| return changed; | |
| } | |
| void BitVector::Intersect(const BitVector* other) { | |
| ASSERT(other->length() == length()); | |
| for (intptr_t i = 0; i < data_length_; i++) { | |
| data_[i] = data_[i] & other->data_[i]; | |
| } | |
| } | |
| bool BitVector::IsEmpty() const { | |
| for (intptr_t i = 0; i < data_length_; i++) { | |
| if (data_[i] != 0) { | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| void BitVector::Print() const { | |
| THR_Print("["); | |
| for (intptr_t i = 0; i < length_; i++) { | |
| THR_Print(Contains(i) ? "1" : "0"); | |
| } | |
| THR_Print("]"); | |
| } | |
| } // namespace dart |