diff options
-rw-r--r-- | libartbase/base/bit_vector.cc | 5 | ||||
-rw-r--r-- | libartbase/base/bit_vector_test.cc | 55 |
2 files changed, 59 insertions, 1 deletions
diff --git a/libartbase/base/bit_vector.cc b/libartbase/base/bit_vector.cc index b32b4117dd..8e3d4c9bf7 100644 --- a/libartbase/base/bit_vector.cc +++ b/libartbase/base/bit_vector.cc @@ -61,7 +61,10 @@ BitVector::BitVector(const BitVector& src, } BitVector::~BitVector() { - allocator_->Free(storage_); + if (storage_ != nullptr) { + // Only free if we haven't been moved out of. + allocator_->Free(storage_); + } } bool BitVector::SameBitsSet(const BitVector *src) const { diff --git a/libartbase/base/bit_vector_test.cc b/libartbase/base/bit_vector_test.cc index bdba22a203..2ef81c6726 100644 --- a/libartbase/base/bit_vector_test.cc +++ b/libartbase/base/bit_vector_test.cc @@ -308,4 +308,59 @@ TEST(BitVector, TransformIterator) { } } +class SingleAllocator : public Allocator { + public: + SingleAllocator() : alloc_count_(0), free_count_(0) {} + ~SingleAllocator() { + EXPECT_EQ(alloc_count_, 1u); + EXPECT_EQ(free_count_, 1u); + } + + void* Alloc(size_t s) override { + EXPECT_LT(s, 1024ull); + EXPECT_EQ(alloc_count_, free_count_); + ++alloc_count_; + return bytes_.begin(); + } + + void Free(void*) override { + ++free_count_; + } + + uint32_t AllocCount() const { + return alloc_count_; + } + uint32_t FreeCount() const { + return free_count_; + } + + private: + std::array<uint8_t, 1024> bytes_; + uint32_t alloc_count_; + uint32_t free_count_; +}; + +TEST(BitVector, MovementFree) { + SingleAllocator alloc; + { + BitVector bv(16, false, &alloc); + bv.SetBit(13); + EXPECT_EQ(alloc.FreeCount(), 0u); + EXPECT_EQ(alloc.AllocCount(), 1u); + ASSERT_TRUE(bv.GetRawStorage() != nullptr); + EXPECT_TRUE(bv.IsBitSet(13)); + { + BitVector bv2(std::move(bv)); + ASSERT_TRUE(bv.GetRawStorage() == nullptr); + EXPECT_TRUE(bv2.IsBitSet(13)); + EXPECT_EQ(alloc.FreeCount(), 0u); + EXPECT_EQ(alloc.AllocCount(), 1u); + } + EXPECT_EQ(alloc.FreeCount(), 1u); + EXPECT_EQ(alloc.AllocCount(), 1u); + } + EXPECT_EQ(alloc.FreeCount(), 1u); + EXPECT_EQ(alloc.AllocCount(), 1u); +} + } // namespace art |