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

Tue, 12 Feb 2019 11:58:44 +0100

author
shade
date
Tue, 12 Feb 2019 11:58:44 +0100
changeset 9616
faa71d8b8ab5
parent 9615
c5e1abd2d0af
child 9617
6384d7f8a123

8211926: Catastrophic size_t underflow in BitMap::*_large methods
Reviewed-by: kbarrett, stuefe

src/share/vm/utilities/bitMap.cpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/bitMap.hpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/bitMap.inline.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/utilities/bitMap.cpp	Mon Feb 11 17:00:04 2019 +0100
     1.2 +++ b/src/share/vm/utilities/bitMap.cpp	Tue Feb 12 11:58:44 2019 +0100
     1.3 @@ -154,14 +154,24 @@
     1.4    }
     1.5  }
     1.6  
     1.7 +bool BitMap::is_small_range_of_words(idx_t beg_full_word, idx_t end_full_word) {
     1.8 +  // There is little point to call large version on small ranges.
     1.9 +  // Need to check carefully, keeping potential idx_t underflow in mind.
    1.10 +  // The threshold should be at least one word.
    1.11 +  STATIC_ASSERT(small_range_words >= 1);
    1.12 +  return (beg_full_word + small_range_words >= end_full_word);
    1.13 +}
    1.14 +
    1.15  void BitMap::set_large_range(idx_t beg, idx_t end) {
    1.16    verify_range(beg, end);
    1.17  
    1.18    idx_t beg_full_word = word_index_round_up(beg);
    1.19    idx_t end_full_word = word_index(end);
    1.20  
    1.21 -  assert(end_full_word - beg_full_word >= 32,
    1.22 -         "the range must include at least 32 bytes");
    1.23 +  if (is_small_range_of_words(beg_full_word, end_full_word)) {
    1.24 +    set_range(beg, end);
    1.25 +    return;
    1.26 +  }
    1.27  
    1.28    // The range includes at least one full word.
    1.29    set_range_within_word(beg, bit_index(beg_full_word));
    1.30 @@ -175,8 +185,10 @@
    1.31    idx_t beg_full_word = word_index_round_up(beg);
    1.32    idx_t end_full_word = word_index(end);
    1.33  
    1.34 -  assert(end_full_word - beg_full_word >= 32,
    1.35 -         "the range must include at least 32 bytes");
    1.36 +  if (is_small_range_of_words(beg_full_word, end_full_word)) {
    1.37 +    clear_range(beg, end);
    1.38 +    return;
    1.39 +  }
    1.40  
    1.41    // The range includes at least one full word.
    1.42    clear_range_within_word(beg, bit_index(beg_full_word));
    1.43 @@ -264,8 +276,10 @@
    1.44    idx_t beg_full_word = word_index_round_up(beg);
    1.45    idx_t end_full_word = word_index(end);
    1.46  
    1.47 -  assert(end_full_word - beg_full_word >= 32,
    1.48 -         "the range must include at least 32 bytes");
    1.49 +  if (is_small_range_of_words(beg_full_word, end_full_word)) {
    1.50 +    par_at_put_range(beg, end, value);
    1.51 +    return;
    1.52 +  }
    1.53  
    1.54    // The range includes at least one full word.
    1.55    par_put_range_within_word(beg, bit_index(beg_full_word), value);
     2.1 --- a/src/share/vm/utilities/bitMap.hpp	Mon Feb 11 17:00:04 2019 +0100
     2.2 +++ b/src/share/vm/utilities/bitMap.hpp	Tue Feb 12 11:58:44 2019 +0100
     2.3 @@ -56,6 +56,10 @@
     2.4    // the bitmap appropriately if needed using factor-of-two expansion.
     2.5    void at_put_grow(idx_t index, bool value);
     2.6  
     2.7 +  // Threshold for performing small range operation, even when large range
     2.8 +  // operation was requested. Measured in words.
     2.9 +  static const size_t small_range_words = 32;
    2.10 +
    2.11   protected:
    2.12    // Return the position of bit within the word that contains it (e.g., if
    2.13    // bitmap words are 32 bits, return a number 0 <= n <= 31).
    2.14 @@ -97,6 +101,8 @@
    2.15    void      set_large_range_of_words   (idx_t beg, idx_t end);
    2.16    void      clear_large_range_of_words (idx_t beg, idx_t end);
    2.17  
    2.18 +  static bool is_small_range_of_words(idx_t beg_full_word, idx_t end_full_word);
    2.19 +
    2.20    // The index of the first full word in a range.
    2.21    idx_t word_index_round_up(idx_t bit) const;
    2.22  
     3.1 --- a/src/share/vm/utilities/bitMap.inline.hpp	Mon Feb 11 17:00:04 2019 +0100
     3.2 +++ b/src/share/vm/utilities/bitMap.inline.hpp	Tue Feb 12 11:58:44 2019 +0100
     3.3 @@ -321,10 +321,12 @@
     3.4  }
     3.5  
     3.6  inline void BitMap::set_large_range_of_words(idx_t beg, idx_t end) {
     3.7 +  assert(beg <= end, "underflow");
     3.8    memset(_map + beg, ~(unsigned char)0, (end - beg) * sizeof(uintptr_t));
     3.9  }
    3.10  
    3.11  inline void BitMap::clear_large_range_of_words(idx_t beg, idx_t end) {
    3.12 +  assert(beg <= end, "underflow");
    3.13    memset(_map + beg, 0, (end - beg) * sizeof(uintptr_t));
    3.14  }
    3.15  

mercurial