提交 0d19cf96 编写于 作者: S shade

8211926: Catastrophic size_t underflow in BitMap::*_large methods

Reviewed-by: kbarrett, stuefe
上级 4012d550
......@@ -154,14 +154,24 @@ void BitMap::clear_range(idx_t beg, idx_t end) {
}
}
bool BitMap::is_small_range_of_words(idx_t beg_full_word, idx_t end_full_word) {
// There is little point to call large version on small ranges.
// Need to check carefully, keeping potential idx_t underflow in mind.
// The threshold should be at least one word.
STATIC_ASSERT(small_range_words >= 1);
return (beg_full_word + small_range_words >= end_full_word);
}
void BitMap::set_large_range(idx_t beg, idx_t end) {
verify_range(beg, end);
idx_t beg_full_word = word_index_round_up(beg);
idx_t end_full_word = word_index(end);
assert(end_full_word - beg_full_word >= 32,
"the range must include at least 32 bytes");
if (is_small_range_of_words(beg_full_word, end_full_word)) {
set_range(beg, end);
return;
}
// The range includes at least one full word.
set_range_within_word(beg, bit_index(beg_full_word));
......@@ -175,8 +185,10 @@ void BitMap::clear_large_range(idx_t beg, idx_t end) {
idx_t beg_full_word = word_index_round_up(beg);
idx_t end_full_word = word_index(end);
assert(end_full_word - beg_full_word >= 32,
"the range must include at least 32 bytes");
if (is_small_range_of_words(beg_full_word, end_full_word)) {
clear_range(beg, end);
return;
}
// The range includes at least one full word.
clear_range_within_word(beg, bit_index(beg_full_word));
......@@ -264,8 +276,10 @@ void BitMap::par_at_put_large_range(idx_t beg, idx_t end, bool value) {
idx_t beg_full_word = word_index_round_up(beg);
idx_t end_full_word = word_index(end);
assert(end_full_word - beg_full_word >= 32,
"the range must include at least 32 bytes");
if (is_small_range_of_words(beg_full_word, end_full_word)) {
par_at_put_range(beg, end, value);
return;
}
// The range includes at least one full word.
par_put_range_within_word(beg, bit_index(beg_full_word), value);
......
......@@ -56,6 +56,10 @@ class BitMap VALUE_OBJ_CLASS_SPEC {
// the bitmap appropriately if needed using factor-of-two expansion.
void at_put_grow(idx_t index, bool value);
// Threshold for performing small range operation, even when large range
// operation was requested. Measured in words.
static const size_t small_range_words = 32;
protected:
// 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).
......@@ -97,6 +101,8 @@ class BitMap VALUE_OBJ_CLASS_SPEC {
void set_large_range_of_words (idx_t beg, idx_t end);
void clear_large_range_of_words (idx_t beg, idx_t end);
static bool is_small_range_of_words(idx_t beg_full_word, idx_t end_full_word);
// The index of the first full word in a range.
idx_t word_index_round_up(idx_t bit) const;
......
......@@ -321,10 +321,12 @@ BitMap::inverted_bit_mask_for_range(idx_t beg, idx_t end) const {
}
inline void BitMap::set_large_range_of_words(idx_t beg, idx_t end) {
assert(beg <= end, "underflow");
memset(_map + beg, ~(unsigned char)0, (end - beg) * sizeof(uintptr_t));
}
inline void BitMap::clear_large_range_of_words(idx_t beg, idx_t end) {
assert(beg <= end, "underflow");
memset(_map + beg, 0, (end - beg) * sizeof(uintptr_t));
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册