summaryrefslogtreecommitdiff
path: root/libartbase/base/bit_vector.h
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2025-02-19 09:55:20 +0000
committer Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2025-02-20 04:26:43 -0800
commit16a42183aff1275ad238bf5fb2e6416ecebc16cd (patch)
tree3527e3cbb618a34ae511a9463f987b21755e2bb2 /libartbase/base/bit_vector.h
parentc6aa6f7f1c7ea91b512d98caf493b8ad93e983b2 (diff)
Introduce `BitVectorView<>`.
Initially implement only simple bit getter and setters and use the new class to avoid overheads of `ArenaBitVector` in a few places. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Bug: 331194861 Change-Id: Ie29dfcd02286770e07131e43b65e6e9fb044a924
Diffstat (limited to 'libartbase/base/bit_vector.h')
-rw-r--r--libartbase/base/bit_vector.h69
1 files changed, 65 insertions, 4 deletions
diff --git a/libartbase/base/bit_vector.h b/libartbase/base/bit_vector.h
index ec94efb09f..35a5e7c95b 100644
--- a/libartbase/base/bit_vector.h
+++ b/libartbase/base/bit_vector.h
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <iterator>
+#include <limits>
#include "bit_utils.h"
#include "globals.h"
@@ -27,7 +28,59 @@
namespace art {
class Allocator;
-class ArenaBitVector;
+
+// A bit vector view encapsulating externally-provided fixed-size storage for bits.
+template <typename StorageType = size_t>
+class BitVectorView {
+ public:
+ using WordType = StorageType;
+ static_assert(std::numeric_limits<WordType>::is_integer);
+ static_assert(!std::numeric_limits<WordType>::is_signed);
+ static constexpr size_t kWordBits = BitSizeOf<WordType>();
+ static_assert(IsPowerOfTwo(kWordBits));
+
+ static constexpr size_t BitsToWords(size_t bits) {
+ return (bits + /* round up */ (kWordBits - 1)) / kWordBits;
+ }
+
+ constexpr BitVectorView(WordType* storage, size_t size_in_bits)
+ : storage_(storage), size_in_bits_(size_in_bits) {}
+
+ // The `BitVectorView<>` can be copied and passed to functions by value.
+ // The new copy shall reference the same underlying data, similarly to `std::string_view`.
+ BitVectorView(const BitVectorView& src) = default;
+
+ constexpr size_t SizeInBits() const {
+ return size_in_bits_;
+ }
+
+ void SetBit(size_t index) {
+ DCHECK_LT(index, size_in_bits_);
+ storage_[WordIndex(index)] |= BitMask(index);
+ }
+
+ void ClearBit(size_t index) {
+ DCHECK_LT(index, size_in_bits_);
+ storage_[WordIndex(index)] &= ~BitMask(index);
+ }
+
+ constexpr bool IsBitSet(size_t index) const {
+ DCHECK_LT(index, size_in_bits_);
+ return (storage_[WordIndex(index)] & BitMask(index)) != 0u;
+ }
+
+ private:
+ static constexpr size_t WordIndex(size_t index) {
+ return index >> WhichPowerOf2(kWordBits);
+ }
+
+ static constexpr WordType BitMask(size_t index) {
+ return static_cast<WordType>(1) << (index % kWordBits);
+ }
+
+ WordType* storage_;
+ size_t size_in_bits_;
+};
/*
* Expanding bitmap. Bits are numbered starting from zero. All operations on a BitVector are
@@ -154,7 +207,7 @@ class BitVector {
if (idx >= storage_size_ * kWordBits) {
EnsureSize(idx);
}
- storage_[WordIndex(idx)] |= BitMask(idx);
+ AsView().SetBit(idx);
}
// Mark the specified bit as "unset".
@@ -162,7 +215,7 @@ class BitVector {
// If the index is over the size, we don't have to do anything, it is cleared.
if (idx < storage_size_ * kWordBits) {
// Otherwise, go ahead and clear it.
- storage_[WordIndex(idx)] &= ~BitMask(idx);
+ AsView().ClearBit(idx);
}
}
@@ -170,7 +223,7 @@ class BitVector {
bool IsBitSet(uint32_t idx) const {
// If the index is over the size, whether it is expandable or not, this bit does not exist:
// thus it is not set.
- return (idx < (storage_size_ * kWordBits)) && IsBitSet(storage_, idx);
+ return (idx < (storage_size_ * kWordBits)) && AsView().IsBitSet(idx);
}
// Mark all bits bit as "clear".
@@ -291,6 +344,14 @@ class BitVector {
*/
void DumpHelper(const char* prefix, std::ostringstream& buffer) const;
+ BitVectorView<uint32_t> AsView() {
+ return {storage_, storage_size_ * kWordBits};
+ }
+
+ BitVectorView<const uint32_t> AsView() const {
+ return {storage_, storage_size_ * kWordBits};
+ }
+
// Ensure there is space for a bit at idx.
void EnsureSize(uint32_t idx);