bitMap.cpp revision 6683:08a2164660fb
1153838Sdfr/*
2153838Sdfr * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
3153838Sdfr * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4153838Sdfr *
5153838Sdfr * This code is free software; you can redistribute it and/or modify it
6153838Sdfr * under the terms of the GNU General Public License version 2 only, as
7153838Sdfr * published by the Free Software Foundation.
8153838Sdfr *
9153838Sdfr * This code is distributed in the hope that it will be useful, but WITHOUT
10153838Sdfr * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11153838Sdfr * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12153838Sdfr * version 2 for more details (a copy is included in the LICENSE file that
13153838Sdfr * accompanied this code).
14153838Sdfr *
15153838Sdfr * You should have received a copy of the GNU General Public License version
16153838Sdfr * 2 along with this work; if not, write to the Free Software Foundation,
17153838Sdfr * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18153838Sdfr *
19153838Sdfr * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20153838Sdfr * or visit www.oracle.com if you need additional information or have any
21153838Sdfr * questions.
22153838Sdfr *
23153838Sdfr */
24153838Sdfr
25153838Sdfr#include "precompiled.hpp"
26153838Sdfr#include "memory/allocation.inline.hpp"
27153838Sdfr#include "memory/resourceArea.hpp"
28153838Sdfr#include "runtime/atomic.inline.hpp"
29153838Sdfr#include "utilities/bitMap.inline.hpp"
30153838Sdfr#include "utilities/copy.hpp"
31153838Sdfr
32153838SdfrBitMap::BitMap(bm_word_t* map, idx_t size_in_bits) :
33153838Sdfr  _map(map), _size(size_in_bits), _map_allocator(false)
34153838Sdfr{
35153838Sdfr  assert(sizeof(bm_word_t) == BytesPerWord, "Implementation assumption.");
36153838Sdfr  assert(size_in_bits >= 0, "just checking");
37153838Sdfr}
38153838Sdfr
39153838Sdfr
40153838SdfrBitMap::BitMap(idx_t size_in_bits, bool in_resource_area) :
41153838Sdfr  _map(NULL), _size(0), _map_allocator(false)
42153838Sdfr{
43153838Sdfr  assert(sizeof(bm_word_t) == BytesPerWord, "Implementation assumption.");
44153838Sdfr  resize(size_in_bits, in_resource_area);
45153838Sdfr}
46153838Sdfr
47153838Sdfrvoid BitMap::resize(idx_t size_in_bits, bool in_resource_area) {
48153838Sdfr  assert(size_in_bits >= 0, "just checking");
49153838Sdfr  idx_t old_size_in_words = size_in_words();
50153838Sdfr  bm_word_t* old_map = map();
51153838Sdfr
52178828Sdfr  _size = size_in_bits;
53178828Sdfr  idx_t new_size_in_words = size_in_words();
54178828Sdfr  if (in_resource_area) {
55178828Sdfr    _map = NEW_RESOURCE_ARRAY(bm_word_t, new_size_in_words);
56178828Sdfr    Copy::disjoint_words((HeapWord*)old_map, (HeapWord*) _map,
57178828Sdfr                         MIN2(old_size_in_words, new_size_in_words));
58178828Sdfr  } else {
59178828Sdfr    _map = _map_allocator.reallocate(new_size_in_words);
60178828Sdfr  }
61178828Sdfr
62178828Sdfr  if (new_size_in_words > old_size_in_words) {
63178828Sdfr    clear_range_of_words(old_size_in_words, new_size_in_words);
64178828Sdfr  }
65178828Sdfr}
66178828Sdfr
67153838Sdfrvoid BitMap::set_range_within_word(idx_t beg, idx_t end) {
68153838Sdfr  // With a valid range (beg <= end), this test ensures that end != 0, as
69178828Sdfr  // required by inverted_bit_mask_for_range.  Also avoids an unnecessary write.
70178828Sdfr  if (beg != end) {
71153838Sdfr    bm_word_t mask = inverted_bit_mask_for_range(beg, end);
72153838Sdfr    *word_addr(beg) |= ~mask;
73153838Sdfr  }
74153838Sdfr}
75153838Sdfr
76153838Sdfrvoid BitMap::clear_range_within_word(idx_t beg, idx_t end) {
77153838Sdfr  // With a valid range (beg <= end), this test ensures that end != 0, as
78178828Sdfr  // required by inverted_bit_mask_for_range.  Also avoids an unnecessary write.
79153838Sdfr  if (beg != end) {
80153838Sdfr    bm_word_t mask = inverted_bit_mask_for_range(beg, end);
81153838Sdfr    *word_addr(beg) &= mask;
82153838Sdfr  }
83153838Sdfr}
84153838Sdfr
85178828Sdfrvoid BitMap::par_put_range_within_word(idx_t beg, idx_t end, bool value) {
86178828Sdfr  assert(value == 0 || value == 1, "0 for clear, 1 for set");
87178828Sdfr  // With a valid range (beg <= end), this test ensures that end != 0, as
88178828Sdfr  // required by inverted_bit_mask_for_range.  Also avoids an unnecessary write.
89153838Sdfr  if (beg != end) {
90153838Sdfr    intptr_t* pw  = (intptr_t*)word_addr(beg);
91153838Sdfr    intptr_t  w   = *pw;
92153838Sdfr    intptr_t  mr  = (intptr_t)inverted_bit_mask_for_range(beg, end);
93153838Sdfr    intptr_t  nw  = value ? (w | ~mr) : (w & mr);
94153838Sdfr    while (true) {
95153838Sdfr      intptr_t res = Atomic::cmpxchg_ptr(nw, pw, w);
96153838Sdfr      if (res == w) break;
97178828Sdfr      w  = res;
98178828Sdfr      nw = value ? (w | ~mr) : (w & mr);
99178828Sdfr    }
100178828Sdfr  }
101178828Sdfr}
102153838Sdfr
103153838Sdfrvoid BitMap::set_range(idx_t beg, idx_t end) {
104153838Sdfr  verify_range(beg, end);
105153838Sdfr
106153838Sdfr  idx_t beg_full_word = word_index_round_up(beg);
107153838Sdfr  idx_t end_full_word = word_index(end);
108153838Sdfr
109153838Sdfr  if (beg_full_word < end_full_word) {
110    // The range includes at least one full word.
111    set_range_within_word(beg, bit_index(beg_full_word));
112    set_range_of_words(beg_full_word, end_full_word);
113    set_range_within_word(bit_index(end_full_word), end);
114  } else {
115    // The range spans at most 2 partial words.
116    idx_t boundary = MIN2(bit_index(beg_full_word), end);
117    set_range_within_word(beg, boundary);
118    set_range_within_word(boundary, end);
119  }
120}
121
122void BitMap::clear_range(idx_t beg, idx_t end) {
123  verify_range(beg, end);
124
125  idx_t beg_full_word = word_index_round_up(beg);
126  idx_t end_full_word = word_index(end);
127
128  if (beg_full_word < end_full_word) {
129    // The range includes at least one full word.
130    clear_range_within_word(beg, bit_index(beg_full_word));
131    clear_range_of_words(beg_full_word, end_full_word);
132    clear_range_within_word(bit_index(end_full_word), end);
133  } else {
134    // The range spans at most 2 partial words.
135    idx_t boundary = MIN2(bit_index(beg_full_word), end);
136    clear_range_within_word(beg, boundary);
137    clear_range_within_word(boundary, end);
138  }
139}
140
141void BitMap::set_large_range(idx_t beg, idx_t end) {
142  verify_range(beg, end);
143
144  idx_t beg_full_word = word_index_round_up(beg);
145  idx_t end_full_word = word_index(end);
146
147  assert(end_full_word - beg_full_word >= 32,
148         "the range must include at least 32 bytes");
149
150  // The range includes at least one full word.
151  set_range_within_word(beg, bit_index(beg_full_word));
152  set_large_range_of_words(beg_full_word, end_full_word);
153  set_range_within_word(bit_index(end_full_word), end);
154}
155
156void BitMap::clear_large_range(idx_t beg, idx_t end) {
157  verify_range(beg, end);
158
159  idx_t beg_full_word = word_index_round_up(beg);
160  idx_t end_full_word = word_index(end);
161
162  assert(end_full_word - beg_full_word >= 32,
163         "the range must include at least 32 bytes");
164
165  // The range includes at least one full word.
166  clear_range_within_word(beg, bit_index(beg_full_word));
167  clear_large_range_of_words(beg_full_word, end_full_word);
168  clear_range_within_word(bit_index(end_full_word), end);
169}
170
171void BitMap::at_put(idx_t offset, bool value) {
172  if (value) {
173    set_bit(offset);
174  } else {
175    clear_bit(offset);
176  }
177}
178
179// Return true to indicate that this thread changed
180// the bit, false to indicate that someone else did.
181// In either case, the requested bit is in the
182// requested state some time during the period that
183// this thread is executing this call. More importantly,
184// if no other thread is executing an action to
185// change the requested bit to a state other than
186// the one that this thread is trying to set it to,
187// then the the bit is in the expected state
188// at exit from this method. However, rather than
189// make such a strong assertion here, based on
190// assuming such constrained use (which though true
191// today, could change in the future to service some
192// funky parallel algorithm), we encourage callers
193// to do such verification, as and when appropriate.
194bool BitMap::par_at_put(idx_t bit, bool value) {
195  return value ? par_set_bit(bit) : par_clear_bit(bit);
196}
197
198void BitMap::at_put_grow(idx_t offset, bool value) {
199  if (offset >= size()) {
200    resize(2 * MAX2(size(), offset));
201  }
202  at_put(offset, value);
203}
204
205void BitMap::at_put_range(idx_t start_offset, idx_t end_offset, bool value) {
206  if (value) {
207    set_range(start_offset, end_offset);
208  } else {
209    clear_range(start_offset, end_offset);
210  }
211}
212
213void BitMap::par_at_put_range(idx_t beg, idx_t end, bool value) {
214  verify_range(beg, end);
215
216  idx_t beg_full_word = word_index_round_up(beg);
217  idx_t end_full_word = word_index(end);
218
219  if (beg_full_word < end_full_word) {
220    // The range includes at least one full word.
221    par_put_range_within_word(beg, bit_index(beg_full_word), value);
222    if (value) {
223      set_range_of_words(beg_full_word, end_full_word);
224    } else {
225      clear_range_of_words(beg_full_word, end_full_word);
226    }
227    par_put_range_within_word(bit_index(end_full_word), end, value);
228  } else {
229    // The range spans at most 2 partial words.
230    idx_t boundary = MIN2(bit_index(beg_full_word), end);
231    par_put_range_within_word(beg, boundary, value);
232    par_put_range_within_word(boundary, end, value);
233  }
234
235}
236
237void BitMap::at_put_large_range(idx_t beg, idx_t end, bool value) {
238  if (value) {
239    set_large_range(beg, end);
240  } else {
241    clear_large_range(beg, end);
242  }
243}
244
245void BitMap::par_at_put_large_range(idx_t beg, idx_t end, bool value) {
246  verify_range(beg, end);
247
248  idx_t beg_full_word = word_index_round_up(beg);
249  idx_t end_full_word = word_index(end);
250
251  assert(end_full_word - beg_full_word >= 32,
252         "the range must include at least 32 bytes");
253
254  // The range includes at least one full word.
255  par_put_range_within_word(beg, bit_index(beg_full_word), value);
256  if (value) {
257    set_large_range_of_words(beg_full_word, end_full_word);
258  } else {
259    clear_large_range_of_words(beg_full_word, end_full_word);
260  }
261  par_put_range_within_word(bit_index(end_full_word), end, value);
262}
263
264bool BitMap::contains(const BitMap other) const {
265  assert(size() == other.size(), "must have same size");
266  bm_word_t* dest_map = map();
267  bm_word_t* other_map = other.map();
268  idx_t size = size_in_words();
269  for (idx_t index = 0; index < size_in_words(); index++) {
270    bm_word_t word_union = dest_map[index] | other_map[index];
271    // If this has more bits set than dest_map[index], then other is not a
272    // subset.
273    if (word_union != dest_map[index]) return false;
274  }
275  return true;
276}
277
278bool BitMap::intersects(const BitMap other) const {
279  assert(size() == other.size(), "must have same size");
280  bm_word_t* dest_map = map();
281  bm_word_t* other_map = other.map();
282  idx_t size = size_in_words();
283  for (idx_t index = 0; index < size_in_words(); index++) {
284    if ((dest_map[index] & other_map[index]) != 0) return true;
285  }
286  // Otherwise, no intersection.
287  return false;
288}
289
290void BitMap::set_union(BitMap other) {
291  assert(size() == other.size(), "must have same size");
292  bm_word_t* dest_map = map();
293  bm_word_t* other_map = other.map();
294  idx_t size = size_in_words();
295  for (idx_t index = 0; index < size_in_words(); index++) {
296    dest_map[index] = dest_map[index] | other_map[index];
297  }
298}
299
300
301void BitMap::set_difference(BitMap other) {
302  assert(size() == other.size(), "must have same size");
303  bm_word_t* dest_map = map();
304  bm_word_t* other_map = other.map();
305  idx_t size = size_in_words();
306  for (idx_t index = 0; index < size_in_words(); index++) {
307    dest_map[index] = dest_map[index] & ~(other_map[index]);
308  }
309}
310
311
312void BitMap::set_intersection(BitMap other) {
313  assert(size() == other.size(), "must have same size");
314  bm_word_t* dest_map = map();
315  bm_word_t* other_map = other.map();
316  idx_t size = size_in_words();
317  for (idx_t index = 0; index < size; index++) {
318    dest_map[index]  = dest_map[index] & other_map[index];
319  }
320}
321
322
323void BitMap::set_intersection_at_offset(BitMap other, idx_t offset) {
324  assert(other.size() >= offset, "offset not in range");
325  assert(other.size() - offset >= size(), "other not large enough");
326  // XXX Ideally, we would remove this restriction.
327  guarantee((offset % (sizeof(bm_word_t) * BitsPerByte)) == 0,
328            "Only handle aligned cases so far.");
329  bm_word_t* dest_map = map();
330  bm_word_t* other_map = other.map();
331  idx_t offset_word_ind = word_index(offset);
332  idx_t size = size_in_words();
333  for (idx_t index = 0; index < size; index++) {
334    dest_map[index] = dest_map[index] & other_map[offset_word_ind + index];
335  }
336}
337
338bool BitMap::set_union_with_result(BitMap other) {
339  assert(size() == other.size(), "must have same size");
340  bool changed = false;
341  bm_word_t* dest_map = map();
342  bm_word_t* other_map = other.map();
343  idx_t size = size_in_words();
344  for (idx_t index = 0; index < size; index++) {
345    idx_t temp = map(index) | other_map[index];
346    changed = changed || (temp != map(index));
347    map()[index] = temp;
348  }
349  return changed;
350}
351
352
353bool BitMap::set_difference_with_result(BitMap other) {
354  assert(size() == other.size(), "must have same size");
355  bool changed = false;
356  bm_word_t* dest_map = map();
357  bm_word_t* other_map = other.map();
358  idx_t size = size_in_words();
359  for (idx_t index = 0; index < size; index++) {
360    bm_word_t temp = dest_map[index] & ~(other_map[index]);
361    changed = changed || (temp != dest_map[index]);
362    dest_map[index] = temp;
363  }
364  return changed;
365}
366
367
368bool BitMap::set_intersection_with_result(BitMap other) {
369  assert(size() == other.size(), "must have same size");
370  bool changed = false;
371  bm_word_t* dest_map = map();
372  bm_word_t* other_map = other.map();
373  idx_t size = size_in_words();
374  for (idx_t index = 0; index < size; index++) {
375    bm_word_t orig = dest_map[index];
376    bm_word_t temp = orig & other_map[index];
377    changed = changed || (temp != orig);
378    dest_map[index]  = temp;
379  }
380  return changed;
381}
382
383
384void BitMap::set_from(BitMap other) {
385  assert(size() == other.size(), "must have same size");
386  bm_word_t* dest_map = map();
387  bm_word_t* other_map = other.map();
388  idx_t size = size_in_words();
389  for (idx_t index = 0; index < size; index++) {
390    dest_map[index] = other_map[index];
391  }
392}
393
394
395bool BitMap::is_same(BitMap other) {
396  assert(size() == other.size(), "must have same size");
397  bm_word_t* dest_map = map();
398  bm_word_t* other_map = other.map();
399  idx_t size = size_in_words();
400  for (idx_t index = 0; index < size; index++) {
401    if (dest_map[index] != other_map[index]) return false;
402  }
403  return true;
404}
405
406bool BitMap::is_full() const {
407  bm_word_t* word = map();
408  idx_t rest = size();
409  for (; rest >= (idx_t) BitsPerWord; rest -= BitsPerWord) {
410    if (*word != (bm_word_t) AllBits) return false;
411    word++;
412  }
413  return rest == 0 || (*word | ~right_n_bits((int)rest)) == (bm_word_t) AllBits;
414}
415
416
417bool BitMap::is_empty() const {
418  bm_word_t* word = map();
419  idx_t rest = size();
420  for (; rest >= (idx_t) BitsPerWord; rest -= BitsPerWord) {
421    if (*word != (bm_word_t) NoBits) return false;
422    word++;
423  }
424  return rest == 0 || (*word & right_n_bits((int)rest)) == (bm_word_t) NoBits;
425}
426
427void BitMap::clear_large() {
428  clear_large_range_of_words(0, size_in_words());
429}
430
431// Note that if the closure itself modifies the bitmap
432// then modifications in and to the left of the _bit_ being
433// currently sampled will not be seen. Note also that the
434// interval [leftOffset, rightOffset) is right open.
435bool BitMap::iterate(BitMapClosure* blk, idx_t leftOffset, idx_t rightOffset) {
436  verify_range(leftOffset, rightOffset);
437
438  idx_t startIndex = word_index(leftOffset);
439  idx_t endIndex   = MIN2(word_index(rightOffset) + 1, size_in_words());
440  for (idx_t index = startIndex, offset = leftOffset;
441       offset < rightOffset && index < endIndex;
442       offset = (++index) << LogBitsPerWord) {
443    idx_t rest = map(index) >> (offset & (BitsPerWord - 1));
444    for (; offset < rightOffset && rest != (bm_word_t)NoBits; offset++) {
445      if (rest & 1) {
446        if (!blk->do_bit(offset)) return false;
447        //  resample at each closure application
448        // (see, for instance, CMS bug 4525989)
449        rest = map(index) >> (offset & (BitsPerWord -1));
450      }
451      rest = rest >> 1;
452    }
453  }
454  return true;
455}
456
457BitMap::idx_t* BitMap::_pop_count_table = NULL;
458
459void BitMap::init_pop_count_table() {
460  if (_pop_count_table == NULL) {
461    BitMap::idx_t *table = NEW_C_HEAP_ARRAY(idx_t, 256, mtInternal);
462    for (uint i = 0; i < 256; i++) {
463      table[i] = num_set_bits(i);
464    }
465
466    intptr_t res = Atomic::cmpxchg_ptr((intptr_t)  table,
467                                       (intptr_t*) &_pop_count_table,
468                                       (intptr_t)  NULL_WORD);
469    if (res != NULL_WORD) {
470      guarantee( _pop_count_table == (void*) res, "invariant" );
471      FREE_C_HEAP_ARRAY(bm_word_t, table, mtInternal);
472    }
473  }
474}
475
476BitMap::idx_t BitMap::num_set_bits(bm_word_t w) {
477  idx_t bits = 0;
478
479  while (w != 0) {
480    while ((w & 1) == 0) {
481      w >>= 1;
482    }
483    bits++;
484    w >>= 1;
485  }
486  return bits;
487}
488
489BitMap::idx_t BitMap::num_set_bits_from_table(unsigned char c) {
490  assert(_pop_count_table != NULL, "precondition");
491  return _pop_count_table[c];
492}
493
494BitMap::idx_t BitMap::count_one_bits() const {
495  init_pop_count_table(); // If necessary.
496  idx_t sum = 0;
497  typedef unsigned char uchar;
498  for (idx_t i = 0; i < size_in_words(); i++) {
499    bm_word_t w = map()[i];
500    for (size_t j = 0; j < sizeof(bm_word_t); j++) {
501      sum += num_set_bits_from_table(uchar(w & 255));
502      w >>= 8;
503    }
504  }
505  return sum;
506}
507
508void BitMap::print_on_error(outputStream* st, const char* prefix) const {
509  st->print_cr("%s[" PTR_FORMAT ", " PTR_FORMAT ")",
510      prefix, p2i(map()), p2i((char*)map() + (size() >> LogBitsPerByte)));
511}
512
513#ifndef PRODUCT
514
515void BitMap::print_on(outputStream* st) const {
516  tty->print("Bitmap(" SIZE_FORMAT "):", size());
517  for (idx_t index = 0; index < size(); index++) {
518    tty->print("%c", at(index) ? '1' : '0');
519  }
520  tty->cr();
521}
522
523class TestBitMap : public AllStatic {
524  const static BitMap::idx_t BITMAP_SIZE = 1024;
525  static void fillBitMap(BitMap& map) {
526    map.set_bit(1);
527    map.set_bit(3);
528    map.set_bit(17);
529    map.set_bit(512);
530  }
531
532  static void testResize(bool in_resource_area) {
533    {
534      BitMap map(0, in_resource_area);
535      map.resize(BITMAP_SIZE, in_resource_area);
536      fillBitMap(map);
537
538      BitMap map2(BITMAP_SIZE, in_resource_area);
539      fillBitMap(map2);
540      assert(map.is_same(map2), "could be");
541    }
542
543    {
544      BitMap map(128, in_resource_area);
545      map.resize(BITMAP_SIZE, in_resource_area);
546      fillBitMap(map);
547
548      BitMap map2(BITMAP_SIZE, in_resource_area);
549      fillBitMap(map2);
550      assert(map.is_same(map2), "could be");
551    }
552
553    {
554      BitMap map(BITMAP_SIZE, in_resource_area);
555      map.resize(BITMAP_SIZE, in_resource_area);
556      fillBitMap(map);
557
558      BitMap map2(BITMAP_SIZE, in_resource_area);
559      fillBitMap(map2);
560      assert(map.is_same(map2), "could be");
561    }
562  }
563
564  static void testResizeResource() {
565    ResourceMark rm;
566    testResize(true);
567  }
568
569  static void testResizeNonResource() {
570    const uintx bitmap_bytes = BITMAP_SIZE / BitsPerByte;
571
572    // Test the default behavior
573    testResize(false);
574
575    {
576      // Make sure that AllocatorMallocLimit is larger than our allocation request
577      // forcing it to call standard malloc()
578      UIntFlagSetting fs(ArrayAllocatorMallocLimit, bitmap_bytes * 4);
579      testResize(false);
580    }
581    {
582      // Make sure that AllocatorMallocLimit is smaller than our allocation request
583      // forcing it to call mmap() (or equivalent)
584      UIntFlagSetting fs(ArrayAllocatorMallocLimit, bitmap_bytes / 4);
585      testResize(false);
586    }
587  }
588
589 public:
590  static void test() {
591    testResizeResource();
592    testResizeNonResource();
593  }
594
595};
596
597void TestBitMap_test() {
598  TestBitMap::test();
599}
600#endif
601
602
603BitMap2D::BitMap2D(bm_word_t* map, idx_t size_in_slots, idx_t bits_per_slot)
604  : _bits_per_slot(bits_per_slot)
605  , _map(map, size_in_slots * bits_per_slot)
606{
607}
608
609
610BitMap2D::BitMap2D(idx_t size_in_slots, idx_t bits_per_slot)
611  : _bits_per_slot(bits_per_slot)
612  , _map(size_in_slots * bits_per_slot)
613{
614}
615