annotate src/share/vm/utilities/bitMap.inline.hpp @ 8733:9def4075da6d

8008079: G1: Add nextObject routine to CMBitMapRO and replace nextWord Summary: Update the task local finger to the start of the next object when marking aborts, in order to avoid the redundant scanning of all 0's when the marking task restarts, if otherwise updating to the next word. In addition, reuse the routine nextObject() in routine iterate(). Reviewed-by: johnc, ysr Contributed-by: tamao <tao.mao@oracle.com>
author tamao
date Tue, 05 Mar 2013 15:36:56 -0800
parents 2e966d967c5c
children 17deed6716af
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
4827
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
2 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. 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 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 844
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 844
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 844
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
25 #ifndef SHARE_VM_UTILITIES_BITMAP_INLINE_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
26 #define SHARE_VM_UTILITIES_BITMAP_INLINE_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "runtime/atomic.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "utilities/bitMap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
30
809
6e2afda171db 6849716: BitMap - performance regression introduced with G1
jcoomes
parents: 342
diff changeset
31 #ifdef ASSERT
6e2afda171db 6849716: BitMap - performance regression introduced with G1
jcoomes
parents: 342
diff changeset
32 inline void BitMap::verify_index(idx_t index) const {
6e2afda171db 6849716: BitMap - performance regression introduced with G1
jcoomes
parents: 342
diff changeset
33 assert(index < _size, "BitMap index out of bounds");
6e2afda171db 6849716: BitMap - performance regression introduced with G1
jcoomes
parents: 342
diff changeset
34 }
6e2afda171db 6849716: BitMap - performance regression introduced with G1
jcoomes
parents: 342
diff changeset
35
6e2afda171db 6849716: BitMap - performance regression introduced with G1
jcoomes
parents: 342
diff changeset
36 inline void BitMap::verify_range(idx_t beg_index, idx_t end_index) const {
6e2afda171db 6849716: BitMap - performance regression introduced with G1
jcoomes
parents: 342
diff changeset
37 assert(beg_index <= end_index, "BitMap range error");
6e2afda171db 6849716: BitMap - performance regression introduced with G1
jcoomes
parents: 342
diff changeset
38 // Note that [0,0) and [size,size) are both valid ranges.
6e2afda171db 6849716: BitMap - performance regression introduced with G1
jcoomes
parents: 342
diff changeset
39 if (end_index != _size) verify_index(end_index);
6e2afda171db 6849716: BitMap - performance regression introduced with G1
jcoomes
parents: 342
diff changeset
40 }
6e2afda171db 6849716: BitMap - performance regression introduced with G1
jcoomes
parents: 342
diff changeset
41 #endif // #ifdef ASSERT
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
42
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
43 inline void BitMap::set_bit(idx_t bit) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
44 verify_index(bit);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
45 *word_addr(bit) |= bit_mask(bit);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
46 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
47
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
48 inline void BitMap::clear_bit(idx_t bit) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
49 verify_index(bit);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
50 *word_addr(bit) &= ~bit_mask(bit);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
51 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
52
0
a61af66fc99e Initial load
duke
parents:
diff changeset
53 inline bool BitMap::par_set_bit(idx_t bit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
54 verify_index(bit);
a61af66fc99e Initial load
duke
parents:
diff changeset
55 volatile idx_t* const addr = word_addr(bit);
a61af66fc99e Initial load
duke
parents:
diff changeset
56 const idx_t mask = bit_mask(bit);
a61af66fc99e Initial load
duke
parents:
diff changeset
57 idx_t old_val = *addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
60 const idx_t new_val = old_val | mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
61 if (new_val == old_val) {
a61af66fc99e Initial load
duke
parents:
diff changeset
62 return false; // Someone else beat us to it.
a61af66fc99e Initial load
duke
parents:
diff changeset
63 }
a61af66fc99e Initial load
duke
parents:
diff changeset
64 const idx_t cur_val = (idx_t) Atomic::cmpxchg_ptr((void*) new_val,
a61af66fc99e Initial load
duke
parents:
diff changeset
65 (volatile void*) addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
66 (void*) old_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
67 if (cur_val == old_val) {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 return true; // Success.
a61af66fc99e Initial load
duke
parents:
diff changeset
69 }
a61af66fc99e Initial load
duke
parents:
diff changeset
70 old_val = cur_val; // The value changed, try again.
a61af66fc99e Initial load
duke
parents:
diff changeset
71 } while (true);
a61af66fc99e Initial load
duke
parents:
diff changeset
72 }
a61af66fc99e Initial load
duke
parents:
diff changeset
73
a61af66fc99e Initial load
duke
parents:
diff changeset
74 inline bool BitMap::par_clear_bit(idx_t bit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
75 verify_index(bit);
a61af66fc99e Initial load
duke
parents:
diff changeset
76 volatile idx_t* const addr = word_addr(bit);
a61af66fc99e Initial load
duke
parents:
diff changeset
77 const idx_t mask = ~bit_mask(bit);
a61af66fc99e Initial load
duke
parents:
diff changeset
78 idx_t old_val = *addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
79
a61af66fc99e Initial load
duke
parents:
diff changeset
80 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
81 const idx_t new_val = old_val & mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
82 if (new_val == old_val) {
a61af66fc99e Initial load
duke
parents:
diff changeset
83 return false; // Someone else beat us to it.
a61af66fc99e Initial load
duke
parents:
diff changeset
84 }
a61af66fc99e Initial load
duke
parents:
diff changeset
85 const idx_t cur_val = (idx_t) Atomic::cmpxchg_ptr((void*) new_val,
a61af66fc99e Initial load
duke
parents:
diff changeset
86 (volatile void*) addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
87 (void*) old_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
88 if (cur_val == old_val) {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 return true; // Success.
a61af66fc99e Initial load
duke
parents:
diff changeset
90 }
a61af66fc99e Initial load
duke
parents:
diff changeset
91 old_val = cur_val; // The value changed, try again.
a61af66fc99e Initial load
duke
parents:
diff changeset
92 } while (true);
a61af66fc99e Initial load
duke
parents:
diff changeset
93 }
a61af66fc99e Initial load
duke
parents:
diff changeset
94
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
95 inline void BitMap::set_range(idx_t beg, idx_t end, RangeSizeHint hint) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
96 if (hint == small_range && end - beg == 1) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
97 set_bit(beg);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
98 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
99 if (hint == large_range) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
100 set_large_range(beg, end);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
101 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
102 set_range(beg, end);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
103 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
104 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
105 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
106
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
107 inline void BitMap::clear_range(idx_t beg, idx_t end, RangeSizeHint hint) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
108 if (hint == small_range && end - beg == 1) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
109 clear_bit(beg);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
110 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
111 if (hint == large_range) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
112 clear_large_range(beg, end);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
113 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
114 clear_range(beg, end);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
115 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
116 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
117 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
118
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
119 inline void BitMap::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
120 if (hint == small_range && end - beg == 1) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
121 par_at_put(beg, true);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
122 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
123 if (hint == large_range) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
124 par_at_put_large_range(beg, end, true);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
125 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
126 par_at_put_range(beg, end, true);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
127 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
128 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
129 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
130
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
131 inline void BitMap::set_range_of_words(idx_t beg, idx_t end) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
132 bm_word_t* map = _map;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
133 for (idx_t i = beg; i < end; ++i) map[i] = ~(uintptr_t)0;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
134 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
135
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
136
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
137 inline void BitMap::clear_range_of_words(idx_t beg, idx_t end) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
138 bm_word_t* map = _map;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
139 for (idx_t i = beg; i < end; ++i) map[i] = 0;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
140 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
141
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
142
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
143 inline void BitMap::clear() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
144 clear_range_of_words(0, size_in_words());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
145 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
146
0
a61af66fc99e Initial load
duke
parents:
diff changeset
147
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
148 inline void BitMap::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
149 if (hint == small_range && end - beg == 1) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
150 par_at_put(beg, false);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
151 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
152 if (hint == large_range) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
153 par_at_put_large_range(beg, end, false);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
154 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
155 par_at_put_range(beg, end, false);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
156 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
157 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
158 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
159
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
160 inline BitMap::idx_t
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
161 BitMap::get_next_one_offset_inline(idx_t l_offset, idx_t r_offset) const {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
162 assert(l_offset <= size(), "BitMap index out of bounds");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
163 assert(r_offset <= size(), "BitMap index out of bounds");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
164 assert(l_offset <= r_offset, "l_offset > r_offset ?");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
165
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
166 if (l_offset == r_offset) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
167 return l_offset;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
168 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
169 idx_t index = word_index(l_offset);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
170 idx_t r_index = word_index(r_offset-1) + 1;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
171 idx_t res_offset = l_offset;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
172
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // check bits including and to the _left_ of offset's position
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
174 idx_t pos = bit_in_word(res_offset);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
175 idx_t res = map(index) >> pos;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
176 if (res != (uintptr_t)NoBits) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // find the position of the 1-bit
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
178 for (; !(res & 1); res_offset++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
179 res = res >> 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
180 }
4827
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
181
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
182 #ifdef ASSERT
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
183 // In the following assert, if r_offset is not bitamp word aligned,
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
184 // checking that res_offset is strictly less than r_offset is too
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
185 // strong and will trip the assert.
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
186 //
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
187 // Consider the case where l_offset is bit 15 and r_offset is bit 17
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
188 // of the same map word, and where bits [15:16:17:18] == [00:00:00:01].
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
189 // All the bits in the range [l_offset:r_offset) are 0.
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
190 // The loop that calculates res_offset, above, would yield the offset
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
191 // of bit 18 because it's in the same map word as l_offset and there
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
192 // is a set bit in that map word above l_offset (i.e. res != NoBits).
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
193 //
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
194 // In this case, however, we can assert is that res_offset is strictly
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
195 // less than size() since we know that there is at least one set bit
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
196 // at an offset above, but in the same map word as, r_offset.
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
197 // Otherwise, if r_offset is word aligned then it will not be in the
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
198 // same map word as l_offset (unless it equals l_offset). So either
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
199 // there won't be a set bit between l_offset and the end of it's map
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
200 // word (i.e. res == NoBits), or res_offset will be less than r_offset.
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
201
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
202 idx_t limit = is_word_aligned(r_offset) ? r_offset : size();
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
203 assert(res_offset >= l_offset && res_offset < limit, "just checking");
2e966d967c5c 7121547: G1: High number mispredicted branches while iterating over the marking bitmap
johnc
parents: 1972
diff changeset
204 #endif // ASSERT
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
205 return MIN2(res_offset, r_offset);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // skip over all word length 0-bit runs
a61af66fc99e Initial load
duke
parents:
diff changeset
208 for (index++; index < r_index; index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
209 res = map(index);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
210 if (res != (uintptr_t)NoBits) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // found a 1, return the offset
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
212 for (res_offset = bit_index(index); !(res & 1); res_offset++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
213 res = res >> 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215 assert(res & 1, "tautology; see loop condition");
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
216 assert(res_offset >= l_offset, "just checking");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
217 return MIN2(res_offset, r_offset);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
218 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
219 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
220 return r_offset;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
221 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
222
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
223 inline BitMap::idx_t
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
224 BitMap::get_next_zero_offset_inline(idx_t l_offset, idx_t r_offset) const {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
225 assert(l_offset <= size(), "BitMap index out of bounds");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
226 assert(r_offset <= size(), "BitMap index out of bounds");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
227 assert(l_offset <= r_offset, "l_offset > r_offset ?");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
228
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
229 if (l_offset == r_offset) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
230 return l_offset;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
231 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
232 idx_t index = word_index(l_offset);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
233 idx_t r_index = word_index(r_offset-1) + 1;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
234 idx_t res_offset = l_offset;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
235
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
236 // check bits including and to the _left_ of offset's position
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
237 idx_t pos = res_offset & (BitsPerWord - 1);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
238 idx_t res = (map(index) >> pos) | left_n_bits((int)pos);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
239
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
240 if (res != (uintptr_t)AllBits) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
241 // find the position of the 0-bit
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
242 for (; res & 1; res_offset++) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
243 res = res >> 1;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
244 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
245 assert(res_offset >= l_offset, "just checking");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
246 return MIN2(res_offset, r_offset);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
247 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
248 // skip over all word length 1-bit runs
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
249 for (index++; index < r_index; index++) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
250 res = map(index);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
251 if (res != (uintptr_t)AllBits) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
252 // found a 0, return the offset
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
253 for (res_offset = index << LogBitsPerWord; res & 1;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
254 res_offset++) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
255 res = res >> 1;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
256 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
257 assert(!(res & 1), "tautology; see loop condition");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
258 assert(res_offset >= l_offset, "just checking");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
259 return MIN2(res_offset, r_offset);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
261 }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
262 return r_offset;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
263 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
264
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
265 inline BitMap::idx_t
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
266 BitMap::get_next_one_offset_inline_aligned_right(idx_t l_offset,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
267 idx_t r_offset) const
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
268 {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
269 verify_range(l_offset, r_offset);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
270 assert(bit_in_word(r_offset) == 0, "r_offset not word-aligned");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
271
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
272 if (l_offset == r_offset) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
273 return l_offset;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
274 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
275 idx_t index = word_index(l_offset);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
276 idx_t r_index = word_index(r_offset);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
277 idx_t res_offset = l_offset;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
278
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
279 // check bits including and to the _left_ of offset's position
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
280 idx_t res = map(index) >> bit_in_word(res_offset);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
281 if (res != (uintptr_t)NoBits) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
282 // find the position of the 1-bit
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
283 for (; !(res & 1); res_offset++) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
284 res = res >> 1;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
285 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
286 assert(res_offset >= l_offset &&
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
287 res_offset < r_offset, "just checking");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
288 return res_offset;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
289 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
290 // skip over all word length 0-bit runs
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
291 for (index++; index < r_index; index++) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
292 res = map(index);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
293 if (res != (uintptr_t)NoBits) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
294 // found a 1, return the offset
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
295 for (res_offset = bit_index(index); !(res & 1); res_offset++) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
296 res = res >> 1;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
297 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
298 assert(res & 1, "tautology; see loop condition");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
299 assert(res_offset >= l_offset && res_offset < r_offset, "just checking");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
300 return res_offset;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
301 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
302 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
303 return r_offset;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
304 }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
305
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
306
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
307 // Returns a bit mask for a range of bits [beg, end) within a single word. Each
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
308 // bit in the mask is 0 if the bit is in the range, 1 if not in the range. The
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
309 // returned mask can be used directly to clear the range, or inverted to set the
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
310 // range. Note: end must not be 0.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
311 inline BitMap::bm_word_t
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
312 BitMap::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
313 assert(end != 0, "does not work when end == 0");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
314 assert(beg == end || word_index(beg) == word_index(end - 1),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
315 "must be a single-word range");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
316 bm_word_t mask = bit_mask(beg) - 1; // low (right) bits
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
317 if (bit_in_word(end) != 0) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
318 mask |= ~(bit_mask(end) - 1); // high (left) bits
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
319 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
320 return mask;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
321 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
322
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
323 inline void BitMap::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
324 memset(_map + beg, ~(unsigned char)0, (end - beg) * sizeof(uintptr_t));
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
325 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
326
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
327 inline void BitMap::clear_large_range_of_words(idx_t beg, idx_t end) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
328 memset(_map + beg, 0, (end - beg) * sizeof(uintptr_t));
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
329 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
330
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
331 inline BitMap::idx_t BitMap::word_index_round_up(idx_t bit) const {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
332 idx_t bit_rounded_up = bit + (BitsPerWord - 1);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
333 // Check for integer arithmetic overflow.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
334 return bit_rounded_up > bit ? word_index(bit_rounded_up) : size_in_words();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
335 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
336
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
337 inline BitMap::idx_t BitMap::get_next_one_offset(idx_t l_offset,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
338 idx_t r_offset) const {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
339 return get_next_one_offset_inline(l_offset, r_offset);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
340 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
341
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
342 inline BitMap::idx_t BitMap::get_next_zero_offset(idx_t l_offset,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
343 idx_t r_offset) const {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
344 return get_next_zero_offset_inline(l_offset, r_offset);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
345 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
346
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
347 inline void BitMap2D::clear() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
348 _map.clear();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
349 }
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
350
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
351 #endif // SHARE_VM_UTILITIES_BITMAP_INLINE_HPP