提交 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) { ...@@ -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) { void BitMap::set_large_range(idx_t beg, idx_t end) {
verify_range(beg, end); verify_range(beg, end);
idx_t beg_full_word = word_index_round_up(beg); idx_t beg_full_word = word_index_round_up(beg);
idx_t end_full_word = word_index(end); idx_t end_full_word = word_index(end);
assert(end_full_word - beg_full_word >= 32, if (is_small_range_of_words(beg_full_word, end_full_word)) {
"the range must include at least 32 bytes"); set_range(beg, end);
return;
}
// The range includes at least one full word. // The range includes at least one full word.
set_range_within_word(beg, bit_index(beg_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) { ...@@ -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 beg_full_word = word_index_round_up(beg);
idx_t end_full_word = word_index(end); idx_t end_full_word = word_index(end);
assert(end_full_word - beg_full_word >= 32, if (is_small_range_of_words(beg_full_word, end_full_word)) {
"the range must include at least 32 bytes"); clear_range(beg, end);
return;
}
// The range includes at least one full word. // The range includes at least one full word.
clear_range_within_word(beg, bit_index(beg_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) { ...@@ -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 beg_full_word = word_index_round_up(beg);
idx_t end_full_word = word_index(end); idx_t end_full_word = word_index(end);
assert(end_full_word - beg_full_word >= 32, if (is_small_range_of_words(beg_full_word, end_full_word)) {
"the range must include at least 32 bytes"); par_at_put_range(beg, end, value);
return;
}
// The range includes at least one full word. // The range includes at least one full word.
par_put_range_within_word(beg, bit_index(beg_full_word), value); par_put_range_within_word(beg, bit_index(beg_full_word), value);
......
...@@ -56,6 +56,10 @@ class BitMap VALUE_OBJ_CLASS_SPEC { ...@@ -56,6 +56,10 @@ class BitMap VALUE_OBJ_CLASS_SPEC {
// the bitmap appropriately if needed using factor-of-two expansion. // the bitmap appropriately if needed using factor-of-two expansion.
void at_put_grow(idx_t index, bool value); 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: 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).
...@@ -97,6 +101,8 @@ class BitMap VALUE_OBJ_CLASS_SPEC { ...@@ -97,6 +101,8 @@ class BitMap VALUE_OBJ_CLASS_SPEC {
void set_large_range_of_words (idx_t beg, idx_t end); void set_large_range_of_words (idx_t beg, idx_t end);
void clear_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. // The index of the first full word in a range.
idx_t word_index_round_up(idx_t bit) const; 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 { ...@@ -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) { 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)); 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) { 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)); 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.
先完成此消息的编辑!
想要评论请 注册