annotate src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @ 453:c96030fff130

6684579: SoftReference processing can be made more efficient Summary: For current soft-ref clearing policies, we can decide at marking time if a soft-reference will definitely not be cleared, postponing the decision of whether it will definitely be cleared to the final reference processing phase. This can be especially beneficial in the case of concurrent collectors where the marking is usually concurrent but reference processing is usually not. Reviewed-by: jmasa
author ysr
date Thu, 20 Nov 2008 16:56:09 -0800
parents 0166ac265d53
children 27a80744a83b
rev   line source
duke@0 1 /*
xdono@196 2 * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
duke@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@0 4 *
duke@0 5 * This code is free software; you can redistribute it and/or modify it
duke@0 6 * under the terms of the GNU General Public License version 2 only, as
duke@0 7 * published by the Free Software Foundation.
duke@0 8 *
duke@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@0 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@0 13 * accompanied this code).
duke@0 14 *
duke@0 15 * You should have received a copy of the GNU General Public License version
duke@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@0 18 *
duke@0 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
duke@0 20 * CA 95054 USA or visit www.sun.com if you need additional information or
duke@0 21 * have any questions.
duke@0 22 *
duke@0 23 */
duke@0 24
duke@0 25 #include "incls/_precompiled.incl"
duke@0 26 #include "incls/_psParallelCompact.cpp.incl"
duke@0 27
duke@0 28 #include <math.h>
duke@0 29
duke@0 30 // All sizes are in HeapWords.
jcoomes@375 31 const size_t ParallelCompactData::Log2RegionSize = 9; // 512 words
jcoomes@375 32 const size_t ParallelCompactData::RegionSize = (size_t)1 << Log2RegionSize;
jcoomes@375 33 const size_t ParallelCompactData::RegionSizeBytes =
jcoomes@375 34 RegionSize << LogHeapWordSize;
jcoomes@375 35 const size_t ParallelCompactData::RegionSizeOffsetMask = RegionSize - 1;
jcoomes@375 36 const size_t ParallelCompactData::RegionAddrOffsetMask = RegionSizeBytes - 1;
jcoomes@375 37 const size_t ParallelCompactData::RegionAddrMask = ~RegionAddrOffsetMask;
duke@0 38
jcoomes@375 39 const ParallelCompactData::RegionData::region_sz_t
jcoomes@375 40 ParallelCompactData::RegionData::dc_shift = 27;
jcoomes@375 41
jcoomes@375 42 const ParallelCompactData::RegionData::region_sz_t
jcoomes@375 43 ParallelCompactData::RegionData::dc_mask = ~0U << dc_shift;
jcoomes@375 44
jcoomes@375 45 const ParallelCompactData::RegionData::region_sz_t
jcoomes@375 46 ParallelCompactData::RegionData::dc_one = 0x1U << dc_shift;
jcoomes@375 47
jcoomes@375 48 const ParallelCompactData::RegionData::region_sz_t
jcoomes@375 49 ParallelCompactData::RegionData::los_mask = ~dc_mask;
jcoomes@375 50
jcoomes@375 51 const ParallelCompactData::RegionData::region_sz_t
jcoomes@375 52 ParallelCompactData::RegionData::dc_claimed = 0x8U << dc_shift;
jcoomes@375 53
jcoomes@375 54 const ParallelCompactData::RegionData::region_sz_t
jcoomes@375 55 ParallelCompactData::RegionData::dc_completed = 0xcU << dc_shift;
duke@0 56
duke@0 57 SpaceInfo PSParallelCompact::_space_info[PSParallelCompact::last_space_id];
duke@0 58 bool PSParallelCompact::_print_phases = false;
duke@0 59
duke@0 60 ReferenceProcessor* PSParallelCompact::_ref_processor = NULL;
duke@0 61 klassOop PSParallelCompact::_updated_int_array_klass_obj = NULL;
duke@0 62
duke@0 63 double PSParallelCompact::_dwl_mean;
duke@0 64 double PSParallelCompact::_dwl_std_dev;
duke@0 65 double PSParallelCompact::_dwl_first_term;
duke@0 66 double PSParallelCompact::_dwl_adjustment;
duke@0 67 #ifdef ASSERT
duke@0 68 bool PSParallelCompact::_dwl_initialized = false;
duke@0 69 #endif // #ifdef ASSERT
duke@0 70
duke@0 71 #ifdef VALIDATE_MARK_SWEEP
coleenp@113 72 GrowableArray<void*>* PSParallelCompact::_root_refs_stack = NULL;
duke@0 73 GrowableArray<oop> * PSParallelCompact::_live_oops = NULL;
duke@0 74 GrowableArray<oop> * PSParallelCompact::_live_oops_moved_to = NULL;
duke@0 75 GrowableArray<size_t>* PSParallelCompact::_live_oops_size = NULL;
duke@0 76 size_t PSParallelCompact::_live_oops_index = 0;
duke@0 77 size_t PSParallelCompact::_live_oops_index_at_perm = 0;
coleenp@113 78 GrowableArray<void*>* PSParallelCompact::_other_refs_stack = NULL;
coleenp@113 79 GrowableArray<void*>* PSParallelCompact::_adjusted_pointers = NULL;
duke@0 80 bool PSParallelCompact::_pointer_tracking = false;
duke@0 81 bool PSParallelCompact::_root_tracking = true;
duke@0 82
duke@0 83 GrowableArray<HeapWord*>* PSParallelCompact::_cur_gc_live_oops = NULL;
duke@0 84 GrowableArray<HeapWord*>* PSParallelCompact::_cur_gc_live_oops_moved_to = NULL;
duke@0 85 GrowableArray<size_t> * PSParallelCompact::_cur_gc_live_oops_size = NULL;
duke@0 86 GrowableArray<HeapWord*>* PSParallelCompact::_last_gc_live_oops = NULL;
duke@0 87 GrowableArray<HeapWord*>* PSParallelCompact::_last_gc_live_oops_moved_to = NULL;
duke@0 88 GrowableArray<size_t> * PSParallelCompact::_last_gc_live_oops_size = NULL;
duke@0 89 #endif
duke@0 90
duke@0 91 #ifndef PRODUCT
duke@0 92 const char* PSParallelCompact::space_names[] = {
duke@0 93 "perm", "old ", "eden", "from", "to "
duke@0 94 };
duke@0 95
jcoomes@375 96 void PSParallelCompact::print_region_ranges()
duke@0 97 {
duke@0 98 tty->print_cr("space bottom top end new_top");
duke@0 99 tty->print_cr("------ ---------- ---------- ---------- ----------");
duke@0 100
duke@0 101 for (unsigned int id = 0; id < last_space_id; ++id) {
duke@0 102 const MutableSpace* space = _space_info[id].space();
duke@0 103 tty->print_cr("%u %s "
jcoomes@264 104 SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " "
jcoomes@264 105 SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " ",
duke@0 106 id, space_names[id],
jcoomes@375 107 summary_data().addr_to_region_idx(space->bottom()),
jcoomes@375 108 summary_data().addr_to_region_idx(space->top()),
jcoomes@375 109 summary_data().addr_to_region_idx(space->end()),
jcoomes@375 110 summary_data().addr_to_region_idx(_space_info[id].new_top()));
duke@0 111 }
duke@0 112 }
duke@0 113
duke@0 114 void
jcoomes@375 115 print_generic_summary_region(size_t i, const ParallelCompactData::RegionData* c)
duke@0 116 {
jcoomes@375 117 #define REGION_IDX_FORMAT SIZE_FORMAT_W(7)
jcoomes@375 118 #define REGION_DATA_FORMAT SIZE_FORMAT_W(5)
duke@0 119
duke@0 120 ParallelCompactData& sd = PSParallelCompact::summary_data();
jcoomes@375 121 size_t dci = c->destination() ? sd.addr_to_region_idx(c->destination()) : 0;
jcoomes@375 122 tty->print_cr(REGION_IDX_FORMAT " " PTR_FORMAT " "
jcoomes@375 123 REGION_IDX_FORMAT " " PTR_FORMAT " "
jcoomes@375 124 REGION_DATA_FORMAT " " REGION_DATA_FORMAT " "
jcoomes@375 125 REGION_DATA_FORMAT " " REGION_IDX_FORMAT " %d",
duke@0 126 i, c->data_location(), dci, c->destination(),
duke@0 127 c->partial_obj_size(), c->live_obj_size(),
jcoomes@375 128 c->data_size(), c->source_region(), c->destination_count());
jcoomes@375 129
jcoomes@375 130 #undef REGION_IDX_FORMAT
jcoomes@375 131 #undef REGION_DATA_FORMAT
duke@0 132 }
duke@0 133
duke@0 134 void
duke@0 135 print_generic_summary_data(ParallelCompactData& summary_data,
duke@0 136 HeapWord* const beg_addr,
duke@0 137 HeapWord* const end_addr)
duke@0 138 {
duke@0 139 size_t total_words = 0;
jcoomes@375 140 size_t i = summary_data.addr_to_region_idx(beg_addr);
jcoomes@375 141 const size_t last = summary_data.addr_to_region_idx(end_addr);
duke@0 142 HeapWord* pdest = 0;
duke@0 143
duke@0 144 while (i <= last) {
jcoomes@375 145 ParallelCompactData::RegionData* c = summary_data.region(i);
duke@0 146 if (c->data_size() != 0 || c->destination() != pdest) {
jcoomes@375 147 print_generic_summary_region(i, c);
duke@0 148 total_words += c->data_size();
duke@0 149 pdest = c->destination();
duke@0 150 }
duke@0 151 ++i;
duke@0 152 }
duke@0 153
duke@0 154 tty->print_cr("summary_data_bytes=" SIZE_FORMAT, total_words * HeapWordSize);
duke@0 155 }
duke@0 156
duke@0 157 void
duke@0 158 print_generic_summary_data(ParallelCompactData& summary_data,
duke@0 159 SpaceInfo* space_info)
duke@0 160 {
duke@0 161 for (unsigned int id = 0; id < PSParallelCompact::last_space_id; ++id) {
duke@0 162 const MutableSpace* space = space_info[id].space();
duke@0 163 print_generic_summary_data(summary_data, space->bottom(),
duke@0 164 MAX2(space->top(), space_info[id].new_top()));
duke@0 165 }
duke@0 166 }
duke@0 167
duke@0 168 void
jcoomes@375 169 print_initial_summary_region(size_t i,
jcoomes@375 170 const ParallelCompactData::RegionData* c,
jcoomes@375 171 bool newline = true)
duke@0 172 {
jcoomes@264 173 tty->print(SIZE_FORMAT_W(5) " " PTR_FORMAT " "
jcoomes@264 174 SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " "
jcoomes@264 175 SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d",
duke@0 176 i, c->destination(),
duke@0 177 c->partial_obj_size(), c->live_obj_size(),
jcoomes@375 178 c->data_size(), c->source_region(), c->destination_count());
duke@0 179 if (newline) tty->cr();
duke@0 180 }
duke@0 181
duke@0 182 void
duke@0 183 print_initial_summary_data(ParallelCompactData& summary_data,
duke@0 184 const MutableSpace* space) {
duke@0 185 if (space->top() == space->bottom()) {
duke@0 186 return;
duke@0 187 }
duke@0 188
jcoomes@375 189 const size_t region_size = ParallelCompactData::RegionSize;
jcoomes@375 190 typedef ParallelCompactData::RegionData RegionData;
jcoomes@375 191 HeapWord* const top_aligned_up = summary_data.region_align_up(space->top());
jcoomes@375 192 const size_t end_region = summary_data.addr_to_region_idx(top_aligned_up);
jcoomes@375 193 const RegionData* c = summary_data.region(end_region - 1);
duke@0 194 HeapWord* end_addr = c->destination() + c->data_size();
duke@0 195 const size_t live_in_space = pointer_delta(end_addr, space->bottom());
duke@0 196
jcoomes@375 197 // Print (and count) the full regions at the beginning of the space.
jcoomes@375 198 size_t full_region_count = 0;
jcoomes@375 199 size_t i = summary_data.addr_to_region_idx(space->bottom());
jcoomes@375 200 while (i < end_region && summary_data.region(i)->data_size() == region_size) {
jcoomes@375 201 print_initial_summary_region(i, summary_data.region(i));
jcoomes@375 202 ++full_region_count;
duke@0 203 ++i;
duke@0 204 }
duke@0 205
jcoomes@375 206 size_t live_to_right = live_in_space - full_region_count * region_size;
duke@0 207
duke@0 208 double max_reclaimed_ratio = 0.0;
jcoomes@375 209 size_t max_reclaimed_ratio_region = 0;
duke@0 210 size_t max_dead_to_right = 0;
duke@0 211 size_t max_live_to_right = 0;
duke@0 212
jcoomes@375 213 // Print the 'reclaimed ratio' for regions while there is something live in
jcoomes@375 214 // the region or to the right of it. The remaining regions are empty (and
duke@0 215 // uninteresting), and computing the ratio will result in division by 0.
jcoomes@375 216 while (i < end_region && live_to_right > 0) {
jcoomes@375 217 c = summary_data.region(i);
jcoomes@375 218 HeapWord* const region_addr = summary_data.region_to_addr(i);
jcoomes@375 219 const size_t used_to_right = pointer_delta(space->top(), region_addr);
duke@0 220 const size_t dead_to_right = used_to_right - live_to_right;
duke@0 221 const double reclaimed_ratio = double(dead_to_right) / live_to_right;
duke@0 222
duke@0 223 if (reclaimed_ratio > max_reclaimed_ratio) {
duke@0 224 max_reclaimed_ratio = reclaimed_ratio;
jcoomes@375 225 max_reclaimed_ratio_region = i;
duke@0 226 max_dead_to_right = dead_to_right;
duke@0 227 max_live_to_right = live_to_right;
duke@0 228 }
duke@0 229
jcoomes@375 230 print_initial_summary_region(i, c, false);
jcoomes@264 231 tty->print_cr(" %12.10f " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10),
duke@0 232 reclaimed_ratio, dead_to_right, live_to_right);
duke@0 233
duke@0 234 live_to_right -= c->data_size();
duke@0 235 ++i;
duke@0 236 }
duke@0 237
jcoomes@375 238 // Any remaining regions are empty. Print one more if there is one.
jcoomes@375 239 if (i < end_region) {
jcoomes@375 240 print_initial_summary_region(i, summary_data.region(i));
duke@0 241 }
duke@0 242
jcoomes@264 243 tty->print_cr("max: " SIZE_FORMAT_W(4) " d2r=" SIZE_FORMAT_W(10) " "
jcoomes@264 244 "l2r=" SIZE_FORMAT_W(10) " max_ratio=%14.12f",
jcoomes@375 245 max_reclaimed_ratio_region, max_dead_to_right,
duke@0 246 max_live_to_right, max_reclaimed_ratio);
duke@0 247 }
duke@0 248
duke@0 249 void
duke@0 250 print_initial_summary_data(ParallelCompactData& summary_data,
duke@0 251 SpaceInfo* space_info) {
duke@0 252 unsigned int id = PSParallelCompact::perm_space_id;
duke@0 253 const MutableSpace* space;
duke@0 254 do {
duke@0 255 space = space_info[id].space();
duke@0 256 print_initial_summary_data(summary_data, space);
duke@0 257 } while (++id < PSParallelCompact::eden_space_id);
duke@0 258
duke@0 259 do {
duke@0 260 space = space_info[id].space();
duke@0 261 print_generic_summary_data(summary_data, space->bottom(), space->top());
duke@0 262 } while (++id < PSParallelCompact::last_space_id);
duke@0 263 }
duke@0 264 #endif // #ifndef PRODUCT
duke@0 265
duke@0 266 #ifdef ASSERT
duke@0 267 size_t add_obj_count;
duke@0 268 size_t add_obj_size;
duke@0 269 size_t mark_bitmap_count;
duke@0 270 size_t mark_bitmap_size;
duke@0 271 #endif // #ifdef ASSERT
duke@0 272
duke@0 273 ParallelCompactData::ParallelCompactData()
duke@0 274 {
duke@0 275 _region_start = 0;
duke@0 276
jcoomes@375 277 _region_vspace = 0;
jcoomes@375 278 _region_data = 0;
jcoomes@375 279 _region_count = 0;
duke@0 280 }
duke@0 281
duke@0 282 bool ParallelCompactData::initialize(MemRegion covered_region)
duke@0 283 {
duke@0 284 _region_start = covered_region.start();
duke@0 285 const size_t region_size = covered_region.word_size();
duke@0 286 DEBUG_ONLY(_region_end = _region_start + region_size;)
duke@0 287
jcoomes@375 288 assert(region_align_down(_region_start) == _region_start,
duke@0 289 "region start not aligned");
jcoomes@375 290 assert((region_size & RegionSizeOffsetMask) == 0,
jcoomes@375 291 "region size not a multiple of RegionSize");
jcoomes@375 292
jcoomes@375 293 bool result = initialize_region_data(region_size);
duke@0 294
duke@0 295 return result;
duke@0 296 }
duke@0 297
duke@0 298 PSVirtualSpace*
duke@0 299 ParallelCompactData::create_vspace(size_t count, size_t element_size)
duke@0 300 {
duke@0 301 const size_t raw_bytes = count * element_size;
duke@0 302 const size_t page_sz = os::page_size_for_region(raw_bytes, raw_bytes, 10);
duke@0 303 const size_t granularity = os::vm_allocation_granularity();
duke@0 304 const size_t bytes = align_size_up(raw_bytes, MAX2(page_sz, granularity));
duke@0 305
duke@0 306 const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :
duke@0 307 MAX2(page_sz, granularity);
jcoomes@79 308 ReservedSpace rs(bytes, rs_align, rs_align > 0);
duke@0 309 os::trace_page_sizes("par compact", raw_bytes, raw_bytes, page_sz, rs.base(),
duke@0 310 rs.size());
duke@0 311 PSVirtualSpace* vspace = new PSVirtualSpace(rs, page_sz);
duke@0 312 if (vspace != 0) {
duke@0 313 if (vspace->expand_by(bytes)) {
duke@0 314 return vspace;
duke@0 315 }
duke@0 316 delete vspace;
coleenp@237 317 // Release memory reserved in the space.
coleenp@237 318 rs.release();
duke@0 319 }
duke@0 320
duke@0 321 return 0;
duke@0 322 }
duke@0 323
jcoomes@375 324 bool ParallelCompactData::initialize_region_data(size_t region_size)
duke@0 325 {
jcoomes@375 326 const size_t count = (region_size + RegionSizeOffsetMask) >> Log2RegionSize;
jcoomes@375 327 _region_vspace = create_vspace(count, sizeof(RegionData));
jcoomes@375 328 if (_region_vspace != 0) {
jcoomes@375 329 _region_data = (RegionData*)_region_vspace->reserved_low_addr();
jcoomes@375 330 _region_count = count;
duke@0 331 return true;
duke@0 332 }
duke@0 333 return false;
duke@0 334 }
duke@0 335
duke@0 336 void ParallelCompactData::clear()
duke@0 337 {
jcoomes@375 338 memset(_region_data, 0, _region_vspace->committed_size());
duke@0 339 }
duke@0 340
jcoomes@375 341 void ParallelCompactData::clear_range(size_t beg_region, size_t end_region) {
jcoomes@375 342 assert(beg_region <= _region_count, "beg_region out of range");
jcoomes@375 343 assert(end_region <= _region_count, "end_region out of range");
jcoomes@375 344
jcoomes@375 345 const size_t region_cnt = end_region - beg_region;
jcoomes@375 346 memset(_region_data + beg_region, 0, region_cnt * sizeof(RegionData));
duke@0 347 }
duke@0 348
jcoomes@375 349 HeapWord* ParallelCompactData::partial_obj_end(size_t region_idx) const
duke@0 350 {
jcoomes@375 351 const RegionData* cur_cp = region(region_idx);
jcoomes@375 352 const RegionData* const end_cp = region(region_count() - 1);
jcoomes@375 353
jcoomes@375 354 HeapWord* result = region_to_addr(region_idx);
duke@0 355 if (cur_cp < end_cp) {
duke@0 356 do {
duke@0 357 result += cur_cp->partial_obj_size();
jcoomes@375 358 } while (cur_cp->partial_obj_size() == RegionSize && ++cur_cp < end_cp);
duke@0 359 }
duke@0 360 return result;
duke@0 361 }
duke@0 362
duke@0 363 void ParallelCompactData::add_obj(HeapWord* addr, size_t len)
duke@0 364 {
duke@0 365 const size_t obj_ofs = pointer_delta(addr, _region_start);
jcoomes@375 366 const size_t beg_region = obj_ofs >> Log2RegionSize;
jcoomes@375 367 const size_t end_region = (obj_ofs + len - 1) >> Log2RegionSize;
duke@0 368
duke@0 369 DEBUG_ONLY(Atomic::inc_ptr(&add_obj_count);)
duke@0 370 DEBUG_ONLY(Atomic::add_ptr(len, &add_obj_size);)
duke@0 371
jcoomes@375 372 if (beg_region == end_region) {
jcoomes@375 373 // All in one region.
jcoomes@375 374 _region_data[beg_region].add_live_obj(len);
duke@0 375 return;
duke@0 376 }
duke@0 377
jcoomes@375 378 // First region.
jcoomes@375 379 const size_t beg_ofs = region_offset(addr);
jcoomes@375 380 _region_data[beg_region].add_live_obj(RegionSize - beg_ofs);
duke@0 381
duke@0 382 klassOop klass = ((oop)addr)->klass();
jcoomes@375 383 // Middle regions--completely spanned by this object.
jcoomes@375 384 for (size_t region = beg_region + 1; region < end_region; ++region) {
jcoomes@375 385 _region_data[region].set_partial_obj_size(RegionSize);
jcoomes@375 386 _region_data[region].set_partial_obj_addr(addr);
duke@0 387 }
duke@0 388
jcoomes@375 389 // Last region.
jcoomes@375 390 const size_t end_ofs = region_offset(addr + len - 1);
jcoomes@375 391 _region_data[end_region].set_partial_obj_size(end_ofs + 1);
jcoomes@375 392 _region_data[end_region].set_partial_obj_addr(addr);
duke@0 393 }
duke@0 394
duke@0 395 void
duke@0 396 ParallelCompactData::summarize_dense_prefix(HeapWord* beg, HeapWord* end)
duke@0 397 {
jcoomes@375 398 assert(region_offset(beg) == 0, "not RegionSize aligned");
jcoomes@375 399 assert(region_offset(end) == 0, "not RegionSize aligned");
jcoomes@375 400
jcoomes@375 401 size_t cur_region = addr_to_region_idx(beg);
jcoomes@375 402 const size_t end_region = addr_to_region_idx(end);
duke@0 403 HeapWord* addr = beg;
jcoomes@375 404 while (cur_region < end_region) {
jcoomes@375 405 _region_data[cur_region].set_destination(addr);
jcoomes@375 406 _region_data[cur_region].set_destination_count(0);
jcoomes@375 407 _region_data[cur_region].set_source_region(cur_region);
jcoomes@375 408 _region_data[cur_region].set_data_location(addr);
jcoomes@375 409
jcoomes@375 410 // Update live_obj_size so the region appears completely full.
jcoomes@375 411 size_t live_size = RegionSize - _region_data[cur_region].partial_obj_size();
jcoomes@375 412 _region_data[cur_region].set_live_obj_size(live_size);
jcoomes@375 413
jcoomes@375 414 ++cur_region;
jcoomes@375 415 addr += RegionSize;
duke@0 416 }
duke@0 417 }
duke@0 418
duke@0 419 bool ParallelCompactData::summarize(HeapWord* target_beg, HeapWord* target_end,
duke@0 420 HeapWord* source_beg, HeapWord* source_end,
duke@0 421 HeapWord** target_next,
duke@0 422 HeapWord** source_next) {
duke@0 423 // This is too strict.
jcoomes@375 424 // assert(region_offset(source_beg) == 0, "not RegionSize aligned");
duke@0 425
duke@0 426 if (TraceParallelOldGCSummaryPhase) {
duke@0 427 tty->print_cr("tb=" PTR_FORMAT " te=" PTR_FORMAT " "
duke@0 428 "sb=" PTR_FORMAT " se=" PTR_FORMAT " "
duke@0 429 "tn=" PTR_FORMAT " sn=" PTR_FORMAT,
duke@0 430 target_beg, target_end,
duke@0 431 source_beg, source_end,
duke@0 432 target_next != 0 ? *target_next : (HeapWord*) 0,
duke@0 433 source_next != 0 ? *source_next : (HeapWord*) 0);
duke@0 434 }
duke@0 435
jcoomes@375 436 size_t cur_region = addr_to_region_idx(source_beg);
jcoomes@375 437 const size_t end_region = addr_to_region_idx(region_align_up(source_end));
duke@0 438
duke@0 439 HeapWord *dest_addr = target_beg;
jcoomes@375 440 while (cur_region < end_region) {
jcoomes@375 441 size_t words = _region_data[cur_region].data_size();
duke@0 442
duke@0 443 #if 1
duke@0 444 assert(pointer_delta(target_end, dest_addr) >= words,
duke@0 445 "source region does not fit into target region");
duke@0 446 #else
jcoomes@375 447 // XXX - need some work on the corner cases here. If the region does not
jcoomes@375 448 // fit, then must either make sure any partial_obj from the region fits, or
jcoomes@375 449 // "undo" the initial part of the partial_obj that is in the previous
jcoomes@375 450 // region.
duke@0 451 if (dest_addr + words >= target_end) {
duke@0 452 // Let the caller know where to continue.
duke@0 453 *target_next = dest_addr;
jcoomes@375 454 *source_next = region_to_addr(cur_region);
duke@0 455 return false;
duke@0 456 }
duke@0 457 #endif // #if 1
duke@0 458
jcoomes@375 459 _region_data[cur_region].set_destination(dest_addr);
jcoomes@375 460
jcoomes@375 461 // Set the destination_count for cur_region, and if necessary, update
jcoomes@375 462 // source_region for a destination region. The source_region field is
jcoomes@375 463 // updated if cur_region is the first (left-most) region to be copied to a
jcoomes@375 464 // destination region.
duke@0 465 //
jcoomes@375 466 // The destination_count calculation is a bit subtle. A region that has
jcoomes@375 467 // data that compacts into itself does not count itself as a destination.
jcoomes@375 468 // This maintains the invariant that a zero count means the region is
jcoomes@375 469 // available and can be claimed and then filled.
duke@0 470 if (words > 0) {
duke@0 471 HeapWord* const last_addr = dest_addr + words - 1;
jcoomes@375 472 const size_t dest_region_1 = addr_to_region_idx(dest_addr);
jcoomes@375 473 const size_t dest_region_2 = addr_to_region_idx(last_addr);
duke@0 474 #if 0
jcoomes@375 475 // Initially assume that the destination regions will be the same and
duke@0 476 // adjust the value below if necessary. Under this assumption, if
jcoomes@375 477 // cur_region == dest_region_2, then cur_region will be compacted
jcoomes@375 478 // completely into itself.
jcoomes@375 479 uint destination_count = cur_region == dest_region_2 ? 0 : 1;
jcoomes@375 480 if (dest_region_1 != dest_region_2) {
jcoomes@375 481 // Destination regions differ; adjust destination_count.
duke@0 482 destination_count += 1;
jcoomes@375 483 // Data from cur_region will be copied to the start of dest_region_2.
jcoomes@375 484 _region_data[dest_region_2].set_source_region(cur_region);
jcoomes@375 485 } else if (region_offset(dest_addr) == 0) {
jcoomes@375 486 // Data from cur_region will be copied to the start of the destination
jcoomes@375 487 // region.
jcoomes@375 488 _region_data[dest_region_1].set_source_region(cur_region);
duke@0 489 }
duke@0 490 #else
jcoomes@375 491 // Initially assume that the destination regions will be different and
duke@0 492 // adjust the value below if necessary. Under this assumption, if
jcoomes@375 493 // cur_region == dest_region2, then cur_region will be compacted partially
jcoomes@375 494 // into dest_region_1 and partially into itself.
jcoomes@375 495 uint destination_count = cur_region == dest_region_2 ? 1 : 2;
jcoomes@375 496 if (dest_region_1 != dest_region_2) {
jcoomes@375 497 // Data from cur_region will be copied to the start of dest_region_2.
jcoomes@375 498 _region_data[dest_region_2].set_source_region(cur_region);
duke@0 499 } else {
jcoomes@375 500 // Destination regions are the same; adjust destination_count.
duke@0 501 destination_count -= 1;
jcoomes@375 502 if (region_offset(dest_addr) == 0) {
jcoomes@375 503 // Data from cur_region will be copied to the start of the destination
jcoomes@375 504 // region.
jcoomes@375 505 _region_data[dest_region_1].set_source_region(cur_region);
duke@0 506 }
duke@0 507 }
duke@0 508 #endif // #if 0
duke@0 509
jcoomes@375 510 _region_data[cur_region].set_destination_count(destination_count);
jcoomes@375 511 _region_data[cur_region].set_data_location(region_to_addr(cur_region));
duke@0 512 dest_addr += words;
duke@0 513 }
duke@0 514
jcoomes@375 515 ++cur_region;
duke@0 516 }
duke@0 517
duke@0 518 *target_next = dest_addr;
duke@0 519 return true;
duke@0 520 }
duke@0 521
duke@0 522 HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr) {
duke@0 523 assert(addr != NULL, "Should detect NULL oop earlier");
duke@0 524 assert(PSParallelCompact::gc_heap()->is_in(addr), "addr not in heap");
duke@0 525 #ifdef ASSERT
duke@0 526 if (PSParallelCompact::mark_bitmap()->is_unmarked(addr)) {
duke@0 527 gclog_or_tty->print_cr("calc_new_pointer:: addr " PTR_FORMAT, addr);
duke@0 528 }
duke@0 529 #endif
duke@0 530 assert(PSParallelCompact::mark_bitmap()->is_marked(addr), "obj not marked");
duke@0 531
jcoomes@375 532 // Region covering the object.
jcoomes@375 533 size_t region_index = addr_to_region_idx(addr);
jcoomes@375 534 const RegionData* const region_ptr = region(region_index);
jcoomes@375 535 HeapWord* const region_addr = region_align_down(addr);
jcoomes@375 536
jcoomes@375 537 assert(addr < region_addr + RegionSize, "Region does not cover object");
jcoomes@375 538 assert(addr_to_region_ptr(region_addr) == region_ptr, "sanity check");
jcoomes@375 539
jcoomes@375 540 HeapWord* result = region_ptr->destination();
jcoomes@375 541
jcoomes@375 542 // If all the data in the region is live, then the new location of the object
jcoomes@375 543 // can be calculated from the destination of the region plus the offset of the
jcoomes@375 544 // object in the region.
jcoomes@375 545 if (region_ptr->data_size() == RegionSize) {
jcoomes@375 546 result += pointer_delta(addr, region_addr);
duke@0 547 return result;
duke@0 548 }
duke@0 549
duke@0 550 // The new location of the object is
jcoomes@375 551 // region destination +
jcoomes@375 552 // size of the partial object extending onto the region +
jcoomes@375 553 // sizes of the live objects in the Region that are to the left of addr
jcoomes@375 554 const size_t partial_obj_size = region_ptr->partial_obj_size();
jcoomes@375 555 HeapWord* const search_start = region_addr + partial_obj_size;
duke@0 556
duke@0 557 const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap();
duke@0 558 size_t live_to_left = bitmap->live_words_in_range(search_start, oop(addr));
duke@0 559
duke@0 560 result += partial_obj_size + live_to_left;
duke@0 561 assert(result <= addr, "object cannot move to the right");
duke@0 562 return result;
duke@0 563 }
duke@0 564
duke@0 565 klassOop ParallelCompactData::calc_new_klass(klassOop old_klass) {
duke@0 566 klassOop updated_klass;
duke@0 567 if (PSParallelCompact::should_update_klass(old_klass)) {
duke@0 568 updated_klass = (klassOop) calc_new_pointer(old_klass);
duke@0 569 } else {
duke@0 570 updated_klass = old_klass;
duke@0 571 }
duke@0 572
duke@0 573 return updated_klass;
duke@0 574 }
duke@0 575
duke@0 576 #ifdef ASSERT
duke@0 577 void ParallelCompactData::verify_clear(const PSVirtualSpace* vspace)
duke@0 578 {
duke@0 579 const size_t* const beg = (const size_t*)vspace->committed_low_addr();
duke@0 580 const size_t* const end = (const size_t*)vspace->committed_high_addr();
duke@0 581 for (const size_t* p = beg; p < end; ++p) {
duke@0 582 assert(*p == 0, "not zero");
duke@0 583 }
duke@0 584 }
duke@0 585
duke@0 586 void ParallelCompactData::verify_clear()
duke@0 587 {
jcoomes@375 588 verify_clear(_region_vspace);
duke@0 589 }
duke@0 590 #endif // #ifdef ASSERT
duke@0 591
duke@0 592 #ifdef NOT_PRODUCT
jcoomes@375 593 ParallelCompactData::RegionData* debug_region(size_t region_index) {
duke@0 594 ParallelCompactData& sd = PSParallelCompact::summary_data();
jcoomes@375 595 return sd.region(region_index);
duke@0 596 }
duke@0 597 #endif
duke@0 598
duke@0 599 elapsedTimer PSParallelCompact::_accumulated_time;
duke@0 600 unsigned int PSParallelCompact::_total_invocations = 0;
duke@0 601 unsigned int PSParallelCompact::_maximum_compaction_gc_num = 0;
duke@0 602 jlong PSParallelCompact::_time_of_last_gc = 0;
duke@0 603 CollectorCounters* PSParallelCompact::_counters = NULL;
duke@0 604 ParMarkBitMap PSParallelCompact::_mark_bitmap;
duke@0 605 ParallelCompactData PSParallelCompact::_summary_data;
duke@0 606
duke@0 607 PSParallelCompact::IsAliveClosure PSParallelCompact::_is_alive_closure;
coleenp@113 608
coleenp@113 609 void PSParallelCompact::IsAliveClosure::do_object(oop p) { ShouldNotReachHere(); }
coleenp@113 610 bool PSParallelCompact::IsAliveClosure::do_object_b(oop p) { return mark_bitmap()->is_marked(p); }
coleenp@113 611
coleenp@113 612 void PSParallelCompact::KeepAliveClosure::do_oop(oop* p) { PSParallelCompact::KeepAliveClosure::do_oop_work(p); }
coleenp@113 613 void PSParallelCompact::KeepAliveClosure::do_oop(narrowOop* p) { PSParallelCompact::KeepAliveClosure::do_oop_work(p); }
coleenp@113 614
duke@0 615 PSParallelCompact::AdjustPointerClosure PSParallelCompact::_adjust_root_pointer_closure(true);
duke@0 616 PSParallelCompact::AdjustPointerClosure PSParallelCompact::_adjust_pointer_closure(false);
duke@0 617
coleenp@113 618 void PSParallelCompact::AdjustPointerClosure::do_oop(oop* p) { adjust_pointer(p, _is_root); }
coleenp@113 619 void PSParallelCompact::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p, _is_root); }
coleenp@113 620
coleenp@113 621 void PSParallelCompact::FollowStackClosure::do_void() { follow_stack(_compaction_manager); }
coleenp@113 622
coleenp@113 623 void PSParallelCompact::MarkAndPushClosure::do_oop(oop* p) { mark_and_push(_compaction_manager, p); }
coleenp@113 624 void PSParallelCompact::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(_compaction_manager, p); }
duke@0 625
duke@0 626 void PSParallelCompact::post_initialize() {
duke@0 627 ParallelScavengeHeap* heap = gc_heap();
duke@0 628 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
duke@0 629
duke@0 630 MemRegion mr = heap->reserved_region();
duke@0 631 _ref_processor = ReferenceProcessor::create_ref_processor(
duke@0 632 mr, // span
duke@0 633 true, // atomic_discovery
duke@0 634 true, // mt_discovery
duke@0 635 &_is_alive_closure,
duke@0 636 ParallelGCThreads,
duke@0 637 ParallelRefProcEnabled);
duke@0 638 _counters = new CollectorCounters("PSParallelCompact", 1);
duke@0 639
duke@0 640 // Initialize static fields in ParCompactionManager.
duke@0 641 ParCompactionManager::initialize(mark_bitmap());
duke@0 642 }
duke@0 643
duke@0 644 bool PSParallelCompact::initialize() {
duke@0 645 ParallelScavengeHeap* heap = gc_heap();
duke@0 646 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
duke@0 647 MemRegion mr = heap->reserved_region();
duke@0 648
duke@0 649 // Was the old gen get allocated successfully?
duke@0 650 if (!heap->old_gen()->is_allocated()) {
duke@0 651 return false;
duke@0 652 }
duke@0 653
duke@0 654 initialize_space_info();
duke@0 655 initialize_dead_wood_limiter();
duke@0 656
duke@0 657 if (!_mark_bitmap.initialize(mr)) {
duke@0 658 vm_shutdown_during_initialization("Unable to allocate bit map for "
duke@0 659 "parallel garbage collection for the requested heap size.");
duke@0 660 return false;
duke@0 661 }
duke@0 662
duke@0 663 if (!_summary_data.initialize(mr)) {
duke@0 664 vm_shutdown_during_initialization("Unable to allocate tables for "
duke@0 665 "parallel garbage collection for the requested heap size.");
duke@0 666 return false;
duke@0 667 }
duke@0 668
duke@0 669 return true;
duke@0 670 }
duke@0 671
duke@0 672 void PSParallelCompact::initialize_space_info()
duke@0 673 {
duke@0 674 memset(&_space_info, 0, sizeof(_space_info));
duke@0 675
duke@0 676 ParallelScavengeHeap* heap = gc_heap();
duke@0 677 PSYoungGen* young_gen = heap->young_gen();
duke@0 678 MutableSpace* perm_space = heap->perm_gen()->object_space();
duke@0 679
duke@0 680 _space_info[perm_space_id].set_space(perm_space);
duke@0 681 _space_info[old_space_id].set_space(heap->old_gen()->object_space());
duke@0 682 _space_info[eden_space_id].set_space(young_gen->eden_space());
duke@0 683 _space_info[from_space_id].set_space(young_gen->from_space());
duke@0 684 _space_info[to_space_id].set_space(young_gen->to_space());
duke@0 685
duke@0 686 _space_info[perm_space_id].set_start_array(heap->perm_gen()->start_array());
duke@0 687 _space_info[old_space_id].set_start_array(heap->old_gen()->start_array());
duke@0 688
duke@0 689 _space_info[perm_space_id].set_min_dense_prefix(perm_space->top());
duke@0 690 if (TraceParallelOldGCDensePrefix) {
duke@0 691 tty->print_cr("perm min_dense_prefix=" PTR_FORMAT,
duke@0 692 _space_info[perm_space_id].min_dense_prefix());
duke@0 693 }
duke@0 694 }
duke@0 695
duke@0 696 void PSParallelCompact::initialize_dead_wood_limiter()
duke@0 697 {
duke@0 698 const size_t max = 100;
duke@0 699 _dwl_mean = double(MIN2(ParallelOldDeadWoodLimiterMean, max)) / 100.0;
duke@0 700 _dwl_std_dev = double(MIN2(ParallelOldDeadWoodLimiterStdDev, max)) / 100.0;
duke@0 701 _dwl_first_term = 1.0 / (sqrt(2.0 * M_PI) * _dwl_std_dev);
duke@0 702 DEBUG_ONLY(_dwl_initialized = true;)
duke@0 703 _dwl_adjustment = normal_distribution(1.0);
duke@0 704 }
duke@0 705
duke@0 706 // Simple class for storing info about the heap at the start of GC, to be used
duke@0 707 // after GC for comparison/printing.
duke@0 708 class PreGCValues {
duke@0 709 public:
duke@0 710 PreGCValues() { }
duke@0 711 PreGCValues(ParallelScavengeHeap* heap) { fill(heap); }
duke@0 712
duke@0 713 void fill(ParallelScavengeHeap* heap) {
duke@0 714 _heap_used = heap->used();
duke@0 715 _young_gen_used = heap->young_gen()->used_in_bytes();
duke@0 716 _old_gen_used = heap->old_gen()->used_in_bytes();
duke@0 717 _perm_gen_used = heap->perm_gen()->used_in_bytes();
duke@0 718 };
duke@0 719
duke@0 720 size_t heap_used() const { return _heap_used; }
duke@0 721 size_t young_gen_used() const { return _young_gen_used; }
duke@0 722 size_t old_gen_used() const { return _old_gen_used; }
duke@0 723 size_t perm_gen_used() const { return _perm_gen_used; }
duke@0 724
duke@0 725 private:
duke@0 726 size_t _heap_used;
duke@0 727 size_t _young_gen_used;
duke@0 728 size_t _old_gen_used;
duke@0 729 size_t _perm_gen_used;
duke@0 730 };
duke@0 731
duke@0 732 void
duke@0 733 PSParallelCompact::clear_data_covering_space(SpaceId id)
duke@0 734 {
duke@0 735 // At this point, top is the value before GC, new_top() is the value that will
duke@0 736 // be set at the end of GC. The marking bitmap is cleared to top; nothing
duke@0 737 // should be marked above top. The summary data is cleared to the larger of
duke@0 738 // top & new_top.
duke@0 739 MutableSpace* const space = _space_info[id].space();
duke@0 740 HeapWord* const bot = space->bottom();
duke@0 741 HeapWord* const top = space->top();
duke@0 742 HeapWord* const max_top = MAX2(top, _space_info[id].new_top());
duke@0 743
duke@0 744 const idx_t beg_bit = _mark_bitmap.addr_to_bit(bot);
duke@0 745 const idx_t end_bit = BitMap::word_align_up(_mark_bitmap.addr_to_bit(top));
duke@0 746 _mark_bitmap.clear_range(beg_bit, end_bit);
duke@0 747
jcoomes@375 748 const size_t beg_region = _summary_data.addr_to_region_idx(bot);
jcoomes@375 749 const size_t end_region =
jcoomes@375 750 _summary_data.addr_to_region_idx(_summary_data.region_align_up(max_top));
jcoomes@375 751 _summary_data.clear_range(beg_region, end_region);
duke@0 752 }
duke@0 753
duke@0 754 void PSParallelCompact::pre_compact(PreGCValues* pre_gc_values)
duke@0 755 {
duke@0 756 // Update the from & to space pointers in space_info, since they are swapped
duke@0 757 // at each young gen gc. Do the update unconditionally (even though a
duke@0 758 // promotion failure does not swap spaces) because an unknown number of minor
duke@0 759 // collections will have swapped the spaces an unknown number of times.
duke@0 760 TraceTime tm("pre compact", print_phases(), true, gclog_or_tty);
duke@0 761 ParallelScavengeHeap* heap = gc_heap();
duke@0 762 _space_info[from_space_id].set_space(heap->young_gen()->from_space());
duke@0 763 _space_info[to_space_id].set_space(heap->young_gen()->to_space());
duke@0 764
duke@0 765 pre_gc_values->fill(heap);
duke@0 766
duke@0 767 ParCompactionManager::reset();
duke@0 768 NOT_PRODUCT(_mark_bitmap.reset_counters());
duke@0 769 DEBUG_ONLY(add_obj_count = add_obj_size = 0;)
duke@0 770 DEBUG_ONLY(mark_bitmap_count = mark_bitmap_size = 0;)
duke@0 771
duke@0 772 // Increment the invocation count
apetrusenko@139 773 heap->increment_total_collections(true);
duke@0 774
duke@0 775 // We need to track unique mark sweep invocations as well.
duke@0 776 _total_invocations++;
duke@0 777
duke@0 778 if (PrintHeapAtGC) {
duke@0 779 Universe::print_heap_before_gc();
duke@0 780 }
duke@0 781
duke@0 782 // Fill in TLABs
duke@0 783 heap->accumulate_statistics_all_tlabs();
duke@0 784 heap->ensure_parsability(true); // retire TLABs
duke@0 785
duke@0 786 if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {
duke@0 787 HandleMark hm; // Discard invalid handles created during verification
duke@0 788 gclog_or_tty->print(" VerifyBeforeGC:");
duke@0 789 Universe::verify(true);
duke@0 790 }
duke@0 791
duke@0 792 // Verify object start arrays
duke@0 793 if (VerifyObjectStartArray &&
duke@0 794 VerifyBeforeGC) {
duke@0 795 heap->old_gen()->verify_object_start_array();
duke@0 796 heap->perm_gen()->verify_object_start_array();
duke@0 797 }
duke@0 798
duke@0 799 DEBUG_ONLY(mark_bitmap()->verify_clear();)
duke@0 800 DEBUG_ONLY(summary_data().verify_clear();)
jcoomes@210 801
jcoomes@210 802 // Have worker threads release resources the next time they run a task.
jcoomes@210 803 gc_task_manager()->release_all_resources();
duke@0 804 }
duke@0 805
duke@0 806 void PSParallelCompact::post_compact()
duke@0 807 {
duke@0 808 TraceTime tm("post compact", print_phases(), true, gclog_or_tty);
duke@0 809
duke@0 810 // Clear the marking bitmap and summary data and update top() in each space.
duke@0 811 for (unsigned int id = perm_space_id; id < last_space_id; ++id) {
duke@0 812 clear_data_covering_space(SpaceId(id));
duke@0 813 _space_info[id].space()->set_top(_space_info[id].new_top());
duke@0 814 }
duke@0 815
duke@0 816 MutableSpace* const eden_space = _space_info[eden_space_id].space();
duke@0 817 MutableSpace* const from_space = _space_info[from_space_id].space();
duke@0 818 MutableSpace* const to_space = _space_info[to_space_id].space();
duke@0 819
duke@0 820 ParallelScavengeHeap* heap = gc_heap();
duke@0 821 bool eden_empty = eden_space->is_empty();
duke@0 822 if (!eden_empty) {
duke@0 823 eden_empty = absorb_live_data_from_eden(heap->size_policy(),
duke@0 824 heap->young_gen(), heap->old_gen());
duke@0 825 }
duke@0 826
duke@0 827 // Update heap occupancy information which is used as input to the soft ref
duke@0 828 // clearing policy at the next gc.
duke@0 829 Universe::update_heap_info_at_gc();
duke@0 830
duke@0 831 bool young_gen_empty = eden_empty && from_space->is_empty() &&
duke@0 832 to_space->is_empty();
duke@0 833
duke@0 834 BarrierSet* bs = heap->barrier_set();
duke@0 835 if (bs->is_a(BarrierSet::ModRef)) {
duke@0 836 ModRefBarrierSet* modBS = (ModRefBarrierSet*)bs;
duke@0 837 MemRegion old_mr = heap->old_gen()->reserved();
duke@0 838 MemRegion perm_mr = heap->perm_gen()->reserved();
duke@0 839 assert(perm_mr.end() <= old_mr.start(), "Generations out of order");
duke@0 840
duke@0 841 if (young_gen_empty) {
duke@0 842 modBS->clear(MemRegion(perm_mr.start(), old_mr.end()));
duke@0 843 } else {
duke@0 844 modBS->invalidate(MemRegion(perm_mr.start(), old_mr.end()));
duke@0 845 }
duke@0 846 }
duke@0 847
duke@0 848 Threads::gc_epilogue();
duke@0 849 CodeCache::gc_epilogue();
duke@0 850
duke@0 851 COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
duke@0 852
duke@0 853 ref_processor()->enqueue_discovered_references(NULL);
duke@0 854
jmasa@263 855 if (ZapUnusedHeapArea) {
jmasa@263 856 heap->gen_mangle_unused_area();
jmasa@263 857 }
jmasa@263 858
duke@0 859 // Update time of last GC
duke@0 860 reset_millis_since_last_gc();
duke@0 861 }
duke@0 862
duke@0 863 HeapWord*
duke@0 864 PSParallelCompact::compute_dense_prefix_via_density(const SpaceId id,
duke@0 865 bool maximum_compaction)
duke@0 866 {
jcoomes@375 867 const size_t region_size = ParallelCompactData::RegionSize;
duke@0 868 const ParallelCompactData& sd = summary_data();
duke@0 869
duke@0 870 const MutableSpace* const space = _space_info[id].space();
jcoomes@375 871 HeapWord* const top_aligned_up = sd.region_align_up(space->top());
jcoomes@375 872 const RegionData* const beg_cp = sd.addr_to_region_ptr(space->bottom());
jcoomes@375 873 const RegionData* const end_cp = sd.addr_to_region_ptr(top_aligned_up);
jcoomes@375 874
jcoomes@375 875 // Skip full regions at the beginning of the space--they are necessarily part
duke@0 876 // of the dense prefix.
duke@0 877 size_t full_count = 0;
jcoomes@375 878 const RegionData* cp;
jcoomes@375 879 for (cp = beg_cp; cp < end_cp && cp->data_size() == region_size; ++cp) {
duke@0 880 ++full_count;
duke@0 881 }
duke@0 882
duke@0 883 assert(total_invocations() >= _maximum_compaction_gc_num, "sanity");
duke@0 884 const size_t gcs_since_max = total_invocations() - _maximum_compaction_gc_num;
duke@0 885 const bool interval_ended = gcs_since_max > HeapMaximumCompactionInterval;
duke@0 886 if (maximum_compaction || cp == end_cp || interval_ended) {
duke@0 887 _maximum_compaction_gc_num = total_invocations();
jcoomes@375 888 return sd.region_to_addr(cp);
duke@0 889 }
duke@0 890
duke@0 891 HeapWord* const new_top = _space_info[id].new_top();
duke@0 892 const size_t space_live = pointer_delta(new_top, space->bottom());
duke@0 893 const size_t space_used = space->used_in_words();
duke@0 894 const size_t space_capacity = space->capacity_in_words();
duke@0 895
duke@0 896 const double cur_density = double(space_live) / space_capacity;
duke@0 897 const double deadwood_density =
duke@0 898 (1.0 - cur_density) * (1.0 - cur_density) * cur_density * cur_density;
duke@0 899 const size_t deadwood_goal = size_t(space_capacity * deadwood_density);
duke@0 900
duke@0 901 if (TraceParallelOldGCDensePrefix) {
duke@0 902 tty->print_cr("cur_dens=%5.3f dw_dens=%5.3f dw_goal=" SIZE_FORMAT,
duke@0 903 cur_density, deadwood_density, deadwood_goal);
duke@0 904 tty->print_cr("space_live=" SIZE_FORMAT " " "space_used=" SIZE_FORMAT " "
duke@0 905 "space_cap=" SIZE_FORMAT,
duke@0 906 space_live, space_used,
duke@0 907 space_capacity);
duke@0 908 }
duke@0 909
duke@0 910 // XXX - Use binary search?
jcoomes@375 911 HeapWord* dense_prefix = sd.region_to_addr(cp);
jcoomes@375 912 const RegionData* full_cp = cp;
jcoomes@375 913 const RegionData* const top_cp = sd.addr_to_region_ptr(space->top() - 1);
duke@0 914 while (cp < end_cp) {
jcoomes@375 915 HeapWord* region_destination = cp->destination();
jcoomes@375 916 const size_t cur_deadwood = pointer_delta(dense_prefix, region_destination);
duke@0 917 if (TraceParallelOldGCDensePrefix && Verbose) {
jcoomes@264 918 tty->print_cr("c#=" SIZE_FORMAT_W(4) " dst=" PTR_FORMAT " "
jcoomes@264 919 "dp=" SIZE_FORMAT_W(8) " " "cdw=" SIZE_FORMAT_W(8),
jcoomes@375 920 sd.region(cp), region_destination,
duke@0 921 dense_prefix, cur_deadwood);
duke@0 922 }
duke@0 923
duke@0 924 if (cur_deadwood >= deadwood_goal) {
jcoomes@375 925 // Found the region that has the correct amount of deadwood to the left.
jcoomes@375 926 // This typically occurs after crossing a fairly sparse set of regions, so
jcoomes@375 927 // iterate backwards over those sparse regions, looking for the region
jcoomes@375 928 // that has the lowest density of live objects 'to the right.'
jcoomes@375 929 size_t space_to_left = sd.region(cp) * region_size;
duke@0 930 size_t live_to_left = space_to_left - cur_deadwood;
duke@0 931 size_t space_to_right = space_capacity - space_to_left;
duke@0 932 size_t live_to_right = space_live - live_to_left;
duke@0 933 double density_to_right = double(live_to_right) / space_to_right;
duke@0 934 while (cp > full_cp) {
duke@0 935 --cp;
jcoomes@375 936 const size_t prev_region_live_to_right = live_to_right -
jcoomes@375 937 cp->data_size();
jcoomes@375 938 const size_t prev_region_space_to_right = space_to_right + region_size;
jcoomes@375 939 double prev_region_density_to_right =
jcoomes@375 940 double(prev_region_live_to_right) / prev_region_space_to_right;
jcoomes@375 941 if (density_to_right <= prev_region_density_to_right) {
duke@0 942 return dense_prefix;
duke@0 943 }
duke@0 944 if (TraceParallelOldGCDensePrefix && Verbose) {
jcoomes@264 945 tty->print_cr("backing up from c=" SIZE_FORMAT_W(4) " d2r=%10.8f "
jcoomes@375 946 "pc_d2r=%10.8f", sd.region(cp), density_to_right,
jcoomes@375 947 prev_region_density_to_right);
duke@0 948 }
jcoomes@375 949 dense_prefix -= region_size;
jcoomes@375 950 live_to_right = prev_region_live_to_right;
jcoomes@375 951 space_to_right = prev_region_space_to_right;
jcoomes@375 952 density_to_right = prev_region_density_to_right;
duke@0 953 }
duke@0 954 return dense_prefix;
duke@0 955 }
duke@0 956
jcoomes@375 957 dense_prefix += region_size;
duke@0 958 ++cp;
duke@0 959 }
duke@0 960
duke@0 961 return dense_prefix;
duke@0 962 }
duke@0 963
duke@0 964 #ifndef PRODUCT
duke@0 965 void PSParallelCompact::print_dense_prefix_stats(const char* const algorithm,
duke@0 966 const SpaceId id,
duke@0 967 const bool maximum_compaction,
duke@0 968 HeapWord* const addr)
duke@0 969 {
jcoomes@375 970 const size_t region_idx = summary_data().addr_to_region_idx(addr);
jcoomes@375 971 RegionData* const cp = summary_data().region(region_idx);
duke@0 972 const MutableSpace* const space = _space_info[id].space();
duke@0 973 HeapWord* const new_top = _space_info[id].new_top();
duke@0 974
duke@0 975 const size_t space_live = pointer_delta(new_top, space->bottom());
duke@0 976 const size_t dead_to_left = pointer_delta(addr, cp->destination());
duke@0 977 const size_t space_cap = space->capacity_in_words();
duke@0 978 const double dead_to_left_pct = double(dead_to_left) / space_cap;
duke@0 979 const size_t live_to_right = new_top - cp->destination();
duke@0 980 const size_t dead_to_right = space->top() - addr - live_to_right;
duke@0 981
jcoomes@264 982 tty->print_cr("%s=" PTR_FORMAT " dpc=" SIZE_FORMAT_W(5) " "
duke@0 983 "spl=" SIZE_FORMAT " "
duke@0 984 "d2l=" SIZE_FORMAT " d2l%%=%6.4f "
duke@0 985 "d2r=" SIZE_FORMAT " l2r=" SIZE_FORMAT
duke@0 986 " ratio=%10.8f",
jcoomes@375 987 algorithm, addr, region_idx,
duke@0 988 space_live,
duke@0 989 dead_to_left, dead_to_left_pct,
duke@0 990 dead_to_right, live_to_right,
duke@0 991 double(dead_to_right) / live_to_right);
duke@0 992 }
duke@0 993 #endif // #ifndef PRODUCT
duke@0 994
duke@0 995 // Return a fraction indicating how much of the generation can be treated as
duke@0 996 // "dead wood" (i.e., not reclaimed). The function uses a normal distribution
duke@0 997 // based on the density of live objects in the generation to determine a limit,
duke@0 998 // which is then adjusted so the return value is min_percent when the density is
duke@0 999 // 1.
duke@0 1000 //
duke@0 1001 // The following table shows some return values for a different values of the
duke@0 1002 // standard deviation (ParallelOldDeadWoodLimiterStdDev); the mean is 0.5 and
duke@0 1003 // min_percent is 1.
duke@0 1004 //
duke@0 1005 // fraction allowed as dead wood
duke@0 1006 // -----------------------------------------------------------------
duke@0 1007 // density std_dev=70 std_dev=75 std_dev=80 std_dev=85 std_dev=90 std_dev=95
duke@0 1008 // ------- ---------- ---------- ---------- ---------- ---------- ----------
duke@0 1009 // 0.00000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000
duke@0 1010 // 0.05000 0.03193096 0.02836880 0.02550828 0.02319280 0.02130337 0.01974941
duke@0 1011 // 0.10000 0.05247504 0.04547452 0.03988045 0.03537016 0.03170171 0.02869272
duke@0 1012 // 0.15000 0.07135702 0.06111390 0.05296419 0.04641639 0.04110601 0.03676066
duke@0 1013 // 0.20000 0.08831616 0.07509618 0.06461766 0.05622444 0.04943437 0.04388975
duke@0 1014 // 0.25000 0.10311208 0.08724696 0.07471205 0.06469760 0.05661313 0.05002313
duke@0 1015 // 0.30000 0.11553050 0.09741183 0.08313394 0.07175114 0.06257797 0.05511132
duke@0 1016 // 0.35000 0.12538832 0.10545958 0.08978741 0.07731366 0.06727491 0.05911289
duke@0 1017 // 0.40000 0.13253818 0.11128511 0.09459590 0.08132834 0.07066107 0.06199500
duke@0 1018 // 0.45000 0.13687208 0.11481163 0.09750361 0.08375387 0.07270534 0.06373386
duke@0 1019 // 0.50000 0.13832410 0.11599237 0.09847664 0.08456518 0.07338887 0.06431510
duke@0 1020 // 0.55000 0.13687208 0.11481163 0.09750361 0.08375387 0.07270534 0.06373386
duke@0 1021 // 0.60000 0.13253818 0.11128511 0.09459590 0.08132834 0.07066107 0.06199500
duke@0 1022 // 0.65000 0.12538832 0.10545958 0.08978741 0.07731366 0.06727491 0.05911289
duke@0 1023 // 0.70000 0.11553050 0.09741183 0.08313394 0.07175114 0.06257797 0.05511132
duke@0 1024 // 0.75000 0.10311208 0.08724696 0.07471205 0.06469760 0.05661313 0.05002313
duke@0 1025 // 0.80000 0.08831616 0.07509618 0.06461766 0.05622444 0.04943437 0.04388975
duke@0 1026 // 0.85000 0.07135702 0.06111390 0.05296419 0.04641639 0.04110601 0.03676066
duke@0 1027 // 0.90000 0.05247504 0.04547452 0.03988045 0.03537016 0.03170171 0.02869272
duke@0 1028 // 0.95000 0.03193096 0.02836880 0.02550828 0.02319280 0.02130337 0.01974941
duke@0 1029 // 1.00000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000
duke@0 1030
duke@0 1031 double PSParallelCompact::dead_wood_limiter(double density, size_t min_percent)
duke@0 1032 {
duke@0 1033 assert(_dwl_initialized, "uninitialized");
duke@0 1034
duke@0 1035 // The raw limit is the value of the normal distribution at x = density.
duke@0 1036 const double raw_limit = normal_distribution(density);
duke@0 1037
duke@0 1038 // Adjust the raw limit so it becomes the minimum when the density is 1.
duke@0 1039 //
duke@0 1040 // First subtract the adjustment value (which is simply the precomputed value
duke@0 1041 // normal_distribution(1.0)); this yields a value of 0 when the density is 1.
duke@0 1042 // Then add the minimum value, so the minimum is returned when the density is
duke@0 1043 // 1. Finally, prevent negative values, which occur when the mean is not 0.5.
duke@0 1044 const double min = double(min_percent) / 100.0;
duke@0 1045 const double limit = raw_limit - _dwl_adjustment + min;
duke@0 1046 return MAX2(limit, 0.0);
duke@0 1047 }
duke@0 1048
jcoomes@375 1049 ParallelCompactData::RegionData*
jcoomes@375 1050 PSParallelCompact::first_dead_space_region(const RegionData* beg,
jcoomes@375 1051 const RegionData* end)
duke@0 1052 {
jcoomes@375 1053 const size_t region_size = ParallelCompactData::RegionSize;
duke@0 1054 ParallelCompactData& sd = summary_data();
jcoomes@375 1055 size_t left = sd.region(beg);
jcoomes@375 1056 size_t right = end > beg ? sd.region(end) - 1 : left;
duke@0 1057
duke@0 1058 // Binary search.
duke@0 1059 while (left < right) {
duke@0 1060 // Equivalent to (left + right) / 2, but does not overflow.
duke@0 1061 const size_t middle = left + (right - left) / 2;
jcoomes@375 1062 RegionData* const middle_ptr = sd.region(middle);
duke@0 1063 HeapWord* const dest = middle_ptr->destination();
jcoomes@375 1064 HeapWord* const addr = sd.region_to_addr(middle);
duke@0 1065 assert(dest != NULL, "sanity");
duke@0 1066 assert(dest <= addr, "must move left");
duke@0 1067
duke@0 1068 if (middle > left && dest < addr) {
duke@0 1069 right = middle - 1;
jcoomes@375 1070 } else if (middle < right && middle_ptr->data_size() == region_size) {
duke@0 1071 left = middle + 1;
duke@0 1072 } else {
duke@0 1073 return middle_ptr;
duke@0 1074 }
duke@0 1075 }
jcoomes@375 1076 return sd.region(left);
duke@0 1077 }
duke@0 1078
jcoomes@375 1079 ParallelCompactData::RegionData*
jcoomes@375 1080 PSParallelCompact::dead_wood_limit_region(const RegionData* beg,
jcoomes@375 1081 const RegionData* end,
jcoomes@375 1082 size_t dead_words)
duke@0 1083 {
duke@0 1084 ParallelCompactData& sd = summary_data();
jcoomes@375 1085 size_t left = sd.region(beg);
jcoomes@375 1086 size_t right = end > beg ? sd.region(end) - 1 : left;
duke@0 1087
duke@0 1088 // Binary search.
duke@0 1089 while (left < right) {
duke@0 1090 // Equivalent to (left + right) / 2, but does not overflow.
duke@0 1091 const size_t middle = left + (right - left) / 2;
jcoomes@375 1092 RegionData* const middle_ptr = sd.region(middle);
duke@0 1093 HeapWord* const dest = middle_ptr->destination();
jcoomes@375 1094 HeapWord* const addr = sd.region_to_addr(middle);
duke@0 1095 assert(dest != NULL, "sanity");
duke@0 1096 assert(dest <= addr, "must move left");
duke@0 1097
duke@0 1098 const size_t dead_to_left = pointer_delta(addr, dest);
duke@0 1099 if (middle > left && dead_to_left > dead_words) {
duke@0 1100 right = middle - 1;
duke@0 1101 } else if (middle < right && dead_to_left < dead_words) {
duke@0 1102 left = middle + 1;
duke@0 1103 } else {
duke@0 1104 return middle_ptr;
duke@0 1105 }
duke@0 1106 }
jcoomes@375 1107 return sd.region(left);
duke@0 1108 }
duke@0 1109
duke@0 1110 // The result is valid during the summary phase, after the initial summarization
duke@0 1111 // of each space into itself, and before final summarization.
duke@0 1112 inline double
jcoomes@375 1113 PSParallelCompact::reclaimed_ratio(const RegionData* const cp,
duke@0 1114 HeapWord* const bottom,
duke@0 1115 HeapWord* const top,
duke@0 1116 HeapWord* const new_top)
duke@0 1117 {
duke@0 1118 ParallelCompactData& sd = summary_data();
duke@0 1119
duke@0 1120 assert(cp != NULL, "sanity");
duke@0 1121 assert(bottom != NULL, "sanity");
duke@0 1122 assert(top != NULL, "sanity");
duke@0 1123 assert(new_top != NULL, "sanity");
duke@0 1124 assert(top >= new_top, "summary data problem?");
duke@0 1125 assert(new_top > bottom, "space is empty; should not be here");
duke@0 1126 assert(new_top >= cp->destination(), "sanity");
jcoomes@375 1127 assert(top >= sd.region_to_addr(cp), "sanity");
duke@0 1128
duke@0 1129 HeapWord* const destination = cp->destination();
duke@0 1130 const size_t dense_prefix_live = pointer_delta(destination, bottom);
duke@0 1131 const size_t compacted_region_live = pointer_delta(new_top, destination);
jcoomes@375 1132 const size_t compacted_region_used = pointer_delta(top,
jcoomes@375 1133 sd.region_to_addr(cp));
duke@0 1134 const size_t reclaimable = compacted_region_used - compacted_region_live;
duke@0 1135
duke@0 1136 const double divisor = dense_prefix_live + 1.25 * compacted_region_live;
duke@0 1137 return double(reclaimable) / divisor;
duke@0 1138 }
duke@0 1139
duke@0 1140 // Return the address of the end of the dense prefix, a.k.a. the start of the
jcoomes@375 1141 // compacted region. The address is always on a region boundary.
duke@0 1142 //
jcoomes@375 1143 // Completely full regions at the left are skipped, since no compaction can
jcoomes@375 1144 // occur in those regions. Then the maximum amount of dead wood to allow is
jcoomes@375 1145 // computed, based on the density (amount live / capacity) of the generation;
jcoomes@375 1146 // the region with approximately that amount of dead space to the left is
jcoomes@375 1147 // identified as the limit region. Regions between the last completely full
jcoomes@375 1148 // region and the limit region are scanned and the one that has the best
jcoomes@375 1149 // (maximum) reclaimed_ratio() is selected.
duke@0 1150 HeapWord*
duke@0 1151 PSParallelCompact::compute_dense_prefix(const SpaceId id,
duke@0 1152 bool maximum_compaction)
duke@0 1153 {
jcoomes@375 1154 const size_t region_size = ParallelCompactData::RegionSize;
duke@0 1155 const ParallelCompactData& sd = summary_data();
duke@0 1156
duke@0 1157 const MutableSpace* const space = _space_info[id].space();
duke@0 1158 HeapWord* const top = space->top();
jcoomes@375 1159 HeapWord* const top_aligned_up = sd.region_align_up(top);
duke@0 1160 HeapWord* const new_top = _space_info[id].new_top();
jcoomes@375 1161 HeapWord* const new_top_aligned_up = sd.region_align_up(new_top);
duke@0 1162 HeapWord* const bottom = space->bottom();
jcoomes@375 1163 const RegionData* const beg_cp = sd.addr_to_region_ptr(bottom);
jcoomes@375 1164 const RegionData* const top_cp = sd.addr_to_region_ptr(top_aligned_up);
jcoomes@375 1165 const RegionData* const new_top_cp =
jcoomes@375 1166 sd.addr_to_region_ptr(new_top_aligned_up);
jcoomes@375 1167
jcoomes@375 1168 // Skip full regions at the beginning of the space--they are necessarily part
duke@0 1169 // of the dense prefix.
jcoomes@375 1170 const RegionData* const full_cp = first_dead_space_region(beg_cp, new_top_cp);
jcoomes@375 1171 assert(full_cp->destination() == sd.region_to_addr(full_cp) ||
duke@0 1172 space->is_empty(), "no dead space allowed to the left");
jcoomes@375 1173 assert(full_cp->data_size() < region_size || full_cp == new_top_cp - 1,
jcoomes@375 1174 "region must have dead space");
duke@0 1175
duke@0 1176 // The gc number is saved whenever a maximum compaction is done, and used to
duke@0 1177 // determine when the maximum compaction interval has expired. This avoids
duke@0 1178 // successive max compactions for different reasons.
duke@0 1179 assert(total_invocations() >= _maximum_compaction_gc_num, "sanity");
duke@0 1180 const size_t gcs_since_max = total_invocations() - _maximum_compaction_gc_num;
duke@0 1181 const bool interval_ended = gcs_since_max > HeapMaximumCompactionInterval ||
duke@0 1182 total_invocations() == HeapFirstMaximumCompactionCount;
duke@0 1183 if (maximum_compaction || full_cp == top_cp || interval_ended) {
duke@0 1184 _maximum_compaction_gc_num = total_invocations();
jcoomes@375 1185 return sd.region_to_addr(full_cp);
duke@0 1186 }
duke@0 1187
duke@0 1188 const size_t space_live = pointer_delta(new_top, bottom);
duke@0 1189 const size_t space_used = space->used_in_words();
duke@0 1190 const size_t space_capacity = space->capacity_in_words();
duke@0 1191
duke@0 1192 const double density = double(space_live) / double(space_capacity);
duke@0 1193 const size_t min_percent_free =
duke@0 1194 id == perm_space_id ? PermMarkSweepDeadRatio : MarkSweepDeadRatio;
duke@0 1195 const double limiter = dead_wood_limiter(density, min_percent_free);
duke@0 1196 const size_t dead_wood_max = space_used - space_live;
duke@0 1197 const size_t dead_wood_limit = MIN2(size_t(space_capacity * limiter),
duke@0 1198 dead_wood_max);
duke@0 1199
duke@0 1200 if (TraceParallelOldGCDensePrefix) {
duke@0 1201 tty->print_cr("space_live=" SIZE_FORMAT " " "space_used=" SIZE_FORMAT " "
duke@0 1202 "space_cap=" SIZE_FORMAT,
duke@0 1203 space_live, space_used,
duke@0 1204 space_capacity);
duke@0 1205 tty->print_cr("dead_wood_limiter(%6.4f, %d)=%6.4f "
duke@0 1206 "dead_wood_max=" SIZE_FORMAT " dead_wood_limit=" SIZE_FORMAT,
duke@0 1207 density, min_percent_free, limiter,
duke@0 1208 dead_wood_max, dead_wood_limit);
duke@0 1209 }
duke@0 1210
jcoomes@375 1211 // Locate the region with the desired amount of dead space to the left.
jcoomes@375 1212 const RegionData* const limit_cp =
jcoomes@375 1213 dead_wood_limit_region(full_cp, top_cp, dead_wood_limit);
jcoomes@375 1214
jcoomes@375 1215 // Scan from the first region with dead space to the limit region and find the
duke@0 1216 // one with the best (largest) reclaimed ratio.
duke@0 1217 double best_ratio = 0.0;
jcoomes@375 1218 const RegionData* best_cp = full_cp;
jcoomes@375 1219 for (const RegionData* cp = full_cp; cp < limit_cp; ++cp) {
duke@0 1220 double tmp_ratio = reclaimed_ratio(cp, bottom, top, new_top);
duke@0 1221 if (tmp_ratio > best_ratio) {
duke@0 1222 best_cp = cp;
duke@0 1223 best_ratio = tmp_ratio;
duke@0 1224 }
duke@0 1225 }
duke@0 1226
duke@0 1227 #if 0
jcoomes@375 1228 // Something to consider: if the region with the best ratio is 'close to' the
jcoomes@375 1229 // first region w/free space, choose the first region with free space
jcoomes@375 1230 // ("first-free"). The first-free region is usually near the start of the
duke@0 1231 // heap, which means we are copying most of the heap already, so copy a bit
duke@0 1232 // more to get complete compaction.
jcoomes@375 1233 if (pointer_delta(best_cp, full_cp, sizeof(RegionData)) < 4) {
duke@0 1234 _maximum_compaction_gc_num = total_invocations();
duke@0 1235 best_cp = full_cp;
duke@0 1236 }
duke@0 1237 #endif // #if 0
duke@0 1238
jcoomes@375 1239 return sd.region_to_addr(best_cp);
duke@0 1240 }
duke@0 1241
duke@0 1242 void PSParallelCompact::summarize_spaces_quick()
duke@0 1243 {
duke@0 1244 for (unsigned int i = 0; i < last_space_id; ++i) {
duke@0 1245 const MutableSpace* space = _space_info[i].space();
duke@0 1246 bool result = _summary_data.summarize(space->bottom(), space->end(),
duke@0 1247 space->bottom(), space->top(),
duke@0 1248 _space_info[i].new_top_addr());
duke@0 1249 assert(result, "should never fail");
duke@0 1250 _space_info[i].set_dense_prefix(space->bottom());
duke@0 1251 }
duke@0 1252 }
duke@0 1253
duke@0 1254 void PSParallelCompact::fill_dense_prefix_end(SpaceId id)
duke@0 1255 {
duke@0 1256 HeapWord* const dense_prefix_end = dense_prefix(id);
jcoomes@375 1257 const RegionData* region = _summary_data.addr_to_region_ptr(dense_prefix_end);
duke@0 1258 const idx_t dense_prefix_bit = _mark_bitmap.addr_to_bit(dense_prefix_end);
jcoomes@375 1259 if (dead_space_crosses_boundary(region, dense_prefix_bit)) {
duke@0 1260 // Only enough dead space is filled so that any remaining dead space to the
duke@0 1261 // left is larger than the minimum filler object. (The remainder is filled
duke@0 1262 // during the copy/update phase.)
duke@0 1263 //
duke@0 1264 // The size of the dead space to the right of the boundary is not a
duke@0 1265 // concern, since compaction will be able to use whatever space is
duke@0 1266 // available.
duke@0 1267 //
duke@0 1268 // Here '||' is the boundary, 'x' represents a don't care bit and a box
duke@0 1269 // surrounds the space to be filled with an object.
duke@0 1270 //
duke@0 1271 // In the 32-bit VM, each bit represents two 32-bit words:
duke@0 1272 // +---+
duke@0 1273 // a) beg_bits: ... x x x | 0 | || 0 x x ...
duke@0 1274 // end_bits: ... x x x | 0 | || 0 x x ...
duke@0 1275 // +---+
duke@0 1276 //
duke@0 1277 // In the 64-bit VM, each bit represents one 64-bit word:
duke@0 1278 // +------------+
duke@0 1279 // b) beg_bits: ... x x x | 0 || 0 | x x ...
duke@0 1280 // end_bits: ... x x 1 | 0 || 0 | x x ...
duke@0 1281 // +------------+
duke@0 1282 // +-------+
duke@0 1283 // c) beg_bits: ... x x | 0 0 | || 0 x x ...
duke@0 1284 // end_bits: ... x 1 | 0 0 | || 0 x x ...
duke@0 1285 // +-------+
duke@0 1286 // +-----------+
duke@0 1287 // d) beg_bits: ... x | 0 0 0 | || 0 x x ...
duke@0 1288 // end_bits: ... 1 | 0 0 0 | || 0 x x ...
duke@0 1289 // +-----------+
duke@0 1290 // +-------+
duke@0 1291 // e) beg_bits: ... 0 0 | 0 0 | || 0 x x ...
duke@0 1292 // end_bits: ... 0 0 | 0 0 | || 0 x x ...
duke@0 1293 // +-------+
duke@0 1294
duke@0 1295 // Initially assume case a, c or e will apply.
duke@0 1296 size_t obj_len = (size_t)oopDesc::header_size();
duke@0 1297 HeapWord* obj_beg = dense_prefix_end - obj_len;
duke@0 1298
duke@0 1299 #ifdef _LP64
duke@0 1300 if (_mark_bitmap.is_obj_end(dense_prefix_bit - 2)) {
duke@0 1301 // Case b above.
duke@0 1302 obj_beg = dense_prefix_end - 1;
duke@0 1303 } else if (!_mark_bitmap.is_obj_end(dense_prefix_bit - 3) &&
duke@0 1304 _mark_bitmap.is_obj_end(dense_prefix_bit - 4)) {
duke@0 1305 // Case d above.
duke@0 1306 obj_beg = dense_prefix_end - 3;
duke@0 1307 obj_len = 3;
duke@0 1308 }
duke@0 1309 #endif // #ifdef _LP64
duke@0 1310
duke@0 1311 MemRegion region(obj_beg, obj_len);
duke@0 1312 SharedHeap::fill_region_with_object(region);
duke@0 1313 _mark_bitmap.mark_obj(obj_beg, obj_len);
duke@0 1314 _summary_data.add_obj(obj_beg, obj_len);
duke@0 1315 assert(start_array(id) != NULL, "sanity");
duke@0 1316 start_array(id)->allocate_block(obj_beg);
duke@0 1317 }
duke@0 1318 }
duke@0 1319
duke@0 1320 void
duke@0 1321 PSParallelCompact::summarize_space(SpaceId id, bool maximum_compaction)
duke@0 1322 {
duke@0 1323 assert(id < last_space_id, "id out of range");
jcoomes@265 1324 assert(_space_info[id].dense_prefix() == _space_info[id].space()->bottom(),
jcoomes@265 1325 "should have been set in summarize_spaces_quick()");
duke@0 1326
duke@0 1327 const MutableSpace* space = _space_info[id].space();
jcoomes@265 1328 if (_space_info[id].new_top() != space->bottom()) {
jcoomes@265 1329 HeapWord* dense_prefix_end = compute_dense_prefix(id, maximum_compaction);
jcoomes@265 1330 _space_info[id].set_dense_prefix(dense_prefix_end);
duke@0 1331
duke@0 1332 #ifndef PRODUCT
jcoomes@265 1333 if (TraceParallelOldGCDensePrefix) {
jcoomes@265 1334 print_dense_prefix_stats("ratio", id, maximum_compaction,
jcoomes@265 1335 dense_prefix_end);
jcoomes@265 1336 HeapWord* addr = compute_dense_prefix_via_density(id, maximum_compaction);
jcoomes@265 1337 print_dense_prefix_stats("density", id, maximum_compaction, addr);
jcoomes@265 1338 }
jcoomes@265 1339 #endif // #ifndef PRODUCT
jcoomes@265 1340
jcoomes@265 1341 // If dead space crosses the dense prefix boundary, it is (at least
jcoomes@265 1342 // partially) filled with a dummy object, marked live and added to the
jcoomes@265 1343 // summary data. This simplifies the copy/update phase and must be done
jcoomes@265 1344 // before the final locations of objects are determined, to prevent leaving
jcoomes@265 1345 // a fragment of dead space that is too small to fill with an object.
jcoomes@265 1346 if (!maximum_compaction && dense_prefix_end != space->bottom()) {
jcoomes@265 1347 fill_dense_prefix_end(id);
jcoomes@265 1348 }
jcoomes@265 1349
jcoomes@375 1350 // Compute the destination of each Region, and thus each object.
jcoomes@265 1351 _summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end);
jcoomes@265 1352 _summary_data.summarize(dense_prefix_end, space->end(),
jcoomes@265 1353 dense_prefix_end, space->top(),
jcoomes@265 1354 _space_info[id].new_top_addr());
duke@0 1355 }
duke@0 1356
duke@0 1357 if (TraceParallelOldGCSummaryPhase) {
jcoomes@375 1358 const size_t region_size = ParallelCompactData::RegionSize;
jcoomes@265 1359 HeapWord* const dense_prefix_end = _space_info[id].dense_prefix();
jcoomes@375 1360 const size_t dp_region = _summary_data.addr_to_region_idx(dense_prefix_end);
duke@0 1361 const size_t dp_words = pointer_delta(dense_prefix_end, space->bottom());
jcoomes@265 1362 HeapWord* const new_top = _space_info[id].new_top();
jcoomes@375 1363 const HeapWord* nt_aligned_up = _summary_data.region_align_up(new_top);
duke@0 1364 const size_t cr_words = pointer_delta(nt_aligned_up, dense_prefix_end);
duke@0 1365 tty->print_cr("id=%d cap=" SIZE_FORMAT " dp=" PTR_FORMAT " "
jcoomes@375 1366 "dp_region=" SIZE_FORMAT " " "dp_count=" SIZE_FORMAT " "
duke@0 1367 "cr_count=" SIZE_FORMAT " " "nt=" PTR_FORMAT,
duke@0 1368 id, space->capacity_in_words(), dense_prefix_end,
jcoomes@375 1369 dp_region, dp_words / region_size,
jcoomes@375 1370 cr_words / region_size, new_top);
duke@0 1371 }
duke@0 1372 }
duke@0 1373
duke@0 1374 void PSParallelCompact::summary_phase(ParCompactionManager* cm,
duke@0 1375 bool maximum_compaction)
duke@0 1376 {
duke@0 1377 EventMark m("2 summarize");
duke@0 1378 TraceTime tm("summary phase", print_phases(), true, gclog_or_tty);
duke@0 1379 // trace("2");
duke@0 1380
duke@0 1381 #ifdef ASSERT
duke@0 1382 if (TraceParallelOldGCMarkingPhase) {
duke@0 1383 tty->print_cr("add_obj_count=" SIZE_FORMAT " "
duke@0 1384 "add_obj_bytes=" SIZE_FORMAT,
duke@0 1385 add_obj_count, add_obj_size * HeapWordSize);
duke@0 1386 tty->print_cr("mark_bitmap_count=" SIZE_FORMAT " "
duke@0 1387 "mark_bitmap_bytes=" SIZE_FORMAT,
duke@0 1388 mark_bitmap_count, mark_bitmap_size * HeapWordSize);
duke@0 1389 }
duke@0 1390 #endif // #ifdef ASSERT
duke@0 1391
duke@0 1392 // Quick summarization of each space into itself, to see how much is live.
duke@0 1393 summarize_spaces_quick();
duke@0 1394
duke@0 1395 if (TraceParallelOldGCSummaryPhase) {
duke@0 1396 tty->print_cr("summary_phase: after summarizing each space to self");
duke@0 1397 Universe::print();
jcoomes@375 1398 NOT_PRODUCT(print_region_ranges());
duke@0 1399 if (Verbose) {
duke@0 1400 NOT_PRODUCT(print_initial_summary_data(_summary_data, _space_info));
duke@0 1401 }
duke@0 1402 }
duke@0 1403
duke@0 1404 // The amount of live data that will end up in old space (assuming it fits).
duke@0 1405 size_t old_space_total_live = 0;
duke@0 1406 unsigned int id;
duke@0 1407 for (id = old_space_id; id < last_space_id; ++id) {
duke@0 1408 old_space_total_live += pointer_delta(_space_info[id].new_top(),
duke@0 1409 _space_info[id].space()->bottom());
duke@0 1410 }
duke@0 1411
duke@0 1412 const MutableSpace* old_space = _space_info[old_space_id].space();
duke@0 1413 if (old_space_total_live > old_space->capacity_in_words()) {
duke@0 1414 // XXX - should also try to expand
duke@0 1415 maximum_compaction = true;
duke@0 1416 } else if (!UseParallelOldGCDensePrefix) {
duke@0 1417 maximum_compaction = true;
duke@0 1418 }
duke@0 1419
duke@0 1420 // Permanent and Old generations.
duke@0 1421 summarize_space(perm_space_id, maximum_compaction);
duke@0 1422 summarize_space(old_space_id, maximum_compaction);
duke@0 1423
duke@0 1424 // Summarize the remaining spaces (those in the young gen) into old space. If
duke@0 1425 // the live data from a space doesn't fit, the existing summarization is left
duke@0 1426 // intact, so the data is compacted down within the space itself.
duke@0 1427 HeapWord** new_top_addr = _space_info[old_space_id].new_top_addr();
duke@0 1428 HeapWord* const target_space_end = old_space->end();
duke@0 1429 for (id = eden_space_id; id < last_space_id; ++id) {
duke@0 1430 const MutableSpace* space = _space_info[id].space();
duke@0 1431 const size_t live = pointer_delta(_space_info[id].new_top(),
duke@0 1432 space->bottom());
duke@0 1433 const size_t available = pointer_delta(target_space_end, *new_top_addr);
jcoomes@266 1434 if (live > 0 && live <= available) {
duke@0 1435 // All the live data will fit.
duke@0 1436 if (TraceParallelOldGCSummaryPhase) {
duke@0 1437 tty->print_cr("summarizing %d into old_space @ " PTR_FORMAT,
duke@0 1438 id, *new_top_addr);
duke@0 1439 }
duke@0 1440 _summary_data.summarize(*new_top_addr, target_space_end,
duke@0 1441 space->bottom(), space->top(),
duke@0 1442 new_top_addr);
duke@0 1443
jcoomes@375 1444 // Clear the source_region field for each region in the space.
jcoomes@266 1445 HeapWord* const new_top = _space_info[id].new_top();
jcoomes@375 1446 HeapWord* const clear_end = _summary_data.region_align_up(new_top);
jcoomes@375 1447 RegionData* beg_region =
jcoomes@375 1448 _summary_data.addr_to_region_ptr(space->bottom());
jcoomes@375 1449 RegionData* end_region = _summary_data.addr_to_region_ptr(clear_end);
jcoomes@375 1450 while (beg_region < end_region) {
jcoomes@375 1451 beg_region->set_source_region(0);
jcoomes@375 1452 ++beg_region;
duke@0 1453 }
jcoomes@266 1454
jcoomes@266 1455 // Reset the new_top value for the space.
jcoomes@266 1456 _space_info[id].set_new_top(space->bottom());
duke@0 1457 }
duke@0 1458 }
duke@0 1459
duke@0 1460 if (TraceParallelOldGCSummaryPhase) {
duke@0 1461 tty->print_cr("summary_phase: after final summarization");
duke@0 1462 Universe::print();
jcoomes@375 1463 NOT_PRODUCT(print_region_ranges());
duke@0 1464 if (Verbose) {
duke@0 1465 NOT_PRODUCT(print_generic_summary_data(_summary_data, _space_info));
duke@0 1466 }
duke@0 1467 }
duke@0 1468 }
duke@0 1469
duke@0 1470 // This method should contain all heap-specific policy for invoking a full
duke@0 1471 // collection. invoke_no_policy() will only attempt to compact the heap; it
duke@0 1472 // will do nothing further. If we need to bail out for policy reasons, scavenge
duke@0 1473 // before full gc, or any other specialized behavior, it needs to be added here.
duke@0 1474 //
duke@0 1475 // Note that this method should only be called from the vm_thread while at a
duke@0 1476 // safepoint.
duke@0 1477 void PSParallelCompact::invoke(bool maximum_heap_compaction) {
duke@0 1478 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
duke@0 1479 assert(Thread::current() == (Thread*)VMThread::vm_thread(),
duke@0 1480 "should be in vm thread");
duke@0 1481 ParallelScavengeHeap* heap = gc_heap();
duke@0 1482 GCCause::Cause gc_cause = heap->gc_cause();
duke@0 1483 assert(!heap->is_gc_active(), "not reentrant");
duke@0 1484
duke@0 1485 PSAdaptiveSizePolicy* policy = heap->size_policy();
duke@0 1486
duke@0 1487 // Before each allocation/collection attempt, find out from the
duke@0 1488 // policy object if GCs are, on the whole, taking too long. If so,
duke@0 1489 // bail out without attempting a collection. The exceptions are
duke@0 1490 // for explicitly requested GC's.
duke@0 1491 if (!policy->gc_time_limit_exceeded() ||
duke@0 1492 GCCause::is_user_requested_gc(gc_cause) ||
duke@0 1493 GCCause::is_serviceability_requested_gc(gc_cause)) {
duke@0 1494 IsGCActiveMark mark;
duke@0 1495
duke@0 1496 if (ScavengeBeforeFullGC) {
duke@0 1497 PSScavenge::invoke_no_policy();
duke@0 1498 }
duke@0 1499
duke@0 1500 PSParallelCompact::invoke_no_policy(maximum_heap_compaction);
duke@0 1501 }
duke@0 1502 }
duke@0 1503
jcoomes@375 1504 bool ParallelCompactData::region_contains(size_t region_index, HeapWord* addr) {
jcoomes@375 1505 size_t addr_region_index = addr_to_region_idx(addr);
jcoomes@375 1506 return region_index == addr_region_index;
duke@0 1507 }
duke@0 1508
duke@0 1509 // This method contains no policy. You should probably
duke@0 1510 // be calling invoke() instead.
duke@0 1511 void PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
duke@0 1512 assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
duke@0 1513 assert(ref_processor() != NULL, "Sanity");
duke@0 1514
apetrusenko@139 1515 if (GC_locker::check_active_before_gc()) {
duke@0 1516 return;
duke@0 1517 }
duke@0 1518
duke@0 1519 TimeStamp marking_start;
duke@0 1520 TimeStamp compaction_start;
duke@0 1521 TimeStamp collection_exit;
duke@0 1522
duke@0 1523 ParallelScavengeHeap* heap = gc_heap();
duke@0 1524 GCCause::Cause gc_cause = heap->gc_cause();
duke@0 1525 PSYoungGen* young_gen = heap->young_gen();
duke@0 1526 PSOldGen* old_gen = heap->old_gen();
duke@0 1527 PSPermGen* perm_gen = heap->perm_gen();
duke@0 1528 PSAdaptiveSizePolicy* size_policy = heap->size_policy();
duke@0 1529
jmasa@263 1530 if (ZapUnusedHeapArea) {
jmasa@263 1531 // Save information needed to minimize mangling
jmasa@263 1532 heap->record_gen_tops_before_GC();
jmasa@263 1533 }
jmasa@263 1534
duke@0 1535 _print_phases = PrintGCDetails && PrintParallelOldGCPhaseTimes;
duke@0 1536
duke@0 1537 // Make sure data structures are sane, make the heap parsable, and do other
duke@0 1538 // miscellaneous bookkeeping.
duke@0 1539 PreGCValues pre_gc_values;
duke@0 1540 pre_compact(&pre_gc_values);
duke@0 1541
jcoomes@210 1542 // Get the compaction manager reserved for the VM thread.
jcoomes@210 1543 ParCompactionManager* const vmthread_cm =
jcoomes@210 1544 ParCompactionManager::manager_array(gc_task_manager()->workers());
jcoomes@210 1545
duke@0 1546 // Place after pre_compact() where the number of invocations is incremented.
duke@0 1547 AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
duke@0 1548
duke@0 1549 {
duke@0 1550 ResourceMark rm;
duke@0 1551 HandleMark hm;
duke@0 1552
duke@0 1553 const bool is_system_gc = gc_cause == GCCause::_java_lang_system_gc;
duke@0 1554
duke@0 1555 // This is useful for debugging but don't change the output the
duke@0 1556 // the customer sees.
duke@0 1557 const char* gc_cause_str = "Full GC";
duke@0 1558 if (is_system_gc && PrintGCDetails) {
duke@0 1559 gc_cause_str = "Full GC (System)";
duke@0 1560 }
duke@0 1561 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
duke@0 1562 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
duke@0 1563 TraceTime t1(gc_cause_str, PrintGC, !PrintGCDetails, gclog_or_tty);
duke@0 1564 TraceCollectorStats tcs(counters());
duke@0 1565 TraceMemoryManagerStats tms(true /* Full GC */);
duke@0 1566
duke@0 1567 if (TraceGen1Time) accumulated_time()->start();
duke@0 1568
duke@0 1569 // Let the size policy know we're starting
duke@0 1570 size_policy->major_collection_begin();
duke@0 1571
duke@0 1572 // When collecting the permanent generation methodOops may be moving,
duke@0 1573 // so we either have to flush all bcp data or convert it into bci.
duke@0 1574 CodeCache::gc_prologue();
duke@0 1575 Threads::gc_prologue();
duke@0 1576
duke@0 1577 NOT_PRODUCT(ref_processor()->verify_no_references_recorded());
duke@0 1578 COMPILER2_PRESENT(DerivedPointerTable::clear());
duke@0 1579
duke@0 1580 ref_processor()->enable_discovery();
ysr@453 1581 ref_processor()->snap_policy(maximum_heap_compaction);
duke@0 1582
duke@0 1583 bool marked_for_unloading = false;
duke@0 1584
duke@0 1585 marking_start.update();
jcoomes@210 1586 marking_phase(vmthread_cm, maximum_heap_compaction);
duke@0 1587
duke@0 1588 #ifndef PRODUCT
duke@0 1589 if (TraceParallelOldGCMarkingPhase) {
duke@0 1590 gclog_or_tty->print_cr("marking_phase: cas_tries %d cas_retries %d "
duke@0 1591 "cas_by_another %d",
duke@0 1592 mark_bitmap()->cas_tries(), mark_bitmap()->cas_retries(),
duke@0 1593 mark_bitmap()->cas_by_another());
duke@0 1594 }
duke@0 1595 #endif // #ifndef PRODUCT
duke@0 1596
duke@0 1597 bool max_on_system_gc = UseMaximumCompactionOnSystemGC && is_system_gc;
jcoomes@210 1598 summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc);
duke@0 1599
duke@0 1600 COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity"));
duke@0 1601 COMPILER2_PRESENT(DerivedPointerTable::set_active(false));
duke@0 1602
duke@0 1603 // adjust_roots() updates Universe::_intArrayKlassObj which is
duke@0 1604 // needed by the compaction for filling holes in the dense prefix.
duke@0 1605 adjust_roots();
duke@0 1606
duke@0 1607 compaction_start.update();
duke@0 1608 // Does the perm gen always have to be done serially because
duke@0 1609 // klasses are used in the update of an object?
jcoomes@210 1610 compact_perm(vmthread_cm);
duke@0 1611
duke@0 1612 if (UseParallelOldGCCompacting) {
duke@0 1613 compact();
duke@0 1614 } else {
jcoomes@210 1615 compact_serial(vmthread_cm);
duke@0 1616 }
duke@0 1617
duke@0 1618 // Reset the mark bitmap, summary data, and do other bookkeeping. Must be
duke@0 1619 // done before resizing.
duke@0 1620 post_compact();
duke@0 1621
duke@0 1622 // Let the size policy know we're done
duke@0 1623 size_policy->major_collection_end(old_gen->used_in_bytes(), gc_cause);
duke@0 1624
duke@0 1625 if (UseAdaptiveSizePolicy) {
duke@0 1626 if (PrintAdaptiveSizePolicy) {
duke@0 1627 gclog_or_tty->print("AdaptiveSizeStart: ");
duke@0 1628 gclog_or_tty->stamp();
duke@0 1629 gclog_or_tty->print_cr(" collection: %d ",
duke@0 1630 heap->total_collections());
duke@0 1631 if (Verbose) {
duke@0 1632 gclog_or_tty->print("old_gen_capacity: %d young_gen_capacity: %d"
duke@0 1633 " perm_gen_capacity: %d ",
duke@0 1634 old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes(),
duke@0 1635 perm_gen->capacity_in_bytes());
duke@0 1636 }
duke@0 1637 }
duke@0 1638
duke@0 1639 // Don't check if the size_policy is ready here. Let
duke@0 1640 // the size_policy check that internally.
duke@0 1641 if (UseAdaptiveGenerationSizePolicyAtMajorCollection &&
duke@0 1642 ((gc_cause != GCCause::_java_lang_system_gc) ||
duke@0 1643 UseAdaptiveSizePolicyWithSystemGC)) {
duke@0 1644 // Calculate optimal free space amounts
duke@0 1645 assert(young_gen->max_size() >
duke@0 1646 young_gen->from_space()->capacity_in_bytes() +
duke@0 1647 young_gen->to_space()->capacity_in_bytes(),
duke@0 1648 "Sizes of space in young gen are out-of-bounds");
duke@0 1649 size_t max_eden_size = young_gen->max_size() -
duke@0 1650 young_gen->from_space()->capacity_in_bytes() -
duke@0 1651 young_gen->to_space()->capacity_in_bytes();
jmasa@263 1652 size_policy->compute_generation_free_space(
jmasa@263 1653 young_gen->used_in_bytes(),
jmasa@263 1654 young_gen->eden_space()->used_in_bytes(),
jmasa@263 1655 old_gen->used_in_bytes(),
jmasa@263 1656 perm_gen->used_in_bytes(),
jmasa@263 1657 young_gen->eden_space()->capacity_in_bytes(),
jmasa@263 1658 old_gen->max_gen_size(),
jmasa@263 1659 max_eden_size,
jmasa@263 1660 true /* full gc*/,
jmasa@263 1661 gc_cause);
jmasa@263 1662
jmasa@263 1663 heap->resize_old_gen(
jmasa@263 1664 size_policy->calculated_old_free_size_in_bytes());
duke@0 1665
duke@0 1666 // Don't resize the young generation at an major collection. A
duke@0 1667 // desired young generation size may have been calculated but
duke@0 1668 // resizing the young generation complicates the code because the
duke@0 1669 // resizing of the old generation may have moved the boundary
duke@0 1670 // between the young generation and the old generation. Let the
duke@0 1671 // young generation resizing happen at the minor collections.
duke@0 1672 }
duke@0 1673 if (PrintAdaptiveSizePolicy) {
duke@0 1674 gclog_or_tty->print_cr("AdaptiveSizeStop: collection: %d ",
duke@0 1675 heap->total_collections());
duke@0 1676 }
duke@0 1677 }
duke@0 1678
duke@0 1679 if (UsePerfData) {
duke@0 1680 PSGCAdaptivePolicyCounters* const counters = heap->gc_policy_counters();
duke@0 1681 counters->update_counters();
duke@0 1682 counters->update_old_capacity(old_gen->capacity_in_bytes());
duke@0 1683 counters->update_young_capacity(young_gen->capacity_in_bytes());
duke@0 1684 }
duke@0 1685
duke@0 1686 heap->resize_all_tlabs();
duke@0 1687
duke@0 1688 // We collected the perm gen, so we'll resize it here.
duke@0 1689 perm_gen->compute_new_size(pre_gc_values.perm_gen_used());
duke@0 1690
duke@0 1691 if (TraceGen1Time) accumulated_time()->stop();
duke@0 1692
duke@0 1693 if (PrintGC) {
duke@0 1694 if (PrintGCDetails) {
duke@0 1695 // No GC timestamp here. This is after GC so it would be confusing.
duke@0 1696 young_gen->print_used_change(pre_gc_values.young_gen_used());
duke@0 1697 old_gen->print_used_change(pre_gc_values.old_gen_used());
duke@0 1698 heap->print_heap_change(pre_gc_values.heap_used());
duke@0 1699 // Print perm gen last (print_heap_change() excludes the perm gen).
duke@0 1700 perm_gen->print_used_change(pre_gc_values.perm_gen_used());
duke@0 1701 } else {
duke@0 1702 heap->print_heap_change(pre_gc_values.heap_used());
duke@0 1703 }
duke@0 1704 }
duke@0 1705
duke@0 1706 // Track memory usage and detect low memory
duke@0 1707 MemoryService::track_memory_usage();
duke@0 1708 heap->update_counters();
duke@0 1709
duke@0 1710 if (PrintGCDetails) {
duke@0 1711 if (size_policy->print_gc_time_limit_would_be_exceeded()) {
duke@0 1712 if (size_policy->gc_time_limit_exceeded()) {
duke@0 1713 gclog_or_tty->print_cr(" GC time is exceeding GCTimeLimit "
duke@0 1714 "of %d%%", GCTimeLimit);
duke@0 1715 } else {
duke@0 1716 gclog_or_tty->print_cr(" GC time would exceed GCTimeLimit "
duke@0 1717 "of %d%%", GCTimeLimit);
duke@0 1718 }
duke@0 1719 }
duke@0 1720 size_policy->set_print_gc_time_limit_would_be_exceeded(false);
duke@0 1721 }
duke@0 1722 }
duke@0 1723
duke@0 1724 if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
duke@0 1725 HandleMark hm; // Discard invalid handles created during verification
duke@0 1726 gclog_or_tty->print(" VerifyAfterGC:");
duke@0 1727 Universe::verify(false);
duke@0 1728 }
duke@0 1729
duke@0 1730 // Re-verify object start arrays
duke@0 1731 if (VerifyObjectStartArray &&
duke@0 1732 VerifyAfterGC) {
duke@0 1733 old_gen->verify_object_start_array();
duke@0 1734 perm_gen->verify_object_start_array();
duke@0 1735 }
duke@0 1736
jmasa@263 1737 if (ZapUnusedHeapArea) {
jmasa@263 1738 old_gen->object_space()->check_mangled_unused_area_complete();
jmasa@263 1739 perm_gen->object_space()->check_mangled_unused_area_complete();
jmasa@263 1740 }
jmasa@263 1741
duke@0 1742 NOT_PRODUCT(ref_processor()->verify_no_references_recorded());
duke@0 1743
duke@0 1744 collection_exit.update();
duke@0 1745
duke@0 1746 if (PrintHeapAtGC) {
duke@0 1747 Universe::print_heap_after_gc();
duke@0 1748 }
duke@0 1749 if (PrintGCTaskTimeStamps) {
duke@0 1750 gclog_or_tty->print_cr("VM-Thread " INT64_FORMAT " " INT64_FORMAT " "
duke@0 1751 INT64_FORMAT,
duke@0 1752 marking_start.ticks(), compaction_start.ticks(),
duke@0 1753 collection_exit.ticks());
duke@0 1754 gc_task_manager()->print_task_time_stamps();
duke@0 1755 }
duke@0 1756 }
duke@0 1757
duke@0 1758 bool PSParallelCompact::absorb_live_data_from_eden(PSAdaptiveSizePolicy* size_policy,
duke@0 1759 PSYoungGen* young_gen,
duke@0 1760 PSOldGen* old_gen) {
duke@0 1761 MutableSpace* const eden_space = young_gen->eden_space();
duke@0 1762 assert(!eden_space->is_empty(), "eden must be non-empty");
duke@0 1763 assert(young_gen->virtual_space()->alignment() ==
duke@0 1764 old_gen->virtual_space()->alignment(), "alignments do not match");
duke@0 1765
duke@0 1766 if (!(UseAdaptiveSizePolicy && UseAdaptiveGCBoundary)) {
duke@0 1767 return false;
duke@0 1768 }
duke@0 1769
duke@0 1770 // Both generations must be completely committed.
duke@0 1771 if (young_gen->virtual_space()->uncommitted_size() != 0) {
duke@0 1772 return false;
duke@0 1773 }
duke@0 1774 if (old_gen->virtual_space()->uncommitted_size() != 0) {
duke@0 1775 return false;
duke@0 1776 }
duke@0 1777
duke@0 1778 // Figure out how much to take from eden. Include the average amount promoted
duke@0 1779 // in the total; otherwise the next young gen GC will simply bail out to a
duke@0 1780 // full GC.
duke@0 1781 const size_t alignment = old_gen->virtual_space()->alignment();
duke@0 1782 const size_t eden_used = eden_space->used_in_bytes();
duke@0 1783 const size_t promoted = (size_t)size_policy->avg_promoted()->padded_average();
duke@0 1784 const size_t absorb_size = align_size_up(eden_used + promoted, alignment);
duke@0 1785 const size_t eden_capacity = eden_space->capacity_in_bytes();
duke@0 1786
duke@0 1787 if (absorb_size >= eden_capacity) {
duke@0 1788 return false; // Must leave some space in eden.
duke@0 1789 }
duke@0 1790
duke@0 1791 const size_t new_young_size = young_gen->capacity_in_bytes() - absorb_size;
duke@0 1792 if (new_young_size < young_gen->min_gen_size()) {
duke@0 1793 return false; // Respect young gen minimum size.
duke@0 1794 }
duke@0 1795
duke@0 1796 if (TraceAdaptiveGCBoundary && Verbose) {
duke@0 1797 gclog_or_tty->print(" absorbing " SIZE_FORMAT "K: "
duke@0 1798 "eden " SIZE_FORMAT "K->" SIZE_FORMAT "K "
duke@0 1799 "from " SIZE_FORMAT "K, to " SIZE_FORMAT "K "
duke@0 1800 "young_gen " SIZE_FORMAT "K->" SIZE_FORMAT "K ",
duke@0 1801 absorb_size / K,
duke@0 1802 eden_capacity / K, (eden_capacity - absorb_size) / K,
duke@0 1803 young_gen->from_space()->used_in_bytes() / K,
duke@0 1804 young_gen->to_space()->used_in_bytes() / K,
duke@0 1805 young_gen->capacity_in_bytes() / K, new_young_size / K);
duke@0 1806 }
duke@0 1807
duke@0 1808 // Fill the unused part of the old gen.
duke@0 1809 MutableSpace* const old_space = old_gen->object_space();
duke@0 1810 MemRegion old_gen_unused(old_space->top(), old_space->end());
duke@0 1811 if (!old_gen_unused.is_empty()) {
duke@0 1812 SharedHeap::fill_region_with_object(old_gen_unused);
duke@0 1813 }
duke@0 1814
duke@0 1815 // Take the live data from eden and set both top and end in the old gen to
duke@0 1816 // eden top. (Need to set end because reset_after_change() mangles the region
duke@0 1817 // from end to virtual_space->high() in debug builds).
duke@0 1818 HeapWord* const new_top = eden_space->top();
duke@0 1819 old_gen->virtual_space()->expand_into(young_gen->virtual_space(),
duke@0 1820 absorb_size);
duke@0 1821 young_gen->reset_after_change();
duke@0 1822 old_space->set_top(new_top);
duke@0 1823 old_space->set_end(new_top);
duke@0 1824 old_gen->reset_after_change();
duke@0 1825
duke@0 1826 // Update the object start array for the filler object and the data from eden.
duke@0 1827 ObjectStartArray* const start_array = old_gen->start_array();
duke@0 1828 HeapWord* const start = old_gen_unused.start();
duke@0 1829 for (HeapWord* addr = start; addr < new_top; addr += oop(addr)->size()) {
duke@0 1830 start_array->allocate_block(addr);
duke@0 1831 }
duke@0 1832
duke@0 1833 // Could update the promoted average here, but it is not typically updated at
duke@0 1834 // full GCs and the value to use is unclear. Something like
duke@0 1835 //
duke@0 1836 // cur_promoted_avg + absorb_size / number_of_scavenges_since_last_full_gc.
duke@0 1837
duke@0 1838 size_policy->set_bytes_absorbed_from_eden(absorb_size);
duke@0 1839 return true;
duke@0 1840 }
duke@0 1841
duke@0 1842 GCTaskManager* const PSParallelCompact::gc_task_manager() {
duke@0 1843 assert(ParallelScavengeHeap::gc_task_manager() != NULL,
duke@0 1844 "shouldn't return NULL");
duke@0 1845 return ParallelScavengeHeap::gc_task_manager();
duke@0 1846 }
duke@0 1847
duke@0 1848 void PSParallelCompact::marking_phase(ParCompactionManager* cm,
duke@0 1849 bool maximum_heap_compaction) {
duke@0 1850 // Recursively traverse all live objects and mark them
duke@0 1851 EventMark m("1 mark object");
duke@0 1852 TraceTime tm("marking phase", print_phases(), true, gclog_or_tty);
duke@0 1853
duke@0 1854 ParallelScavengeHeap* heap = gc_heap();
duke@0 1855 uint parallel_gc_threads = heap->gc_task_manager()->workers();
jcoomes@375 1856 TaskQueueSetSuper* qset = ParCompactionManager::region_array();
duke@0 1857 ParallelTaskTerminator terminator(parallel_gc_threads, qset);
duke@0 1858
duke@0 1859 PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm);
duke@0 1860 PSParallelCompact::FollowStackClosure follow_stack_closure(cm);
duke@0 1861
duke@0 1862 {
duke@0 1863 TraceTime tm_m("par mark", print_phases(), true, gclog_or_tty);
duke@0 1864
duke@0 1865 GCTaskQueue* q = GCTaskQueue::create();
duke@0 1866
duke@0 1867 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::universe));
duke@0 1868 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jni_handles));
duke@0 1869 // We scan the thread roots in parallel
duke@0 1870 Threads::create_thread_roots_marking_tasks(q);
duke@0 1871 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::object_synchronizer));
duke@0 1872 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::flat_profiler));
duke@0 1873 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::management));
duke@0 1874 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::system_dictionary));
duke@0 1875 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti));
duke@0 1876 q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::vm_symbols));
duke@0 1877
duke@0 1878 if (parallel_gc_threads > 1) {
duke@0 1879 for (uint j = 0; j < parallel_gc_threads; j++) {
duke@0 1880 q->enqueue(new StealMarkingTask(&terminator));
duke@0 1881 }
duke@0 1882 }
duke@0 1883
duke@0 1884 WaitForBarrierGCTask* fin = WaitForBarrierGCTask::create();
duke@0 1885 q->enqueue(fin);
duke@0 1886
duke@0 1887 gc_task_manager()->add_list(q);
duke@0 1888
duke@0 1889 fin->wait_for();
duke@0 1890
duke@0 1891 // We have to release the barrier tasks!
duke@0 1892 WaitForBarrierGCTask::destroy(fin);
duke@0 1893 }
duke@0 1894
duke@0 1895 // Process reference objects found during marking
duke@0 1896 {
duke@0 1897 TraceTime tm_r("reference processing", print_phases(), true, gclog_or_tty);
duke@0 1898 if (ref_processor()->processing_is_mt()) {
duke@0 1899 RefProcTaskExecutor task_executor;
duke@0 1900 ref_processor()->process_discovered_references(
ysr@453 1901 is_alive_closure(), &mark_and_push_closure, &follow_stack_closure,
ysr@453 1902 &task_executor);
duke@0 1903 } else {
duke@0 1904 ref_processor()->process_discovered_references(
ysr@453 1905 is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, NULL);
duke@0 1906 }
duke@0 1907 }
duke@0 1908
duke@0 1909 TraceTime tm_c("class unloading", print_phases(), true, gclog_or_tty);
duke@0 1910 // Follow system dictionary roots and unload classes.
duke@0 1911 bool purged_class = SystemDictionary::do_unloading(is_alive_closure());
duke@0 1912
duke@0 1913 // Follow code cache roots.
duke@0 1914 CodeCache::do_unloading(is_alive_closure(), &mark_and_push_closure,
duke@0 1915 purged_class);
duke@0 1916 follow_stack(cm); // Flush marking stack.
duke@0 1917
duke@0 1918 // Update subklass/sibling/implementor links of live klasses
duke@0 1919 // revisit_klass_stack is used in follow_weak_klass_links().
duke@0 1920 follow_weak_klass_links(cm);
duke@0 1921
duke@0 1922 // Visit symbol and interned string tables and delete unmarked oops
duke@0 1923 SymbolTable::unlink(is_alive_closure());
duke@0 1924 StringTable::unlink(is_alive_closure());
duke@0 1925
duke@0 1926 assert(cm->marking_stack()->size() == 0, "stack should be empty by now");
duke@0 1927 assert(cm->overflow_stack()->is_empty(), "stack should be empty by now");
duke@0 1928 }
duke@0 1929
duke@0 1930 // This should be moved to the shared markSweep code!
duke@0 1931 class PSAlwaysTrueClosure: public BoolObjectClosure {
duke@0 1932 public:
duke@0 1933 void do_object(oop p) { ShouldNotReachHere(); }
duke@0 1934 bool do_object_b(oop p) { return true; }
duke@0 1935 };
duke@0 1936 static PSAlwaysTrueClosure always_true;
duke@0 1937
duke@0 1938 void PSParallelCompact::adjust_roots() {
duke@0 1939 // Adjust the pointers to reflect the new locations
duke@0 1940 EventMark m("3 adjust roots");
duke@0 1941 TraceTime tm("adjust roots", print_phases(), true, gclog_or_tty);
duke@0 1942
duke@0 1943 // General strong roots.
duke@0 1944 Universe::oops_do(adjust_root_pointer_closure());
duke@0 1945 ReferenceProcessor::oops_do(adjust_root_pointer_closure());
duke@0 1946 JNIHandles::oops_do(adjust_root_pointer_closure()); // Global (strong) JNI handles
duke@0 1947 Threads::oops_do(adjust_root_pointer_closure());
duke@0 1948 ObjectSynchronizer::oops_do(adjust_root_pointer_closure());
duke@0 1949 FlatProfiler::oops_do(adjust_root_pointer_closure());
duke@0 1950 Management::oops_do(adjust_root_pointer_closure());
duke@0 1951 JvmtiExport::oops_do(adjust_root_pointer_closure());
duke@0 1952 // SO_AllClasses
duke@0 1953 SystemDictionary::oops_do(adjust_root_pointer_closure());
duke@0 1954 vmSymbols::oops_do(adjust_root_pointer_closure());
duke@0 1955
duke@0 1956 // Now adjust pointers in remaining weak roots. (All of which should
duke@0 1957 // have been cleared if they pointed to non-surviving objects.)
duke@0 1958 // Global (weak) JNI handles
duke@0 1959 JNIHandles::weak_oops_do(&always_true, adjust_root_pointer_closure());
duke@0 1960
duke@0 1961 CodeCache::oops_do(adjust_pointer_closure());
duke@0 1962 SymbolTable::oops_do(adjust_root_pointer_closure());
duke@0 1963 StringTable::oops_do(adjust_root_pointer_closure());
duke@0 1964 ref_processor()->weak_oops_do(adjust_root_pointer_closure());
duke@0 1965 // Roots were visited so references into the young gen in roots
duke@0 1966 // may have been scanned. Process them also.
duke@0 1967 // Should the reference processor have a span that excludes
duke@0 1968 // young gen objects?
duke@0 1969 PSScavenge::reference_processor()->weak_oops_do(
duke@0 1970 adjust_root_pointer_closure());
duke@0 1971 }
duke@0 1972
duke@0 1973 void PSParallelCompact::compact_perm(ParCompactionManager* cm) {
duke@0 1974 EventMark m("4 compact perm");
duke@0 1975 TraceTime tm("compact perm gen", print_phases(), true, gclog_or_tty);
duke@0 1976 // trace("4");
duke@0 1977
duke@0 1978 gc_heap()->perm_gen()->start_array()->reset();
duke@0 1979 move_and_update(cm, perm_space_id);
duke@0 1980 }
duke@0 1981
jcoomes@375 1982 void PSParallelCompact::enqueue_region_draining_tasks(GCTaskQueue* q,
jcoomes@375 1983 uint parallel_gc_threads)
jcoomes@375 1984 {
duke@0 1985 TraceTime tm("drain task setup", print_phases(), true, gclog_or_tty);
duke@0 1986
duke@0 1987 const unsigned int task_count = MAX2(parallel_gc_threads, 1U);
duke@0 1988 for (unsigned int j = 0; j < task_count; j++) {
duke@0 1989 q->enqueue(new DrainStacksCompactionTask());
duke@0 1990 }
duke@0 1991
jcoomes@375 1992 // Find all regions that are available (can be filled immediately) and
duke@0 1993 // distribute them to the thread stacks. The iteration is done in reverse
jcoomes@375 1994 // order (high to low) so the regions will be removed in ascending order.
duke@0 1995
duke@0 1996 const ParallelCompactData& sd = PSParallelCompact::summary_data();
duke@0 1997
jcoomes@375 1998 size_t fillable_regions = 0; // A count for diagnostic purposes.
duke@0 1999 unsigned int which = 0; // The worker thread number.
duke@0 2000
duke@0 2001 for (unsigned int id = to_space_id; id > perm_space_id; --id) {
duke@0 2002 SpaceInfo* const space_info = _space_info + id;
duke@0 2003 MutableSpace* const space = space_info->space();
duke@0 2004 HeapWord* const new_top = space_info->new_top();
duke@0 2005
jcoomes@375 2006 const size_t beg_region = sd.addr_to_region_idx(space_info->dense_prefix());
jcoomes@375 2007 const size_t end_region =
jcoomes@375 2008 sd.addr_to_region_idx(sd.region_align_up(new_top));
jcoomes@375 2009 assert(end_region > 0, "perm gen cannot be empty");
jcoomes@375 2010
jcoomes@375 2011 for (size_t cur = end_region - 1; cur >= beg_region; --cur) {
jcoomes@375 2012 if (sd.region(cur)->claim_unsafe()) {
duke@0 2013 ParCompactionManager* cm = ParCompactionManager::manager_array(which);
duke@0 2014 cm->save_for_processing(cur);
duke@0 2015
duke@0 2016 if (TraceParallelOldGCCompactionPhase && Verbose) {
jcoomes@375 2017 const size_t count_mod_8 = fillable_regions & 7;
duke@0 2018 if (count_mod_8 == 0) gclog_or_tty->print("fillable: ");
jcoomes@264 2019 gclog_or_tty->print(" " SIZE_FORMAT_W(7), cur);
duke@0 2020 if (count_mod_8 == 7) gclog_or_tty->cr();
duke@0 2021 }
duke@0 2022
jcoomes@375 2023 NOT_PRODUCT(++fillable_regions;)
jcoomes@375 2024
jcoomes@375 2025 // Assign regions to threads in round-robin fashion.
duke@0 2026 if (++which == task_count) {
duke@0 2027 which = 0;
duke@0 2028 }
duke@0 2029 }
duke@0 2030 }
duke@0 2031 }
duke@0 2032
duke@0 2033 if (TraceParallelOldGCCompactionPhase) {
jcoomes@375 2034 if (Verbose && (fillable_regions & 7) != 0) gclog_or_tty->cr();
jcoomes@375 2035 gclog_or_tty->print_cr("%u initially fillable regions", fillable_regions);
duke@0 2036 }
duke@0 2037 }
duke@0 2038
duke@0 2039 #define PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING 4
duke@0 2040
duke@0 2041 void PSParallelCompact::enqueue_dense_prefix_tasks(GCTaskQueue* q,
duke@0 2042 uint parallel_gc_threads) {
duke@0 2043 TraceTime tm("dense prefix task setup", print_phases(), true, gclog_or_tty);
duke@0 2044
duke@0 2045 ParallelCompactData& sd = PSParallelCompact::summary_data();
duke@0 2046
duke@0 2047 // Iterate over all the spaces adding tasks for updating
jcoomes@375 2048 // regions in the dense prefix. Assume that 1 gc thread
duke@0 2049 // will work on opening the gaps and the remaining gc threads
duke@0 2050 // will work on the dense prefix.
duke@0 2051 SpaceId space_id = old_space_id;
duke@0 2052 while (space_id != last_space_id) {
duke@0 2053 HeapWord* const dense_prefix_end = _space_info[space_id].dense_prefix();
duke@0 2054 const MutableSpace* const space = _space_info[space_id].space();
duke@0 2055
duke@0 2056 if (dense_prefix_end == space->bottom()) {
duke@0 2057 // There is no dense prefix for this space.
duke@0 2058 space_id = next_compaction_space_id(space_id);
duke@0 2059 continue;
duke@0 2060 }
duke@0 2061
jcoomes@375 2062 // The dense prefix is before this region.
jcoomes@375 2063 size_t region_index_end_dense_prefix =
jcoomes@375 2064 sd.addr_to_region_idx(dense_prefix_end);
jcoomes@375 2065 RegionData* const dense_prefix_cp =
jcoomes@375 2066 sd.region(region_index_end_dense_prefix);
duke@0 2067 assert(dense_prefix_end == space->end() ||
duke@0 2068 dense_prefix_cp->available() ||
duke@0 2069 dense_prefix_cp->claimed(),
jcoomes@375 2070 "The region after the dense prefix should always be ready to fill");
jcoomes@375 2071
jcoomes@375 2072 size_t region_index_start = sd.addr_to_region_idx(space->bottom());
duke@0 2073
duke@0 2074 // Is there dense prefix work?
jcoomes@375 2075 size_t total_dense_prefix_regions =
jcoomes@375 2076 region_index_end_dense_prefix - region_index_start;
jcoomes@375 2077 // How many regions of the dense prefix should be given to
duke@0 2078 // each thread?
jcoomes@375 2079 if (total_dense_prefix_regions > 0) {
duke@0 2080 uint tasks_for_dense_prefix = 1;
duke@0 2081 if (UseParallelDensePrefixUpdate) {
jcoomes@375 2082 if (total_dense_prefix_regions <=
duke@0 2083 (parallel_gc_threads * PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING)) {
duke@0 2084 // Don't over partition. This assumes that
duke@0 2085 // PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING is a small integer value
jcoomes@375 2086 // so there are not many regions to process.
duke@0 2087 tasks_for_dense_prefix = parallel_gc_threads;
duke@0 2088 } else {
duke@0 2089 // Over partition
duke@0 2090 tasks_for_dense_prefix = parallel_gc_threads *
duke@0 2091 PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING;
duke@0 2092 }
duke@0 2093 }
jcoomes@375 2094 size_t regions_per_thread = total_dense_prefix_regions /
duke@0 2095 tasks_for_dense_prefix;
jcoomes@375 2096 // Give each thread at least 1 region.
jcoomes@375 2097 if (regions_per_thread == 0) {
jcoomes@375 2098 regions_per_thread = 1;
duke@0 2099 }
duke@0 2100
duke@0 2101 for (uint k = 0; k < tasks_for_dense_prefix; k++) {
jcoomes@375 2102 if (region_index_start >= region_index_end_dense_prefix) {
duke@0 2103 break;
duke@0 2104 }
jcoomes@375 2105 // region_index_end is not processed
jcoomes@375 2106 size_t region_index_end = MIN2(region_index_start + regions_per_thread,
jcoomes@375 2107 region_index_end_dense_prefix);
duke@0 2108 q->enqueue(new UpdateDensePrefixTask(
duke@0 2109 space_id,
jcoomes@375 2110 region_index_start,
jcoomes@375 2111 region_index_end));
jcoomes@375 2112 region_index_start = region_index_end;
duke@0 2113 }
duke@0 2114 }
duke@0 2115 // This gets any part of the dense prefix that did not
duke@0 2116 // fit evenly.
jcoomes@375 2117 if (region_index_start < region_index_end_dense_prefix) {
duke@0 2118 q->enqueue(new UpdateDensePrefixTask(
duke@0 2119 space_id,
jcoomes@375 2120 region_index_start,
jcoomes@375 2121 region_index_end_dense_prefix));
duke@0 2122 }
duke@0 2123 space_id = next_compaction_space_id(space_id);
duke@0 2124 } // End tasks for dense prefix
duke@0 2125 }
duke@0 2126
jcoomes@375 2127 void PSParallelCompact::enqueue_region_stealing_tasks(
duke@0 2128 GCTaskQueue* q,
duke@0 2129 ParallelTaskTerminator* terminator_ptr,
duke@0 2130 uint parallel_gc_threads) {
duke@0 2131 TraceTime tm("steal task setup", print_phases(), true, gclog_or_tty);
duke@0 2132
jcoomes@375 2133 // Once a thread has drained it's stack, it should try to steal regions from
duke@0 2134 // other threads.
duke@0 2135 if (parallel_gc_threads > 1) {
duke@0 2136 for (uint j = 0; j < parallel_gc_threads; j++) {
jcoomes@375 2137 q->enqueue(new StealRegionCompactionTask(terminator_ptr));
duke@0 2138 }
duke@0 2139 }
duke@0 2140 }
duke@0 2141
duke@0 2142 void PSParallelCompact::compact() {
duke@0 2143 EventMark m("5 compact");
duke@0 2144 // trace("5");
duke@0 2145 TraceTime tm("compaction phase", print_phases(), true, gclog_or_tty);
duke@0 2146
duke@0 2147 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
duke@0 2148 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
duke@0 2149 PSOldGen* old_gen = heap->old_gen();
duke@0 2150 old_gen->start_array()->reset();
duke@0 2151 uint parallel_gc_threads = heap->gc_task_manager()->workers();
jcoomes@375 2152 TaskQueueSetSuper* qset = ParCompactionManager::region_array();
duke@0 2153 ParallelTaskTerminator terminator(parallel_gc_threads, qset);
duke@0 2154
duke@0 2155 GCTaskQueue* q = GCTaskQueue::create();
jcoomes@375 2156 enqueue_region_draining_tasks(q, parallel_gc_threads);
duke@0 2157 enqueue_dense_prefix_tasks(q, parallel_gc_threads);
jcoomes@375 2158 enqueue_region_stealing_tasks(q, &terminator, parallel_gc_threads);
duke@0 2159
duke@0 2160 {
duke@0 2161 TraceTime tm_pc("par compact", print_phases(), true, gclog_or_tty);
duke@0 2162
duke@0 2163 WaitForBarrierGCTask* fin = WaitForBarrierGCTask::create();
duke@0 2164 q->enqueue(fin);
duke@0 2165
duke@0 2166 gc_task_manager()->add_list(q);
duke@0 2167
duke@0 2168 fin->wait_for();
duke@0 2169
duke@0 2170 // We have to release the barrier tasks!
duke@0 2171 WaitForBarrierGCTask::destroy(fin);
duke@0 2172
duke@0 2173 #ifdef ASSERT
jcoomes@375 2174 // Verify that all regions have been processed before the deferred updates.
duke@0 2175 // Note that perm_space_id is skipped; this type of verification is not
jcoomes@375 2176 // valid until the perm gen is compacted by regions.
duke@0 2177 for (unsigned int id = old_space_id; id < last_space_id; ++id) {
duke@0 2178 verify_complete(SpaceId(id));
duke@0 2179 }
duke@0 2180 #endif
duke@0 2181 }
duke@0 2182
duke@0 2183 {
duke@0 2184 // Update the deferred objects, if any. Any compaction manager can be used.
duke@0 2185 TraceTime tm_du("deferred updates", print_phases(), true, gclog_or_tty);
duke@0 2186 ParCompactionManager* cm = ParCompactionManager::manager_array(0);
duke@0 2187 for (unsigned int id = old_space_id; id < last_space_id; ++id) {
duke@0 2188 update_deferred_objects(cm, SpaceId(id));
duke@0 2189 }
duke@0 2190 }
duke@0 2191 }
duke@0 2192
duke@0 2193 #ifdef ASSERT
duke@0 2194 void PSParallelCompact::verify_complete(SpaceId space_id) {
jcoomes@375 2195 // All Regions between space bottom() to new_top() should be marked as filled
jcoomes@375 2196 // and all Regions between new_top() and top() should be available (i.e.,
duke@0 2197 // should have been emptied).
duke@0 2198 ParallelCompactData& sd = summary_data();
duke@0 2199 SpaceInfo si = _space_info[space_id];
jcoomes@375 2200 HeapWord* new_top_addr = sd.region_align_up(si.new_top());
jcoomes@375 2201 HeapWord* old_top_addr = sd.region_align_up(si.space()->top());
jcoomes@375 2202 const size_t beg_region = sd.addr_to_region_idx(si.space()->bottom());
jcoomes@375 2203 const size_t new_top_region = sd.addr_to_region_idx(new_top_addr);
jcoomes@375 2204 const size_t old_top_region = sd.addr_to_region_idx(old_top_addr);
duke@0 2205
duke@0 2206 bool issued_a_warning = false;
duke@0 2207
jcoomes@375 2208 size_t cur_region;
jcoomes@375 2209 for (cur_region = beg_region; cur_region < new_top_region; ++cur_region) {
jcoomes@375 2210 const RegionData* const c = sd.region(cur_region);
duke@0 2211 if (!c->completed()) {
jcoomes@375 2212 warning("region " SIZE_FORMAT " not filled: "
duke@0 2213 "destination_count=" SIZE_FORMAT,
jcoomes@375 2214 cur_region, c->destination_count());
duke@0 2215 issued_a_warning = true;
duke@0 2216 }
duke@0 2217 }
duke@0 2218
jcoomes@375 2219 for (cur_region = new_top_region; cur_region < old_top_region; ++cur_region) {
jcoomes@375 2220 const RegionData* const c = sd.region(cur_region);
duke@0 2221 if (!c->available()) {
jcoomes@375 2222 warning("region " SIZE_FORMAT " not empty: "
duke@0 2223 "destination_count=" SIZE_FORMAT,
jcoomes@375 2224 cur_region, c->destination_count());
duke@0 2225 issued_a_warning = true;
duke@0 2226 }
duke@0 2227 }
duke@0 2228
duke@0 2229 if (issued_a_warning) {
jcoomes@375 2230 print_region_ranges();
duke@0 2231 }
duke@0 2232 }
duke@0 2233 #endif // #ifdef ASSERT
duke@0 2234
duke@0 2235 void PSParallelCompact::compact_serial(ParCompactionManager* cm) {
duke@0 2236 EventMark m("5 compact serial");
duke@0 2237 TraceTime tm("compact serial", print_phases(), true, gclog_or_tty);
duke@0 2238
duke@0 2239 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
duke@0 2240 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
duke@0 2241
duke@0 2242 PSYoungGen* young_gen = heap->young_gen();
duke@0 2243 PSOldGen* old_gen = heap->old_gen();
duke@0 2244
duke@0 2245 old_gen->start_array()->reset();
duke@0 2246 old_gen->move_and_update(cm);
duke@0 2247 young_gen->move_and_update(cm);
duke@0 2248 }
duke@0 2249
duke@0 2250
duke@0 2251 void PSParallelCompact::follow_stack(ParCompactionManager* cm) {
duke@0 2252 while(!cm->overflow_stack()->is_empty()) {
duke@0 2253 oop obj = cm->overflow_stack()->pop();
duke@0 2254 obj->follow_contents(cm);
duke@0 2255 }
duke@0 2256
duke@0 2257 oop obj;
duke@0 2258 // obj is a reference!!!
duke@0 2259 while (cm->marking_stack()->pop_local(obj)) {
duke@0 2260 // It would be nice to assert about the type of objects we might
duke@0 2261 // pop, but they can come from anywhere, unfortunately.
duke@0 2262 obj->follow_contents(cm);
duke@0 2263 }
duke@0 2264 }
duke@0 2265
duke@0 2266 void
duke@0 2267 PSParallelCompact::follow_weak_klass_links(ParCompactionManager* serial_cm) {
duke@0 2268 // All klasses on the revisit stack are marked at this point.
duke@0 2269 // Update and follow all subklass, sibling and implementor links.
duke@0 2270 for (uint i = 0; i < ParallelGCThreads+1; i++) {
duke@0 2271 ParCompactionManager* cm = ParCompactionManager::manager_array(i);
duke@0 2272 KeepAliveClosure keep_alive_closure(cm);
duke@0 2273 for (int i = 0; i < cm->revisit_klass_stack()->length(); i++) {
duke@0 2274 cm->revisit_klass_stack()->at(i)->follow_weak_klass_links(
duke@0 2275 is_alive_closure(),
duke@0 2276 &keep_alive_closure);
duke@0 2277 }
duke@0 2278 follow_stack(cm);
duke@0 2279 }
duke@0 2280 }
duke@0 2281
duke@0 2282 void
duke@0 2283 PSParallelCompact::revisit_weak_klass_link(ParCompactionManager* cm, Klass* k) {
duke@0 2284 cm->revisit_klass_stack()->push(k);
duke@0 2285 }
duke@0 2286
duke@0 2287 #ifdef VALIDATE_MARK_SWEEP
duke@0 2288
coleenp@113 2289 void PSParallelCompact::track_adjusted_pointer(void* p, bool isroot) {
duke@0 2290 if (!ValidateMarkSweep)
duke@0 2291 return;
duke@0 2292
duke@0 2293 if (!isroot) {
duke@0 2294 if (_pointer_tracking) {
duke@0 2295 guarantee(_adjusted_pointers->contains(p), "should have seen this pointer");
duke@0 2296 _adjusted_pointers->remove(p);
duke@0 2297 }
duke@0 2298 } else {
duke@0 2299 ptrdiff_t index = _root_refs_stack->find(p);
duke@0 2300 if (index != -1) {
duke@0 2301 int l = _root_refs_stack->length();
duke@0 2302 if (l > 0 && l - 1 != index) {
coleenp@113 2303 void* last = _root_refs_stack->pop();
duke@0 2304 assert(last != p, "should be different");
duke@0 2305 _root_refs_stack->at_put(index, last);
duke@0 2306 } else {
duke@0 2307 _root_refs_stack->remove(p);
duke@0 2308 }
duke@0 2309 }
duke@0 2310 }
duke@0 2311 }
duke@0 2312
duke@0 2313
coleenp@113 2314 void PSParallelCompact::check_adjust_pointer(void* p) {
duke@0 2315 _adjusted_pointers->push(p);
duke@0 2316 }
duke@0 2317
duke@0 2318
duke@0 2319 class AdjusterTracker: public OopClosure {
duke@0 2320 public:
duke@0 2321 AdjusterTracker() {};
coleenp@113 2322 void do_oop(oop* o) { PSParallelCompact::check_adjust_pointer(o); }
coleenp@113 2323 void do_oop(narrowOop* o) { PSParallelCompact::check_adjust_pointer(o); }
duke@0 2324 };
duke@0 2325
duke@0 2326
duke@0 2327 void PSParallelCompact::track_interior_pointers(oop obj) {
duke@0 2328 if (ValidateMarkSweep) {
duke@0 2329 _adjusted_pointers->clear();
duke@0 2330 _pointer_tracking = true;
duke@0 2331
duke@0 2332 AdjusterTracker checker;
duke@0 2333 obj->oop_iterate(&checker);
duke@0 2334 }
duke@0 2335 }
duke@0 2336
duke@0 2337
duke@0 2338 void PSParallelCompact::check_interior_pointers() {
duke@0 2339 if (ValidateMarkSweep) {
duke@0 2340 _pointer_tracking = false;
duke@0 2341 guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers");
duke@0 2342 }
duke@0 2343 }
duke@0 2344
duke@0 2345
duke@0 2346 void PSParallelCompact::reset_live_oop_tracking(bool at_perm) {
duke@0 2347 if (ValidateMarkSweep) {
duke@0 2348 guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops");
duke@0 2349 _live_oops_index = at_perm ? _live_oops_index_at_perm : 0;
duke@0 2350 }
duke@0 2351 }
duke@0 2352
duke@0 2353
duke@0 2354 void PSParallelCompact::register_live_oop(oop p, size_t size) {
duke@0 2355 if (ValidateMarkSweep) {
duke@0 2356 _live_oops->push(p);
duke@0 2357 _live_oops_size->push(size);
duke@0 2358 _live_oops_index++;
duke@0 2359 }
duke@0 2360 }
duke@0 2361
duke@0 2362 void PSParallelCompact::validate_live_oop(oop p, size_t size) {
duke@0 2363 if (ValidateMarkSweep) {
duke@0 2364 oop obj = _live_oops->at((int)_live_oops_index);
duke@0 2365 guarantee(obj == p, "should be the same object");
duke@0 2366 guarantee(_live_oops_size->at((int)_live_oops_index) == size, "should be the same size");
duke@0 2367 _live_oops_index++;
duke@0 2368 }
duke@0 2369 }
duke@0 2370
duke@0 2371 void PSParallelCompact::live_oop_moved_to(HeapWord* q, size_t size,
duke@0 2372 HeapWord* compaction_top) {
duke@0 2373 assert(oop(q)->forwardee() == NULL || oop(q)->forwardee() == oop(compaction_top),
duke@0 2374 "should be moved to forwarded location");
duke@0 2375 if (ValidateMarkSweep) {
duke@0 2376 PSParallelCompact::validate_live_oop(oop(q), size);
duke@0 2377 _live_oops_moved_to->push(oop(compaction_top));
duke@0 2378 }
duke@0 2379 if (RecordMarkSweepCompaction) {
duke@0 2380 _cur_gc_live_oops->push(q);
duke@0 2381 _cur_gc_live_oops_moved_to->push(compaction_top);
duke@0 2382 _cur_gc_live_oops_size->push(size);
duke@0 2383 }
duke@0 2384 }
duke@0 2385
duke@0 2386
duke@0 2387 void PSParallelCompact::compaction_complete() {
duke@0 2388 if (RecordMarkSweepCompaction) {
duke@0 2389 GrowableArray<HeapWord*>* _tmp_live_oops = _cur_gc_live_oops;
duke@0 2390 GrowableArray<HeapWord*>* _tmp_live_oops_moved_to = _cur_gc_live_oops_moved_to;
duke@0 2391 GrowableArray<size_t> * _tmp_live_oops_size = _cur_gc_live_oops_size;
duke@0 2392
duke@0 2393 _cur_gc_live_oops = _last_gc_live_oops;
duke@0 2394 _cur_gc_live_oops_moved_to = _last_gc_live_oops_moved_to;
duke@0 2395 _cur_gc_live_oops_size = _last_gc_live_oops_size;
duke@0 2396 _last_gc_live_oops = _tmp_live_oops;
duke@0 2397 _last_gc_live_oops_moved_to = _tmp_live_oops_moved_to;
duke@0 2398 _last_gc_live_oops_size = _tmp_live_oops_size;
duke@0 2399 }
duke@0 2400 }
duke@0 2401
duke@0 2402
duke@0 2403 void PSParallelCompact::print_new_location_of_heap_address(HeapWord* q) {
duke@0 2404 if (!RecordMarkSweepCompaction) {
duke@0 2405 tty->print_cr("Requires RecordMarkSweepCompaction to be enabled");
duke@0 2406 return;
duke@0 2407 }
duke@0 2408
duke@0 2409 if (_last_gc_live_oops == NULL) {
duke@0 2410 tty->print_cr("No compaction information gathered yet");
duke@0 2411 return;
duke@0 2412 }
duke@0 2413
duke@0 2414 for (int i = 0; i < _last_gc_live_oops->length(); i++) {
duke@0 2415 HeapWord* old_oop = _last_gc_live_oops->at(i);
duke@0 2416 size_t sz = _last_gc_live_oops_size->at(i);
duke@0 2417 if (old_oop <= q && q < (old_oop + sz)) {
duke@0 2418 HeapWord* new_oop = _last_gc_live_oops_moved_to->at(i);
duke@0 2419 size_t offset = (q - old_oop);
duke@0 2420 tty->print_cr("Address " PTR_FORMAT, q);
duke@0 2421 tty->print_cr(" Was in oop " PTR_FORMAT ", size %d, at offset %d", old_oop, sz, offset);
duke@0 2422 tty->print_cr(" Now in oop " PTR_FORMAT ", actual address " PTR_FORMAT, new_oop, new_oop + offset);
duke@0 2423 return;
duke@0 2424 }
duke@0 2425 }
duke@0 2426
duke@0 2427 tty->print_cr("Address " PTR_FORMAT " not found in live oop information from last GC", q);
duke@0 2428 }
duke@0 2429 #endif //VALIDATE_MARK_SWEEP
duke@0 2430
jcoomes@375 2431 // Update interior oops in the ranges of regions [beg_region, end_region).
duke@0 2432 void
duke@0 2433 PSParallelCompact::update_and_deadwood_in_dense_prefix(ParCompactionManager* cm,
duke@0 2434 SpaceId space_id,
jcoomes@375 2435 size_t beg_region,
jcoomes@375 2436 size_t end_region) {
duke@0 2437 ParallelCompactData& sd = summary_data();
duke@0 2438 ParMarkBitMap* const mbm = mark_bitmap();
duke@0 2439
jcoomes@375 2440 HeapWord* beg_addr = sd.region_to_addr(beg_region);
jcoomes@375 2441 HeapWord* const end_addr = sd.region_to_addr(end_region);
jcoomes@375 2442 assert(beg_region <= end_region, "bad region range");
duke@0 2443 assert(end_addr <= dense_prefix(space_id), "not in the dense prefix");
duke@0 2444
duke@0 2445 #ifdef ASSERT
jcoomes@375 2446 // Claim the regions to avoid triggering an assert when they are marked as
duke@0 2447 // filled.
jcoomes@375 2448 for (size_t claim_region = beg_region; claim_region < end_region; ++claim_region) {
jcoomes@375 2449 assert(sd.region(claim_region)->claim_unsafe(), "claim() failed");
duke@0 2450 }
duke@0 2451 #endif // #ifdef ASSERT
duke@0 2452
duke@0 2453 if (beg_addr != space(space_id)->bottom()) {
duke@0 2454 // Find the first live object or block of dead space that *starts* in this
jcoomes@375 2455 // range of regions. If a partial object crosses onto the region, skip it;
jcoomes@375 2456 // it will be marked for 'deferred update' when the object head is
jcoomes@375 2457 // processed. If dead space crosses onto the region, it is also skipped; it
jcoomes@375 2458 // will be filled when the prior region is processed. If neither of those
jcoomes@375 2459 // apply, the first word in the region is the start of a live object or dead
jcoomes@375 2460 // space.
duke@0 2461 assert(beg_addr > space(space_id)->bottom(), "sanity");
jcoomes@375 2462 const RegionData* const cp = sd.region(beg_region);
duke@0 2463 if (cp->partial_obj_size() != 0) {
jcoomes@375 2464 beg_addr = sd.partial_obj_end(beg_region);
duke@0 2465 } else if (dead_space_crosses_boundary(cp, mbm->addr_to_bit(beg_addr))) {
duke@0 2466 beg_addr = mbm->find_obj_beg(beg_addr, end_addr);
duke@0 2467 }
duke@0 2468 }
duke@0 2469
duke@0 2470 if (beg_addr < end_addr) {
jcoomes@375 2471 // A live object or block of dead space starts in this range of Regions.
duke@0 2472 HeapWord* const dense_prefix_end = dense_prefix(space_id);
duke@0 2473
duke@0 2474 // Create closures and iterate.
duke@0 2475 UpdateOnlyClosure update_closure(mbm, cm, space_id);
duke@0 2476 FillClosure fill_closure(cm, space_id);
duke@0 2477 ParMarkBitMap::IterationStatus status;
duke@0 2478 status = mbm->iterate(&update_closure, &fill_closure, beg_addr, end_addr,
duke@0 2479 dense_prefix_end);
duke@0 2480 if (status == ParMarkBitMap::incomplete) {
duke@0 2481 update_closure.do_addr(update_closure.source());
duke@0 2482 }
duke@0 2483 }
duke@0 2484
jcoomes@375 2485 // Mark the regions as filled.
jcoomes@375 2486 RegionData* const beg_cp = sd.region(beg_region);
jcoomes@375 2487 RegionData* const end_cp = sd.region(end_region);
jcoomes@375 2488 for (RegionData* cp = beg_cp; cp < end_cp; ++cp) {
duke@0 2489 cp->set_completed();
duke@0 2490 }
duke@0 2491 }
duke@0 2492
duke@0 2493 // Return the SpaceId for the space containing addr. If addr is not in the
duke@0 2494 // heap, last_space_id is returned. In debug mode it expects the address to be
duke@0 2495 // in the heap and asserts such.
duke@0 2496 PSParallelCompact::SpaceId PSParallelCompact::space_id(HeapWord* addr) {
duke@0 2497 assert(Universe::heap()->is_in_reserved(addr), "addr not in the heap");
duke@0 2498
duke@0 2499 for (unsigned int id = perm_space_id; id < last_space_id; ++id) {
duke@0 2500 if (_space_info[id].space()->contains(addr)) {
duke@0 2501 return SpaceId(id);
duke@0 2502 }
duke@0 2503 }
duke@0 2504
duke@0 2505 assert(false, "no space contains the addr");
duke@0 2506 return last_space_id;
duke@0 2507 }
duke@0 2508
duke@0 2509 void PSParallelCompact::update_deferred_objects(ParCompactionManager* cm,
duke@0 2510 SpaceId id) {
duke@0 2511 assert(id < last_space_id, "bad space id");
duke@0 2512
duke@0 2513 ParallelCompactData& sd = summary_data();
duke@0 2514 const SpaceInfo* const space_info = _space_info + id;
duke@0 2515 ObjectStartArray* const start_array = space_info->start_array();
duke@0 2516
duke@0 2517 const MutableSpace* const space = space_info->space();
duke@0 2518 assert(space_info->dense_prefix() >= space->bottom(), "dense_prefix not set");
duke@0 2519 HeapWord* const beg_addr = space_info->dense_prefix();
jcoomes@375 2520 HeapWord* const end_addr = sd.region_align_up(space_info->new_top());
jcoomes@375 2521
jcoomes@375 2522 const RegionData* const beg_region = sd.addr_to_region_ptr(beg_addr);
jcoomes@375 2523 const RegionData* const end_region = sd.addr_to_region_ptr(end_addr);
jcoomes@375 2524 const RegionData* cur_region;
jcoomes@375 2525 for (cur_region = beg_region; cur_region < end_region; ++cur_region) {
jcoomes@375 2526 HeapWord* const addr = cur_region->deferred_obj_addr();
duke@0 2527 if (addr != NULL) {
duke@0 2528 if (start_array != NULL) {
duke@0 2529 start_array->allocate_block(addr);
duke@0 2530 }
duke@0 2531 oop(addr)->update_contents(cm);
duke@0 2532 assert(oop(addr)->is_oop_or_null(), "should be an oop now");
duke@0 2533 }
duke@0 2534 }
duke@0 2535 }
duke@0 2536
duke@0 2537 // Skip over count live words starting from beg, and return the address of the
duke@0 2538 // next live word. Unless marked, the word corresponding to beg is assumed to
duke@0 2539 // be dead. Callers must either ensure beg does not correspond to the middle of
duke@0 2540 // an object, or account for those live words in some other way. Callers must
duke@0 2541 // also ensure that there are enough live words in the range [beg, end) to skip.
duke@0 2542 HeapWord*
duke@0 2543 PSParallelCompact::skip_live_words(HeapWord* beg, HeapWord* end, size_t count)
duke@0 2544 {
duke@0 2545 assert(count > 0, "sanity");
duke@0 2546
duke@0 2547 ParMarkBitMap* m = mark_bitmap();
duke@0 2548 idx_t bits_to_skip = m->words_to_bits(count);
duke@0 2549 idx_t cur_beg = m->addr_to_bit(beg);
duke@0 2550 const idx_t search_end = BitMap::word_align_up(m->addr_to_bit(end));
duke@0 2551
duke@0 2552 do {
duke@0 2553 cur_beg = m->find_obj_beg(cur_beg, search_end);
duke@0 2554 idx_t cur_end = m->find_obj_end(cur_beg, search_end);
duke@0 2555 const size_t obj_bits = cur_end - cur_beg + 1;
duke@0 2556 if (obj_bits > bits_to_skip) {
duke@0 2557 return m->bit_to_addr(cur_beg + bits_to_skip);
duke@0 2558 }
duke@0 2559 bits_to_skip -= obj_bits;
duke@0 2560 cur_beg = cur_end + 1;
duke@0 2561 } while (bits_to_skip > 0);
duke@0 2562
duke@0 2563 // Skipping the desired number of words landed just past the end of an object.
duke@0 2564 // Find the start of the next object.
duke@0 2565 cur_beg = m->find_obj_beg(cur_beg, search_end);
duke@0 2566 assert(cur_beg < m->addr_to_bit(end), "not enough live words to skip");
duke@0 2567 return m->bit_to_addr(cur_beg);
duke@0 2568 }
duke@0 2569
duke@0 2570 HeapWord*
duke@0 2571 PSParallelCompact::first_src_addr(HeapWord* const dest_addr,
jcoomes@375 2572 size_t src_region_idx)
duke@0 2573 {
duke@0 2574 ParMarkBitMap* const bitmap = mark_bitmap();
duke@0 2575 const ParallelCompactData& sd = summary_data();
jcoomes@375 2576 const size_t RegionSize = ParallelCompactData::RegionSize;
jcoomes@375 2577
jcoomes@375 2578 assert(sd.is_region_aligned(dest_addr), "not aligned");
jcoomes@375 2579
jcoomes@375 2580 const RegionData* const src_region_ptr = sd.region(src_region_idx);
jcoomes@375 2581 const size_t partial_obj_size = src_region_ptr->partial_obj_size();
jcoomes@375 2582 HeapWord* const src_region_destination = src_region_ptr->destination();
jcoomes@375 2583
jcoomes@375 2584 assert(dest_addr >= src_region_destination, "wrong src region");
jcoomes@375 2585 assert(src_region_ptr->data_size() > 0, "src region cannot be empty");
jcoomes@375 2586
jcoomes@375 2587 HeapWord* const src_region_beg = sd.region_to_addr(src_region_idx);
jcoomes@375 2588 HeapWord* const src_region_end = src_region_beg + RegionSize;
jcoomes@375 2589
jcoomes@375 2590 HeapWord* addr = src_region_beg;
jcoomes@375 2591 if (dest_addr == src_region_destination) {
jcoomes@375 2592 // Return the first live word in the source region.
duke@0 2593 if (partial_obj_size == 0) {
jcoomes@375 2594 addr = bitmap->find_obj_beg(addr, src_region_end);
jcoomes@375 2595 assert(addr < src_region_end, "no objects start in src region");
duke@0 2596 }
duke@0 2597 return addr;
duke@0 2598 }
duke@0 2599
duke@0 2600 // Must skip some live data.
jcoomes@375 2601 size_t words_to_skip = dest_addr - src_region_destination;
jcoomes@375 2602 assert(src_region_ptr->data_size() > words_to_skip, "wrong src region");
duke@0 2603
duke@0 2604 if (partial_obj_size >= words_to_skip) {
duke@0 2605 // All the live words to skip are part of the partial object.
duke@0 2606 addr += words_to_skip;
duke@0 2607 if (partial_obj_size == words_to_skip) {
duke@0 2608 // Find the first live word past the partial object.
jcoomes@375 2609 addr = bitmap->find_obj_beg(addr, src_region_end);
jcoomes@375 2610 assert(addr < src_region_end, "wrong src region");
duke@0 2611 }
duke@0 2612 return addr;
duke@0 2613 }
duke@0 2614
duke@0 2615 // Skip over the partial object (if any).
duke@0 2616 if (partial_obj_size != 0) {
duke@0 2617 words_to_skip -= partial_obj_size;
duke@0 2618 addr += partial_obj_size;
duke@0 2619 }
duke@0 2620
jcoomes@375 2621 // Skip over live words due to objects that start in the region.
jcoomes@375 2622 addr = skip_live_words(addr, src_region_end, words_to_skip);
jcoomes@375 2623 assert(addr < src_region_end, "wrong src region");
duke@0 2624 return addr;
duke@0 2625 }
duke@0 2626
duke@0 2627 void PSParallelCompact::decrement_destination_counts(ParCompactionManager* cm,
jcoomes@375 2628 size_t beg_region,
duke@0 2629 HeapWord* end_addr)
duke@0 2630 {
duke@0 2631 ParallelCompactData& sd = summary_data();
jcoomes@375 2632 RegionData* const beg = sd.region(beg_region);
jcoomes@375 2633 HeapWord* const end_addr_aligned_up = sd.region_align_up(end_addr);
jcoomes@375 2634 RegionData* const end = sd.addr_to_region_ptr(end_addr_aligned_up);
jcoomes@375 2635 size_t cur_idx = beg_region;
jcoomes@375 2636 for (RegionData* cur = beg; cur < end; ++cur, ++cur_idx) {
jcoomes@375 2637 assert(cur->data_size() > 0, "region must have live data");
duke@0 2638 cur->decrement_destination_count();
jcoomes@375 2639 if (cur_idx <= cur->source_region() && cur->available() && cur->claim()) {
duke@0 2640 cm->save_for_processing(cur_idx);
duke@0 2641 }
duke@0 2642 }
duke@0 2643 }
duke@0 2644
jcoomes@375 2645 size_t PSParallelCompact::next_src_region(MoveAndUpdateClosure& closure,
jcoomes@375 2646 SpaceId& src_space_id,
jcoomes@375 2647 HeapWord*& src_space_top,
jcoomes@375 2648 HeapWord* end_addr)
duke@0 2649 {
jcoomes@375 2650 typedef ParallelCompactData::RegionData RegionData;
duke@0 2651
duke@0 2652 ParallelCompactData& sd = PSParallelCompact::summary_data();
jcoomes@375 2653 const size_t region_size = ParallelCompactData::RegionSize;
jcoomes@375 2654
jcoomes@375 2655 size_t src_region_idx = 0;
jcoomes@375 2656
jcoomes@375 2657 // Skip empty regions (if any) up to the top of the space.
jcoomes@375 2658 HeapWord* const src_aligned_up = sd.region_align_up(end_addr);
jcoomes@375 2659 RegionData* src_region_ptr = sd.addr_to_region_ptr(src_aligned_up);
jcoomes@375 2660 HeapWord* const top_aligned_up = sd.region_align_up(src_space_top);
jcoomes@375 2661 const RegionData* const top_region_ptr =
jcoomes@375 2662 sd.addr_to_region_ptr(top_aligned_up);
jcoomes@375 2663 while (src_region_ptr < top_region_ptr && src_region_ptr->data_size() == 0) {
jcoomes@375 2664 ++src_region_ptr;
duke@0 2665 }
duke@0 2666
jcoomes@375 2667 if (src_region_ptr < top_region_ptr) {
jcoomes@375 2668 // The next source region is in the current space. Update src_region_idx
jcoomes@375 2669 // and the source address to match src_region_ptr.
jcoomes@375 2670 src_region_idx = sd.region(src_region_ptr);
jcoomes@375 2671 HeapWord* const src_region_addr = sd.region_to_addr(src_region_idx);
jcoomes@375 2672 if (src_region_addr > closure.source()) {
jcoomes@375 2673 closure.set_source(src_region_addr);
duke@0 2674 }
jcoomes@375 2675 return src_region_idx;
duke@0 2676 }
duke@0 2677
jcoomes@375 2678 // Switch to a new source space and find the first non-empty region.
duke@0 2679 unsigned int space_id = src_space_id + 1;
duke@0 2680 assert(space_id < last_space_id, "not enough spaces");
duke@0 2681
duke@0 2682 HeapWord* const destination = closure.destination();
duke@0 2683
duke@0 2684 do {
duke@0 2685 MutableSpace* space = _space_info[space_id].space();
duke@0 2686 HeapWord* const bottom = space->bottom();
jcoomes@375 2687 const RegionData* const bottom_cp = sd.addr_to_region_ptr(bottom);
duke@0 2688
duke@0 2689 // Iterate over the spaces that do not compact into themselves.
duke@0 2690 if (bottom_cp->destination() != bottom) {
jcoomes@375 2691 HeapWord* const top_aligned_up = sd.region_align_up(space->top());
jcoomes@375 2692 const RegionData* const top_cp = sd.addr_to_region_ptr(top_aligned_up);
jcoomes@375 2693
jcoomes@375 2694 for (const RegionData* src_cp = bottom_cp; src_cp < top_cp; ++src_cp) {
duke@0 2695 if (src_cp->live_obj_size() > 0) {
duke@0 2696 // Found it.
duke@0 2697 assert(src_cp->destination() == destination,
duke@0 2698 "first live obj in the space must match the destination");
duke@0 2699 assert(src_cp->partial_obj_size() == 0,
duke@0 2700 "a space cannot begin with a partial obj");
duke@0 2701
duke@0 2702 src_space_id = SpaceId(space_id);
duke@0 2703 src_space_top = space->top();
jcoomes@375 2704 const size_t src_region_idx = sd.region(src_cp);
jcoomes@375 2705 closure.set_source(sd.region_to_addr(src_region_idx));
jcoomes@375 2706 return src_region_idx;
duke@0 2707 } else {
duke@0 2708 assert(src_cp->data_size() == 0, "sanity");
duke@0 2709 }
duke@0 2710 }
duke@0 2711 }
duke@0 2712 } while (++space_id < last_space_id);
duke@0 2713
jcoomes@375 2714 assert(false, "no source region was found");
duke@0 2715 return 0;
duke@0 2716 }
duke@0 2717
jcoomes@375 2718 void PSParallelCompact::fill_region(ParCompactionManager* cm, size_t region_idx)
duke@0 2719 {
duke@0 2720 typedef ParMarkBitMap::IterationStatus IterationStatus;
jcoomes@375 2721 const size_t RegionSize = ParallelCompactData::RegionSize;
duke@0 2722 ParMarkBitMap* const bitmap = mark_bitmap();
duke@0 2723 ParallelCompactData& sd = summary_data();
jcoomes@375 2724 RegionData* const region_ptr = sd.region(region_idx);
duke@0 2725
duke@0 2726 // Get the items needed to construct the closure.
jcoomes@375 2727 HeapWord* dest_addr = sd.region_to_addr(region_idx);
duke@0 2728 SpaceId dest_space_id = space_id(dest_addr);
duke@0 2729 ObjectStartArray* start_array = _space_info[dest_space_id].start_array();
duke@0 2730 HeapWord* new_top = _space_info[dest_space_id].new_top();
duke@0 2731 assert(dest_addr < new_top, "sanity");
jcoomes@375 2732 const size_t words = MIN2(pointer_delta(new_top, dest_addr), RegionSize);
jcoomes@375 2733
jcoomes@375 2734 // Get the source region and related info.
jcoomes@375 2735 size_t src_region_idx = region_ptr->source_region();
jcoomes@375 2736 SpaceId src_space_id = space_id(sd.region_to_addr(src_region_idx));
duke@0 2737 HeapWord* src_space_top = _space_info[src_space_id].space()->top();
duke@0 2738
duke@0 2739 MoveAndUpdateClosure closure(bitmap, cm, start_array, dest_addr, words);
jcoomes@375 2740 closure.set_source(first_src_addr(dest_addr, src_region_idx));
jcoomes@375 2741
jcoomes@375 2742 // Adjust src_region_idx to prepare for decrementing destination counts (the
jcoomes@375 2743 // destination count is not decremented when a region is copied to itself).
jcoomes@375 2744 if (src_region_idx == region_idx) {
jcoomes@375 2745 src_region_idx += 1;
duke@0 2746 }
duke@0 2747
duke@0 2748 if (bitmap->is_unmarked(closure.source())) {
duke@0 2749 // The first source word is in the middle of an object; copy the remainder
duke@0 2750 // of the object or as much as will fit. The fact that pointer updates were
duke@0 2751 // deferred will be noted when the object header is processed.
duke@0 2752 HeapWord* const old_src_addr = closure.source();
duke@0 2753 closure.copy_partial_obj();
duke@0 2754 if (closure.is_full()) {
jcoomes@375 2755 decrement_destination_counts(cm, src_region_idx, closure.source());
jcoomes@375 2756 region_ptr->set_deferred_obj_addr(NULL);
jcoomes@375 2757 region_ptr->set_completed();
duke@0 2758 return;
duke@0 2759 }
duke@0 2760
jcoomes@375 2761 HeapWord* const end_addr = sd.region_align_down(closure.source());
jcoomes@375 2762 if (sd.region_align_down(old_src_addr) != end_addr) {
jcoomes@375 2763 // The partial object was copied from more than one source region.
jcoomes@375 2764 decrement_destination_counts(cm, src_region_idx, end_addr);
jcoomes@375 2765
jcoomes@375 2766 // Move to the next source region, possibly switching spaces as well. All
duke@0 2767 // args except end_addr may be modified.
jcoomes@375 2768 src_region_idx = next_src_region(closure, src_space_id, src_space_top,
jcoomes@375 2769 end_addr);
duke@0 2770 }
duke@0 2771 }
duke@0 2772
duke@0 2773 do {
duke@0 2774 HeapWord* const cur_addr = closure.source();
jcoomes@375 2775 HeapWord* const end_addr = MIN2(sd.region_align_up(cur_addr + 1),
duke@0 2776 src_space_top);
duke@0 2777 IterationStatus status = bitmap->iterate(&closure, cur_addr, end_addr);
duke@0 2778
duke@0 2779 if (status == ParMarkBitMap::incomplete) {
jcoomes@375 2780 // The last obj that starts in the source region does not end in the
jcoomes@375 2781 // region.
duke@0 2782 assert(closure.source() < end_addr, "sanity")
duke@0 2783 HeapWord* const obj_beg = closure.source();
duke@0 2784 HeapWord* const range_end = MIN2(obj_beg + closure.words_remaining(),
duke@0 2785 src_space_top);
duke@0 2786 HeapWord* const obj_end = bitmap->find_obj_end(obj_beg, range_end);
duke@0 2787 if (obj_end < range_end) {
duke@0 2788 // The end was found; the entire object will fit.
duke@0 2789 status = closure.do_addr(obj_beg, bitmap->obj_size(obj_beg, obj_end));
duke@0 2790 assert(status != ParMarkBitMap::would_overflow, "sanity");
duke@0 2791 } else {
duke@0 2792 // The end was not found; the object will not fit.
duke@0 2793 assert(range_end < src_space_top, "obj cannot cross space boundary");
duke@0 2794 status = ParMarkBitMap::would_overflow;
duke@0 2795 }
duke@0 2796 }
duke@0 2797
duke@0 2798 if (status == ParMarkBitMap::would_overflow) {
duke@0 2799 // The last object did not fit. Note that interior oop updates were
jcoomes@375 2800 // deferred, then copy enough of the object to fill the region.
jcoomes@375 2801 region_ptr->set_deferred_obj_addr(closure.destination());
duke@0 2802 status = closure.copy_until_full(); // copies from closure.source()
duke@0 2803
jcoomes@375 2804 decrement_destination_counts(cm, src_region_idx, closure.source());
jcoomes@375 2805 region_ptr->set_completed();
duke@0 2806 return;
duke@0 2807 }
duke@0 2808
duke@0 2809 if (status == ParMarkBitMap::full) {
jcoomes@375 2810 decrement_destination_counts(cm, src_region_idx, closure.source());
jcoomes@375 2811 region_ptr->set_deferred_obj_addr(NULL);
jcoomes@375 2812 region_ptr->set_completed();
duke@0 2813 return;
duke@0 2814 }
duke@0 2815
jcoomes@375 2816 decrement_destination_counts(cm, src_region_idx, end_addr);
jcoomes@375 2817
jcoomes@375 2818 // Move to the next source region, possibly switching spaces as well. All
duke@0 2819 // args except end_addr may be modified.
jcoomes@375 2820 src_region_idx = next_src_region(closure, src_space_id, src_space_top,
jcoomes@375 2821 end_addr);
duke@0 2822 } while (true);
duke@0 2823 }
duke@0 2824
duke@0 2825 void
duke@0 2826 PSParallelCompact::move_and_update(ParCompactionManager* cm, SpaceId space_id) {
duke@0 2827 const MutableSpace* sp = space(space_id);
duke@0 2828 if (sp->is_empty()) {
duke@0 2829 return;
duke@0 2830 }
duke@0 2831
duke@0 2832 ParallelCompactData& sd = PSParallelCompact::summary_data();
duke@0 2833 ParMarkBitMap* const bitmap = mark_bitmap();
duke@0 2834 HeapWord* const dp_addr = dense_prefix(space_id);
duke@0 2835 HeapWord* beg_addr = sp->bottom();
duke@0 2836 HeapWord* end_addr = sp->top();
duke@0 2837
duke@0 2838 #ifdef ASSERT
duke@0 2839 assert(beg_addr <= dp_addr && dp_addr <= end_addr, "bad dense prefix");
duke@0 2840 if (cm->should_verify_only()) {
duke@0 2841 VerifyUpdateClosure verify_update(cm, sp);
duke@0 2842 bitmap->iterate(&verify_update, beg_addr, end_addr);
duke@0 2843 return;
duke@0 2844 }
duke@0 2845
duke@0 2846 if (cm->should_reset_only()) {
duke@0 2847 ResetObjectsClosure reset_objects(cm);
duke@0 2848 bitmap->iterate(&reset_objects, beg_addr, end_addr);
duke@0 2849 return;
duke@0 2850 }
duke@0 2851 #endif
duke@0 2852
jcoomes@375 2853 const size_t beg_region = sd.addr_to_region_idx(beg_addr);
jcoomes@375 2854 const size_t dp_region = sd.addr_to_region_idx(dp_addr);
jcoomes@375 2855 if (beg_region < dp_region) {
jcoomes@375 2856 update_and_deadwood_in_dense_prefix(cm, space_id, beg_region, dp_region);
duke@0 2857 }
duke@0 2858
jcoomes@375 2859 // The destination of the first live object that starts in the region is one
jcoomes@375 2860 // past the end of the partial object entering the region (if any).
jcoomes@375 2861 HeapWord* const dest_addr = sd.partial_obj_end(dp_region);
duke@0 2862 HeapWord* const new_top = _space_info[space_id].new_top();
duke@0 2863 assert(new_top >= dest_addr, "bad new_top value");
duke@0 2864 const size_t words = pointer_delta(new_top, dest_addr);
duke@0 2865
duke@0 2866 if (words > 0) {
duke@0 2867 ObjectStartArray* start_array = _space_info[space_id].start_array();
duke@0 2868 MoveAndUpdateClosure closure(bitmap, cm, start_array, dest_addr, words);
duke@0 2869
duke@0 2870 ParMarkBitMap::IterationStatus status;
duke@0 2871 status = bitmap->iterate(&closure, dest_addr, end_addr);
duke@0 2872 assert(status == ParMarkBitMap::full, "iteration not complete");
duke@0 2873 assert(bitmap->find_obj_beg(closure.source(), end_addr) == end_addr,
duke@0 2874 "live objects skipped because closure is full");
duke@0 2875 }
duke@0 2876 }
duke@0 2877
duke@0 2878 jlong PSParallelCompact::millis_since_last_gc() {
duke@0 2879 jlong ret_val = os::javaTimeMillis() - _time_of_last_gc;
duke@0 2880 // XXX See note in genCollectedHeap::millis_since_last_gc().
duke@0 2881 if (ret_val < 0) {
duke@0 2882 NOT_PRODUCT(warning("time warp: %d", ret_val);)
duke@0 2883 return 0;
duke@0 2884 }
duke@0 2885 return ret_val;
duke@0 2886 }
duke@0 2887
duke@0 2888 void PSParallelCompact::reset_millis_since_last_gc() {
duke@0 2889 _time_of_last_gc = os::javaTimeMillis();
duke@0 2890 }
duke@0 2891
duke@0 2892 ParMarkBitMap::IterationStatus MoveAndUpdateClosure::copy_until_full()
duke@0 2893 {
duke@0 2894 if (source() != destination()) {
duke@0 2895 assert(source() > destination(), "must copy to the left");
duke@0 2896 Copy::aligned_conjoint_words(source(), destination(), words_remaining());
duke@0 2897 }
duke@0 2898 update_state(words_remaining());
duke@0 2899 assert(is_full(), "sanity");
duke@0 2900 return ParMarkBitMap::full;
duke@0 2901 }
duke@0 2902
duke@0 2903 void MoveAndUpdateClosure::copy_partial_obj()
duke@0 2904 {
duke@0 2905 size_t words = words_remaining();
duke@0 2906
duke@0 2907 HeapWord* const range_end = MIN2(source() + words, bitmap()->region_end());
duke@0 2908 HeapWord* const end_addr = bitmap()->find_obj_end(source(), range_end);
duke@0 2909 if (end_addr < range_end) {
duke@0 2910 words = bitmap()->obj_size(source(), end_addr);
duke@0 2911 }
duke@0 2912
duke@0 2913 // This test is necessary; if omitted, the pointer updates to a partial object
duke@0 2914 // that crosses the dense prefix boundary could be overwritten.
duke@0 2915 if (source() != destination()) {
duke@0 2916 assert(source() > destination(), "must copy to the left");
duke@0 2917 Copy::aligned_conjoint_words(source(), destination(), words);
duke@0 2918 }
duke@0 2919 update_state(words);
duke@0 2920 }
duke@0 2921
duke@0 2922 ParMarkBitMapClosure::IterationStatus
duke@0 2923 MoveAndUpdateClosure::do_addr(HeapWord* addr, size_t words) {
duke@0 2924 assert(destination() != NULL, "sanity");
duke@0 2925 assert(bitmap()->obj_size(addr) == words, "bad size");
duke@0 2926
duke@0 2927 _source = addr;
duke@0 2928 assert(PSParallelCompact::summary_data().calc_new_pointer(source()) ==
duke@0 2929 destination(), "wrong destination");
duke@0 2930
duke@0 2931 if (words > words_remaining()) {
duke@0 2932 return ParMarkBitMap::would_overflow;
duke@0 2933 }
duke@0 2934
duke@0 2935 // The start_array must be updated even if the object is not moving.
duke@0 2936 if (_start_array != NULL) {
duke@0 2937 _start_array->allocate_block(destination());
duke@0 2938 }
duke@0 2939
duke@0 2940 if (destination() != source()) {
duke@0 2941 assert(destination() < source(), "must copy to the left");
duke@0 2942 Copy::aligned_conjoint_words(source(), destination(), words);
duke@0 2943 }
duke@0 2944
duke@0 2945 oop moved_oop = (oop) destination();
duke@0 2946 moved_oop->update_contents(compaction_manager());
duke@0 2947 assert(moved_oop->is_oop_or_null(), "Object should be whole at this point");
duke@0 2948
duke@0 2949 update_state(words);
duke@0 2950 assert(destination() == (HeapWord*)moved_oop + moved_oop->size(), "sanity");
duke@0 2951 return is_full() ? ParMarkBitMap::full : ParMarkBitMap::incomplete;
duke@0 2952 }
duke@0 2953
duke@0 2954 UpdateOnlyClosure::UpdateOnlyClosure(ParMarkBitMap* mbm,
duke@0 2955 ParCompactionManager* cm,
duke@0 2956 PSParallelCompact::SpaceId space_id) :
duke@0 2957 ParMarkBitMapClosure(mbm, cm),
duke@0 2958 _space_id(space_id),
duke@0 2959 _start_array(PSParallelCompact::start_array(space_id))
duke@0 2960 {
duke@0 2961 }
duke@0 2962
duke@0 2963 // Updates the references in the object to their new values.
duke@0 2964 ParMarkBitMapClosure::IterationStatus
duke@0 2965 UpdateOnlyClosure::do_addr(HeapWord* addr, size_t words) {
duke@0 2966 do_addr(addr);
duke@0 2967 return ParMarkBitMap::incomplete;
duke@0 2968 }
duke@0 2969
duke@0 2970 // Verify the new location using the forwarding pointer
duke@0 2971 // from MarkSweep::mark_sweep_phase2(). Set the mark_word
duke@0 2972 // to the initial value.
duke@0 2973 ParMarkBitMapClosure::IterationStatus
duke@0 2974 PSParallelCompact::VerifyUpdateClosure::do_addr(HeapWord* addr, size_t words) {
duke@0 2975 // The second arg (words) is not used.
duke@0 2976 oop obj = (oop) addr;
duke@0 2977 HeapWord* forwarding_ptr = (HeapWord*) obj->mark()->decode_pointer();
duke@0 2978 HeapWord* new_pointer = summary_data().calc_new_pointer(obj);
duke@0 2979 if (forwarding_ptr == NULL) {
duke@0 2980 // The object is dead or not moving.
duke@0 2981 assert(bitmap()->is_unmarked(obj) || (new_pointer == (HeapWord*) obj),
duke@0 2982 "Object liveness is wrong.");
duke@0 2983 return ParMarkBitMap::incomplete;
duke@0 2984 }
duke@0 2985 assert(UseParallelOldGCDensePrefix ||
duke@0 2986 (HeapMaximumCompactionInterval > 1) ||
duke@0 2987 (MarkSweepAlwaysCompactCount > 1) ||
duke@0 2988 (forwarding_ptr == new_pointer),
duke@0 2989 "Calculation of new location is incorrect");
duke@0 2990 return ParMarkBitMap::incomplete;
duke@0 2991 }
duke@0 2992
duke@0 2993 // Reset objects modified for debug checking.
duke@0 2994 ParMarkBitMapClosure::IterationStatus
duke@0 2995 PSParallelCompact::ResetObjectsClosure::do_addr(HeapWord* addr, size_t words) {
duke@0 2996 // The second arg (words) is not used.
duke@0 2997 oop obj = (oop) addr;
duke@0 2998 obj->init_mark();
duke@0 2999 return ParMarkBitMap::incomplete;
duke@0 3000 }
duke@0 3001
duke@0 3002 // Prepare for compaction. This method is executed once
duke@0 3003 // (i.e., by a single thread) before compaction.
duke@0 3004 // Save the updated location of the intArrayKlassObj for
duke@0 3005 // filling holes in the dense prefix.
duke@0 3006 void PSParallelCompact::compact_prologue() {
duke@0 3007 _updated_int_array_klass_obj = (klassOop)
duke@0 3008 summary_data().calc_new_pointer(Universe::intArrayKlassObj());
duke@0 3009 }
duke@0 3010
duke@0 3011 // The initial implementation of this method created a field
duke@0 3012 // _next_compaction_space_id in SpaceInfo and initialized
duke@0 3013 // that field in SpaceInfo::initialize_space_info(). That
duke@0 3014 // required that _next_compaction_space_id be declared a
duke@0 3015 // SpaceId in SpaceInfo and that would have required that
duke@0 3016 // either SpaceId be declared in a separate class or that
duke@0 3017 // it be declared in SpaceInfo. It didn't seem consistent
duke@0 3018 // to declare it in SpaceInfo (didn't really fit logically).
duke@0 3019 // Alternatively, defining a separate class to define SpaceId
duke@0 3020 // seem excessive. This implementation is simple and localizes
duke@0 3021 // the knowledge.
duke@0 3022
duke@0 3023 PSParallelCompact::SpaceId
duke@0 3024 PSParallelCompact::next_compaction_space_id(SpaceId id) {
duke@0 3025 assert(id < last_space_id, "id out of range");
duke@0 3026 switch (id) {
duke@0 3027 case perm_space_id :
duke@0 3028 return last_space_id;
duke@0 3029 case old_space_id :
duke@0 3030 return eden_space_id;
duke@0 3031 case eden_space_id :
duke@0 3032 return from_space_id;
duke@0 3033 case from_space_id :
duke@0 3034 return to_space_id;
duke@0 3035 case to_space_id :
duke@0 3036 return last_space_id;
duke@0 3037 default:
duke@0 3038 assert(false, "Bad space id");
duke@0 3039 return last_space_id;
duke@0 3040 }
duke@0 3041 }