--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Fri Jul 25 11:29:03 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Mon Jul 28 15:30:23 2008 -0700
@@ -200,8 +200,8 @@
for (unsigned int id = 0; id < last_space_id; ++id) {
const MutableSpace* space = _space_info[id].space();
tty->print_cr("%u %s "
- SIZE_FORMAT_W("10") " " SIZE_FORMAT_W("10") " "
- SIZE_FORMAT_W("10") " " SIZE_FORMAT_W("10") " ",
+ SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " "
+ SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " ",
id, space_names[id],
summary_data().addr_to_chunk_idx(space->bottom()),
summary_data().addr_to_chunk_idx(space->top()),
@@ -213,8 +213,8 @@
void
print_generic_summary_chunk(size_t i, const ParallelCompactData::ChunkData* c)
{
-#define CHUNK_IDX_FORMAT SIZE_FORMAT_W("7")
-#define CHUNK_DATA_FORMAT SIZE_FORMAT_W("5")
+#define CHUNK_IDX_FORMAT SIZE_FORMAT_W(7)
+#define CHUNK_DATA_FORMAT SIZE_FORMAT_W(5)
ParallelCompactData& sd = PSParallelCompact::summary_data();
size_t dci = c->destination() ? sd.addr_to_chunk_idx(c->destination()) : 0;
@@ -269,9 +269,9 @@
const ParallelCompactData::ChunkData* c,
bool newline = true)
{
- tty->print(SIZE_FORMAT_W("5") " " PTR_FORMAT " "
- SIZE_FORMAT_W("5") " " SIZE_FORMAT_W("5") " "
- SIZE_FORMAT_W("5") " " SIZE_FORMAT_W("5") " %d",
+ tty->print(SIZE_FORMAT_W(5) " " PTR_FORMAT " "
+ SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " "
+ SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d",
i, c->destination(),
c->partial_obj_size(), c->live_obj_size(),
c->data_size(), c->source_chunk(), c->destination_count());
@@ -326,7 +326,7 @@
}
print_initial_summary_chunk(i, c, false);
- tty->print_cr(" %12.10f " SIZE_FORMAT_W("10") " " SIZE_FORMAT_W("10"),
+ tty->print_cr(" %12.10f " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10),
reclaimed_ratio, dead_to_right, live_to_right);
live_to_right -= c->data_size();
@@ -338,8 +338,8 @@
print_initial_summary_chunk(i, summary_data.chunk(i));
}
- tty->print_cr("max: " SIZE_FORMAT_W("4") " d2r=" SIZE_FORMAT_W("10") " "
- "l2r=" SIZE_FORMAT_W("10") " max_ratio=%14.12f",
+ tty->print_cr("max: " SIZE_FORMAT_W(4) " d2r=" SIZE_FORMAT_W(10) " "
+ "l2r=" SIZE_FORMAT_W(10) " max_ratio=%14.12f",
max_reclaimed_ratio_chunk, max_dead_to_right,
max_live_to_right, max_reclaimed_ratio);
}
@@ -1060,6 +1060,10 @@
ref_processor()->enqueue_discovered_references(NULL);
+ if (ZapUnusedHeapArea) {
+ heap->gen_mangle_unused_area();
+ }
+
// Update time of last GC
reset_millis_since_last_gc();
}
@@ -1119,8 +1123,8 @@
HeapWord* chunk_destination = cp->destination();
const size_t cur_deadwood = pointer_delta(dense_prefix, chunk_destination);
if (TraceParallelOldGCDensePrefix && Verbose) {
- tty->print_cr("c#=" SIZE_FORMAT_W("04") " dst=" PTR_FORMAT " "
- "dp=" SIZE_FORMAT_W("08") " " "cdw=" SIZE_FORMAT_W("08"),
+ tty->print_cr("c#=" SIZE_FORMAT_W(4) " dst=" PTR_FORMAT " "
+ "dp=" SIZE_FORMAT_W(8) " " "cdw=" SIZE_FORMAT_W(8),
sd.chunk(cp), chunk_destination,
dense_prefix, cur_deadwood);
}
@@ -1145,7 +1149,7 @@
return dense_prefix;
}
if (TraceParallelOldGCDensePrefix && Verbose) {
- tty->print_cr("backing up from c=" SIZE_FORMAT_W("4") " d2r=%10.8f "
+ tty->print_cr("backing up from c=" SIZE_FORMAT_W(4) " d2r=%10.8f "
"pc_d2r=%10.8f", sd.chunk(cp), density_to_right,
prev_chunk_density_to_right);
}
@@ -1182,7 +1186,7 @@
const size_t live_to_right = new_top - cp->destination();
const size_t dead_to_right = space->top() - addr - live_to_right;
- tty->print_cr("%s=" PTR_FORMAT " dpc=" SIZE_FORMAT_W("05") " "
+ tty->print_cr("%s=" PTR_FORMAT " dpc=" SIZE_FORMAT_W(5) " "
"spl=" SIZE_FORMAT " "
"d2l=" SIZE_FORMAT " d2l%%=%6.4f "
"d2r=" SIZE_FORMAT " l2r=" SIZE_FORMAT
@@ -1522,48 +1526,53 @@
PSParallelCompact::summarize_space(SpaceId id, bool maximum_compaction)
{
assert(id < last_space_id, "id out of range");
+ assert(_space_info[id].dense_prefix() == _space_info[id].space()->bottom(),
+ "should have been set in summarize_spaces_quick()");
const MutableSpace* space = _space_info[id].space();
- HeapWord** new_top_addr = _space_info[id].new_top_addr();
-
- HeapWord* dense_prefix_end = compute_dense_prefix(id, maximum_compaction);
- _space_info[id].set_dense_prefix(dense_prefix_end);
+ if (_space_info[id].new_top() != space->bottom()) {
+ HeapWord* dense_prefix_end = compute_dense_prefix(id, maximum_compaction);
+ _space_info[id].set_dense_prefix(dense_prefix_end);
#ifndef PRODUCT
- if (TraceParallelOldGCDensePrefix) {
- print_dense_prefix_stats("ratio", id, maximum_compaction, dense_prefix_end);
- HeapWord* addr = compute_dense_prefix_via_density(id, maximum_compaction);
- print_dense_prefix_stats("density", id, maximum_compaction, addr);
- }
+ if (TraceParallelOldGCDensePrefix) {
+ print_dense_prefix_stats("ratio", id, maximum_compaction,
+ dense_prefix_end);
+ HeapWord* addr = compute_dense_prefix_via_density(id, maximum_compaction);
+ print_dense_prefix_stats("density", id, maximum_compaction, addr);
+ }
#endif // #ifndef PRODUCT
- // If dead space crosses the dense prefix boundary, it is (at least partially)
- // filled with a dummy object, marked live and added to the summary data.
- // This simplifies the copy/update phase and must be done before the final
- // locations of objects are determined, to prevent leaving a fragment of dead
- // space that is too small to fill with an object.
- if (!maximum_compaction && dense_prefix_end != space->bottom()) {
- fill_dense_prefix_end(id);
+ // If dead space crosses the dense prefix boundary, it is (at least
+ // partially) filled with a dummy object, marked live and added to the
+ // summary data. This simplifies the copy/update phase and must be done
+ // before the final locations of objects are determined, to prevent leaving
+ // a fragment of dead space that is too small to fill with an object.
+ if (!maximum_compaction && dense_prefix_end != space->bottom()) {
+ fill_dense_prefix_end(id);
+ }
+
+ // Compute the destination of each Chunk, and thus each object.
+ _summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end);
+ _summary_data.summarize(dense_prefix_end, space->end(),
+ dense_prefix_end, space->top(),
+ _space_info[id].new_top_addr());
}
- // Compute the destination of each Chunk, and thus each object.
- _summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end);
- _summary_data.summarize(dense_prefix_end, space->end(),
- dense_prefix_end, space->top(),
- new_top_addr);
-
if (TraceParallelOldGCSummaryPhase) {
const size_t chunk_size = ParallelCompactData::ChunkSize;
+ HeapWord* const dense_prefix_end = _space_info[id].dense_prefix();
const size_t dp_chunk = _summary_data.addr_to_chunk_idx(dense_prefix_end);
const size_t dp_words = pointer_delta(dense_prefix_end, space->bottom());
- const HeapWord* nt_aligned_up = _summary_data.chunk_align_up(*new_top_addr);
+ HeapWord* const new_top = _space_info[id].new_top();
+ const HeapWord* nt_aligned_up = _summary_data.chunk_align_up(new_top);
const size_t cr_words = pointer_delta(nt_aligned_up, dense_prefix_end);
tty->print_cr("id=%d cap=" SIZE_FORMAT " dp=" PTR_FORMAT " "
"dp_chunk=" SIZE_FORMAT " " "dp_count=" SIZE_FORMAT " "
"cr_count=" SIZE_FORMAT " " "nt=" PTR_FORMAT,
id, space->capacity_in_words(), dense_prefix_end,
dp_chunk, dp_words / chunk_size,
- cr_words / chunk_size, *new_top_addr);
+ cr_words / chunk_size, new_top);
}
}
@@ -1632,7 +1641,7 @@
const size_t live = pointer_delta(_space_info[id].new_top(),
space->bottom());
const size_t available = pointer_delta(target_space_end, *new_top_addr);
- if (live <= available) {
+ if (live > 0 && live <= available) {
// All the live data will fit.
if (TraceParallelOldGCSummaryPhase) {
tty->print_cr("summarizing %d into old_space @ " PTR_FORMAT,
@@ -1642,16 +1651,18 @@
space->bottom(), space->top(),
new_top_addr);
- // Reset the new_top value for the space.
- _space_info[id].set_new_top(space->bottom());
-
// Clear the source_chunk field for each chunk in the space.
+ HeapWord* const new_top = _space_info[id].new_top();
+ HeapWord* const clear_end = _summary_data.chunk_align_up(new_top);
ChunkData* beg_chunk = _summary_data.addr_to_chunk_ptr(space->bottom());
- ChunkData* end_chunk = _summary_data.addr_to_chunk_ptr(space->top() - 1);
- while (beg_chunk <= end_chunk) {
+ ChunkData* end_chunk = _summary_data.addr_to_chunk_ptr(clear_end);
+ while (beg_chunk < end_chunk) {
beg_chunk->set_source_chunk(0);
++beg_chunk;
}
+
+ // Reset the new_top value for the space.
+ _space_info[id].set_new_top(space->bottom());
}
}
@@ -1961,6 +1972,11 @@
PSPermGen* perm_gen = heap->perm_gen();
PSAdaptiveSizePolicy* size_policy = heap->size_policy();
+ if (ZapUnusedHeapArea) {
+ // Save information needed to minimize mangling
+ heap->record_gen_tops_before_GC();
+ }
+
_print_phases = PrintGCDetails && PrintParallelOldGCPhaseTimes;
// Make sure data structures are sane, make the heap parsable, and do other
@@ -2129,17 +2145,19 @@
size_t max_eden_size = young_gen->max_size() -
young_gen->from_space()->capacity_in_bytes() -
young_gen->to_space()->capacity_in_bytes();
- size_policy->compute_generation_free_space(young_gen->used_in_bytes(),
- young_gen->eden_space()->used_in_bytes(),
- old_gen->used_in_bytes(),
- perm_gen->used_in_bytes(),
- young_gen->eden_space()->capacity_in_bytes(),
- old_gen->max_gen_size(),
- max_eden_size,
- true /* full gc*/,
- gc_cause);
-
- heap->resize_old_gen(size_policy->calculated_old_free_size_in_bytes());
+ size_policy->compute_generation_free_space(
+ young_gen->used_in_bytes(),
+ young_gen->eden_space()->used_in_bytes(),
+ old_gen->used_in_bytes(),
+ perm_gen->used_in_bytes(),
+ young_gen->eden_space()->capacity_in_bytes(),
+ old_gen->max_gen_size(),
+ max_eden_size,
+ true /* full gc*/,
+ gc_cause);
+
+ heap->resize_old_gen(
+ size_policy->calculated_old_free_size_in_bytes());
// Don't resize the young generation at an major collection. A
// desired young generation size may have been calculated but
@@ -2212,6 +2230,11 @@
perm_gen->verify_object_start_array();
}
+ if (ZapUnusedHeapArea) {
+ old_gen->object_space()->check_mangled_unused_area_complete();
+ perm_gen->object_space()->check_mangled_unused_area_complete();
+ }
+
NOT_PRODUCT(ref_processor()->verify_no_references_recorded());
collection_exit.update();
@@ -2499,7 +2522,7 @@
if (TraceParallelOldGCCompactionPhase && Verbose) {
const size_t count_mod_8 = fillable_chunks & 7;
if (count_mod_8 == 0) gclog_or_tty->print("fillable: ");
- gclog_or_tty->print(" " SIZE_FORMAT_W("7"), cur);
+ gclog_or_tty->print(" " SIZE_FORMAT_W(7), cur);
if (count_mod_8 == 7) gclog_or_tty->cr();
}