1 /*
2  * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  *
23  */
24 
25 #include "precompiled.hpp"
26 #include "memory/allocation.inline.hpp"
27 #include "memory/resourceArea.hpp"
28 #include "runtime/atomic.hpp"
29 #include "utilities/bitMap.inline.hpp"
30 #include "utilities/copy.hpp"
31 #include "utilities/debug.hpp"
32 #include "utilities/population_count.hpp"
33 
34 STATIC_ASSERT(sizeof(BitMap::bm_word_t) == BytesPerWord); // "Implementation assumption."
35 
36 typedef BitMap::bm_word_t bm_word_t;
37 typedef BitMap::idx_t     idx_t;
38 
39 class ResourceBitMapAllocator : StackObj {
40  public:
allocate(idx_t size_in_words) const41   bm_word_t* allocate(idx_t size_in_words) const {
42     return NEW_RESOURCE_ARRAY(bm_word_t, size_in_words);
43   }
free(bm_word_t * map,idx_t size_in_words) const44   void free(bm_word_t* map, idx_t size_in_words) const {
45     // Don't free resource allocated arrays.
46   }
47 };
48 
49 class CHeapBitMapAllocator : StackObj {
50   MEMFLAGS _flags;
51 
52  public:
CHeapBitMapAllocator(MEMFLAGS flags)53   CHeapBitMapAllocator(MEMFLAGS flags) : _flags(flags) {}
allocate(size_t size_in_words) const54   bm_word_t* allocate(size_t size_in_words) const {
55     return ArrayAllocator<bm_word_t>::allocate(size_in_words, _flags);
56   }
free(bm_word_t * map,idx_t size_in_words) const57   void free(bm_word_t* map, idx_t size_in_words) const {
58     ArrayAllocator<bm_word_t>::free(map, size_in_words);
59   }
60 };
61 
62 class ArenaBitMapAllocator : StackObj {
63   Arena* _arena;
64 
65  public:
ArenaBitMapAllocator(Arena * arena)66   ArenaBitMapAllocator(Arena* arena) : _arena(arena) {}
allocate(idx_t size_in_words) const67   bm_word_t* allocate(idx_t size_in_words) const {
68     return (bm_word_t*)_arena->Amalloc(size_in_words * BytesPerWord);
69   }
free(bm_word_t * map,idx_t size_in_words) const70   void free(bm_word_t* map, idx_t size_in_words) const {
71     // ArenaBitMaps currently don't free memory.
72   }
73 };
74 
75 template <class Allocator>
reallocate(const Allocator & allocator,bm_word_t * old_map,idx_t old_size_in_bits,idx_t new_size_in_bits,bool clear)76 BitMap::bm_word_t* BitMap::reallocate(const Allocator& allocator, bm_word_t* old_map, idx_t old_size_in_bits, idx_t new_size_in_bits, bool clear) {
77   size_t old_size_in_words = calc_size_in_words(old_size_in_bits);
78   size_t new_size_in_words = calc_size_in_words(new_size_in_bits);
79 
80   bm_word_t* map = NULL;
81 
82   if (new_size_in_words > 0) {
83     map = allocator.allocate(new_size_in_words);
84 
85     if (old_map != NULL) {
86       Copy::disjoint_words((HeapWord*)old_map, (HeapWord*) map,
87                            MIN2(old_size_in_words, new_size_in_words));
88     }
89 
90     if (clear && (new_size_in_bits > old_size_in_bits)) {
91       // If old_size_in_bits is not word-aligned, then the preceeding
92       // copy can include some trailing bits in the final copied word
93       // that also need to be cleared.  See clear_range_within_word.
94       bm_word_t mask = bit_mask(old_size_in_bits) - 1;
95       map[raw_to_words_align_down(old_size_in_bits)] &= mask;
96       // Clear the remaining full words.
97       clear_range_of_words(map, old_size_in_words, new_size_in_words);
98     }
99   }
100 
101   if (old_map != NULL) {
102     allocator.free(old_map, old_size_in_words);
103   }
104 
105   return map;
106 }
107 
108 template <class Allocator>
allocate(const Allocator & allocator,idx_t size_in_bits,bool clear)109 bm_word_t* BitMap::allocate(const Allocator& allocator, idx_t size_in_bits, bool clear) {
110   // Reuse reallocate to ensure that the new memory is cleared.
111   return reallocate(allocator, NULL, 0, size_in_bits, clear);
112 }
113 
114 template <class Allocator>
free(const Allocator & allocator,bm_word_t * map,idx_t size_in_bits)115 void BitMap::free(const Allocator& allocator, bm_word_t* map, idx_t  size_in_bits) {
116   bm_word_t* ret = reallocate(allocator, map, size_in_bits, 0);
117   assert(ret == NULL, "Reallocate shouldn't have allocated");
118 }
119 
120 template <class Allocator>
resize(const Allocator & allocator,idx_t new_size_in_bits,bool clear)121 void BitMap::resize(const Allocator& allocator, idx_t new_size_in_bits, bool clear) {
122   bm_word_t* new_map = reallocate(allocator, map(), size(), new_size_in_bits, clear);
123 
124   update(new_map, new_size_in_bits);
125 }
126 
127 template <class Allocator>
initialize(const Allocator & allocator,idx_t size_in_bits,bool clear)128 void BitMap::initialize(const Allocator& allocator, idx_t size_in_bits, bool clear) {
129   assert(map() == NULL, "precondition");
130   assert(size() == 0,   "precondition");
131 
132   resize(allocator, size_in_bits, clear);
133 }
134 
135 template <class Allocator>
reinitialize(const Allocator & allocator,idx_t new_size_in_bits,bool clear)136 void BitMap::reinitialize(const Allocator& allocator, idx_t new_size_in_bits, bool clear) {
137   // Remove previous bits - no need to clear
138   resize(allocator, 0, false /* clear */);
139 
140   initialize(allocator, new_size_in_bits, clear);
141 }
142 
ResourceBitMap(idx_t size_in_bits,bool clear)143 ResourceBitMap::ResourceBitMap(idx_t size_in_bits, bool clear)
144     : BitMap(allocate(ResourceBitMapAllocator(), size_in_bits, clear), size_in_bits) {
145 }
146 
resize(idx_t new_size_in_bits)147 void ResourceBitMap::resize(idx_t new_size_in_bits) {
148   BitMap::resize(ResourceBitMapAllocator(), new_size_in_bits, true /* clear */);
149 }
150 
initialize(idx_t size_in_bits)151 void ResourceBitMap::initialize(idx_t size_in_bits) {
152   BitMap::initialize(ResourceBitMapAllocator(), size_in_bits, true /* clear */);
153 }
154 
reinitialize(idx_t size_in_bits)155 void ResourceBitMap::reinitialize(idx_t size_in_bits) {
156   BitMap::reinitialize(ResourceBitMapAllocator(), size_in_bits, true /* clear */);
157 }
158 
ArenaBitMap(Arena * arena,idx_t size_in_bits)159 ArenaBitMap::ArenaBitMap(Arena* arena, idx_t size_in_bits)
160     : BitMap(allocate(ArenaBitMapAllocator(arena), size_in_bits), size_in_bits) {
161 }
162 
CHeapBitMap(idx_t size_in_bits,MEMFLAGS flags,bool clear)163 CHeapBitMap::CHeapBitMap(idx_t size_in_bits, MEMFLAGS flags, bool clear)
164     : BitMap(allocate(CHeapBitMapAllocator(flags), size_in_bits, clear), size_in_bits), _flags(flags) {
165 }
166 
~CHeapBitMap()167 CHeapBitMap::~CHeapBitMap() {
168   free(CHeapBitMapAllocator(_flags), map(), size());
169 }
170 
resize(idx_t new_size_in_bits,bool clear)171 void CHeapBitMap::resize(idx_t new_size_in_bits, bool clear) {
172   BitMap::resize(CHeapBitMapAllocator(_flags), new_size_in_bits, clear);
173 }
174 
initialize(idx_t size_in_bits,bool clear)175 void CHeapBitMap::initialize(idx_t size_in_bits, bool clear) {
176   BitMap::initialize(CHeapBitMapAllocator(_flags), size_in_bits, clear);
177 }
178 
reinitialize(idx_t size_in_bits,bool clear)179 void CHeapBitMap::reinitialize(idx_t size_in_bits, bool clear) {
180   BitMap::reinitialize(CHeapBitMapAllocator(_flags), size_in_bits, clear);
181 }
182 
183 #ifdef ASSERT
verify_size(idx_t size_in_bits)184 void BitMap::verify_size(idx_t size_in_bits) {
185   assert(size_in_bits <= max_size_in_bits(),
186          "out of bounds: " SIZE_FORMAT, size_in_bits);
187 }
188 
verify_index(idx_t bit) const189 void BitMap::verify_index(idx_t bit) const {
190   assert(bit < _size,
191          "BitMap index out of bounds: " SIZE_FORMAT " >= " SIZE_FORMAT,
192          bit, _size);
193 }
194 
verify_limit(idx_t bit) const195 void BitMap::verify_limit(idx_t bit) const {
196   assert(bit <= _size,
197          "BitMap limit out of bounds: " SIZE_FORMAT " > " SIZE_FORMAT,
198          bit, _size);
199 }
200 
verify_range(idx_t beg,idx_t end) const201 void BitMap::verify_range(idx_t beg, idx_t end) const {
202   assert(beg <= end,
203          "BitMap range error: " SIZE_FORMAT " > " SIZE_FORMAT, beg, end);
204   verify_limit(end);
205 }
206 #endif // #ifdef ASSERT
207 
pretouch()208 void BitMap::pretouch() {
209   os::pretouch_memory(word_addr(0), word_addr(size()));
210 }
211 
set_range_within_word(idx_t beg,idx_t end)212 void BitMap::set_range_within_word(idx_t beg, idx_t end) {
213   // With a valid range (beg <= end), this test ensures that end != 0, as
214   // required by inverted_bit_mask_for_range.  Also avoids an unnecessary write.
215   if (beg != end) {
216     bm_word_t mask = inverted_bit_mask_for_range(beg, end);
217     *word_addr(beg) |= ~mask;
218   }
219 }
220 
clear_range_within_word(idx_t beg,idx_t end)221 void BitMap::clear_range_within_word(idx_t beg, idx_t end) {
222   // With a valid range (beg <= end), this test ensures that end != 0, as
223   // required by inverted_bit_mask_for_range.  Also avoids an unnecessary write.
224   if (beg != end) {
225     bm_word_t mask = inverted_bit_mask_for_range(beg, end);
226     *word_addr(beg) &= mask;
227   }
228 }
229 
par_put_range_within_word(idx_t beg,idx_t end,bool value)230 void BitMap::par_put_range_within_word(idx_t beg, idx_t end, bool value) {
231   assert(value == 0 || value == 1, "0 for clear, 1 for set");
232   // With a valid range (beg <= end), this test ensures that end != 0, as
233   // required by inverted_bit_mask_for_range.  Also avoids an unnecessary write.
234   if (beg != end) {
235     bm_word_t* pw = word_addr(beg);
236     bm_word_t  w  = *pw;
237     bm_word_t  mr = inverted_bit_mask_for_range(beg, end);
238     bm_word_t  nw = value ? (w | ~mr) : (w & mr);
239     while (true) {
240       bm_word_t res = Atomic::cmpxchg(pw, w, nw);
241       if (res == w) break;
242       w  = res;
243       nw = value ? (w | ~mr) : (w & mr);
244     }
245   }
246 }
247 
set_range(idx_t beg,idx_t end)248 void BitMap::set_range(idx_t beg, idx_t end) {
249   verify_range(beg, end);
250 
251   idx_t beg_full_word = to_words_align_up(beg);
252   idx_t end_full_word = to_words_align_down(end);
253 
254   if (beg_full_word < end_full_word) {
255     // The range includes at least one full word.
256     set_range_within_word(beg, bit_index(beg_full_word));
257     set_range_of_words(beg_full_word, end_full_word);
258     set_range_within_word(bit_index(end_full_word), end);
259   } else {
260     // The range spans at most 2 partial words.
261     idx_t boundary = MIN2(bit_index(beg_full_word), end);
262     set_range_within_word(beg, boundary);
263     set_range_within_word(boundary, end);
264   }
265 }
266 
clear_range(idx_t beg,idx_t end)267 void BitMap::clear_range(idx_t beg, idx_t end) {
268   verify_range(beg, end);
269 
270   idx_t beg_full_word = to_words_align_up(beg);
271   idx_t end_full_word = to_words_align_down(end);
272 
273   if (beg_full_word < end_full_word) {
274     // The range includes at least one full word.
275     clear_range_within_word(beg, bit_index(beg_full_word));
276     clear_range_of_words(beg_full_word, end_full_word);
277     clear_range_within_word(bit_index(end_full_word), end);
278   } else {
279     // The range spans at most 2 partial words.
280     idx_t boundary = MIN2(bit_index(beg_full_word), end);
281     clear_range_within_word(beg, boundary);
282     clear_range_within_word(boundary, end);
283   }
284 }
285 
is_small_range_of_words(idx_t beg_full_word,idx_t end_full_word)286 bool BitMap::is_small_range_of_words(idx_t beg_full_word, idx_t end_full_word) {
287   // There is little point to call large version on small ranges.
288   // Need to check carefully, keeping potential idx_t over/underflow in mind,
289   // because beg_full_word > end_full_word can occur when beg and end are in
290   // the same word.
291   // The threshold should be at least one word.
292   STATIC_ASSERT(small_range_words >= 1);
293   return beg_full_word + small_range_words >= end_full_word;
294 }
295 
set_large_range(idx_t beg,idx_t end)296 void BitMap::set_large_range(idx_t beg, idx_t end) {
297   verify_range(beg, end);
298 
299   idx_t beg_full_word = to_words_align_up(beg);
300   idx_t end_full_word = to_words_align_down(end);
301 
302   if (is_small_range_of_words(beg_full_word, end_full_word)) {
303     set_range(beg, end);
304     return;
305   }
306 
307   // The range includes at least one full word.
308   set_range_within_word(beg, bit_index(beg_full_word));
309   set_large_range_of_words(beg_full_word, end_full_word);
310   set_range_within_word(bit_index(end_full_word), end);
311 }
312 
clear_large_range(idx_t beg,idx_t end)313 void BitMap::clear_large_range(idx_t beg, idx_t end) {
314   verify_range(beg, end);
315 
316   idx_t beg_full_word = to_words_align_up(beg);
317   idx_t end_full_word = to_words_align_down(end);
318 
319   if (is_small_range_of_words(beg_full_word, end_full_word)) {
320     clear_range(beg, end);
321     return;
322   }
323 
324   // The range includes at least one full word.
325   clear_range_within_word(beg, bit_index(beg_full_word));
326   clear_large_range_of_words(beg_full_word, end_full_word);
327   clear_range_within_word(bit_index(end_full_word), end);
328 }
329 
at_put(idx_t offset,bool value)330 void BitMap::at_put(idx_t offset, bool value) {
331   if (value) {
332     set_bit(offset);
333   } else {
334     clear_bit(offset);
335   }
336 }
337 
338 // Return true to indicate that this thread changed
339 // the bit, false to indicate that someone else did.
340 // In either case, the requested bit is in the
341 // requested state some time during the period that
342 // this thread is executing this call. More importantly,
343 // if no other thread is executing an action to
344 // change the requested bit to a state other than
345 // the one that this thread is trying to set it to,
346 // then the the bit is in the expected state
347 // at exit from this method. However, rather than
348 // make such a strong assertion here, based on
349 // assuming such constrained use (which though true
350 // today, could change in the future to service some
351 // funky parallel algorithm), we encourage callers
352 // to do such verification, as and when appropriate.
par_at_put(idx_t bit,bool value)353 bool BitMap::par_at_put(idx_t bit, bool value) {
354   return value ? par_set_bit(bit) : par_clear_bit(bit);
355 }
356 
at_put_range(idx_t start_offset,idx_t end_offset,bool value)357 void BitMap::at_put_range(idx_t start_offset, idx_t end_offset, bool value) {
358   if (value) {
359     set_range(start_offset, end_offset);
360   } else {
361     clear_range(start_offset, end_offset);
362   }
363 }
364 
par_at_put_range(idx_t beg,idx_t end,bool value)365 void BitMap::par_at_put_range(idx_t beg, idx_t end, bool value) {
366   verify_range(beg, end);
367 
368   idx_t beg_full_word = to_words_align_up(beg);
369   idx_t end_full_word = to_words_align_down(end);
370 
371   if (beg_full_word < end_full_word) {
372     // The range includes at least one full word.
373     par_put_range_within_word(beg, bit_index(beg_full_word), value);
374     if (value) {
375       set_range_of_words(beg_full_word, end_full_word);
376     } else {
377       clear_range_of_words(beg_full_word, end_full_word);
378     }
379     par_put_range_within_word(bit_index(end_full_word), end, value);
380   } else {
381     // The range spans at most 2 partial words.
382     idx_t boundary = MIN2(bit_index(beg_full_word), end);
383     par_put_range_within_word(beg, boundary, value);
384     par_put_range_within_word(boundary, end, value);
385   }
386 
387 }
388 
at_put_large_range(idx_t beg,idx_t end,bool value)389 void BitMap::at_put_large_range(idx_t beg, idx_t end, bool value) {
390   if (value) {
391     set_large_range(beg, end);
392   } else {
393     clear_large_range(beg, end);
394   }
395 }
396 
par_at_put_large_range(idx_t beg,idx_t end,bool value)397 void BitMap::par_at_put_large_range(idx_t beg, idx_t end, bool value) {
398   verify_range(beg, end);
399 
400   idx_t beg_full_word = to_words_align_up(beg);
401   idx_t end_full_word = to_words_align_down(end);
402 
403   if (is_small_range_of_words(beg_full_word, end_full_word)) {
404     par_at_put_range(beg, end, value);
405     return;
406   }
407 
408   // The range includes at least one full word.
409   par_put_range_within_word(beg, bit_index(beg_full_word), value);
410   if (value) {
411     set_large_range_of_words(beg_full_word, end_full_word);
412   } else {
413     clear_large_range_of_words(beg_full_word, end_full_word);
414   }
415   par_put_range_within_word(bit_index(end_full_word), end, value);
416 }
417 
tail_mask(idx_t tail_bits)418 inline bm_word_t tail_mask(idx_t tail_bits) {
419   assert(tail_bits != 0, "precondition"); // Works, but shouldn't be called.
420   assert(tail_bits < (idx_t)BitsPerWord, "precondition");
421   return (bm_word_t(1) << tail_bits) - 1;
422 }
423 
424 // Get the low tail_bits of value, which is the last partial word of a map.
tail_of_map(bm_word_t value,idx_t tail_bits)425 inline bm_word_t tail_of_map(bm_word_t value, idx_t tail_bits) {
426   return value & tail_mask(tail_bits);
427 }
428 
429 // Compute the new last word of a map with a non-aligned length.
430 // new_value has the new trailing bits of the map in the low tail_bits.
431 // old_value is the last word of the map, including bits beyond the end.
432 // Returns old_value with the low tail_bits replaced by the corresponding
433 // bits in new_value.
merge_tail_of_map(bm_word_t new_value,bm_word_t old_value,idx_t tail_bits)434 inline bm_word_t merge_tail_of_map(bm_word_t new_value,
435                                    bm_word_t old_value,
436                                    idx_t tail_bits) {
437   bm_word_t mask = tail_mask(tail_bits);
438   return (new_value & mask) | (old_value & ~mask);
439 }
440 
contains(const BitMap & other) const441 bool BitMap::contains(const BitMap& other) const {
442   assert(size() == other.size(), "must have same size");
443   const bm_word_t* dest_map = map();
444   const bm_word_t* other_map = other.map();
445   idx_t limit = to_words_align_down(size());
446   for (idx_t index = 0; index < limit; ++index) {
447     // false if other bitmap has bits set which are clear in this bitmap.
448     if ((~dest_map[index] & other_map[index]) != 0) return false;
449   }
450   idx_t rest = bit_in_word(size());
451   // true unless there is a partial-word tail in which the other
452   // bitmap has bits set which are clear in this bitmap.
453   return (rest == 0) || tail_of_map(~dest_map[limit] & other_map[limit], rest) == 0;
454 }
455 
intersects(const BitMap & other) const456 bool BitMap::intersects(const BitMap& other) const {
457   assert(size() == other.size(), "must have same size");
458   const bm_word_t* dest_map = map();
459   const bm_word_t* other_map = other.map();
460   idx_t limit = to_words_align_down(size());
461   for (idx_t index = 0; index < limit; ++index) {
462     if ((dest_map[index] & other_map[index]) != 0) return true;
463   }
464   idx_t rest = bit_in_word(size());
465   // false unless there is a partial-word tail with non-empty intersection.
466   return (rest > 0) && tail_of_map(dest_map[limit] & other_map[limit], rest) != 0;
467 }
468 
set_union(const BitMap & other)469 void BitMap::set_union(const BitMap& other) {
470   assert(size() == other.size(), "must have same size");
471   bm_word_t* dest_map = map();
472   const bm_word_t* other_map = other.map();
473   idx_t limit = to_words_align_down(size());
474   for (idx_t index = 0; index < limit; ++index) {
475     dest_map[index] |= other_map[index];
476   }
477   idx_t rest = bit_in_word(size());
478   if (rest > 0) {
479     bm_word_t orig = dest_map[limit];
480     dest_map[limit] = merge_tail_of_map(orig | other_map[limit], orig, rest);
481   }
482 }
483 
set_difference(const BitMap & other)484 void BitMap::set_difference(const BitMap& other) {
485   assert(size() == other.size(), "must have same size");
486   bm_word_t* dest_map = map();
487   const bm_word_t* other_map = other.map();
488   idx_t limit = to_words_align_down(size());
489   for (idx_t index = 0; index < limit; ++index) {
490     dest_map[index] &= ~other_map[index];
491   }
492   idx_t rest = bit_in_word(size());
493   if (rest > 0) {
494     bm_word_t orig = dest_map[limit];
495     dest_map[limit] = merge_tail_of_map(orig & ~other_map[limit], orig, rest);
496   }
497 }
498 
set_intersection(const BitMap & other)499 void BitMap::set_intersection(const BitMap& other) {
500   assert(size() == other.size(), "must have same size");
501   bm_word_t* dest_map = map();
502   const bm_word_t* other_map = other.map();
503   idx_t limit = to_words_align_down(size());
504   for (idx_t index = 0; index < limit; ++index) {
505     dest_map[index] &= other_map[index];
506   }
507   idx_t rest = bit_in_word(size());
508   if (rest > 0) {
509     bm_word_t orig = dest_map[limit];
510     dest_map[limit] = merge_tail_of_map(orig & other_map[limit], orig, rest);
511   }
512 }
513 
set_union_with_result(const BitMap & other)514 bool BitMap::set_union_with_result(const BitMap& other) {
515   assert(size() == other.size(), "must have same size");
516   bool changed = false;
517   bm_word_t* dest_map = map();
518   const bm_word_t* other_map = other.map();
519   idx_t limit = to_words_align_down(size());
520   for (idx_t index = 0; index < limit; ++index) {
521     bm_word_t orig = dest_map[index];
522     bm_word_t temp = orig | other_map[index];
523     changed = changed || (temp != orig);
524     dest_map[index] = temp;
525   }
526   idx_t rest = bit_in_word(size());
527   if (rest > 0) {
528     bm_word_t orig = dest_map[limit];
529     bm_word_t temp = merge_tail_of_map(orig | other_map[limit], orig, rest);
530     changed = changed || (temp != orig);
531     dest_map[limit] = temp;
532   }
533   return changed;
534 }
535 
set_difference_with_result(const BitMap & other)536 bool BitMap::set_difference_with_result(const BitMap& other) {
537   assert(size() == other.size(), "must have same size");
538   bool changed = false;
539   bm_word_t* dest_map = map();
540   const bm_word_t* other_map = other.map();
541   idx_t limit = to_words_align_down(size());
542   for (idx_t index = 0; index < limit; ++index) {
543     bm_word_t orig = dest_map[index];
544     bm_word_t temp = orig & ~other_map[index];
545     changed = changed || (temp != orig);
546     dest_map[index] = temp;
547   }
548   idx_t rest = bit_in_word(size());
549   if (rest > 0) {
550     bm_word_t orig = dest_map[limit];
551     bm_word_t temp = merge_tail_of_map(orig & ~other_map[limit], orig, rest);
552     changed = changed || (temp != orig);
553     dest_map[limit] = temp;
554   }
555   return changed;
556 }
557 
set_intersection_with_result(const BitMap & other)558 bool BitMap::set_intersection_with_result(const BitMap& other) {
559   assert(size() == other.size(), "must have same size");
560   bool changed = false;
561   bm_word_t* dest_map = map();
562   const bm_word_t* other_map = other.map();
563   idx_t limit = to_words_align_down(size());
564   for (idx_t index = 0; index < limit; ++index) {
565     bm_word_t orig = dest_map[index];
566     bm_word_t temp = orig & other_map[index];
567     changed = changed || (temp != orig);
568     dest_map[index] = temp;
569   }
570   idx_t rest = bit_in_word(size());
571   if (rest > 0) {
572     bm_word_t orig = dest_map[limit];
573     bm_word_t temp = merge_tail_of_map(orig & other_map[limit], orig, rest);
574     changed = changed || (temp != orig);
575     dest_map[limit] = temp;
576   }
577   return changed;
578 }
579 
set_from(const BitMap & other)580 void BitMap::set_from(const BitMap& other) {
581   assert(size() == other.size(), "must have same size");
582   bm_word_t* dest_map = map();
583   const bm_word_t* other_map = other.map();
584   idx_t copy_words = to_words_align_down(size());
585   Copy::disjoint_words((HeapWord*)other_map, (HeapWord*)dest_map, copy_words);
586   idx_t rest = bit_in_word(size());
587   if (rest > 0) {
588     dest_map[copy_words] = merge_tail_of_map(other_map[copy_words],
589                                              dest_map[copy_words],
590                                              rest);
591   }
592 }
593 
is_same(const BitMap & other) const594 bool BitMap::is_same(const BitMap& other) const {
595   assert(size() == other.size(), "must have same size");
596   const bm_word_t* dest_map = map();
597   const bm_word_t* other_map = other.map();
598   idx_t limit = to_words_align_down(size());
599   for (idx_t index = 0; index < limit; ++index) {
600     if (dest_map[index] != other_map[index]) return false;
601   }
602   idx_t rest = bit_in_word(size());
603   return (rest == 0) || (tail_of_map(dest_map[limit] ^ other_map[limit], rest) == 0);
604 }
605 
is_full() const606 bool BitMap::is_full() const {
607   const bm_word_t* words = map();
608   idx_t limit = to_words_align_down(size());
609   for (idx_t index = 0; index < limit; ++index) {
610     if (~words[index] != 0) return false;
611   }
612   idx_t rest = bit_in_word(size());
613   return (rest == 0) || (tail_of_map(~words[limit], rest) == 0);
614 }
615 
is_empty() const616 bool BitMap::is_empty() const {
617   const bm_word_t* words = map();
618   idx_t limit = to_words_align_down(size());
619   for (idx_t index = 0; index < limit; ++index) {
620     if (words[index] != 0) return false;
621   }
622   idx_t rest = bit_in_word(size());
623   return (rest == 0) || (tail_of_map(words[limit], rest) == 0);
624 }
625 
clear_large()626 void BitMap::clear_large() {
627   clear_large_range_of_words(0, size_in_words());
628 }
629 
count_one_bits_in_range_of_words(idx_t beg_full_word,idx_t end_full_word) const630 BitMap::idx_t BitMap::count_one_bits_in_range_of_words(idx_t beg_full_word, idx_t end_full_word) const {
631   idx_t sum = 0;
632   for (idx_t i = beg_full_word; i < end_full_word; i++) {
633     bm_word_t w = map()[i];
634     sum += population_count(w);
635   }
636   return sum;
637 }
638 
count_one_bits_within_word(idx_t beg,idx_t end) const639 BitMap::idx_t BitMap::count_one_bits_within_word(idx_t beg, idx_t end) const {
640   if (beg != end) {
641     assert(end > beg, "must be");
642     bm_word_t mask = ~inverted_bit_mask_for_range(beg, end);
643     bm_word_t w = *word_addr(beg);
644     w &= mask;
645     return population_count(w);
646   }
647   return 0;
648 }
649 
count_one_bits() const650 BitMap::idx_t BitMap::count_one_bits() const {
651   return count_one_bits(0, size());
652 }
653 
654 // Returns the number of bits set within  [beg, end).
count_one_bits(idx_t beg,idx_t end) const655 BitMap::idx_t BitMap::count_one_bits(idx_t beg, idx_t end) const {
656   verify_range(beg, end);
657 
658   idx_t beg_full_word = to_words_align_up(beg);
659   idx_t end_full_word = to_words_align_down(end);
660 
661   idx_t sum = 0;
662 
663   if (beg_full_word < end_full_word) {
664     // The range includes at least one full word.
665     sum += count_one_bits_within_word(beg, bit_index(beg_full_word));
666     sum += count_one_bits_in_range_of_words(beg_full_word, end_full_word);
667     sum += count_one_bits_within_word(bit_index(end_full_word), end);
668   } else {
669     // The range spans at most 2 partial words.
670     idx_t boundary = MIN2(bit_index(beg_full_word), end);
671     sum += count_one_bits_within_word(beg, boundary);
672     sum += count_one_bits_within_word(boundary, end);
673   }
674 
675   assert(sum <= (beg - end), "must be");
676 
677   return sum;
678 
679 }
680 
print_on_error(outputStream * st,const char * prefix) const681 void BitMap::print_on_error(outputStream* st, const char* prefix) const {
682   st->print_cr("%s[" PTR_FORMAT ", " PTR_FORMAT ")",
683       prefix, p2i(map()), p2i((char*)map() + (size() >> LogBitsPerByte)));
684 }
685 
write_to(bm_word_t * buffer,size_t buffer_size_in_bytes) const686 void BitMap::write_to(bm_word_t* buffer, size_t buffer_size_in_bytes) const {
687   assert(buffer_size_in_bytes == size_in_bytes(), "must be");
688   memcpy(buffer, _map, size_in_bytes());
689 }
690 
691 #ifndef PRODUCT
692 
print_on(outputStream * st) const693 void BitMap::print_on(outputStream* st) const {
694   tty->print("Bitmap(" SIZE_FORMAT "):", size());
695   for (idx_t index = 0; index < size(); index++) {
696     tty->print("%c", at(index) ? '1' : '0');
697   }
698   tty->cr();
699 }
700 
701 #endif
702