hotspot/src/share/vm/memory/cardGeneration.cpp
changeset 28033 ab63acbd99ec
parent 28031 10aec24d2b61
child 30173 13cf7580b000
--- a/hotspot/src/share/vm/memory/cardGeneration.cpp	Wed Dec 10 11:31:43 2014 +0100
+++ b/hotspot/src/share/vm/memory/cardGeneration.cpp	Wed Dec 10 11:32:22 2014 +0100
@@ -23,7 +23,9 @@
  */
 
 #include "precompiled.hpp"
+
 #include "memory/blockOffsetTable.inline.hpp"
+#include "memory/cardGeneration.inline.hpp"
 #include "memory/gcLocker.hpp"
 #include "memory/generationSpec.hpp"
 #include "memory/genOopClosures.inline.hpp"
@@ -49,8 +51,9 @@
                                     heap_word_size(initial_byte_size));
   MemRegion committed_mr(start, heap_word_size(initial_byte_size));
   _rs->resize_covered_region(committed_mr);
-  if (_bts == NULL)
+  if (_bts == NULL) {
     vm_exit_during_initialization("Could not allocate a BlockOffsetArray");
+  }
 
   // Verify that the start and end of this generation is the start of a card.
   // If this wasn't true, a single card could span more than on generation,
@@ -67,6 +70,43 @@
   _used_at_prologue = 0;
 }
 
+bool CardGeneration::grow_by(size_t bytes) {
+  assert_correct_size_change_locking();
+  bool result = _virtual_space.expand_by(bytes);
+  if (result) {
+    size_t new_word_size =
+       heap_word_size(_virtual_space.committed_size());
+    MemRegion mr(space()->bottom(), new_word_size);
+    // Expand card table
+    Universe::heap()->barrier_set()->resize_covered_region(mr);
+    // Expand shared block offset array
+    _bts->resize(new_word_size);
+
+    // Fix for bug #4668531
+    if (ZapUnusedHeapArea) {
+      MemRegion mangle_region(space()->end(),
+      (HeapWord*)_virtual_space.high());
+      SpaceMangler::mangle_region(mangle_region);
+    }
+
+    // Expand space -- also expands space's BOT
+    // (which uses (part of) shared array above)
+    space()->set_end((HeapWord*)_virtual_space.high());
+
+    // update the space and generation capacity counters
+    update_counters();
+
+    if (Verbose && PrintGC) {
+      size_t new_mem_size = _virtual_space.committed_size();
+      size_t old_mem_size = new_mem_size - bytes;
+      gclog_or_tty->print_cr("Expanding %s from " SIZE_FORMAT "K by "
+                      SIZE_FORMAT "K to " SIZE_FORMAT "K",
+                      name(), old_mem_size/K, bytes/K, new_mem_size/K);
+    }
+  }
+  return result;
+}
+
 bool CardGeneration::expand(size_t bytes, size_t expand_bytes) {
   assert_locked_or_safepoint(Heap_lock);
   if (bytes == 0) {
@@ -102,6 +142,44 @@
   return success;
 }
 
+bool CardGeneration::grow_to_reserved() {
+  assert_correct_size_change_locking();
+  bool success = true;
+  const size_t remaining_bytes = _virtual_space.uncommitted_size();
+  if (remaining_bytes > 0) {
+    success = grow_by(remaining_bytes);
+    DEBUG_ONLY(if (!success) warning("grow to reserved failed");)
+  }
+  return success;
+}
+
+void CardGeneration::shrink(size_t bytes) {
+  assert_correct_size_change_locking();
+
+  size_t size = ReservedSpace::page_align_size_down(bytes);
+  if (size == 0) {
+    return;
+  }
+
+  // Shrink committed space
+  _virtual_space.shrink_by(size);
+  // Shrink space; this also shrinks the space's BOT
+  space()->set_end((HeapWord*) _virtual_space.high());
+  size_t new_word_size = heap_word_size(space()->capacity());
+  // Shrink the shared block offset array
+  _bts->resize(new_word_size);
+  MemRegion mr(space()->bottom(), new_word_size);
+  // Shrink the card table
+  Universe::heap()->barrier_set()->resize_covered_region(mr);
+
+  if (Verbose && PrintGC) {
+    size_t new_mem_size = _virtual_space.committed_size();
+    size_t old_mem_size = new_mem_size + size;
+    gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K to " SIZE_FORMAT "K",
+                  name(), old_mem_size/K, new_mem_size/K);
+  }
+}
+
 // No young generation references, clear this generation's cards.
 void CardGeneration::clear_remembered_set() {
   _rs->clear(reserved());
@@ -269,3 +347,14 @@
 
 // Currently nothing to do.
 void CardGeneration::prepare_for_verify() {}
+
+void CardGeneration::space_iterate(SpaceClosure* blk,
+                                                 bool usedOnly) {
+  blk->do_space(space());
+}
+
+void CardGeneration::younger_refs_iterate(OopsInGenClosure* blk) {
+  blk->set_generation(this);
+  younger_refs_in_space_iterate(space(), blk);
+  blk->reset_generation();
+}