8066780: Split CardGeneration out to its own file
Reviewed-by: kbarrett, tschatzl
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Tue Dec 09 12:47:19 2014 +0100
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Wed Dec 10 11:30:46 2014 +0100
@@ -30,8 +30,8 @@
#include "gc_implementation/shared/gcStats.hpp"
#include "gc_implementation/shared/gcWhen.hpp"
#include "gc_implementation/shared/generationCounters.hpp"
+#include "memory/cardGeneration.hpp"
#include "memory/freeBlockDictionary.hpp"
-#include "memory/generation.hpp"
#include "memory/iterator.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/virtualspace.hpp"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/memory/cardGeneration.cpp Wed Dec 10 11:30:46 2014 +0100
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "memory/blockOffsetTable.inline.hpp"
+#include "memory/gcLocker.hpp"
+#include "memory/generationSpec.hpp"
+#include "memory/genOopClosures.inline.hpp"
+#include "memory/genRemSet.hpp"
+#include "memory/iterator.hpp"
+#include "memory/memRegion.hpp"
+#include "memory/space.inline.hpp"
+#include "runtime/java.hpp"
+
+CardGeneration::CardGeneration(ReservedSpace rs, size_t initial_byte_size,
+ int level,
+ GenRemSet* remset) :
+ Generation(rs, initial_byte_size, level), _rs(remset),
+ _shrink_factor(0), _min_heap_delta_bytes(), _capacity_at_prologue(),
+ _used_at_prologue()
+{
+ HeapWord* start = (HeapWord*)rs.base();
+ size_t reserved_byte_size = rs.size();
+ assert((uintptr_t(start) & 3) == 0, "bad alignment");
+ assert((reserved_byte_size & 3) == 0, "bad alignment");
+ MemRegion reserved_mr(start, heap_word_size(reserved_byte_size));
+ _bts = new BlockOffsetSharedArray(reserved_mr,
+ 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)
+ 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,
+ // which would cause problems when we commit/uncommit memory, and when we
+ // clear and dirty cards.
+ guarantee(_rs->is_aligned(reserved_mr.start()), "generation must be card aligned");
+ if (reserved_mr.end() != Universe::heap()->reserved_region().end()) {
+ // Don't check at the very end of the heap as we'll assert that we're probing off
+ // the end if we try.
+ guarantee(_rs->is_aligned(reserved_mr.end()), "generation must be card aligned");
+ }
+ _min_heap_delta_bytes = MinHeapDeltaBytes;
+ _capacity_at_prologue = initial_byte_size;
+ _used_at_prologue = 0;
+}
+
+bool CardGeneration::expand(size_t bytes, size_t expand_bytes) {
+ assert_locked_or_safepoint(Heap_lock);
+ if (bytes == 0) {
+ return true; // That's what grow_by(0) would return
+ }
+ size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes);
+ if (aligned_bytes == 0){
+ // The alignment caused the number of bytes to wrap. An expand_by(0) will
+ // return true with the implication that an expansion was done when it
+ // was not. A call to expand implies a best effort to expand by "bytes"
+ // but not a guarantee. Align down to give a best effort. This is likely
+ // the most that the generation can expand since it has some capacity to
+ // start with.
+ aligned_bytes = ReservedSpace::page_align_size_down(bytes);
+ }
+ size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
+ bool success = false;
+ if (aligned_expand_bytes > aligned_bytes) {
+ success = grow_by(aligned_expand_bytes);
+ }
+ if (!success) {
+ success = grow_by(aligned_bytes);
+ }
+ if (!success) {
+ success = grow_to_reserved();
+ }
+ if (PrintGC && Verbose) {
+ if (success && GC_locker::is_active_and_needs_gc()) {
+ gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
+ }
+ }
+
+ return success;
+}
+
+// No young generation references, clear this generation's cards.
+void CardGeneration::clear_remembered_set() {
+ _rs->clear(reserved());
+}
+
+// Objects in this generation may have moved, invalidate this
+// generation's cards.
+void CardGeneration::invalidate_remembered_set() {
+ _rs->invalidate(used_region());
+}
+
+void CardGeneration::compute_new_size() {
+ assert(_shrink_factor <= 100, "invalid shrink factor");
+ size_t current_shrink_factor = _shrink_factor;
+ _shrink_factor = 0;
+
+ // We don't have floating point command-line arguments
+ // Note: argument processing ensures that MinHeapFreeRatio < 100.
+ const double minimum_free_percentage = MinHeapFreeRatio / 100.0;
+ const double maximum_used_percentage = 1.0 - minimum_free_percentage;
+
+ // Compute some numbers about the state of the heap.
+ const size_t used_after_gc = used();
+ const size_t capacity_after_gc = capacity();
+
+ const double min_tmp = used_after_gc / maximum_used_percentage;
+ size_t minimum_desired_capacity = (size_t)MIN2(min_tmp, double(max_uintx));
+ // Don't shrink less than the initial generation size
+ minimum_desired_capacity = MAX2(minimum_desired_capacity,
+ spec()->init_size());
+ assert(used_after_gc <= minimum_desired_capacity, "sanity check");
+
+ if (PrintGC && Verbose) {
+ const size_t free_after_gc = free();
+ const double free_percentage = ((double)free_after_gc) / capacity_after_gc;
+ gclog_or_tty->print_cr("TenuredGeneration::compute_new_size: ");
+ gclog_or_tty->print_cr(" "
+ " minimum_free_percentage: %6.2f"
+ " maximum_used_percentage: %6.2f",
+ minimum_free_percentage,
+ maximum_used_percentage);
+ gclog_or_tty->print_cr(" "
+ " free_after_gc : %6.1fK"
+ " used_after_gc : %6.1fK"
+ " capacity_after_gc : %6.1fK",
+ free_after_gc / (double) K,
+ used_after_gc / (double) K,
+ capacity_after_gc / (double) K);
+ gclog_or_tty->print_cr(" "
+ " free_percentage: %6.2f",
+ free_percentage);
+ }
+
+ if (capacity_after_gc < minimum_desired_capacity) {
+ // If we have less free space than we want then expand
+ size_t expand_bytes = minimum_desired_capacity - capacity_after_gc;
+ // Don't expand unless it's significant
+ if (expand_bytes >= _min_heap_delta_bytes) {
+ expand(expand_bytes, 0); // safe if expansion fails
+ }
+ if (PrintGC && Verbose) {
+ gclog_or_tty->print_cr(" expanding:"
+ " minimum_desired_capacity: %6.1fK"
+ " expand_bytes: %6.1fK"
+ " _min_heap_delta_bytes: %6.1fK",
+ minimum_desired_capacity / (double) K,
+ expand_bytes / (double) K,
+ _min_heap_delta_bytes / (double) K);
+ }
+ return;
+ }
+
+ // No expansion, now see if we want to shrink
+ size_t shrink_bytes = 0;
+ // We would never want to shrink more than this
+ size_t max_shrink_bytes = capacity_after_gc - minimum_desired_capacity;
+
+ if (MaxHeapFreeRatio < 100) {
+ const double maximum_free_percentage = MaxHeapFreeRatio / 100.0;
+ const double minimum_used_percentage = 1.0 - maximum_free_percentage;
+ const double max_tmp = used_after_gc / minimum_used_percentage;
+ size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(max_uintx));
+ maximum_desired_capacity = MAX2(maximum_desired_capacity,
+ spec()->init_size());
+ if (PrintGC && Verbose) {
+ gclog_or_tty->print_cr(" "
+ " maximum_free_percentage: %6.2f"
+ " minimum_used_percentage: %6.2f",
+ maximum_free_percentage,
+ minimum_used_percentage);
+ gclog_or_tty->print_cr(" "
+ " _capacity_at_prologue: %6.1fK"
+ " minimum_desired_capacity: %6.1fK"
+ " maximum_desired_capacity: %6.1fK",
+ _capacity_at_prologue / (double) K,
+ minimum_desired_capacity / (double) K,
+ maximum_desired_capacity / (double) K);
+ }
+ assert(minimum_desired_capacity <= maximum_desired_capacity,
+ "sanity check");
+
+ if (capacity_after_gc > maximum_desired_capacity) {
+ // Capacity too large, compute shrinking size
+ shrink_bytes = capacity_after_gc - maximum_desired_capacity;
+ // We don't want shrink all the way back to initSize if people call
+ // System.gc(), because some programs do that between "phases" and then
+ // we'd just have to grow the heap up again for the next phase. So we
+ // damp the shrinking: 0% on the first call, 10% on the second call, 40%
+ // on the third call, and 100% by the fourth call. But if we recompute
+ // size without shrinking, it goes back to 0%.
+ shrink_bytes = shrink_bytes / 100 * current_shrink_factor;
+ assert(shrink_bytes <= max_shrink_bytes, "invalid shrink size");
+ if (current_shrink_factor == 0) {
+ _shrink_factor = 10;
+ } else {
+ _shrink_factor = MIN2(current_shrink_factor * 4, (size_t) 100);
+ }
+ if (PrintGC && Verbose) {
+ gclog_or_tty->print_cr(" "
+ " shrinking:"
+ " initSize: %.1fK"
+ " maximum_desired_capacity: %.1fK",
+ spec()->init_size() / (double) K,
+ maximum_desired_capacity / (double) K);
+ gclog_or_tty->print_cr(" "
+ " shrink_bytes: %.1fK"
+ " current_shrink_factor: " SIZE_FORMAT
+ " new shrink factor: " SIZE_FORMAT
+ " _min_heap_delta_bytes: %.1fK",
+ shrink_bytes / (double) K,
+ current_shrink_factor,
+ _shrink_factor,
+ _min_heap_delta_bytes / (double) K);
+ }
+ }
+ }
+
+ if (capacity_after_gc > _capacity_at_prologue) {
+ // We might have expanded for promotions, in which case we might want to
+ // take back that expansion if there's room after GC. That keeps us from
+ // stretching the heap with promotions when there's plenty of room.
+ size_t expansion_for_promotion = capacity_after_gc - _capacity_at_prologue;
+ expansion_for_promotion = MIN2(expansion_for_promotion, max_shrink_bytes);
+ // We have two shrinking computations, take the largest
+ shrink_bytes = MAX2(shrink_bytes, expansion_for_promotion);
+ assert(shrink_bytes <= max_shrink_bytes, "invalid shrink size");
+ if (PrintGC && Verbose) {
+ gclog_or_tty->print_cr(" "
+ " aggressive shrinking:"
+ " _capacity_at_prologue: %.1fK"
+ " capacity_after_gc: %.1fK"
+ " expansion_for_promotion: %.1fK"
+ " shrink_bytes: %.1fK",
+ capacity_after_gc / (double) K,
+ _capacity_at_prologue / (double) K,
+ expansion_for_promotion / (double) K,
+ shrink_bytes / (double) K);
+ }
+ }
+ // Don't shrink unless it's significant
+ if (shrink_bytes >= _min_heap_delta_bytes) {
+ shrink(shrink_bytes);
+ }
+}
+
+// Currently nothing to do.
+void CardGeneration::prepare_for_verify() {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/memory/cardGeneration.hpp Wed Dec 10 11:30:46 2014 +0100
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_VM_MEMORY_CARDGENERATION_HPP
+#define SHARE_VM_MEMORY_CARDGENERATION_HPP
+
+// Class CardGeneration is a generation that is covered by a card table,
+// and uses a card-size block-offset array to implement block_start.
+
+#include "memory/generation.hpp"
+
+class BlockOffsetSharedArray;
+
+class CardGeneration: public Generation {
+ friend class VMStructs;
+ protected:
+ // This is shared with other generations.
+ GenRemSet* _rs;
+ // This is local to this generation.
+ BlockOffsetSharedArray* _bts;
+
+ // current shrinking effect: this damps shrinking when the heap gets empty.
+ size_t _shrink_factor;
+
+ size_t _min_heap_delta_bytes; // Minimum amount to expand.
+
+ // Some statistics from before gc started.
+ // These are gathered in the gc_prologue (and should_collect)
+ // to control growing/shrinking policy in spite of promotions.
+ size_t _capacity_at_prologue;
+ size_t _used_at_prologue;
+
+ CardGeneration(ReservedSpace rs, size_t initial_byte_size, int level,
+ GenRemSet* remset);
+
+ public:
+
+ // Attempt to expand the generation by "bytes". Expand by at a
+ // minimum "expand_bytes". Return true if some amount (not
+ // necessarily the full "bytes") was done.
+ virtual bool expand(size_t bytes, size_t expand_bytes);
+
+ // Shrink generation with specified size
+ virtual void shrink(size_t bytes) = 0;
+
+ virtual void compute_new_size();
+
+ virtual void clear_remembered_set();
+
+ virtual void invalidate_remembered_set();
+
+ virtual void prepare_for_verify();
+
+ // Grow generation with specified size (returns false if unable to grow)
+ virtual bool grow_by(size_t bytes) = 0;
+ // Grow generation to reserved size.
+ virtual bool grow_to_reserved() = 0;
+};
+
+#endif // SHARE_VM_MEMORY_CARDGENERATION_HPP
--- a/hotspot/src/share/vm/memory/generation.cpp Tue Dec 09 12:47:19 2014 +0100
+++ b/hotspot/src/share/vm/memory/generation.cpp Wed Dec 10 11:30:46 2014 +0100
@@ -361,244 +361,3 @@
sp = sp->next_compaction_space();
}
}
-
-CardGeneration::CardGeneration(ReservedSpace rs, size_t initial_byte_size,
- int level,
- GenRemSet* remset) :
- Generation(rs, initial_byte_size, level), _rs(remset),
- _shrink_factor(0), _min_heap_delta_bytes(), _capacity_at_prologue(),
- _used_at_prologue()
-{
- HeapWord* start = (HeapWord*)rs.base();
- size_t reserved_byte_size = rs.size();
- assert((uintptr_t(start) & 3) == 0, "bad alignment");
- assert((reserved_byte_size & 3) == 0, "bad alignment");
- MemRegion reserved_mr(start, heap_word_size(reserved_byte_size));
- _bts = new BlockOffsetSharedArray(reserved_mr,
- 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)
- 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,
- // which would cause problems when we commit/uncommit memory, and when we
- // clear and dirty cards.
- guarantee(_rs->is_aligned(reserved_mr.start()), "generation must be card aligned");
- if (reserved_mr.end() != Universe::heap()->reserved_region().end()) {
- // Don't check at the very end of the heap as we'll assert that we're probing off
- // the end if we try.
- guarantee(_rs->is_aligned(reserved_mr.end()), "generation must be card aligned");
- }
- _min_heap_delta_bytes = MinHeapDeltaBytes;
- _capacity_at_prologue = initial_byte_size;
- _used_at_prologue = 0;
-}
-
-bool CardGeneration::expand(size_t bytes, size_t expand_bytes) {
- assert_locked_or_safepoint(Heap_lock);
- if (bytes == 0) {
- return true; // That's what grow_by(0) would return
- }
- size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes);
- if (aligned_bytes == 0){
- // The alignment caused the number of bytes to wrap. An expand_by(0) will
- // return true with the implication that an expansion was done when it
- // was not. A call to expand implies a best effort to expand by "bytes"
- // but not a guarantee. Align down to give a best effort. This is likely
- // the most that the generation can expand since it has some capacity to
- // start with.
- aligned_bytes = ReservedSpace::page_align_size_down(bytes);
- }
- size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes);
- bool success = false;
- if (aligned_expand_bytes > aligned_bytes) {
- success = grow_by(aligned_expand_bytes);
- }
- if (!success) {
- success = grow_by(aligned_bytes);
- }
- if (!success) {
- success = grow_to_reserved();
- }
- if (PrintGC && Verbose) {
- if (success && GC_locker::is_active_and_needs_gc()) {
- gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead");
- }
- }
-
- return success;
-}
-
-
-// No young generation references, clear this generation's cards.
-void CardGeneration::clear_remembered_set() {
- _rs->clear(reserved());
-}
-
-
-// Objects in this generation may have moved, invalidate this
-// generation's cards.
-void CardGeneration::invalidate_remembered_set() {
- _rs->invalidate(used_region());
-}
-
-
-void CardGeneration::compute_new_size() {
- assert(_shrink_factor <= 100, "invalid shrink factor");
- size_t current_shrink_factor = _shrink_factor;
- _shrink_factor = 0;
-
- // We don't have floating point command-line arguments
- // Note: argument processing ensures that MinHeapFreeRatio < 100.
- const double minimum_free_percentage = MinHeapFreeRatio / 100.0;
- const double maximum_used_percentage = 1.0 - minimum_free_percentage;
-
- // Compute some numbers about the state of the heap.
- const size_t used_after_gc = used();
- const size_t capacity_after_gc = capacity();
-
- const double min_tmp = used_after_gc / maximum_used_percentage;
- size_t minimum_desired_capacity = (size_t)MIN2(min_tmp, double(max_uintx));
- // Don't shrink less than the initial generation size
- minimum_desired_capacity = MAX2(minimum_desired_capacity,
- spec()->init_size());
- assert(used_after_gc <= minimum_desired_capacity, "sanity check");
-
- if (PrintGC && Verbose) {
- const size_t free_after_gc = free();
- const double free_percentage = ((double)free_after_gc) / capacity_after_gc;
- gclog_or_tty->print_cr("TenuredGeneration::compute_new_size: ");
- gclog_or_tty->print_cr(" "
- " minimum_free_percentage: %6.2f"
- " maximum_used_percentage: %6.2f",
- minimum_free_percentage,
- maximum_used_percentage);
- gclog_or_tty->print_cr(" "
- " free_after_gc : %6.1fK"
- " used_after_gc : %6.1fK"
- " capacity_after_gc : %6.1fK",
- free_after_gc / (double) K,
- used_after_gc / (double) K,
- capacity_after_gc / (double) K);
- gclog_or_tty->print_cr(" "
- " free_percentage: %6.2f",
- free_percentage);
- }
-
- if (capacity_after_gc < minimum_desired_capacity) {
- // If we have less free space than we want then expand
- size_t expand_bytes = minimum_desired_capacity - capacity_after_gc;
- // Don't expand unless it's significant
- if (expand_bytes >= _min_heap_delta_bytes) {
- expand(expand_bytes, 0); // safe if expansion fails
- }
- if (PrintGC && Verbose) {
- gclog_or_tty->print_cr(" expanding:"
- " minimum_desired_capacity: %6.1fK"
- " expand_bytes: %6.1fK"
- " _min_heap_delta_bytes: %6.1fK",
- minimum_desired_capacity / (double) K,
- expand_bytes / (double) K,
- _min_heap_delta_bytes / (double) K);
- }
- return;
- }
-
- // No expansion, now see if we want to shrink
- size_t shrink_bytes = 0;
- // We would never want to shrink more than this
- size_t max_shrink_bytes = capacity_after_gc - minimum_desired_capacity;
-
- if (MaxHeapFreeRatio < 100) {
- const double maximum_free_percentage = MaxHeapFreeRatio / 100.0;
- const double minimum_used_percentage = 1.0 - maximum_free_percentage;
- const double max_tmp = used_after_gc / minimum_used_percentage;
- size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(max_uintx));
- maximum_desired_capacity = MAX2(maximum_desired_capacity,
- spec()->init_size());
- if (PrintGC && Verbose) {
- gclog_or_tty->print_cr(" "
- " maximum_free_percentage: %6.2f"
- " minimum_used_percentage: %6.2f",
- maximum_free_percentage,
- minimum_used_percentage);
- gclog_or_tty->print_cr(" "
- " _capacity_at_prologue: %6.1fK"
- " minimum_desired_capacity: %6.1fK"
- " maximum_desired_capacity: %6.1fK",
- _capacity_at_prologue / (double) K,
- minimum_desired_capacity / (double) K,
- maximum_desired_capacity / (double) K);
- }
- assert(minimum_desired_capacity <= maximum_desired_capacity,
- "sanity check");
-
- if (capacity_after_gc > maximum_desired_capacity) {
- // Capacity too large, compute shrinking size
- shrink_bytes = capacity_after_gc - maximum_desired_capacity;
- // We don't want shrink all the way back to initSize if people call
- // System.gc(), because some programs do that between "phases" and then
- // we'd just have to grow the heap up again for the next phase. So we
- // damp the shrinking: 0% on the first call, 10% on the second call, 40%
- // on the third call, and 100% by the fourth call. But if we recompute
- // size without shrinking, it goes back to 0%.
- shrink_bytes = shrink_bytes / 100 * current_shrink_factor;
- assert(shrink_bytes <= max_shrink_bytes, "invalid shrink size");
- if (current_shrink_factor == 0) {
- _shrink_factor = 10;
- } else {
- _shrink_factor = MIN2(current_shrink_factor * 4, (size_t) 100);
- }
- if (PrintGC && Verbose) {
- gclog_or_tty->print_cr(" "
- " shrinking:"
- " initSize: %.1fK"
- " maximum_desired_capacity: %.1fK",
- spec()->init_size() / (double) K,
- maximum_desired_capacity / (double) K);
- gclog_or_tty->print_cr(" "
- " shrink_bytes: %.1fK"
- " current_shrink_factor: " SIZE_FORMAT
- " new shrink factor: " SIZE_FORMAT
- " _min_heap_delta_bytes: %.1fK",
- shrink_bytes / (double) K,
- current_shrink_factor,
- _shrink_factor,
- _min_heap_delta_bytes / (double) K);
- }
- }
- }
-
- if (capacity_after_gc > _capacity_at_prologue) {
- // We might have expanded for promotions, in which case we might want to
- // take back that expansion if there's room after GC. That keeps us from
- // stretching the heap with promotions when there's plenty of room.
- size_t expansion_for_promotion = capacity_after_gc - _capacity_at_prologue;
- expansion_for_promotion = MIN2(expansion_for_promotion, max_shrink_bytes);
- // We have two shrinking computations, take the largest
- shrink_bytes = MAX2(shrink_bytes, expansion_for_promotion);
- assert(shrink_bytes <= max_shrink_bytes, "invalid shrink size");
- if (PrintGC && Verbose) {
- gclog_or_tty->print_cr(" "
- " aggressive shrinking:"
- " _capacity_at_prologue: %.1fK"
- " capacity_after_gc: %.1fK"
- " expansion_for_promotion: %.1fK"
- " shrink_bytes: %.1fK",
- capacity_after_gc / (double) K,
- _capacity_at_prologue / (double) K,
- expansion_for_promotion / (double) K,
- shrink_bytes / (double) K);
- }
- }
- // Don't shrink unless it's significant
- if (shrink_bytes >= _min_heap_delta_bytes) {
- shrink(shrink_bytes);
- }
-}
-
-// Currently nothing to do.
-void CardGeneration::prepare_for_verify() {}
-
--- a/hotspot/src/share/vm/memory/generation.hpp Tue Dec 09 12:47:19 2014 +0100
+++ b/hotspot/src/share/vm/memory/generation.hpp Wed Dec 10 11:30:46 2014 +0100
@@ -584,57 +584,4 @@
virtual CollectorCounters* counters() { return _gc_counters; }
};
-// Class CardGeneration is a generation that is covered by a card table,
-// and uses a card-size block-offset array to implement block_start.
-
-// class BlockOffsetArray;
-// class BlockOffsetArrayContigSpace;
-class BlockOffsetSharedArray;
-
-class CardGeneration: public Generation {
- friend class VMStructs;
- protected:
- // This is shared with other generations.
- GenRemSet* _rs;
- // This is local to this generation.
- BlockOffsetSharedArray* _bts;
-
- // current shrinking effect: this damps shrinking when the heap gets empty.
- size_t _shrink_factor;
-
- size_t _min_heap_delta_bytes; // Minimum amount to expand.
-
- // Some statistics from before gc started.
- // These are gathered in the gc_prologue (and should_collect)
- // to control growing/shrinking policy in spite of promotions.
- size_t _capacity_at_prologue;
- size_t _used_at_prologue;
-
- CardGeneration(ReservedSpace rs, size_t initial_byte_size, int level,
- GenRemSet* remset);
-
- public:
-
- // Attempt to expand the generation by "bytes". Expand by at a
- // minimum "expand_bytes". Return true if some amount (not
- // necessarily the full "bytes") was done.
- virtual bool expand(size_t bytes, size_t expand_bytes);
-
- // Shrink generation with specified size (returns false if unable to shrink)
- virtual void shrink(size_t bytes) = 0;
-
- virtual void compute_new_size();
-
- virtual void clear_remembered_set();
-
- virtual void invalidate_remembered_set();
-
- virtual void prepare_for_verify();
-
- // Grow generation with specified size (returns false if unable to grow)
- virtual bool grow_by(size_t bytes) = 0;
- // Grow generation to reserved size.
- virtual bool grow_to_reserved() = 0;
-};
-
#endif // SHARE_VM_MEMORY_GENERATION_HPP
--- a/hotspot/src/share/vm/memory/tenuredGeneration.hpp Tue Dec 09 12:47:19 2014 +0100
+++ b/hotspot/src/share/vm/memory/tenuredGeneration.hpp Wed Dec 10 11:30:46 2014 +0100
@@ -28,7 +28,7 @@
#include "gc_implementation/shared/cSpaceCounters.hpp"
#include "gc_implementation/shared/gcStats.hpp"
#include "gc_implementation/shared/generationCounters.hpp"
-#include "memory/generation.hpp"
+#include "memory/cardGeneration.hpp"
#include "utilities/macros.hpp"
// TenuredGeneration models the heap containing old (promoted/tenured) objects