# HG changeset patch # User brutisso # Date 1376463752 -7200 # Node ID 330dfb0476f493864e89a8f10c1364eff5cd265e # Parent 39127bb12d324396295c54a61a348d3e75028c4a 8022800: Use specific generations rather than generation iteration Reviewed-by: jmasa, ehelin diff -r 39127bb12d32 -r 330dfb0476f4 src/share/vm/gc_implementation/parNew/parNewGeneration.cpp --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Fri Aug 09 01:39:11 2013 -0700 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Wed Aug 14 09:02:32 2013 +0200 @@ -927,11 +927,9 @@ workers->active_workers(), Threads::number_of_non_daemon_threads()); workers->set_active_workers(active_workers); - _next_gen = gch->next_gen(this); - assert(_next_gen != NULL, - "This must be the youngest gen, and not the only gen"); assert(gch->n_gens() == 2, "Par collection currently only works with single older gen."); + _next_gen = gch->next_gen(this); // Do we have to avoid promotion_undo? if (gch->collector_policy()->is_concurrent_mark_sweep_policy()) { set_avoid_promotion_undo(true); diff -r 39127bb12d32 -r 330dfb0476f4 src/share/vm/memory/cardTableRS.cpp --- a/src/share/vm/memory/cardTableRS.cpp Fri Aug 09 01:39:11 2013 -0700 +++ b/src/share/vm/memory/cardTableRS.cpp Wed Aug 14 09:02:32 2013 +0200 @@ -321,35 +321,25 @@ // below to avoid missing cards at the fringes. If clear() or // invalidate() are changed in the future, this code should // be revisited. 20040107.ysr - Generation* g = gen; - for(Generation* prev_gen = gch->prev_gen(g); - prev_gen != NULL; - g = prev_gen, prev_gen = gch->prev_gen(g)) { - MemRegion to_be_cleared_mr = g->prev_used_region(); - clear(to_be_cleared_mr); - } + Generation* old_gen = gen; + clear(old_gen->prev_used_region()); + Generation* young_gen = gch->prev_gen(old_gen); + clear(young_gen->prev_used_region()); } -void CardTableRS::invalidate_or_clear(Generation* gen, bool younger) { - GenCollectedHeap* gch = GenCollectedHeap::heap(); - // For each generation gen (and younger) - // invalidate the cards for the currently occupied part - // of that generation and clear the cards for the +void CardTableRS::invalidate_or_clear(Generation* gen) { + // For generation gen invalidate the cards for the currently + // occupied part of that generation and clear the cards for the // unoccupied part of the generation (if any, making use // of that generation's prev_used_region to determine that // region). No need to do anything for the youngest // generation. Also see note#20040107.ysr above. - Generation* g = gen; - for(Generation* prev_gen = gch->prev_gen(g); prev_gen != NULL; - g = prev_gen, prev_gen = gch->prev_gen(g)) { - MemRegion used_mr = g->used_region(); - MemRegion to_be_cleared_mr = g->prev_used_region().minus(used_mr); - if (!to_be_cleared_mr.is_empty()) { - clear(to_be_cleared_mr); - } - invalidate(used_mr); - if (!younger) break; + MemRegion used_mr = gen->used_region(); + MemRegion to_be_cleared_mr = gen->prev_used_region().minus(used_mr); + if (!to_be_cleared_mr.is_empty()) { + clear(to_be_cleared_mr); } + invalidate(used_mr); } diff -r 39127bb12d32 -r 330dfb0476f4 src/share/vm/memory/cardTableRS.hpp --- a/src/share/vm/memory/cardTableRS.hpp Fri Aug 09 01:39:11 2013 -0700 +++ b/src/share/vm/memory/cardTableRS.hpp Wed Aug 14 09:02:32 2013 +0200 @@ -147,7 +147,7 @@ void invalidate(MemRegion mr, bool whole_heap = false) { _ct_bs->invalidate(mr, whole_heap); } - void invalidate_or_clear(Generation* gen, bool younger); + void invalidate_or_clear(Generation* gen); static uintx ct_max_alignment_constraint() { return CardTableModRefBS::ct_max_alignment_constraint(); diff -r 39127bb12d32 -r 330dfb0476f4 src/share/vm/memory/defNewGeneration.cpp --- a/src/share/vm/memory/defNewGeneration.cpp Fri Aug 09 01:39:11 2013 -0700 +++ b/src/share/vm/memory/defNewGeneration.cpp Wed Aug 14 09:02:32 2013 +0200 @@ -567,8 +567,6 @@ gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start()); _next_gen = gch->next_gen(this); - assert(_next_gen != NULL, - "This must be the youngest gen, and not the only gen"); // If the next generation is too full to accommodate promotion // from this generation, pass on collection; let the next generation @@ -901,8 +899,6 @@ if (_next_gen == NULL) { GenCollectedHeap* gch = GenCollectedHeap::heap(); _next_gen = gch->next_gen(this); - assert(_next_gen != NULL, - "This must be the youngest gen, and not the only gen"); } return _next_gen->promotion_attempt_is_safe(used()); } diff -r 39127bb12d32 -r 330dfb0476f4 src/share/vm/memory/genCollectedHeap.cpp --- a/src/share/vm/memory/genCollectedHeap.cpp Fri Aug 09 01:39:11 2013 -0700 +++ b/src/share/vm/memory/genCollectedHeap.cpp Wed Aug 14 09:02:32 2013 +0200 @@ -1070,13 +1070,13 @@ void GenCollectedHeap::prepare_for_compaction() { - Generation* scanning_gen = _gens[_n_gens-1]; + guarantee(_n_gens = 2, "Wrong number of generations"); + Generation* old_gen = _gens[1]; // Start by compacting into same gen. - CompactPoint cp(scanning_gen, NULL, NULL); - while (scanning_gen != NULL) { - scanning_gen->prepare_for_compaction(&cp); - scanning_gen = prev_gen(scanning_gen); - } + CompactPoint cp(old_gen, NULL, NULL); + old_gen->prepare_for_compaction(&cp); + Generation* young_gen = _gens[0]; + young_gen->prepare_for_compaction(&cp); } GCStats* GenCollectedHeap::gc_stats(int level) const { @@ -1245,27 +1245,14 @@ generation_iterate(&ep_cl, false); } -oop GenCollectedHeap::handle_failed_promotion(Generation* gen, +oop GenCollectedHeap::handle_failed_promotion(Generation* old_gen, oop obj, size_t obj_size) { + guarantee(old_gen->level() == 1, "We only get here with an old generation"); assert(obj_size == (size_t)obj->size(), "bad obj_size passed in"); HeapWord* result = NULL; - // First give each higher generation a chance to allocate the promoted object. - Generation* allocator = next_gen(gen); - if (allocator != NULL) { - do { - result = allocator->allocate(obj_size, false); - } while (result == NULL && (allocator = next_gen(allocator)) != NULL); - } - - if (result == NULL) { - // Then give gen and higher generations a chance to expand and allocate the - // object. - do { - result = gen->expand_and_allocate(obj_size, false); - } while (result == NULL && (gen = next_gen(gen)) != NULL); - } + result = old_gen->expand_and_allocate(obj_size, false); if (result != NULL) { Copy::aligned_disjoint_words((HeapWord*)obj, result, obj_size); diff -r 39127bb12d32 -r 330dfb0476f4 src/share/vm/memory/genCollectedHeap.hpp --- a/src/share/vm/memory/genCollectedHeap.hpp Fri Aug 09 01:39:11 2013 -0700 +++ b/src/share/vm/memory/genCollectedHeap.hpp Wed Aug 14 09:02:32 2013 +0200 @@ -368,25 +368,23 @@ // collection. virtual bool is_maximal_no_gc() const; - // Return the generation before "gen", or else NULL. + // Return the generation before "gen". Generation* prev_gen(Generation* gen) const { int l = gen->level(); - if (l == 0) return NULL; - else return _gens[l-1]; + guarantee(l > 0, "Out of bounds"); + return _gens[l-1]; } - // Return the generation after "gen", or else NULL. + // Return the generation after "gen". Generation* next_gen(Generation* gen) const { int l = gen->level() + 1; - if (l == _n_gens) return NULL; - else return _gens[l]; + guarantee(l < _n_gens, "Out of bounds"); + return _gens[l]; } Generation* get_gen(int i) const { - if (i >= 0 && i < _n_gens) - return _gens[i]; - else - return NULL; + guarantee(i >= 0 && i < _n_gens, "Out of bounds"); + return _gens[i]; } int n_gens() const { @@ -485,9 +483,9 @@ // Promotion of obj into gen failed. Try to promote obj to higher // gens in ascending order; return the new location of obj if successful. - // Otherwise, try expand-and-allocate for obj in each generation starting at - // gen; return the new location of obj if successful. Otherwise, return NULL. - oop handle_failed_promotion(Generation* gen, + // Otherwise, try expand-and-allocate for obj in both the young and old + // generation; return the new location of obj if successful. Otherwise, return NULL. + oop handle_failed_promotion(Generation* old_gen, oop obj, size_t obj_size); diff -r 39127bb12d32 -r 330dfb0476f4 src/share/vm/memory/genMarkSweep.cpp --- a/src/share/vm/memory/genMarkSweep.cpp Fri Aug 09 01:39:11 2013 -0700 +++ b/src/share/vm/memory/genMarkSweep.cpp Wed Aug 14 09:02:32 2013 +0200 @@ -52,8 +52,8 @@ #include "utilities/copy.hpp" #include "utilities/events.hpp" -void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, - bool clear_all_softrefs) { +void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, bool clear_all_softrefs) { + guarantee(level == 1, "We always collect both old and young."); assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); GenCollectedHeap* gch = GenCollectedHeap::heap(); @@ -84,11 +84,6 @@ // Capture heap size before collection for printing. size_t gch_prev_used = gch->used(); - // Some of the card table updates below assume that the perm gen is - // also being collected. - assert(level == gch->n_gens() - 1, - "All generations are being collected, ergo perm gen too."); - // Capture used regions for each generation that will be // subject to collection, so that card table adjustments can // be made intelligently (see clear / invalidate further below). @@ -134,9 +129,9 @@ } else { // Invalidate the cards corresponding to the currently used // region and clear those corresponding to the evacuated region - // of all generations just collected (i.e. level and younger). - rs->invalidate_or_clear(gch->get_gen(level), - true /* younger */); + // of all generations just collected. + rs->invalidate_or_clear(gch->get_gen(1)); + rs->invalidate_or_clear(gch->get_gen(0)); } Threads::gc_epilogue(); diff -r 39127bb12d32 -r 330dfb0476f4 src/share/vm/memory/genRemSet.hpp --- a/src/share/vm/memory/genRemSet.hpp Fri Aug 09 01:39:11 2013 -0700 +++ b/src/share/vm/memory/genRemSet.hpp Wed Aug 14 09:02:32 2013 +0200 @@ -146,11 +146,8 @@ // Informs the RS that refs in this generation // may have changed arbitrarily, and therefore may contain - // old-to-young pointers in arbitrary locations. The parameter - // younger indicates if the same should be done for younger generations - // as well. The parameter perm indicates if the same should be done for - // perm gen as well. - virtual void invalidate_or_clear(Generation* gen, bool younger) = 0; + // old-to-young pointers in arbitrary locations. + virtual void invalidate_or_clear(Generation* gen) = 0; }; #endif // SHARE_VM_MEMORY_GENREMSET_HPP