annotate src/share/vm/utilities/bitMap.hpp @ 1091:6aa7255741f3

6906727: UseCompressedOops: some card-marking fixes related to object arrays Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17). Reviewed-by: kvn, coleenp, jmasa
author ysr
date Thu, 03 Dec 2009 15:01:57 -0800
parents bd02caa94611
children c18cbe5936b8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
844
bd02caa94611 6862919: Update copyright year
xdono
parents: 809
diff changeset
2 * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
25 // Forward decl;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
26 class BitMapClosure;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
27
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
28 // Operations for bitmaps represented as arrays of unsigned integers.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
29 // Bit offsets are numbered from 0 to size-1.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
30
a61af66fc99e Initial load
duke
parents:
diff changeset
31 class BitMap VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
32 friend class BitMap2D;
a61af66fc99e Initial load
duke
parents:
diff changeset
33
a61af66fc99e Initial load
duke
parents:
diff changeset
34 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
35 typedef size_t idx_t; // Type used for bit and word indices.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
36 typedef uintptr_t bm_word_t; // Element type of array that represents
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
37 // the bitmap.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
38
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // Hints for range sizes.
a61af66fc99e Initial load
duke
parents:
diff changeset
40 typedef enum {
a61af66fc99e Initial load
duke
parents:
diff changeset
41 unknown_range, small_range, large_range
a61af66fc99e Initial load
duke
parents:
diff changeset
42 } RangeSizeHint;
a61af66fc99e Initial load
duke
parents:
diff changeset
43
a61af66fc99e Initial load
duke
parents:
diff changeset
44 private:
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
45 bm_word_t* _map; // First word in bitmap
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
46 idx_t _size; // Size of bitmap (in bits)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
47
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // Puts the given value at the given offset, using resize() to size
a61af66fc99e Initial load
duke
parents:
diff changeset
49 // the bitmap appropriately if needed using factor-of-two expansion.
a61af66fc99e Initial load
duke
parents:
diff changeset
50 void at_put_grow(idx_t index, bool value);
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // Return the position of bit within the word that contains it (e.g., if
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // bitmap words are 32 bits, return a number 0 <= n <= 31).
a61af66fc99e Initial load
duke
parents:
diff changeset
55 static idx_t bit_in_word(idx_t bit) { return bit & (BitsPerWord - 1); }
a61af66fc99e Initial load
duke
parents:
diff changeset
56
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // Return a mask that will select the specified bit, when applied to the word
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // containing the bit.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
59 static bm_word_t bit_mask(idx_t bit) { return (bm_word_t)1 << bit_in_word(bit); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
60
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // Return the index of the word containing the specified bit.
a61af66fc99e Initial load
duke
parents:
diff changeset
62 static idx_t word_index(idx_t bit) { return bit >> LogBitsPerWord; }
a61af66fc99e Initial load
duke
parents:
diff changeset
63
a61af66fc99e Initial load
duke
parents:
diff changeset
64 // Return the bit number of the first bit in the specified word.
a61af66fc99e Initial load
duke
parents:
diff changeset
65 static idx_t bit_index(idx_t word) { return word << LogBitsPerWord; }
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 // Return the array of bitmap words, or a specific word from it.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
68 bm_word_t* map() const { return _map; }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
69 bm_word_t map(idx_t word) const { return _map[word]; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // Return a pointer to the word containing the specified bit.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
72 bm_word_t* word_addr(idx_t bit) const { return map() + word_index(bit); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
73
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // Set a word to a specified value or to all ones; clear a word.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
75 void set_word (idx_t word, bm_word_t val) { _map[word] = val; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
76 void set_word (idx_t word) { set_word(word, ~(uintptr_t)0); }
a61af66fc99e Initial load
duke
parents:
diff changeset
77 void clear_word(idx_t word) { _map[word] = 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // Utilities for ranges of bits. Ranges are half-open [beg, end).
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // Ranges within a single word.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
82 bm_word_t inverted_bit_mask_for_range(idx_t beg, idx_t end) const;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
83 void set_range_within_word (idx_t beg, idx_t end);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
84 void clear_range_within_word (idx_t beg, idx_t end);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
85 void par_put_range_within_word (idx_t beg, idx_t end, bool value);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // Ranges spanning entire words.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
88 void set_range_of_words (idx_t beg, idx_t end);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
89 void clear_range_of_words (idx_t beg, idx_t end);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
90 void set_large_range_of_words (idx_t beg, idx_t end);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
91 void clear_large_range_of_words (idx_t beg, idx_t end);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // The index of the first full word in a range.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
94 idx_t word_index_round_up(idx_t bit) const;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
95
809
6e2afda171db 6849716: BitMap - performance regression introduced with G1
jcoomes
parents: 342
diff changeset
96 // Verification.
6e2afda171db 6849716: BitMap - performance regression introduced with G1
jcoomes
parents: 342
diff changeset
97 inline void verify_index(idx_t index) const NOT_DEBUG_RETURN;
6e2afda171db 6849716: BitMap - performance regression introduced with G1
jcoomes
parents: 342
diff changeset
98 inline void verify_range(idx_t beg_index, idx_t end_index) const
6e2afda171db 6849716: BitMap - performance regression introduced with G1
jcoomes
parents: 342
diff changeset
99 NOT_DEBUG_RETURN;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
100
809
6e2afda171db 6849716: BitMap - performance regression introduced with G1
jcoomes
parents: 342
diff changeset
101 // Statistics.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
102 static idx_t* _pop_count_table;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
103 static void init_pop_count_table();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
104 static idx_t num_set_bits(bm_word_t w);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
105 static idx_t num_set_bits_from_table(unsigned char c);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
106
a61af66fc99e Initial load
duke
parents:
diff changeset
107 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // Constructs a bitmap with no map, and size 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
110 BitMap() : _map(NULL), _size(0) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
111
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
112 // Constructs a bitmap with the given map and size.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
113 BitMap(bm_word_t* map, idx_t size_in_bits);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
114
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
115 // Constructs an empty bitmap of the given size (that is, this clears the
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
116 // new bitmap). Allocates the map array in resource area if
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
117 // "in_resource_area" is true, else in the C heap.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
118 BitMap(idx_t size_in_bits, bool in_resource_area = true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
119
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
120 // Set the map and size.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
121 void set_map(bm_word_t* map) { _map = map; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
122 void set_size(idx_t size_in_bits) { _size = size_in_bits; }
a61af66fc99e Initial load
duke
parents:
diff changeset
123
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
124 // Allocates necessary data structure, either in the resource area
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
125 // or in the C heap, as indicated by "in_resource_area."
0
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // Preserves state currently in bit map by copying data.
a61af66fc99e Initial load
duke
parents:
diff changeset
127 // Zeros any newly-addressable bits.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
128 // If "in_resource_area" is false, frees the current map.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
129 // (Note that this assumes that all calls to "resize" on the same BitMap
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
130 // use the same value for "in_resource_area".)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
131 void resize(idx_t size_in_bits, bool in_resource_area = true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // Accessing
a61af66fc99e Initial load
duke
parents:
diff changeset
134 idx_t size() const { return _size; }
a61af66fc99e Initial load
duke
parents:
diff changeset
135 idx_t size_in_words() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
136 return word_index(size() + BitsPerWord - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 bool at(idx_t index) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
140 verify_index(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
141 return (*word_addr(index) & bit_mask(index)) != 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144 // Align bit index up or down to the next bitmap word boundary, or check
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // alignment.
a61af66fc99e Initial load
duke
parents:
diff changeset
146 static idx_t word_align_up(idx_t bit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
147 return align_size_up(bit, BitsPerWord);
a61af66fc99e Initial load
duke
parents:
diff changeset
148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
149 static idx_t word_align_down(idx_t bit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
150 return align_size_down(bit, BitsPerWord);
a61af66fc99e Initial load
duke
parents:
diff changeset
151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
152 static bool is_word_aligned(idx_t bit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
153 return word_align_up(bit) == bit;
a61af66fc99e Initial load
duke
parents:
diff changeset
154 }
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // Set or clear the specified bit.
a61af66fc99e Initial load
duke
parents:
diff changeset
157 inline void set_bit(idx_t bit);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
158 void clear_bit(idx_t bit);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
159
a61af66fc99e Initial load
duke
parents:
diff changeset
160 // Atomically set or clear the specified bit.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
161 bool par_set_bit(idx_t bit);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
162 bool par_clear_bit(idx_t bit);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
163
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // Put the given value at the given offset. The parallel version
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // will CAS the value into the bitmap and is quite a bit slower.
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // The parallel version also returns a value indicating if the
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // calling thread was the one that changed the value of the bit.
a61af66fc99e Initial load
duke
parents:
diff changeset
168 void at_put(idx_t index, bool value);
a61af66fc99e Initial load
duke
parents:
diff changeset
169 bool par_at_put(idx_t index, bool value);
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // Update a range of bits. Ranges are half-open [beg, end).
a61af66fc99e Initial load
duke
parents:
diff changeset
172 void set_range (idx_t beg, idx_t end);
a61af66fc99e Initial load
duke
parents:
diff changeset
173 void clear_range (idx_t beg, idx_t end);
a61af66fc99e Initial load
duke
parents:
diff changeset
174 void set_large_range (idx_t beg, idx_t end);
a61af66fc99e Initial load
duke
parents:
diff changeset
175 void clear_large_range (idx_t beg, idx_t end);
a61af66fc99e Initial load
duke
parents:
diff changeset
176 void at_put_range(idx_t beg, idx_t end, bool value);
a61af66fc99e Initial load
duke
parents:
diff changeset
177 void par_at_put_range(idx_t beg, idx_t end, bool value);
a61af66fc99e Initial load
duke
parents:
diff changeset
178 void at_put_large_range(idx_t beg, idx_t end, bool value);
a61af66fc99e Initial load
duke
parents:
diff changeset
179 void par_at_put_large_range(idx_t beg, idx_t end, bool value);
a61af66fc99e Initial load
duke
parents:
diff changeset
180
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // Update a range of bits, using a hint about the size. Currently only
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // inlines the predominant case of a 1-bit range. Works best when hint is a
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // compile-time constant.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
184 void set_range(idx_t beg, idx_t end, RangeSizeHint hint);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
185 void clear_range(idx_t beg, idx_t end, RangeSizeHint hint);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
186 void par_set_range(idx_t beg, idx_t end, RangeSizeHint hint);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
187 void par_clear_range (idx_t beg, idx_t end, RangeSizeHint hint);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
188
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
189 // It performs the union operation between subsets of equal length
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
190 // of two bitmaps (the target bitmap of the method and the
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
191 // from_bitmap) and stores the result to the target bitmap. The
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
192 // from_start_index represents the first bit index of the subrange
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
193 // of the from_bitmap. The to_start_index is the equivalent of the
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
194 // target bitmap. Both indexes should be word-aligned, i.e. they
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
195 // should correspond to the first bit on a bitmap word (it's up to
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
196 // the caller to ensure this; the method does check it). The length
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
197 // of the subset is specified with word_num and it is in number of
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
198 // bitmap words. The caller should ensure that this is at least 2
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
199 // (smaller ranges are not support to save extra checks). Again,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
200 // this is checked in the method.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
201 //
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
202 // Atomicity concerns: it is assumed that any contention on the
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
203 // target bitmap with other threads will happen on the first and
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
204 // last words; the ones in between will be "owned" exclusively by
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
205 // the calling thread and, in fact, they will already be 0. So, the
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
206 // method performs a CAS on the first word, copies the next
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
207 // word_num-2 words, and finally performs a CAS on the last word.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
208 void mostly_disjoint_range_union(BitMap* from_bitmap,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
209 idx_t from_start_index,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
210 idx_t to_start_index,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
211 size_t word_num);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
212
0
a61af66fc99e Initial load
duke
parents:
diff changeset
213
a61af66fc99e Initial load
duke
parents:
diff changeset
214 // Clearing
a61af66fc99e Initial load
duke
parents:
diff changeset
215 void clear_large();
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
216 inline void clear();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
217
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
218 // Iteration support. Returns "true" if the iteration completed, false
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
219 // if the iteration terminated early (because the closure "blk" returned
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
220 // false).
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
221 bool iterate(BitMapClosure* blk, idx_t leftIndex, idx_t rightIndex);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
222 bool iterate(BitMapClosure* blk) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
223 // call the version that takes an interval
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
224 return iterate(blk, 0, size());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
226
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
227 // Looking for 1's and 0's at indices equal to or greater than "l_index",
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
228 // stopping if none has been found before "r_index", and returning
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
229 // "r_index" (which must be at most "size") in that case.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
230 idx_t get_next_one_offset_inline (idx_t l_index, idx_t r_index) const;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
231 idx_t get_next_zero_offset_inline(idx_t l_index, idx_t r_index) const;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
232
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
233 // Like "get_next_one_offset_inline", except requires that "r_index" is
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
234 // aligned to bitsizeof(bm_word_t).
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
235 idx_t get_next_one_offset_inline_aligned_right(idx_t l_index,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
236 idx_t r_index) const;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
237
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
238 // Non-inline versionsof the above.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
239 idx_t get_next_one_offset (idx_t l_index, idx_t r_index) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
240 idx_t get_next_zero_offset(idx_t l_index, idx_t r_index) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
241
a61af66fc99e Initial load
duke
parents:
diff changeset
242 idx_t get_next_one_offset(idx_t offset) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
243 return get_next_one_offset(offset, size());
a61af66fc99e Initial load
duke
parents:
diff changeset
244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
245 idx_t get_next_zero_offset(idx_t offset) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
246 return get_next_zero_offset(offset, size());
a61af66fc99e Initial load
duke
parents:
diff changeset
247 }
a61af66fc99e Initial load
duke
parents:
diff changeset
248
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
249 // Returns the number of bits set in the bitmap.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
250 idx_t count_one_bits() const;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
251
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // Set operations.
a61af66fc99e Initial load
duke
parents:
diff changeset
253 void set_union(BitMap bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
254 void set_difference(BitMap bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
255 void set_intersection(BitMap bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
256 // Returns true iff "this" is a superset of "bits".
a61af66fc99e Initial load
duke
parents:
diff changeset
257 bool contains(const BitMap bits) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
258 // Returns true iff "this and "bits" have a non-empty intersection.
a61af66fc99e Initial load
duke
parents:
diff changeset
259 bool intersects(const BitMap bits) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
260
a61af66fc99e Initial load
duke
parents:
diff changeset
261 // Returns result of whether this map changed
a61af66fc99e Initial load
duke
parents:
diff changeset
262 // during the operation
a61af66fc99e Initial load
duke
parents:
diff changeset
263 bool set_union_with_result(BitMap bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
264 bool set_difference_with_result(BitMap bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
265 bool set_intersection_with_result(BitMap bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
266
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
267 // Requires the submap of "bits" starting at offset to be at least as
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
268 // large as "this". Modifies "this" to be the intersection of its
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
269 // current contents and the submap of "bits" starting at "offset" of the
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
270 // same length as "this."
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
271 // (For expedience, currently requires the offset to be aligned to the
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
272 // bitsize of a uintptr_t. This should go away in the future though it
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
273 // will probably remain a good case to optimize.)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
274 void set_intersection_at_offset(BitMap bits, idx_t offset);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
275
0
a61af66fc99e Initial load
duke
parents:
diff changeset
276 void set_from(BitMap bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
277
a61af66fc99e Initial load
duke
parents:
diff changeset
278 bool is_same(BitMap bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
279
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // Test if all bits are set or cleared
a61af66fc99e Initial load
duke
parents:
diff changeset
281 bool is_full() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
282 bool is_empty() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
283
a61af66fc99e Initial load
duke
parents:
diff changeset
284
a61af66fc99e Initial load
duke
parents:
diff changeset
285 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
286 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
287 // Printing
a61af66fc99e Initial load
duke
parents:
diff changeset
288 void print_on(outputStream* st) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
289 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
290 };
a61af66fc99e Initial load
duke
parents:
diff changeset
291
a61af66fc99e Initial load
duke
parents:
diff changeset
292 // Convenience class wrapping BitMap which provides multiple bits per slot.
a61af66fc99e Initial load
duke
parents:
diff changeset
293 class BitMap2D VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
294 public:
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
295 typedef BitMap::idx_t idx_t; // Type used for bit and word indices.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
296 typedef BitMap::bm_word_t bm_word_t; // Element type of array that
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
297 // represents the bitmap.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
298 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
299 BitMap _map;
a61af66fc99e Initial load
duke
parents:
diff changeset
300 idx_t _bits_per_slot;
a61af66fc99e Initial load
duke
parents:
diff changeset
301
a61af66fc99e Initial load
duke
parents:
diff changeset
302 idx_t bit_index(idx_t slot_index, idx_t bit_within_slot_index) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
303 return slot_index * _bits_per_slot + bit_within_slot_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
304 }
a61af66fc99e Initial load
duke
parents:
diff changeset
305
a61af66fc99e Initial load
duke
parents:
diff changeset
306 void verify_bit_within_slot_index(idx_t index) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
307 assert(index < _bits_per_slot, "bit_within_slot index out of bounds");
a61af66fc99e Initial load
duke
parents:
diff changeset
308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
309
a61af66fc99e Initial load
duke
parents:
diff changeset
310 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // Construction. bits_per_slot must be greater than 0.
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
312 BitMap2D(bm_word_t* map, idx_t size_in_slots, idx_t bits_per_slot);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
313
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // Allocates necessary data structure in resource area. bits_per_slot must be greater than 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
315 BitMap2D(idx_t size_in_slots, idx_t bits_per_slot);
a61af66fc99e Initial load
duke
parents:
diff changeset
316
a61af66fc99e Initial load
duke
parents:
diff changeset
317 idx_t size_in_bits() {
a61af66fc99e Initial load
duke
parents:
diff changeset
318 return _map.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
320
a61af66fc99e Initial load
duke
parents:
diff changeset
321 // Returns number of full slots that have been allocated
a61af66fc99e Initial load
duke
parents:
diff changeset
322 idx_t size_in_slots() {
a61af66fc99e Initial load
duke
parents:
diff changeset
323 // Round down
a61af66fc99e Initial load
duke
parents:
diff changeset
324 return _map.size() / _bits_per_slot;
a61af66fc99e Initial load
duke
parents:
diff changeset
325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
326
a61af66fc99e Initial load
duke
parents:
diff changeset
327 bool is_valid_index(idx_t slot_index, idx_t bit_within_slot_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
328 verify_bit_within_slot_index(bit_within_slot_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
329 return (bit_index(slot_index, bit_within_slot_index) < size_in_bits());
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331
a61af66fc99e Initial load
duke
parents:
diff changeset
332 bool at(idx_t slot_index, idx_t bit_within_slot_index) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
333 verify_bit_within_slot_index(bit_within_slot_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
334 return _map.at(bit_index(slot_index, bit_within_slot_index));
a61af66fc99e Initial load
duke
parents:
diff changeset
335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
336
a61af66fc99e Initial load
duke
parents:
diff changeset
337 void set_bit(idx_t slot_index, idx_t bit_within_slot_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
338 verify_bit_within_slot_index(bit_within_slot_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
339 _map.set_bit(bit_index(slot_index, bit_within_slot_index));
a61af66fc99e Initial load
duke
parents:
diff changeset
340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
341
a61af66fc99e Initial load
duke
parents:
diff changeset
342 void clear_bit(idx_t slot_index, idx_t bit_within_slot_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
343 verify_bit_within_slot_index(bit_within_slot_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
344 _map.clear_bit(bit_index(slot_index, bit_within_slot_index));
a61af66fc99e Initial load
duke
parents:
diff changeset
345 }
a61af66fc99e Initial load
duke
parents:
diff changeset
346
a61af66fc99e Initial load
duke
parents:
diff changeset
347 void at_put(idx_t slot_index, idx_t bit_within_slot_index, bool value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
348 verify_bit_within_slot_index(bit_within_slot_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
349 _map.at_put(bit_index(slot_index, bit_within_slot_index), value);
a61af66fc99e Initial load
duke
parents:
diff changeset
350 }
a61af66fc99e Initial load
duke
parents:
diff changeset
351
a61af66fc99e Initial load
duke
parents:
diff changeset
352 void at_put_grow(idx_t slot_index, idx_t bit_within_slot_index, bool value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
353 verify_bit_within_slot_index(bit_within_slot_index);
a61af66fc99e Initial load
duke
parents:
diff changeset
354 _map.at_put_grow(bit_index(slot_index, bit_within_slot_index), value);
a61af66fc99e Initial load
duke
parents:
diff changeset
355 }
a61af66fc99e Initial load
duke
parents:
diff changeset
356
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
357 void clear();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
358 };
a61af66fc99e Initial load
duke
parents:
diff changeset
359
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
360 // Closure for iterating over BitMaps
0
a61af66fc99e Initial load
duke
parents:
diff changeset
361
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
362 class BitMapClosure VALUE_OBJ_CLASS_SPEC {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
363 public:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
364 // Callback when bit in map is set. Should normally return "true";
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
365 // return of false indicates that the bitmap iteration should terminate.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
366 virtual bool do_bit(BitMap::idx_t offset) = 0;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
367 };