hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
changeset 977 b90650e2a9f7
parent 823 9a5271881bc0
parent 974 6bbfda0c2a55
child 1406 e5e2b519fc11
--- 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();
         }