Mercurial > hg > graal-compiler
annotate src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp @ 10185:d50cc62e94ff
8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
Summary: In graphKit INT operations were generated to access PtrQueue::_index which has type size_t. This is 64 bit on 64-bit machines. No problems occur on little endian machines as long as the index fits into 32 bit, but on big endian machines the upper part is read, which is zero. This leads to unnecessary branches to the slow path in the runtime.
Reviewed-by: twisti, johnc
Contributed-by: Martin Doerr <martin.doerr@sap.com>
author | johnc |
---|---|
date | Wed, 24 Apr 2013 14:48:43 -0700 |
parents | b9a9ed0f8eeb |
children | 4868caa99ecf |
rev | line source |
---|---|
0 | 1 /* |
6842
b9a9ed0f8eeb
7197424: update copyright year to match last edit in jdk8 hotspot repository
mikael
parents:
6197
diff
changeset
|
2 * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
237
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
237
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:
237
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "gc_implementation/parallelScavenge/parMarkBitMap.hpp" | |
27 #include "gc_implementation/parallelScavenge/parMarkBitMap.inline.hpp" | |
28 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp" | |
29 #include "oops/oop.inline.hpp" | |
30 #include "runtime/os.hpp" | |
31 #include "utilities/bitMap.inline.hpp" | |
6197 | 32 #include "services/memTracker.hpp" |
1972 | 33 #ifdef TARGET_OS_FAMILY_linux |
34 # include "os_linux.inline.hpp" | |
35 #endif | |
36 #ifdef TARGET_OS_FAMILY_solaris | |
37 # include "os_solaris.inline.hpp" | |
38 #endif | |
39 #ifdef TARGET_OS_FAMILY_windows | |
40 # include "os_windows.inline.hpp" | |
41 #endif | |
3960 | 42 #ifdef TARGET_OS_FAMILY_bsd |
43 # include "os_bsd.inline.hpp" | |
44 #endif | |
0 | 45 |
46 bool | |
47 ParMarkBitMap::initialize(MemRegion covered_region) | |
48 { | |
49 const idx_t bits = bits_required(covered_region); | |
50 // The bits will be divided evenly between two bitmaps; each of them should be | |
51 // an integral number of words. | |
52 assert(bits % (BitsPerWord * 2) == 0, "region size unaligned"); | |
53 | |
54 const size_t words = bits / BitsPerWord; | |
55 const size_t raw_bytes = words * sizeof(idx_t); | |
56 const size_t page_sz = os::page_size_for_region(raw_bytes, raw_bytes, 10); | |
57 const size_t granularity = os::vm_allocation_granularity(); | |
58 const size_t bytes = align_size_up(raw_bytes, MAX2(page_sz, granularity)); | |
59 | |
60 const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 : | |
61 MAX2(page_sz, granularity); | |
79
82db0859acbe
6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents:
0
diff
changeset
|
62 ReservedSpace rs(bytes, rs_align, rs_align > 0); |
0 | 63 os::trace_page_sizes("par bitmap", raw_bytes, raw_bytes, page_sz, |
64 rs.base(), rs.size()); | |
6197 | 65 |
66 MemTracker::record_virtual_memory_type((address)rs.base(), mtGC); | |
67 | |
0 | 68 _virtual_space = new PSVirtualSpace(rs, page_sz); |
69 if (_virtual_space != NULL && _virtual_space->expand_by(bytes)) { | |
70 _region_start = covered_region.start(); | |
71 _region_size = covered_region.word_size(); | |
72 idx_t* map = (idx_t*)_virtual_space->reserved_low_addr(); | |
73 _beg_bits.set_map(map); | |
74 _beg_bits.set_size(bits / 2); | |
75 _end_bits.set_map(map + words / 2); | |
76 _end_bits.set_size(bits / 2); | |
77 return true; | |
78 } | |
79 | |
80 _region_start = 0; | |
81 _region_size = 0; | |
82 if (_virtual_space != NULL) { | |
83 delete _virtual_space; | |
84 _virtual_space = NULL; | |
237
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
196
diff
changeset
|
85 // Release memory reserved in the space. |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
196
diff
changeset
|
86 rs.release(); |
0 | 87 } |
88 return false; | |
89 } | |
90 | |
91 #ifdef ASSERT | |
92 extern size_t mark_bitmap_count; | |
93 extern size_t mark_bitmap_size; | |
94 #endif // #ifdef ASSERT | |
95 | |
96 bool | |
97 ParMarkBitMap::mark_obj(HeapWord* addr, size_t size) | |
98 { | |
99 const idx_t beg_bit = addr_to_bit(addr); | |
100 if (_beg_bits.par_set_bit(beg_bit)) { | |
101 const idx_t end_bit = addr_to_bit(addr + size - 1); | |
102 bool end_bit_ok = _end_bits.par_set_bit(end_bit); | |
103 assert(end_bit_ok, "concurrency problem"); | |
104 DEBUG_ONLY(Atomic::inc_ptr(&mark_bitmap_count)); | |
105 DEBUG_ONLY(Atomic::add_ptr(size, &mark_bitmap_size)); | |
106 return true; | |
107 } | |
108 return false; | |
109 } | |
110 | |
111 size_t | |
112 ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, HeapWord* end_addr) const | |
113 { | |
114 assert(beg_addr <= end_addr, "bad range"); | |
115 | |
116 idx_t live_bits = 0; | |
117 | |
118 // The bitmap routines require the right boundary to be word-aligned. | |
119 const idx_t end_bit = addr_to_bit(end_addr); | |
120 const idx_t range_end = BitMap::word_align_up(end_bit); | |
121 | |
122 idx_t beg_bit = find_obj_beg(addr_to_bit(beg_addr), range_end); | |
123 while (beg_bit < end_bit) { | |
124 idx_t tmp_end = find_obj_end(beg_bit, range_end); | |
125 if (tmp_end < end_bit) { | |
126 live_bits += tmp_end - beg_bit + 1; | |
127 beg_bit = find_obj_beg(tmp_end + 1, range_end); | |
128 } else { | |
129 live_bits += end_bit - beg_bit; // No + 1 here; end_bit is not counted. | |
130 return bits_to_words(live_bits); | |
131 } | |
132 } | |
133 return bits_to_words(live_bits); | |
134 } | |
135 | |
136 size_t ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, oop end_obj) const | |
137 { | |
138 assert(beg_addr <= (HeapWord*)end_obj, "bad range"); | |
139 assert(is_marked(end_obj), "end_obj must be live"); | |
140 | |
141 idx_t live_bits = 0; | |
142 | |
143 // The bitmap routines require the right boundary to be word-aligned. | |
144 const idx_t end_bit = addr_to_bit((HeapWord*)end_obj); | |
145 const idx_t range_end = BitMap::word_align_up(end_bit); | |
146 | |
147 idx_t beg_bit = find_obj_beg(addr_to_bit(beg_addr), range_end); | |
148 while (beg_bit < end_bit) { | |
149 idx_t tmp_end = find_obj_end(beg_bit, range_end); | |
150 assert(tmp_end < end_bit, "missing end bit"); | |
151 live_bits += tmp_end - beg_bit + 1; | |
152 beg_bit = find_obj_beg(tmp_end + 1, range_end); | |
153 } | |
154 return bits_to_words(live_bits); | |
155 } | |
156 | |
157 ParMarkBitMap::IterationStatus | |
158 ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure, | |
159 idx_t range_beg, idx_t range_end) const | |
160 { | |
161 DEBUG_ONLY(verify_bit(range_beg);) | |
162 DEBUG_ONLY(verify_bit(range_end);) | |
163 assert(range_beg <= range_end, "live range invalid"); | |
164 | |
165 // The bitmap routines require the right boundary to be word-aligned. | |
166 const idx_t search_end = BitMap::word_align_up(range_end); | |
167 | |
168 idx_t cur_beg = find_obj_beg(range_beg, search_end); | |
169 while (cur_beg < range_end) { | |
170 const idx_t cur_end = find_obj_end(cur_beg, search_end); | |
171 if (cur_end >= range_end) { | |
172 // The obj ends outside the range. | |
173 live_closure->set_source(bit_to_addr(cur_beg)); | |
174 return incomplete; | |
175 } | |
176 | |
177 const size_t size = obj_size(cur_beg, cur_end); | |
178 IterationStatus status = live_closure->do_addr(bit_to_addr(cur_beg), size); | |
179 if (status != incomplete) { | |
180 assert(status == would_overflow || status == full, "sanity"); | |
181 return status; | |
182 } | |
183 | |
184 // Successfully processed the object; look for the next object. | |
185 cur_beg = find_obj_beg(cur_end + 1, search_end); | |
186 } | |
187 | |
188 live_closure->set_source(bit_to_addr(range_end)); | |
189 return complete; | |
190 } | |
191 | |
192 ParMarkBitMap::IterationStatus | |
193 ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure, | |
194 ParMarkBitMapClosure* dead_closure, | |
195 idx_t range_beg, idx_t range_end, | |
196 idx_t dead_range_end) const | |
197 { | |
198 DEBUG_ONLY(verify_bit(range_beg);) | |
199 DEBUG_ONLY(verify_bit(range_end);) | |
200 DEBUG_ONLY(verify_bit(dead_range_end);) | |
201 assert(range_beg <= range_end, "live range invalid"); | |
202 assert(range_end <= dead_range_end, "dead range invalid"); | |
203 | |
204 // The bitmap routines require the right boundary to be word-aligned. | |
205 const idx_t live_search_end = BitMap::word_align_up(range_end); | |
206 const idx_t dead_search_end = BitMap::word_align_up(dead_range_end); | |
207 | |
208 idx_t cur_beg = range_beg; | |
209 if (range_beg < range_end && is_unmarked(range_beg)) { | |
210 // The range starts with dead space. Look for the next object, then fill. | |
211 cur_beg = find_obj_beg(range_beg + 1, dead_search_end); | |
212 const idx_t dead_space_end = MIN2(cur_beg - 1, dead_range_end - 1); | |
213 const size_t size = obj_size(range_beg, dead_space_end); | |
214 dead_closure->do_addr(bit_to_addr(range_beg), size); | |
215 } | |
216 | |
217 while (cur_beg < range_end) { | |
218 const idx_t cur_end = find_obj_end(cur_beg, live_search_end); | |
219 if (cur_end >= range_end) { | |
220 // The obj ends outside the range. | |
221 live_closure->set_source(bit_to_addr(cur_beg)); | |
222 return incomplete; | |
223 } | |
224 | |
225 const size_t size = obj_size(cur_beg, cur_end); | |
226 IterationStatus status = live_closure->do_addr(bit_to_addr(cur_beg), size); | |
227 if (status != incomplete) { | |
228 assert(status == would_overflow || status == full, "sanity"); | |
229 return status; | |
230 } | |
231 | |
232 // Look for the start of the next object. | |
233 const idx_t dead_space_beg = cur_end + 1; | |
234 cur_beg = find_obj_beg(dead_space_beg, dead_search_end); | |
235 if (cur_beg > dead_space_beg) { | |
236 // Found dead space; compute the size and invoke the dead closure. | |
237 const idx_t dead_space_end = MIN2(cur_beg - 1, dead_range_end - 1); | |
238 const size_t size = obj_size(dead_space_beg, dead_space_end); | |
239 dead_closure->do_addr(bit_to_addr(dead_space_beg), size); | |
240 } | |
241 } | |
242 | |
243 live_closure->set_source(bit_to_addr(range_end)); | |
244 return complete; | |
245 } | |
246 | |
247 #ifndef PRODUCT | |
248 void ParMarkBitMap::reset_counters() | |
249 { | |
250 _cas_tries = _cas_retries = _cas_by_another = 0; | |
251 } | |
252 #endif // #ifndef PRODUCT | |
253 | |
254 #ifdef ASSERT | |
255 void ParMarkBitMap::verify_clear() const | |
256 { | |
257 const idx_t* const beg = (const idx_t*)_virtual_space->committed_low_addr(); | |
258 const idx_t* const end = (const idx_t*)_virtual_space->committed_high_addr(); | |
259 for (const idx_t* p = beg; p < end; ++p) { | |
260 assert(*p == 0, "bitmap not clear"); | |
261 } | |
262 } | |
263 #endif // #ifdef ASSERT |