src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp

Thu, 22 Sep 2011 10:57:37 -0700

author
johnc
date
Thu, 22 Sep 2011 10:57:37 -0700
changeset 3175
4dfb2df418f2
parent 2314
f95d63e2154a
child 3156
f08d439fab8c
permissions
-rw-r--r--

6484982: G1: process references during evacuation pauses
Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate.
Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp

duke@435 1 /*
stefank@2314 2 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
stefank@2314 25 #include "precompiled.hpp"
stefank@2314 26 #include "gc_implementation/parallelScavenge/parMarkBitMap.hpp"
stefank@2314 27 #include "gc_implementation/parallelScavenge/parMarkBitMap.inline.hpp"
stefank@2314 28 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
stefank@2314 29 #include "oops/oop.inline.hpp"
stefank@2314 30 #include "runtime/os.hpp"
stefank@2314 31 #include "utilities/bitMap.inline.hpp"
stefank@2314 32 #ifdef TARGET_OS_FAMILY_linux
stefank@2314 33 # include "os_linux.inline.hpp"
stefank@2314 34 #endif
stefank@2314 35 #ifdef TARGET_OS_FAMILY_solaris
stefank@2314 36 # include "os_solaris.inline.hpp"
stefank@2314 37 #endif
stefank@2314 38 #ifdef TARGET_OS_FAMILY_windows
stefank@2314 39 # include "os_windows.inline.hpp"
stefank@2314 40 #endif
duke@435 41
duke@435 42 bool
duke@435 43 ParMarkBitMap::initialize(MemRegion covered_region)
duke@435 44 {
duke@435 45 const idx_t bits = bits_required(covered_region);
duke@435 46 // The bits will be divided evenly between two bitmaps; each of them should be
duke@435 47 // an integral number of words.
duke@435 48 assert(bits % (BitsPerWord * 2) == 0, "region size unaligned");
duke@435 49
duke@435 50 const size_t words = bits / BitsPerWord;
duke@435 51 const size_t raw_bytes = words * sizeof(idx_t);
duke@435 52 const size_t page_sz = os::page_size_for_region(raw_bytes, raw_bytes, 10);
duke@435 53 const size_t granularity = os::vm_allocation_granularity();
duke@435 54 const size_t bytes = align_size_up(raw_bytes, MAX2(page_sz, granularity));
duke@435 55
duke@435 56 const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
duke@435 57 MAX2(page_sz, granularity);
jcoomes@514 58 ReservedSpace rs(bytes, rs_align, rs_align > 0);
duke@435 59 os::trace_page_sizes("par bitmap", raw_bytes, raw_bytes, page_sz,
duke@435 60 rs.base(), rs.size());
duke@435 61 _virtual_space = new PSVirtualSpace(rs, page_sz);
duke@435 62 if (_virtual_space != NULL && _virtual_space->expand_by(bytes)) {
duke@435 63 _region_start = covered_region.start();
duke@435 64 _region_size = covered_region.word_size();
duke@435 65 idx_t* map = (idx_t*)_virtual_space->reserved_low_addr();
duke@435 66 _beg_bits.set_map(map);
duke@435 67 _beg_bits.set_size(bits / 2);
duke@435 68 _end_bits.set_map(map + words / 2);
duke@435 69 _end_bits.set_size(bits / 2);
duke@435 70 return true;
duke@435 71 }
duke@435 72
duke@435 73 _region_start = 0;
duke@435 74 _region_size = 0;
duke@435 75 if (_virtual_space != NULL) {
duke@435 76 delete _virtual_space;
duke@435 77 _virtual_space = NULL;
coleenp@672 78 // Release memory reserved in the space.
coleenp@672 79 rs.release();
duke@435 80 }
duke@435 81 return false;
duke@435 82 }
duke@435 83
duke@435 84 #ifdef ASSERT
duke@435 85 extern size_t mark_bitmap_count;
duke@435 86 extern size_t mark_bitmap_size;
duke@435 87 #endif // #ifdef ASSERT
duke@435 88
duke@435 89 bool
duke@435 90 ParMarkBitMap::mark_obj(HeapWord* addr, size_t size)
duke@435 91 {
duke@435 92 const idx_t beg_bit = addr_to_bit(addr);
duke@435 93 if (_beg_bits.par_set_bit(beg_bit)) {
duke@435 94 const idx_t end_bit = addr_to_bit(addr + size - 1);
duke@435 95 bool end_bit_ok = _end_bits.par_set_bit(end_bit);
duke@435 96 assert(end_bit_ok, "concurrency problem");
duke@435 97 DEBUG_ONLY(Atomic::inc_ptr(&mark_bitmap_count));
duke@435 98 DEBUG_ONLY(Atomic::add_ptr(size, &mark_bitmap_size));
duke@435 99 return true;
duke@435 100 }
duke@435 101 return false;
duke@435 102 }
duke@435 103
duke@435 104 size_t
duke@435 105 ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, HeapWord* end_addr) const
duke@435 106 {
duke@435 107 assert(beg_addr <= end_addr, "bad range");
duke@435 108
duke@435 109 idx_t live_bits = 0;
duke@435 110
duke@435 111 // The bitmap routines require the right boundary to be word-aligned.
duke@435 112 const idx_t end_bit = addr_to_bit(end_addr);
duke@435 113 const idx_t range_end = BitMap::word_align_up(end_bit);
duke@435 114
duke@435 115 idx_t beg_bit = find_obj_beg(addr_to_bit(beg_addr), range_end);
duke@435 116 while (beg_bit < end_bit) {
duke@435 117 idx_t tmp_end = find_obj_end(beg_bit, range_end);
duke@435 118 if (tmp_end < end_bit) {
duke@435 119 live_bits += tmp_end - beg_bit + 1;
duke@435 120 beg_bit = find_obj_beg(tmp_end + 1, range_end);
duke@435 121 } else {
duke@435 122 live_bits += end_bit - beg_bit; // No + 1 here; end_bit is not counted.
duke@435 123 return bits_to_words(live_bits);
duke@435 124 }
duke@435 125 }
duke@435 126 return bits_to_words(live_bits);
duke@435 127 }
duke@435 128
duke@435 129 size_t ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, oop end_obj) const
duke@435 130 {
duke@435 131 assert(beg_addr <= (HeapWord*)end_obj, "bad range");
duke@435 132 assert(is_marked(end_obj), "end_obj must be live");
duke@435 133
duke@435 134 idx_t live_bits = 0;
duke@435 135
duke@435 136 // The bitmap routines require the right boundary to be word-aligned.
duke@435 137 const idx_t end_bit = addr_to_bit((HeapWord*)end_obj);
duke@435 138 const idx_t range_end = BitMap::word_align_up(end_bit);
duke@435 139
duke@435 140 idx_t beg_bit = find_obj_beg(addr_to_bit(beg_addr), range_end);
duke@435 141 while (beg_bit < end_bit) {
duke@435 142 idx_t tmp_end = find_obj_end(beg_bit, range_end);
duke@435 143 assert(tmp_end < end_bit, "missing end bit");
duke@435 144 live_bits += tmp_end - beg_bit + 1;
duke@435 145 beg_bit = find_obj_beg(tmp_end + 1, range_end);
duke@435 146 }
duke@435 147 return bits_to_words(live_bits);
duke@435 148 }
duke@435 149
duke@435 150 ParMarkBitMap::IterationStatus
duke@435 151 ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure,
duke@435 152 idx_t range_beg, idx_t range_end) const
duke@435 153 {
duke@435 154 DEBUG_ONLY(verify_bit(range_beg);)
duke@435 155 DEBUG_ONLY(verify_bit(range_end);)
duke@435 156 assert(range_beg <= range_end, "live range invalid");
duke@435 157
duke@435 158 // The bitmap routines require the right boundary to be word-aligned.
duke@435 159 const idx_t search_end = BitMap::word_align_up(range_end);
duke@435 160
duke@435 161 idx_t cur_beg = find_obj_beg(range_beg, search_end);
duke@435 162 while (cur_beg < range_end) {
duke@435 163 const idx_t cur_end = find_obj_end(cur_beg, search_end);
duke@435 164 if (cur_end >= range_end) {
duke@435 165 // The obj ends outside the range.
duke@435 166 live_closure->set_source(bit_to_addr(cur_beg));
duke@435 167 return incomplete;
duke@435 168 }
duke@435 169
duke@435 170 const size_t size = obj_size(cur_beg, cur_end);
duke@435 171 IterationStatus status = live_closure->do_addr(bit_to_addr(cur_beg), size);
duke@435 172 if (status != incomplete) {
duke@435 173 assert(status == would_overflow || status == full, "sanity");
duke@435 174 return status;
duke@435 175 }
duke@435 176
duke@435 177 // Successfully processed the object; look for the next object.
duke@435 178 cur_beg = find_obj_beg(cur_end + 1, search_end);
duke@435 179 }
duke@435 180
duke@435 181 live_closure->set_source(bit_to_addr(range_end));
duke@435 182 return complete;
duke@435 183 }
duke@435 184
duke@435 185 ParMarkBitMap::IterationStatus
duke@435 186 ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure,
duke@435 187 ParMarkBitMapClosure* dead_closure,
duke@435 188 idx_t range_beg, idx_t range_end,
duke@435 189 idx_t dead_range_end) const
duke@435 190 {
duke@435 191 DEBUG_ONLY(verify_bit(range_beg);)
duke@435 192 DEBUG_ONLY(verify_bit(range_end);)
duke@435 193 DEBUG_ONLY(verify_bit(dead_range_end);)
duke@435 194 assert(range_beg <= range_end, "live range invalid");
duke@435 195 assert(range_end <= dead_range_end, "dead range invalid");
duke@435 196
duke@435 197 // The bitmap routines require the right boundary to be word-aligned.
duke@435 198 const idx_t live_search_end = BitMap::word_align_up(range_end);
duke@435 199 const idx_t dead_search_end = BitMap::word_align_up(dead_range_end);
duke@435 200
duke@435 201 idx_t cur_beg = range_beg;
duke@435 202 if (range_beg < range_end && is_unmarked(range_beg)) {
duke@435 203 // The range starts with dead space. Look for the next object, then fill.
duke@435 204 cur_beg = find_obj_beg(range_beg + 1, dead_search_end);
duke@435 205 const idx_t dead_space_end = MIN2(cur_beg - 1, dead_range_end - 1);
duke@435 206 const size_t size = obj_size(range_beg, dead_space_end);
duke@435 207 dead_closure->do_addr(bit_to_addr(range_beg), size);
duke@435 208 }
duke@435 209
duke@435 210 while (cur_beg < range_end) {
duke@435 211 const idx_t cur_end = find_obj_end(cur_beg, live_search_end);
duke@435 212 if (cur_end >= range_end) {
duke@435 213 // The obj ends outside the range.
duke@435 214 live_closure->set_source(bit_to_addr(cur_beg));
duke@435 215 return incomplete;
duke@435 216 }
duke@435 217
duke@435 218 const size_t size = obj_size(cur_beg, cur_end);
duke@435 219 IterationStatus status = live_closure->do_addr(bit_to_addr(cur_beg), size);
duke@435 220 if (status != incomplete) {
duke@435 221 assert(status == would_overflow || status == full, "sanity");
duke@435 222 return status;
duke@435 223 }
duke@435 224
duke@435 225 // Look for the start of the next object.
duke@435 226 const idx_t dead_space_beg = cur_end + 1;
duke@435 227 cur_beg = find_obj_beg(dead_space_beg, dead_search_end);
duke@435 228 if (cur_beg > dead_space_beg) {
duke@435 229 // Found dead space; compute the size and invoke the dead closure.
duke@435 230 const idx_t dead_space_end = MIN2(cur_beg - 1, dead_range_end - 1);
duke@435 231 const size_t size = obj_size(dead_space_beg, dead_space_end);
duke@435 232 dead_closure->do_addr(bit_to_addr(dead_space_beg), size);
duke@435 233 }
duke@435 234 }
duke@435 235
duke@435 236 live_closure->set_source(bit_to_addr(range_end));
duke@435 237 return complete;
duke@435 238 }
duke@435 239
duke@435 240 #ifndef PRODUCT
duke@435 241 void ParMarkBitMap::reset_counters()
duke@435 242 {
duke@435 243 _cas_tries = _cas_retries = _cas_by_another = 0;
duke@435 244 }
duke@435 245 #endif // #ifndef PRODUCT
duke@435 246
duke@435 247 #ifdef ASSERT
duke@435 248 void ParMarkBitMap::verify_clear() const
duke@435 249 {
duke@435 250 const idx_t* const beg = (const idx_t*)_virtual_space->committed_low_addr();
duke@435 251 const idx_t* const end = (const idx_t*)_virtual_space->committed_high_addr();
duke@435 252 for (const idx_t* p = beg; p < end; ++p) {
duke@435 253 assert(*p == 0, "bitmap not clear");
duke@435 254 }
duke@435 255 }
duke@435 256 #endif // #ifdef ASSERT

mercurial