// 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_SET_H_ #define RUNTIME_VM_BIT_SET_H_ #include "platform/utils.h" #include "vm/globals.h" namespace dart { // Just like its namesake in the STL, a BitSet object contains a fixed // length sequence of bits. template class BitSet { public: BitSet() { Reset(); } void Set(intptr_t i, bool value) { ASSERT(i >= 0); ASSERT(i < N); uword mask = (static_cast(1) << (i & (kBitsPerWord - 1))); if (value) { data_[i >> kBitsPerWordLog2] |= mask; } else { data_[i >> kBitsPerWordLog2] &= ~mask; } } bool Test(intptr_t i) const { ASSERT(i >= 0); ASSERT(i < N); uword mask = (static_cast(1) << (i & (kBitsPerWord - 1))); return (data_[i >> kBitsPerWordLog2] & mask) != 0; } intptr_t Next(intptr_t i) const { ASSERT(i >= 0); ASSERT(i < N); intptr_t w = i >> kBitsPerWordLog2; uword mask = ~static_cast(0) << (i & (kBitsPerWord - 1)); if ((data_[w] & mask) != 0) { uword tz = Utils::CountTrailingZerosWord(data_[w] & mask); return (w << kBitsPerWordLog2) + tz; } while (++w < kLengthInWords) { if (data_[w] != 0) { return (w << kBitsPerWordLog2) + Utils::CountTrailingZerosWord(data_[w]); } } return -1; } intptr_t Last() const { for (int w = kLengthInWords - 1; w >= 0; --w) { uword d = data_[w]; if (d != 0) { return ((w + 1) << kBitsPerWordLog2) - Utils::CountLeadingZerosWord(d) - 1; } } return -1; } intptr_t ClearLastAndFindPrevious(intptr_t current_last) { ASSERT(Test(current_last)); ASSERT(Last() == current_last); intptr_t w = current_last >> kBitsPerWordLog2; uword bits = data_[w]; // Clear the current last. bits ^= (static_cast(1) << (current_last & (kBitsPerWord - 1))); data_[w] = bits; // Search backwards for a non-zero word. while (bits == 0 && w > 0) { bits = data_[--w]; } if (bits == 0) { // None found. return -1; } else { // Bitlength incl. w, minus leading zeroes of w, minus 1 to 0-based index. return ((w + 1) << kBitsPerWordLog2) - Utils::CountLeadingZerosWord(bits) - 1; } } void Reset() { memset(data_, 0, sizeof(data_)); } intptr_t Size() const { return N; } private: static constexpr int kLengthInWords = 1 + ((N - 1) / kBitsPerWord); uword data_[kLengthInWords]; }; } // namespace dart #endif // RUNTIME_VM_BIT_SET_H_