< prev index next >

src/hotspot/share/utilities/bitMap.cpp

Print this page




 200 
 201 void BitMap::clear_range_within_word(idx_t beg, idx_t end) {
 202   // With a valid range (beg <= end), this test ensures that end != 0, as
 203   // required by inverted_bit_mask_for_range.  Also avoids an unnecessary write.
 204   if (beg != end) {
 205     bm_word_t mask = inverted_bit_mask_for_range(beg, end);
 206     *word_addr(beg) &= mask;
 207   }
 208 }
 209 
 210 void BitMap::par_put_range_within_word(idx_t beg, idx_t end, bool value) {
 211   assert(value == 0 || value == 1, "0 for clear, 1 for set");
 212   // With a valid range (beg <= end), this test ensures that end != 0, as
 213   // required by inverted_bit_mask_for_range.  Also avoids an unnecessary write.
 214   if (beg != end) {
 215     bm_word_t* pw = word_addr(beg);
 216     bm_word_t  w  = *pw;
 217     bm_word_t  mr = inverted_bit_mask_for_range(beg, end);
 218     bm_word_t  nw = value ? (w | ~mr) : (w & mr);
 219     while (true) {
 220       bm_word_t res = Atomic::cmpxchg(nw, pw, w);
 221       if (res == w) break;
 222       w  = res;
 223       nw = value ? (w | ~mr) : (w & mr);
 224     }
 225   }
 226 }
 227 
 228 void BitMap::set_range(idx_t beg, idx_t end) {
 229   verify_range(beg, end);
 230 
 231   idx_t beg_full_word = word_index_round_up(beg);
 232   idx_t end_full_word = word_index(end);
 233 
 234   if (beg_full_word < end_full_word) {
 235     // The range includes at least one full word.
 236     set_range_within_word(beg, bit_index(beg_full_word));
 237     set_range_of_words(beg_full_word, end_full_word);
 238     set_range_within_word(bit_index(end_full_word), end);
 239   } else {
 240     // The range spans at most 2 partial words.


 623         if (!blk->do_bit(offset)) return false;
 624         //  resample at each closure application
 625         // (see, for instance, CMS bug 4525989)
 626         rest = map(index) >> (offset & (BitsPerWord -1));
 627       }
 628       rest = rest >> 1;
 629     }
 630   }
 631   return true;
 632 }
 633 
 634 const BitMap::idx_t* BitMap::_pop_count_table = NULL;
 635 
 636 void BitMap::init_pop_count_table() {
 637   if (_pop_count_table == NULL) {
 638     BitMap::idx_t *table = NEW_C_HEAP_ARRAY(idx_t, 256, mtInternal);
 639     for (uint i = 0; i < 256; i++) {
 640       table[i] = num_set_bits(i);
 641     }
 642 
 643     if (!Atomic::replace_if_null(table, &_pop_count_table)) {
 644       guarantee(_pop_count_table != NULL, "invariant");
 645       FREE_C_HEAP_ARRAY(idx_t, table);
 646     }
 647   }
 648 }
 649 
 650 BitMap::idx_t BitMap::num_set_bits(bm_word_t w) {
 651   idx_t bits = 0;
 652 
 653   while (w != 0) {
 654     while ((w & 1) == 0) {
 655       w >>= 1;
 656     }
 657     bits++;
 658     w >>= 1;
 659   }
 660   return bits;
 661 }
 662 
 663 BitMap::idx_t BitMap::num_set_bits_from_table(unsigned char c) {




 200 
 201 void BitMap::clear_range_within_word(idx_t beg, idx_t end) {
 202   // With a valid range (beg <= end), this test ensures that end != 0, as
 203   // required by inverted_bit_mask_for_range.  Also avoids an unnecessary write.
 204   if (beg != end) {
 205     bm_word_t mask = inverted_bit_mask_for_range(beg, end);
 206     *word_addr(beg) &= mask;
 207   }
 208 }
 209 
 210 void BitMap::par_put_range_within_word(idx_t beg, idx_t end, bool value) {
 211   assert(value == 0 || value == 1, "0 for clear, 1 for set");
 212   // With a valid range (beg <= end), this test ensures that end != 0, as
 213   // required by inverted_bit_mask_for_range.  Also avoids an unnecessary write.
 214   if (beg != end) {
 215     bm_word_t* pw = word_addr(beg);
 216     bm_word_t  w  = *pw;
 217     bm_word_t  mr = inverted_bit_mask_for_range(beg, end);
 218     bm_word_t  nw = value ? (w | ~mr) : (w & mr);
 219     while (true) {
 220       bm_word_t res = Atomic::cmpxchg(pw, w, nw);
 221       if (res == w) break;
 222       w  = res;
 223       nw = value ? (w | ~mr) : (w & mr);
 224     }
 225   }
 226 }
 227 
 228 void BitMap::set_range(idx_t beg, idx_t end) {
 229   verify_range(beg, end);
 230 
 231   idx_t beg_full_word = word_index_round_up(beg);
 232   idx_t end_full_word = word_index(end);
 233 
 234   if (beg_full_word < end_full_word) {
 235     // The range includes at least one full word.
 236     set_range_within_word(beg, bit_index(beg_full_word));
 237     set_range_of_words(beg_full_word, end_full_word);
 238     set_range_within_word(bit_index(end_full_word), end);
 239   } else {
 240     // The range spans at most 2 partial words.


 623         if (!blk->do_bit(offset)) return false;
 624         //  resample at each closure application
 625         // (see, for instance, CMS bug 4525989)
 626         rest = map(index) >> (offset & (BitsPerWord -1));
 627       }
 628       rest = rest >> 1;
 629     }
 630   }
 631   return true;
 632 }
 633 
 634 const BitMap::idx_t* BitMap::_pop_count_table = NULL;
 635 
 636 void BitMap::init_pop_count_table() {
 637   if (_pop_count_table == NULL) {
 638     BitMap::idx_t *table = NEW_C_HEAP_ARRAY(idx_t, 256, mtInternal);
 639     for (uint i = 0; i < 256; i++) {
 640       table[i] = num_set_bits(i);
 641     }
 642 
 643     if (!Atomic::replace_if_null(&_pop_count_table, table)) {
 644       guarantee(_pop_count_table != NULL, "invariant");
 645       FREE_C_HEAP_ARRAY(idx_t, table);
 646     }
 647   }
 648 }
 649 
 650 BitMap::idx_t BitMap::num_set_bits(bm_word_t w) {
 651   idx_t bits = 0;
 652 
 653   while (w != 0) {
 654     while ((w & 1) == 0) {
 655       w >>= 1;
 656     }
 657     bits++;
 658     w >>= 1;
 659   }
 660   return bits;
 661 }
 662 
 663 BitMap::idx_t BitMap::num_set_bits_from_table(unsigned char c) {


< prev index next >