8296139: Make GrowableBitMap the base class of all implementations
Reviewed-by: aboldtch, stefank, simonis
This commit is contained in:
parent
cc8bf95046
commit
1b94ae13d3
@ -31,56 +31,21 @@
|
|||||||
#include "utilities/debug.hpp"
|
#include "utilities/debug.hpp"
|
||||||
#include "utilities/population_count.hpp"
|
#include "utilities/population_count.hpp"
|
||||||
|
|
||||||
STATIC_ASSERT(sizeof(BitMap::bm_word_t) == BytesPerWord); // "Implementation assumption."
|
using bm_word_t = BitMap::bm_word_t;
|
||||||
|
using idx_t = BitMap::idx_t;
|
||||||
|
|
||||||
typedef BitMap::bm_word_t bm_word_t;
|
STATIC_ASSERT(sizeof(bm_word_t) == BytesPerWord); // "Implementation assumption."
|
||||||
typedef BitMap::idx_t idx_t;
|
|
||||||
|
|
||||||
class ResourceBitMapAllocator : StackObj {
|
template <class BitMapWithAllocator>
|
||||||
public:
|
bm_word_t* GrowableBitMap<BitMapWithAllocator>::reallocate(bm_word_t* old_map, idx_t old_size_in_bits, idx_t new_size_in_bits, bool clear) {
|
||||||
bm_word_t* allocate(idx_t size_in_words) const {
|
|
||||||
return NEW_RESOURCE_ARRAY(bm_word_t, size_in_words);
|
|
||||||
}
|
|
||||||
void free(bm_word_t* map, idx_t size_in_words) const {
|
|
||||||
// Don't free resource allocated arrays.
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class CHeapBitMapAllocator : StackObj {
|
|
||||||
MEMFLAGS _flags;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CHeapBitMapAllocator(MEMFLAGS flags) : _flags(flags) {}
|
|
||||||
bm_word_t* allocate(size_t size_in_words) const {
|
|
||||||
return ArrayAllocator<bm_word_t>::allocate(size_in_words, _flags);
|
|
||||||
}
|
|
||||||
void free(bm_word_t* map, idx_t size_in_words) const {
|
|
||||||
ArrayAllocator<bm_word_t>::free(map, size_in_words);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ArenaBitMapAllocator : StackObj {
|
|
||||||
Arena* _arena;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ArenaBitMapAllocator(Arena* arena) : _arena(arena) {}
|
|
||||||
bm_word_t* allocate(idx_t size_in_words) const {
|
|
||||||
return (bm_word_t*)_arena->Amalloc(size_in_words * BytesPerWord);
|
|
||||||
}
|
|
||||||
void free(bm_word_t* map, idx_t size_in_words) const {
|
|
||||||
// ArenaBitMaps currently don't free memory.
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Allocator>
|
|
||||||
BitMap::bm_word_t* BitMap::reallocate(const Allocator& allocator, bm_word_t* old_map, idx_t old_size_in_bits, idx_t new_size_in_bits, bool clear) {
|
|
||||||
size_t old_size_in_words = calc_size_in_words(old_size_in_bits);
|
size_t old_size_in_words = calc_size_in_words(old_size_in_bits);
|
||||||
size_t new_size_in_words = calc_size_in_words(new_size_in_bits);
|
size_t new_size_in_words = calc_size_in_words(new_size_in_bits);
|
||||||
|
|
||||||
bm_word_t* map = NULL;
|
bm_word_t* map = NULL;
|
||||||
|
BitMapWithAllocator* derived = static_cast<BitMapWithAllocator*>(this);
|
||||||
|
|
||||||
if (new_size_in_words > 0) {
|
if (new_size_in_words > 0) {
|
||||||
map = allocator.allocate(new_size_in_words);
|
map = derived->allocate(new_size_in_words);
|
||||||
|
|
||||||
if (old_map != NULL) {
|
if (old_map != NULL) {
|
||||||
Copy::disjoint_words((HeapWord*)old_map, (HeapWord*) map,
|
Copy::disjoint_words((HeapWord*)old_map, (HeapWord*) map,
|
||||||
@ -99,85 +64,45 @@ BitMap::bm_word_t* BitMap::reallocate(const Allocator& allocator, bm_word_t* old
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (old_map != NULL) {
|
if (old_map != NULL) {
|
||||||
allocator.free(old_map, old_size_in_words);
|
derived->free(old_map, old_size_in_words);
|
||||||
}
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Allocator>
|
ArenaBitMap::ArenaBitMap(Arena* arena, idx_t size_in_bits, bool clear)
|
||||||
bm_word_t* BitMap::allocate(const Allocator& allocator, idx_t size_in_bits, bool clear) {
|
: GrowableBitMap<ArenaBitMap>(), _arena(arena) {
|
||||||
// Reuse reallocate to ensure that the new memory is cleared.
|
initialize(size_in_bits, clear);
|
||||||
return reallocate(allocator, NULL, 0, size_in_bits, clear);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Allocator>
|
bm_word_t* ArenaBitMap::allocate(idx_t size_in_words) const {
|
||||||
void BitMap::free(const Allocator& allocator, bm_word_t* map, idx_t size_in_bits) {
|
return (bm_word_t*)_arena->Amalloc(size_in_words * BytesPerWord);
|
||||||
bm_word_t* ret = reallocate(allocator, map, size_in_bits, 0);
|
|
||||||
assert(ret == NULL, "Reallocate shouldn't have allocated");
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Allocator>
|
|
||||||
void BitMap::resize(const Allocator& allocator, idx_t new_size_in_bits, bool clear) {
|
|
||||||
bm_word_t* new_map = reallocate(allocator, map(), size(), new_size_in_bits, clear);
|
|
||||||
|
|
||||||
update(new_map, new_size_in_bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Allocator>
|
|
||||||
void BitMap::initialize(const Allocator& allocator, idx_t size_in_bits, bool clear) {
|
|
||||||
assert(map() == NULL, "precondition");
|
|
||||||
assert(size() == 0, "precondition");
|
|
||||||
|
|
||||||
resize(allocator, size_in_bits, clear);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Allocator>
|
|
||||||
void BitMap::reinitialize(const Allocator& allocator, idx_t new_size_in_bits, bool clear) {
|
|
||||||
// Remove previous bits - no need to clear
|
|
||||||
resize(allocator, 0, false /* clear */);
|
|
||||||
|
|
||||||
initialize(allocator, new_size_in_bits, clear);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceBitMap::ResourceBitMap(idx_t size_in_bits, bool clear)
|
ResourceBitMap::ResourceBitMap(idx_t size_in_bits, bool clear)
|
||||||
: BitMap(allocate(ResourceBitMapAllocator(), size_in_bits, clear), size_in_bits) {
|
: GrowableBitMap<ResourceBitMap>() {
|
||||||
|
initialize(size_in_bits, clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceBitMap::resize(idx_t new_size_in_bits) {
|
bm_word_t* ResourceBitMap::allocate(idx_t size_in_words) const {
|
||||||
BitMap::resize(ResourceBitMapAllocator(), new_size_in_bits, true /* clear */);
|
return (bm_word_t*)NEW_RESOURCE_ARRAY(bm_word_t, size_in_words);
|
||||||
}
|
|
||||||
|
|
||||||
void ResourceBitMap::initialize(idx_t size_in_bits) {
|
|
||||||
BitMap::initialize(ResourceBitMapAllocator(), size_in_bits, true /* clear */);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResourceBitMap::reinitialize(idx_t size_in_bits) {
|
|
||||||
BitMap::reinitialize(ResourceBitMapAllocator(), size_in_bits, true /* clear */);
|
|
||||||
}
|
|
||||||
|
|
||||||
ArenaBitMap::ArenaBitMap(Arena* arena, idx_t size_in_bits)
|
|
||||||
: BitMap(allocate(ArenaBitMapAllocator(arena), size_in_bits), size_in_bits) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CHeapBitMap::CHeapBitMap(idx_t size_in_bits, MEMFLAGS flags, bool clear)
|
CHeapBitMap::CHeapBitMap(idx_t size_in_bits, MEMFLAGS flags, bool clear)
|
||||||
: BitMap(allocate(CHeapBitMapAllocator(flags), size_in_bits, clear), size_in_bits), _flags(flags) {
|
: GrowableBitMap<CHeapBitMap>(), _flags(flags) {
|
||||||
|
initialize(size_in_bits, clear);
|
||||||
}
|
}
|
||||||
|
|
||||||
CHeapBitMap::~CHeapBitMap() {
|
CHeapBitMap::~CHeapBitMap() {
|
||||||
free(CHeapBitMapAllocator(_flags), map(), size());
|
free(map(), size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHeapBitMap::resize(idx_t new_size_in_bits, bool clear) {
|
bm_word_t* CHeapBitMap::allocate(idx_t size_in_words) const {
|
||||||
BitMap::resize(CHeapBitMapAllocator(_flags), new_size_in_bits, clear);
|
return ArrayAllocator<bm_word_t>::allocate(size_in_words, _flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHeapBitMap::initialize(idx_t size_in_bits, bool clear) {
|
void CHeapBitMap::free(bm_word_t* map, idx_t size_in_words) const {
|
||||||
BitMap::initialize(CHeapBitMapAllocator(_flags), size_in_bits, clear);
|
ArrayAllocator<bm_word_t>::free(map, size_in_words);
|
||||||
}
|
|
||||||
|
|
||||||
void CHeapBitMap::reinitialize(idx_t size_in_bits, bool clear) {
|
|
||||||
BitMap::reinitialize(CHeapBitMapAllocator(_flags), size_in_bits, clear);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
@ -706,3 +631,7 @@ void BitMap::print_on(outputStream* st) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template class GrowableBitMap<ArenaBitMap>;
|
||||||
|
template class GrowableBitMap<ResourceBitMap>;
|
||||||
|
template class GrowableBitMap<CHeapBitMap>;
|
||||||
|
@ -64,6 +64,7 @@ class BitMap {
|
|||||||
bm_word_t* _map; // First word in bitmap
|
bm_word_t* _map; // First word in bitmap
|
||||||
idx_t _size; // Size of bitmap (in bits)
|
idx_t _size; // Size of bitmap (in bits)
|
||||||
|
|
||||||
|
protected:
|
||||||
// The maximum allowable size of a bitmap, in words or bits.
|
// The maximum allowable size of a bitmap, in words or bits.
|
||||||
// Limit max_size_in_bits so aligning up to a word boundary never overflows.
|
// Limit max_size_in_bits so aligning up to a word boundary never overflows.
|
||||||
static idx_t max_size_in_words() { return raw_to_words_align_down(~idx_t(0)); }
|
static idx_t max_size_in_words() { return raw_to_words_align_down(~idx_t(0)); }
|
||||||
@ -110,7 +111,6 @@ class BitMap {
|
|||||||
|
|
||||||
static bool is_small_range_of_words(idx_t beg_full_word, idx_t end_full_word);
|
static bool is_small_range_of_words(idx_t beg_full_word, idx_t end_full_word);
|
||||||
|
|
||||||
protected:
|
|
||||||
// Return the position of bit within the word that contains it (e.g., if
|
// Return the position of bit within the word that contains it (e.g., if
|
||||||
// bitmap words are 32 bits, return a number 0 <= n <= 31).
|
// bitmap words are 32 bits, return a number 0 <= n <= 31).
|
||||||
static idx_t bit_in_word(idx_t bit) { return bit & (BitsPerWord - 1); }
|
static idx_t bit_in_word(idx_t bit) { return bit & (BitsPerWord - 1); }
|
||||||
@ -161,42 +161,6 @@ class BitMap {
|
|||||||
idx_t count_one_bits_within_word(idx_t beg, idx_t end) const;
|
idx_t count_one_bits_within_word(idx_t beg, idx_t end) const;
|
||||||
idx_t count_one_bits_in_range_of_words(idx_t beg_full_word, idx_t end_full_word) const;
|
idx_t count_one_bits_in_range_of_words(idx_t beg_full_word, idx_t end_full_word) const;
|
||||||
|
|
||||||
// Allocation Helpers.
|
|
||||||
|
|
||||||
// Allocates and clears the bitmap memory.
|
|
||||||
template <class Allocator>
|
|
||||||
static bm_word_t* allocate(const Allocator&, idx_t size_in_bits, bool clear = true);
|
|
||||||
|
|
||||||
// Reallocates and clears the new bitmap memory.
|
|
||||||
template <class Allocator>
|
|
||||||
static bm_word_t* reallocate(const Allocator&, bm_word_t* map, idx_t old_size_in_bits, idx_t new_size_in_bits, bool clear = true);
|
|
||||||
|
|
||||||
// Free the bitmap memory.
|
|
||||||
template <class Allocator>
|
|
||||||
static void free(const Allocator&, bm_word_t* map, idx_t size_in_bits);
|
|
||||||
|
|
||||||
// Protected functions, that are used by BitMap sub-classes that support them.
|
|
||||||
|
|
||||||
// Resize the backing bitmap memory.
|
|
||||||
//
|
|
||||||
// Old bits are transferred to the new memory
|
|
||||||
// and the extended memory is cleared.
|
|
||||||
template <class Allocator>
|
|
||||||
void resize(const Allocator& allocator, idx_t new_size_in_bits, bool clear);
|
|
||||||
|
|
||||||
// Set up and clear the bitmap memory.
|
|
||||||
//
|
|
||||||
// Precondition: The bitmap was default constructed and has
|
|
||||||
// not yet had memory allocated via resize or (re)initialize.
|
|
||||||
template <class Allocator>
|
|
||||||
void initialize(const Allocator& allocator, idx_t size_in_bits, bool clear);
|
|
||||||
|
|
||||||
// Set up and clear the bitmap memory.
|
|
||||||
//
|
|
||||||
// Can be called on previously initialized bitmaps.
|
|
||||||
template <class Allocator>
|
|
||||||
void reinitialize(const Allocator& allocator, idx_t new_size_in_bits, bool clear);
|
|
||||||
|
|
||||||
// Set the map and size.
|
// Set the map and size.
|
||||||
void update(bm_word_t* map, idx_t size) {
|
void update(bm_word_t* map, idx_t size) {
|
||||||
_map = map;
|
_map = map;
|
||||||
@ -354,84 +318,108 @@ class BitMap {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// A concrete implementation of the "abstract" BitMap class.
|
// CRTP: BitmapWithAllocator exposes the following Allocator interfaces upward to GrowableBitMap.
|
||||||
//
|
//
|
||||||
// The BitMapView is used when the backing storage is managed externally.
|
// bm_word_t* allocate(idx_t size_in_words) const;
|
||||||
class BitMapView : public BitMap {
|
// void free(bm_word_t* map, idx_t size_in_words) const
|
||||||
public:
|
//
|
||||||
BitMapView() : BitMap(NULL, 0) {}
|
template <class BitMapWithAllocator>
|
||||||
BitMapView(bm_word_t* map, idx_t size_in_bits) : BitMap(map, size_in_bits) {}
|
class GrowableBitMap : public BitMap {
|
||||||
};
|
protected:
|
||||||
|
bm_word_t* reallocate(bm_word_t* map, idx_t old_size_in_bits, idx_t new_size_in_bits, bool clear);
|
||||||
|
|
||||||
// A BitMap with storage in a ResourceArea.
|
GrowableBitMap() : GrowableBitMap(nullptr, 0) {}
|
||||||
class ResourceBitMap : public BitMap {
|
GrowableBitMap(bm_word_t* map, idx_t size_in_bits) : BitMap(map, size_in_bits) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ResourceBitMap() : BitMap(NULL, 0) {}
|
// Set up and clear the bitmap memory.
|
||||||
// Conditionally clears the bitmap memory.
|
//
|
||||||
ResourceBitMap(idx_t size_in_bits, bool clear = true);
|
// Precondition: The bitmap was default constructed and has
|
||||||
|
// not yet had memory allocated via resize or (re)initialize.
|
||||||
|
void initialize(idx_t size_in_bits, bool clear = true) {
|
||||||
|
assert(map() == NULL, "precondition");
|
||||||
|
assert(size() == 0, "precondition");
|
||||||
|
|
||||||
|
resize(size_in_bits, clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up and clear the bitmap memory.
|
||||||
|
//
|
||||||
|
// Can be called on previously initialized bitmaps.
|
||||||
|
void reinitialize(idx_t new_size_in_bits, bool clear = true) {
|
||||||
|
// Remove previous bits - no need to clear
|
||||||
|
resize(0, false /* clear */);
|
||||||
|
|
||||||
|
initialize(new_size_in_bits, clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Protected functions, that are used by BitMap sub-classes that support them.
|
||||||
|
|
||||||
// Resize the backing bitmap memory.
|
// Resize the backing bitmap memory.
|
||||||
//
|
//
|
||||||
// Old bits are transferred to the new memory
|
// Old bits are transferred to the new memory
|
||||||
// and the extended memory is cleared.
|
// and the extended memory is cleared.
|
||||||
void resize(idx_t new_size_in_bits);
|
void resize(idx_t new_size_in_bits, bool clear = true) {
|
||||||
|
bm_word_t* new_map = reallocate(map(), size(), new_size_in_bits, clear);
|
||||||
|
update(new_map, new_size_in_bits);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Set up and clear the bitmap memory.
|
// A concrete implementation of the "abstract" BitMap class.
|
||||||
//
|
//
|
||||||
// Precondition: The bitmap was default constructed and has
|
// The BitMapView is used when the backing storage is managed externally.
|
||||||
// not yet had memory allocated via resize or initialize.
|
class BitMapView : public BitMap {
|
||||||
void initialize(idx_t size_in_bits);
|
public:
|
||||||
|
BitMapView() : BitMapView(nullptr, 0) {}
|
||||||
// Set up and clear the bitmap memory.
|
BitMapView(bm_word_t* map, idx_t size_in_bits) : BitMap(map, size_in_bits) {}
|
||||||
//
|
|
||||||
// Can be called on previously initialized bitmaps.
|
|
||||||
void reinitialize(idx_t size_in_bits);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// A BitMap with storage in a specific Arena.
|
// A BitMap with storage in a specific Arena.
|
||||||
class ArenaBitMap : public BitMap {
|
class ArenaBitMap : public GrowableBitMap<ArenaBitMap> {
|
||||||
|
Arena* const _arena;
|
||||||
|
|
||||||
|
NONCOPYABLE(ArenaBitMap);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Clears the bitmap memory.
|
// Clears the bitmap memory.
|
||||||
ArenaBitMap(Arena* arena, idx_t size_in_bits);
|
ArenaBitMap(Arena* arena, idx_t size_in_bits, bool clear = true);
|
||||||
|
|
||||||
private:
|
bm_word_t* allocate(idx_t size_in_words) const;
|
||||||
NONCOPYABLE(ArenaBitMap);
|
void free(bm_word_t* map, idx_t size_in_words) const {
|
||||||
|
// ArenaBitMaps currently don't free memory.
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// A BitMap with storage in the current threads resource area.
|
||||||
|
class ResourceBitMap : public GrowableBitMap<ResourceBitMap> {
|
||||||
|
public:
|
||||||
|
ResourceBitMap() : ResourceBitMap(0) {}
|
||||||
|
ResourceBitMap(idx_t size_in_bits, bool clear = true);
|
||||||
|
|
||||||
|
bm_word_t* allocate(idx_t size_in_words) const;
|
||||||
|
void free(bm_word_t* map, idx_t size_in_words) const {
|
||||||
|
// ArenaBitMaps currently don't free memory.
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// A BitMap with storage in the CHeap.
|
// A BitMap with storage in the CHeap.
|
||||||
class CHeapBitMap : public BitMap {
|
class CHeapBitMap : public GrowableBitMap<CHeapBitMap> {
|
||||||
|
// NMT memory type
|
||||||
|
const MEMFLAGS _flags;
|
||||||
|
|
||||||
private:
|
|
||||||
// Don't allow copy or assignment, to prevent the
|
// Don't allow copy or assignment, to prevent the
|
||||||
// allocated memory from leaking out to other instances.
|
// allocated memory from leaking out to other instances.
|
||||||
NONCOPYABLE(CHeapBitMap);
|
NONCOPYABLE(CHeapBitMap);
|
||||||
|
|
||||||
// NMT memory type
|
|
||||||
MEMFLAGS _flags;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CHeapBitMap(MEMFLAGS flags = mtInternal) : BitMap(NULL, 0), _flags(flags) {}
|
CHeapBitMap() : CHeapBitMap(mtInternal) {}
|
||||||
|
explicit CHeapBitMap(MEMFLAGS flags) : GrowableBitMap(0, false), _flags(flags) {}
|
||||||
// Clears the bitmap memory.
|
// Clears the bitmap memory.
|
||||||
CHeapBitMap(idx_t size_in_bits, MEMFLAGS flags = mtInternal, bool clear = true);
|
CHeapBitMap(idx_t size_in_bits, MEMFLAGS flags = mtInternal, bool clear = true);
|
||||||
~CHeapBitMap();
|
~CHeapBitMap();
|
||||||
|
|
||||||
// Resize the backing bitmap memory.
|
bm_word_t* allocate(idx_t size_in_words) const;
|
||||||
//
|
void free(bm_word_t* map, idx_t size_in_words) const;
|
||||||
// Old bits are transferred to the new memory
|
|
||||||
// and the extended memory is (optionally) cleared.
|
|
||||||
void resize(idx_t new_size_in_bits, bool clear = true);
|
|
||||||
|
|
||||||
// Set up and (optionally) clear the bitmap memory.
|
|
||||||
//
|
|
||||||
// Precondition: The bitmap was default constructed and has
|
|
||||||
// not yet had memory allocated via resize or initialize.
|
|
||||||
void initialize(idx_t size_in_bits, bool clear = true);
|
|
||||||
|
|
||||||
// Set up and (optionally) clear the bitmap memory.
|
|
||||||
//
|
|
||||||
// Can be called on previously initialized bitmaps.
|
|
||||||
void reinitialize(idx_t size_in_bits, bool clear = true);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Convenience class wrapping BitMap which provides multiple bits per slot.
|
// Convenience class wrapping BitMap which provides multiple bits per slot.
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
#include "logging/logStream.hpp"
|
#include "logging/logStream.hpp"
|
||||||
|
#include "memory/arena.hpp"
|
||||||
#include "memory/resourceArea.hpp"
|
#include "memory/resourceArea.hpp"
|
||||||
#include "utilities/bitMap.inline.hpp"
|
#include "utilities/bitMap.inline.hpp"
|
||||||
#include "unittest.hpp"
|
#include "unittest.hpp"
|
||||||
@ -83,25 +84,25 @@ class BitMapTest {
|
|||||||
EXPECT_TRUE(map.is_same(map2));
|
EXPECT_TRUE(map.is_same(map2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class ReinitializableBitMapClass>
|
||||||
static void testReinitialize(BitMap::idx_t init_size) {
|
static void testReinitialize(BitMap::idx_t init_size) {
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
|
|
||||||
ResourceBitMap map(init_size);
|
ReinitializableBitMapClass map(init_size);
|
||||||
map.reinitialize(BITMAP_SIZE);
|
map.reinitialize(BITMAP_SIZE);
|
||||||
fillBitMap(map);
|
fillBitMap(map);
|
||||||
|
|
||||||
ResourceBitMap map2(BITMAP_SIZE);
|
ReinitializableBitMapClass map2(BITMAP_SIZE);
|
||||||
fillBitMap(map2);
|
fillBitMap(map2);
|
||||||
EXPECT_TRUE(map.is_same(map2)) << "With init_size " << init_size;
|
EXPECT_TRUE(map.is_same(map2)) << "With init_size " << init_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
|
template <class PrintableBitMapClass>
|
||||||
static void testPrintOn(BitMap::idx_t size) {
|
static void testPrintOn(BitMap::idx_t size) {
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
|
|
||||||
ResourceBitMap map(size);
|
PrintableBitMapClass map(size);
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
map.set_bit(size / 2);
|
map.set_bit(size / 2);
|
||||||
}
|
}
|
||||||
@ -113,9 +114,19 @@ class BitMapTest {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TestArenaBitMap is the shorthand combination of Arena and ArenaBitMap.
|
||||||
|
// Multiple inheritance guarantees to construct Arena first.
|
||||||
|
class TestArenaBitMap : private Arena, public ArenaBitMap {
|
||||||
|
public:
|
||||||
|
TestArenaBitMap() : TestArenaBitMap(0) {}
|
||||||
|
TestArenaBitMap(idx_t size_in_bits, bool clear = true) : Arena(mtTest),
|
||||||
|
ArenaBitMap(static_cast<Arena*>(this), size_in_bits, clear) {}
|
||||||
|
};
|
||||||
|
|
||||||
class TestCHeapBitMap : public CHeapBitMap {
|
class TestCHeapBitMap : public CHeapBitMap {
|
||||||
public:
|
public:
|
||||||
TestCHeapBitMap(size_t size = 0) : CHeapBitMap(size, mtTest) {}
|
TestCHeapBitMap(size_t size = 0) : CHeapBitMap(size, mtTest) {}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_VM(BitMap, resize_grow) {
|
TEST_VM(BitMap, resize_grow) {
|
||||||
@ -123,6 +134,8 @@ TEST_VM(BitMap, resize_grow) {
|
|||||||
EXPECT_FALSE(HasFailure()) << "Failed on type ResourceBitMap";
|
EXPECT_FALSE(HasFailure()) << "Failed on type ResourceBitMap";
|
||||||
BitMapTest::testResizeGrow<TestCHeapBitMap>();
|
BitMapTest::testResizeGrow<TestCHeapBitMap>();
|
||||||
EXPECT_FALSE(HasFailure()) << "Failed on type CHeapBitMap";
|
EXPECT_FALSE(HasFailure()) << "Failed on type CHeapBitMap";
|
||||||
|
BitMapTest::testResizeGrow<TestArenaBitMap>();
|
||||||
|
EXPECT_FALSE(HasFailure()) << "Failed on type ArenaBitMap";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_VM(BitMap, resize_shrink) {
|
TEST_VM(BitMap, resize_shrink) {
|
||||||
@ -130,6 +143,8 @@ TEST_VM(BitMap, resize_shrink) {
|
|||||||
EXPECT_FALSE(HasFailure()) << "Failed on type ResourceBitMap";
|
EXPECT_FALSE(HasFailure()) << "Failed on type ResourceBitMap";
|
||||||
BitMapTest::testResizeShrink<TestCHeapBitMap>();
|
BitMapTest::testResizeShrink<TestCHeapBitMap>();
|
||||||
EXPECT_FALSE(HasFailure()) << "Failed on type CHeapBitMap";
|
EXPECT_FALSE(HasFailure()) << "Failed on type CHeapBitMap";
|
||||||
|
BitMapTest::testResizeShrink<TestArenaBitMap>();
|
||||||
|
EXPECT_FALSE(HasFailure()) << "Failed on type ArenaBitMap";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_VM(BitMap, resize_same) {
|
TEST_VM(BitMap, resize_same) {
|
||||||
@ -137,6 +152,8 @@ TEST_VM(BitMap, resize_same) {
|
|||||||
EXPECT_FALSE(HasFailure()) << "Failed on type ResourceBitMap";
|
EXPECT_FALSE(HasFailure()) << "Failed on type ResourceBitMap";
|
||||||
BitMapTest::testResizeSame<TestCHeapBitMap>();
|
BitMapTest::testResizeSame<TestCHeapBitMap>();
|
||||||
EXPECT_FALSE(HasFailure()) << "Failed on type CHeapBitMap";
|
EXPECT_FALSE(HasFailure()) << "Failed on type CHeapBitMap";
|
||||||
|
BitMapTest::testResizeSame<TestArenaBitMap>();
|
||||||
|
EXPECT_FALSE(HasFailure()) << "Failed on type ArenaBitMap";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that when growing with clear, all added bits get cleared,
|
// Verify that when growing with clear, all added bits get cleared,
|
||||||
@ -162,20 +179,28 @@ TEST_VM(BitMap, initialize) {
|
|||||||
EXPECT_FALSE(HasFailure()) << "Failed on type ResourceBitMap";
|
EXPECT_FALSE(HasFailure()) << "Failed on type ResourceBitMap";
|
||||||
BitMapTest::testInitialize<TestCHeapBitMap>();
|
BitMapTest::testInitialize<TestCHeapBitMap>();
|
||||||
EXPECT_FALSE(HasFailure()) << "Failed on type CHeapBitMap";
|
EXPECT_FALSE(HasFailure()) << "Failed on type CHeapBitMap";
|
||||||
|
BitMapTest::testInitialize<TestArenaBitMap>();
|
||||||
|
EXPECT_FALSE(HasFailure()) << "Failed on type ArenaBitMap";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_VM(BitMap, reinitialize) {
|
TEST_VM(BitMap, reinitialize) {
|
||||||
BitMapTest::testReinitialize(0);
|
constexpr BitMap::idx_t sizes[] = {0, BitMapTest::BITMAP_SIZE >> 3, BitMapTest::BITMAP_SIZE};
|
||||||
BitMapTest::testReinitialize(BitMapTest::BITMAP_SIZE >> 3);
|
|
||||||
BitMapTest::testReinitialize(BitMapTest::BITMAP_SIZE);
|
for (auto size : sizes) {
|
||||||
|
BitMapTest::testReinitialize<ResourceBitMap>(size);
|
||||||
|
BitMapTest::testReinitialize<TestArenaBitMap>(size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
|
|
||||||
TEST_VM(BitMap, print_on) {
|
TEST_VM(BitMap, print_on) {
|
||||||
BitMapTest::testPrintOn(0);
|
constexpr BitMap::idx_t sizes[] = {0, BitMapTest::BITMAP_SIZE >> 3, BitMapTest::BITMAP_SIZE};
|
||||||
BitMapTest::testPrintOn(BitMapTest::BITMAP_SIZE >> 3);
|
|
||||||
BitMapTest::testPrintOn(BitMapTest::BITMAP_SIZE);
|
for (auto size : sizes) {
|
||||||
|
BitMapTest::testPrintOn<ResourceBitMap>(size);
|
||||||
|
BitMapTest::testPrintOn<TestArenaBitMap>(size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user