--- old/agent/src/share/classes/sun/jvm/hotspot/memory/Generation.java 2014-10-17 16:09:53.000000000 +0200 +++ new/agent/src/share/classes/sun/jvm/hotspot/memory/Generation.java 2014-10-17 16:09:53.000000000 +0200 @@ -51,7 +51,7 @@ public abstract class Generation extends VMObject { private static long reservedFieldOffset; private static long virtualSpaceFieldOffset; - private static CIntegerField levelField; + private static int levelField; protected static final int K = 1024; // Fields for class StatRecord private static Field statRecordField; @@ -77,7 +77,7 @@ reservedFieldOffset = type.getField("_reserved").getOffset(); virtualSpaceFieldOffset = type.getField("_virtual_space").getOffset(); - levelField = type.getCIntegerField("_level"); + levelField = 0; // StatRecord statRecordField = type.getField("_stat_record"); type = db.lookupType("Generation::StatRecord"); @@ -137,7 +137,7 @@ } public int level() { - return (int) levelField.getValue(addr); + return levelField; } public int invocations() { --- old/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2014-10-17 16:09:53.000000000 +0200 +++ new/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2014-10-17 16:09:53.000000000 +0200 @@ -197,10 +197,10 @@ }; ConcurrentMarkSweepGeneration::ConcurrentMarkSweepGeneration( - ReservedSpace rs, size_t initial_byte_size, int level, + ReservedSpace rs, size_t initial_byte_size, CardTableRS* ct, bool use_adaptive_freelists, FreeBlockDictionary::DictionaryChoice dictionaryChoice) : - CardGeneration(rs, initial_byte_size, level, ct), + CardGeneration(rs, initial_byte_size, ct), _dilatation_factor(((double)MinChunkSize)/((double)(CollectedHeap::min_fill_size()))), _debug_collection_type(Concurrent_collection_type), _did_compact(false) @@ -819,12 +819,17 @@ void ConcurrentMarkSweepGeneration::printOccupancy(const char *s) { GenCollectedHeap* gch = GenCollectedHeap::heap(); if (PrintGCDetails) { + // I didn't want to change the logging when removing the level concept, + // but I guess this logging could say "old" or something instead of "1". + assert(this == gch->old_gen(), + "The CMS generation should be the old generation"); + int level = 1; if (Verbose) { gclog_or_tty->print("[%d %s-%s: "SIZE_FORMAT"("SIZE_FORMAT")]", - level(), short_name(), s, used(), capacity()); + level, short_name(), s, used(), capacity()); } else { gclog_or_tty->print("[%d %s-%s: "SIZE_FORMAT"K("SIZE_FORMAT"K)]", - level(), short_name(), s, used() / K, capacity() / K); + level, short_name(), s, used() / K, capacity() / K); } } if (Verbose) { @@ -945,27 +950,24 @@ gclog_or_tty->print_cr("\nFrom compute_new_size: "); gclog_or_tty->print_cr(" Free fraction %f", free_percentage); gclog_or_tty->print_cr(" Desired free fraction %f", - desired_free_percentage); + desired_free_percentage); gclog_or_tty->print_cr(" Maximum free fraction %f", - maximum_free_percentage); - gclog_or_tty->print_cr(" Capacity "SIZE_FORMAT, capacity()/1000); + maximum_free_percentage); + gclog_or_tty->print_cr(" Capacity "SIZE_FORMAT, capacity() / 1000); gclog_or_tty->print_cr(" Desired capacity "SIZE_FORMAT, - desired_capacity/1000); - int prev_level = level() - 1; - if (prev_level >= 0) { - size_t prev_size = 0; - GenCollectedHeap* gch = GenCollectedHeap::heap(); - Generation* prev_gen = gch->young_gen(); - prev_size = prev_gen->capacity(); - gclog_or_tty->print_cr(" Younger gen size "SIZE_FORMAT, - prev_size/1000); - } + desired_capacity / 1000); + GenCollectedHeap* gch = GenCollectedHeap::heap(); + assert(this == gch->_old_gen, + "The CMS generation should always be the old generation"); + size_t young_size = gch->_young_gen->capacity(); + gclog_or_tty->print_cr(" Young gen size "SIZE_FORMAT, + young_size / 1000); gclog_or_tty->print_cr(" unsafe_max_alloc_nogc "SIZE_FORMAT, - unsafe_max_alloc_nogc()/1000); + unsafe_max_alloc_nogc() / 1000); gclog_or_tty->print_cr(" contiguous available "SIZE_FORMAT, - contiguous_available()/1000); + contiguous_available() / 1000); gclog_or_tty->print_cr(" Expand by "SIZE_FORMAT" (bytes)", - expand_bytes); + expand_bytes); } // safe if expansion fails expand(expand_bytes, 0, CMSExpansionCause::_satisfy_free_ratio); @@ -2054,8 +2056,7 @@ _intra_sweep_estimate.padded_average()); } - GenMarkSweep::invoke_at_safepoint(_cmsGen->level(), - ref_processor(), clear_all_soft_refs); + GenMarkSweep::invoke_at_safepoint(ref_processor(), clear_all_soft_refs); #ifdef ASSERT CompactibleFreeListSpace* cms_space = _cmsGen->cmsSpace(); size_t free_size = cms_space->free(); @@ -3003,7 +3004,7 @@ MarkRefsIntoClosure notOlder(_span, verification_mark_bm()); gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel. - gch->gen_process_roots(_cmsGen->level(), + gch->gen_process_roots(Generation::Old, true, // younger gens are roots true, // activate StrongRootsScope SharedHeap::ScanningOption(roots_scanning_options()), @@ -3071,7 +3072,7 @@ gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel. - gch->gen_process_roots(_cmsGen->level(), + gch->gen_process_roots(Generation::Old, true, // younger gens are roots true, // activate StrongRootsScope SharedHeap::ScanningOption(roots_scanning_options()), @@ -3685,7 +3686,7 @@ // The serial version. CLDToOopClosure cld_closure(¬Older, true); gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel. - gch->gen_process_roots(_cmsGen->level(), + gch->gen_process_roots(Generation::Old, true, // younger gens are roots true, // activate StrongRootsScope SharedHeap::ScanningOption(roots_scanning_options()), @@ -4961,15 +4962,12 @@ FlagSetting fl(gch->_is_gc_active, false); NOT_PRODUCT(GCTraceTime t("Scavenge-Before-Remark", PrintGCDetails && Verbose, true, _gc_timer_cm, _gc_tracer_cm->gc_id());) - int level = _cmsGen->level() - 1; - if (level >= 0) { - gch->do_collection(true, // full (i.e. force, see below) - false, // !clear_all_soft_refs - 0, // size - false, // is_tlab - level // max_level - ); - } + gch->do_collection(true, // full (i.e. force, see below) + false, // !clear_all_soft_refs + 0, // size + false, // is_tlab + Generation::Young // type + ); } FreelistLocker x(this); MutexLockerEx y(bitMapLock(), @@ -5156,7 +5154,7 @@ CLDToOopClosure cld_closure(&par_mri_cl, true); - gch->gen_process_roots(_collector->_cmsGen->level(), + gch->gen_process_roots(Generation::Old, false, // yg was scanned above false, // this is parallel code SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()), @@ -5292,7 +5290,7 @@ // ---------- remaining roots -------------- _timer.reset(); _timer.start(); - gch->gen_process_roots(_collector->_cmsGen->level(), + gch->gen_process_roots(Generation::Old, false, // yg was scanned above false, // this is parallel code SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()), @@ -5884,7 +5882,7 @@ gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel. GenCollectedHeap::StrongRootsScope srs(gch); - gch->gen_process_roots(_cmsGen->level(), + gch->gen_process_roots(Generation::Old, true, // younger gens as roots false, // use the local StrongRootsScope SharedHeap::ScanningOption(roots_scanning_options()), @@ -6361,11 +6359,12 @@ return _cmsSpace->find_chunk_at_end(); } -void ConcurrentMarkSweepGeneration::update_gc_stats(int current_level, +void ConcurrentMarkSweepGeneration::update_gc_stats(Generation* current_generation, bool full) { - // The next lower level has been collected. Gather any statistics + // If the young generation has been collected. Gather any statistics // that are of interest at this point. - if (!full && (current_level + 1) == level()) { + bool current_is_young = (current_generation == GenCollectedHeap::heap()->young_gen()); + if (!full && current_is_young) { // Gather statistics on the young generation collection. collector()->stats().record_gc0_end(used()); } --- old/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp 2014-10-17 16:09:54.000000000 +0200 +++ new/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp 2014-10-17 16:09:54.000000000 +0200 @@ -1122,7 +1122,7 @@ void shrink_free_list_by(size_t bytes); // Update statistics for GC - virtual void update_gc_stats(int level, bool full); + virtual void update_gc_stats(Generation* current_generation, bool full); // Maximum available space in the generation (including uncommitted) // space. @@ -1134,7 +1134,7 @@ public: ConcurrentMarkSweepGeneration(ReservedSpace rs, size_t initial_byte_size, - int level, CardTableRS* ct, + CardTableRS* ct, bool use_adaptive_freelists, FreeBlockDictionary::DictionaryChoice); --- old/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp 2014-10-17 16:09:55.000000000 +0200 +++ new/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp 2014-10-17 16:09:55.000000000 +0200 @@ -197,7 +197,7 @@ "We can only be executing this arm of if at a safepoint"); GCCauseSetter gccs(gch, _gc_cause); gch->do_full_collection(gch->must_clear_all_soft_refs(), - 0 /* collect only youngest gen */); + Generation::Young /* collect only youngest gen */); } // Else no need for a foreground young gc assert((_gc_count_before < gch->total_collections()) || (GC_locker::is_active() /* gc may have been skipped */ --- old/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp 2014-10-17 16:09:56.000000000 +0200 +++ new/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp 2014-10-17 16:09:56.000000000 +0200 @@ -63,25 +63,25 @@ #pragma warning( disable:4355 ) // 'this' : used in base member initializer list #endif ParScanThreadState::ParScanThreadState(Space* to_space_, - ParNewGeneration* gen_, + ParNewGeneration* young_gen_, Generation* old_gen_, int thread_num_, ObjToScanQueueSet* work_queue_set_, Stack* overflow_stacks_, size_t desired_plab_sz_, ParallelTaskTerminator& term_) : - _to_space(to_space_), _old_gen(old_gen_), _young_gen(gen_), _thread_num(thread_num_), + _to_space(to_space_), _old_gen(old_gen_), _young_gen(young_gen_), _thread_num(thread_num_), _work_queue(work_queue_set_->queue(thread_num_)), _to_space_full(false), _overflow_stack(overflow_stacks_ ? overflow_stacks_ + thread_num_ : NULL), _ageTable(false), // false ==> not the global age table, no perf data. _to_space_alloc_buffer(desired_plab_sz_), - _to_space_closure(gen_, this), _old_gen_closure(gen_, this), - _to_space_root_closure(gen_, this), _old_gen_root_closure(gen_, this), - _older_gen_closure(gen_, this), + _to_space_closure(young_gen_, this), _old_gen_closure(young_gen_, this), + _to_space_root_closure(young_gen_, this), _old_gen_root_closure(young_gen_, this), + _older_gen_closure(young_gen_, this), _evacuate_followers(this, &_to_space_closure, &_old_gen_closure, - &_to_space_root_closure, gen_, &_old_gen_root_closure, + &_to_space_root_closure, young_gen_, &_old_gen_root_closure, work_queue_set_, &term_), - _is_alive_closure(gen_), _scan_weak_ref_closure(gen_, this), + _is_alive_closure(young_gen_), _scan_weak_ref_closure(young_gen_, this), _keep_alive_closure(&_scan_weak_ref_closure), _strong_roots_time(0.0), _term_time(0.0) { @@ -493,7 +493,6 @@ ParScanThreadState* par_scan_state) : OopsInKlassOrGenClosure(g), _par_scan_state(par_scan_state), _g(g) { - assert(_g->level() == 0, "Optimized for youngest generation"); _boundary = _g->reserved().end(); } @@ -578,10 +577,10 @@ par_scan_state()->end_term_time(); } -ParNewGenTask::ParNewGenTask(ParNewGeneration* gen, Generation* old_gen, +ParNewGenTask::ParNewGenTask(ParNewGeneration* young_gen, Generation* old_gen, HeapWord* young_old_boundary, ParScanThreadStateSet* state_set) : AbstractGangTask("ParNewGeneration collection"), - _gen(gen), _old_gen(old_gen), + _young_gen(young_gen), _old_gen(old_gen), _young_old_boundary(young_old_boundary), _state_set(state_set) {} @@ -589,7 +588,7 @@ // Reset the terminator for the given number of // active threads. void ParNewGenTask::set_for_termination(int active_workers) { - _state_set->reset(active_workers, _gen->promotion_failed()); + _state_set->reset(active_workers, _young_gen->promotion_failed()); // Should the heap be passed in? There's only 1 for now so // grab it instead. GenCollectedHeap* gch = GenCollectedHeap::heap(); @@ -602,8 +601,6 @@ // and handle marks. ResourceMark rm; HandleMark hm; - // We would need multiple old-gen queues otherwise. - assert(gch->n_gens() == 2, "Par young collection currently only works with one older gen."); Generation* old_gen = gch->old_gen(); @@ -619,7 +616,7 @@ false); par_scan_state.start_strong_roots(); - gch->gen_process_roots(_gen->level(), + gch->gen_process_roots(Generation::Young, true, // Process younger gens, if any, // as strong roots. false, // no scope; this is parallel code @@ -640,8 +637,8 @@ #pragma warning( disable:4355 ) // 'this' : used in base member initializer list #endif ParNewGeneration:: -ParNewGeneration(ReservedSpace rs, size_t initial_byte_size, int level) - : DefNewGeneration(rs, initial_byte_size, level, "PCopy"), +ParNewGeneration(ReservedSpace rs, size_t initial_byte_size) + : DefNewGeneration(rs, initial_byte_size, "PCopy"), _overflow_list(NULL), _is_alive_closure(this), _plab_stats(YoungPLABSize, PLABWeight) @@ -778,7 +775,7 @@ _state_set.terminator()->reset_for_reuse(active_workers); } private: - ParNewGeneration& _gen; + ParNewGeneration& _young_gen; ProcessTask& _task; Generation& _old_gen; HeapWord* _young_old_boundary; @@ -786,12 +783,12 @@ }; ParNewRefProcTaskProxy::ParNewRefProcTaskProxy( - ProcessTask& task, ParNewGeneration& gen, + ProcessTask& task, ParNewGeneration& young_gen, Generation& old_gen, HeapWord* young_old_boundary, ParScanThreadStateSet& state_set) : AbstractGangTask("ParNewGeneration parallel reference processing"), - _gen(gen), + _young_gen(young_gen), _task(task), _old_gen(old_gen), _young_old_boundary(young_old_boundary), @@ -835,7 +832,7 @@ FlexibleWorkGang* workers = gch->workers(); assert(workers != NULL, "Need parallel worker threads."); _state_set.reset(workers->active_workers(), _generation.promotion_failed()); - ParNewRefProcTaskProxy rp_task(task, _generation, *_generation.next_gen(), + ParNewRefProcTaskProxy rp_task(task, _generation, *(gch->old_gen()), _generation.reserved().end(), _state_set); workers->run_task(&rp_task); _state_set.reset(0 /* bad value in debug if not reset */, @@ -864,10 +861,10 @@ ScanClosure(g, gc_barrier) {} EvacuateFollowersClosureGeneral:: -EvacuateFollowersClosureGeneral(GenCollectedHeap* gch, int level, +EvacuateFollowersClosureGeneral(GenCollectedHeap* gch, OopsInGenClosure* cur, OopsInGenClosure* older) : - _gch(gch), _level(level), + _gch(gch), _scan_cur_or_nonheap(cur), _scan_older(older) {} @@ -875,10 +872,10 @@ do { // Beware: this call will lead to closure applications via virtual // calls. - _gch->oop_since_save_marks_iterate(_level, + _gch->oop_since_save_marks_iterate(Generation::Young, _scan_cur_or_nonheap, _scan_older); - } while (!_gch->no_allocs_since_save_marks(_level)); + } while (!_gch->no_allocs_since_save_marks(true /* include_young */)); } @@ -931,8 +928,6 @@ workers->active_workers(), Threads::number_of_non_daemon_threads()); workers->set_active_workers(active_workers); - assert(gch->n_gens() == 2, - "Par collection currently only works with single older gen."); _old_gen = gch->old_gen(); // Do we have to avoid promotion_undo? if (gch->collector_policy()->is_concurrent_mark_sweep_policy()) { @@ -1007,7 +1002,7 @@ ScanClosure scan_without_gc_barrier(this, false); ScanClosureWithParBarrier scan_with_gc_barrier(this, true); set_promo_failure_scan_stack_closure(&scan_without_gc_barrier); - EvacuateFollowersClosureGeneral evacuate_followers(gch, _level, + EvacuateFollowersClosureGeneral evacuate_followers(gch, &scan_without_gc_barrier, &scan_with_gc_barrier); rp->setup_policy(clear_all_soft_refs); // Can the mt_degree be set later (at run_task() time would be best)? --- old/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp 2014-10-17 16:09:56.000000000 +0200 +++ new/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp 2014-10-17 16:09:56.000000000 +0200 @@ -232,13 +232,13 @@ class ParNewGenTask: public AbstractGangTask { private: - ParNewGeneration* _gen; + ParNewGeneration* _young_gen; Generation* _old_gen; HeapWord* _young_old_boundary; class ParScanThreadStateSet* _state_set; public: - ParNewGenTask(ParNewGeneration* gen, + ParNewGenTask(ParNewGeneration* young_gen, Generation* old_gen, HeapWord* young_old_boundary, ParScanThreadStateSet* state_set); @@ -264,11 +264,10 @@ class EvacuateFollowersClosureGeneral: public VoidClosure { private: GenCollectedHeap* _gch; - int _level; OopsInGenClosure* _scan_cur_or_nonheap; OopsInGenClosure* _scan_older; public: - EvacuateFollowersClosureGeneral(GenCollectedHeap* gch, int level, + EvacuateFollowersClosureGeneral(GenCollectedHeap* gch, OopsInGenClosure* cur, OopsInGenClosure* older); virtual void do_void(); @@ -356,7 +355,7 @@ void set_survivor_overflow(bool v) { _survivor_overflow = v; } public: - ParNewGeneration(ReservedSpace rs, size_t initial_byte_size, int level); + ParNewGeneration(ReservedSpace rs, size_t initial_byte_size); ~ParNewGeneration() { for (uint i = 0; i < ParallelGCThreads; i++) --- old/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp 2014-10-17 16:09:57.000000000 +0200 +++ new/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp 2014-10-17 16:09:57.000000000 +0200 @@ -70,7 +70,7 @@ bool root_scan) { assert((!Universe::heap()->is_in_reserved(p) || generation()->is_in_reserved(p)) - && (generation()->level() == 0 || gc_barrier), + && (generation() == GenCollectedHeap::heap()->young_gen() || gc_barrier), "The gen must be right, and we must be doing the barrier " "in older generations."); T heap_oop = oopDesc::load_heap_oop(p); --- old/src/share/vm/gc_implementation/shared/vmGCOperations.cpp 2014-10-17 16:09:58.000000000 +0200 +++ new/src/share/vm/gc_implementation/shared/vmGCOperations.cpp 2014-10-17 16:09:58.000000000 +0200 @@ -192,7 +192,7 @@ GenCollectedHeap* gch = GenCollectedHeap::heap(); GCCauseSetter gccs(gch, _gc_cause); - gch->do_full_collection(gch->must_clear_all_soft_refs(), _max_level); + gch->do_full_collection(gch->must_clear_all_soft_refs(), _max_generation); } // Returns true iff concurrent GCs unloads metadata. --- old/src/share/vm/gc_implementation/shared/vmGCOperations.hpp 2014-10-17 16:09:58.000000000 +0200 +++ new/src/share/vm/gc_implementation/shared/vmGCOperations.hpp 2014-10-17 16:09:58.000000000 +0200 @@ -186,14 +186,14 @@ // GenCollectedHeap heap. class VM_GenCollectFull: public VM_GC_Operation { private: - int _max_level; + Generation::Type _max_generation; public: VM_GenCollectFull(unsigned int gc_count_before, unsigned int full_gc_count_before, GCCause::Cause gc_cause, - int max_level) + Generation::Type max_generation) : VM_GC_Operation(gc_count_before, gc_cause, full_gc_count_before, true /* full */), - _max_level(max_level) { } + _max_generation(max_generation) { } ~VM_GenCollectFull() {} virtual VMOp_Type type() const { return VMOp_GenCollectFull; } virtual void doit(); --- old/src/share/vm/memory/cardTableRS.cpp 2014-10-17 16:09:59.000000000 +0200 +++ new/src/share/vm/memory/cardTableRS.cpp 2014-10-17 16:09:59.000000000 +0200 @@ -118,7 +118,7 @@ void CardTableRS::younger_refs_iterate(Generation* g, OopsInGenClosure* blk) { - _last_cur_val_in_gen[g->level()+1] = cur_youngergen_card_val(); + _last_cur_val_in_gen[2 /* Number of generations */] = cur_youngergen_card_val(); g->younger_refs_iterate(blk); } @@ -316,7 +316,8 @@ } void CardTableRS::clear_into_younger(Generation* old_gen) { - assert(old_gen->level() == 1, "Should only be called for the old generation"); + assert(old_gen == GenCollectedHeap::heap()->old_gen(), + "Should only be called for the old generation"); // The card tables for the youngest gen need never be cleared. // There's a bit of subtlety in the clear() and invalidate() // methods that we exploit here and in invalidate_or_clear() @@ -327,7 +328,8 @@ } void CardTableRS::invalidate_or_clear(Generation* old_gen) { - assert(old_gen->level() == 1, "Should only be called for the old generation"); + assert(old_gen == GenCollectedHeap::heap()->old_gen(), + "Should only be called for the old generation"); // Invalidate the cards for the currently occupied part of // the old generation and clear the cards for the // unoccupied part of the generation (if any, making use @@ -393,7 +395,9 @@ VerifyCTGenClosure(CardTableRS* ct) : _ct(ct) {} void do_generation(Generation* gen) { // Skip the youngest generation. - if (gen->level() == 0) return; + if (gen == GenCollectedHeap::heap()->young_gen()) { + return; + } // Normally, we're interested in pointers to younger generations. VerifyCTSpaceClosure blk(_ct, gen->reserved().start()); gen->space_iterate(&blk, true); --- old/src/share/vm/memory/collectorPolicy.cpp 2014-10-17 16:10:00.000000000 +0200 +++ new/src/share/vm/memory/collectorPolicy.cpp 2014-10-17 16:10:00.000000000 +0200 @@ -751,7 +751,7 @@ false /* clear_all_soft_refs */, size /* size */, is_tlab /* is_tlab */, - number_of_generations() - 1 /* max_level */); + Generation::Old /* max_gen */); } else { if (Verbose && PrintGCDetails) { gclog_or_tty->print(" :: Trying full because partial may fail :: "); @@ -764,7 +764,7 @@ false /* clear_all_soft_refs */, size /* size */, is_tlab /* is_tlab */, - number_of_generations() - 1 /* max_level */); + Generation::Old /* max_gen */); } result = gch->attempt_allocation(size, is_tlab, false /*first_only*/); @@ -792,7 +792,7 @@ true /* clear_all_soft_refs */, size /* size */, is_tlab /* is_tlab */, - number_of_generations() - 1 /* max_level */); + Generation::Old /* max_gen */); } result = gch->attempt_allocation(size, is_tlab, false /* first_only */); --- old/src/share/vm/memory/defNewGeneration.cpp 2014-10-17 16:10:01.000000000 +0200 +++ new/src/share/vm/memory/defNewGeneration.cpp 2014-10-17 16:10:00.000000000 +0200 @@ -56,9 +56,7 @@ // Methods of protected closure types. -DefNewGeneration::IsAliveClosure::IsAliveClosure(Generation* g) : _g(g) { - assert(g->level() == 0, "Optimized for youngest gen."); -} +DefNewGeneration::IsAliveClosure::IsAliveClosure(Generation* g) : _g(g) { } bool DefNewGeneration::IsAliveClosure::do_object_b(oop p) { return (HeapWord*)p >= _g->reserved().end() || p->is_forwarded(); } @@ -83,39 +81,36 @@ void DefNewGeneration::FastKeepAliveClosure::do_oop(narrowOop* p) { DefNewGeneration::FastKeepAliveClosure::do_oop_work(p); } DefNewGeneration::EvacuateFollowersClosure:: -EvacuateFollowersClosure(GenCollectedHeap* gch, int level, +EvacuateFollowersClosure(GenCollectedHeap* gch, ScanClosure* cur, ScanClosure* older) : - _gch(gch), _level(level), - _scan_cur_or_nonheap(cur), _scan_older(older) + _gch(gch), _scan_cur_or_nonheap(cur), _scan_older(older) {} void DefNewGeneration::EvacuateFollowersClosure::do_void() { do { - _gch->oop_since_save_marks_iterate(_level, _scan_cur_or_nonheap, + _gch->oop_since_save_marks_iterate(Generation::Young, _scan_cur_or_nonheap, _scan_older); - } while (!_gch->no_allocs_since_save_marks(_level)); + } while (!_gch->no_allocs_since_save_marks(Generation::Young)); } DefNewGeneration::FastEvacuateFollowersClosure:: -FastEvacuateFollowersClosure(GenCollectedHeap* gch, int level, +FastEvacuateFollowersClosure(GenCollectedHeap* gch, DefNewGeneration* gen, FastScanClosure* cur, FastScanClosure* older) : - _gch(gch), _level(level), _gen(gen), - _scan_cur_or_nonheap(cur), _scan_older(older) + _gch(gch), _gen(gen), _scan_cur_or_nonheap(cur), _scan_older(older) {} void DefNewGeneration::FastEvacuateFollowersClosure::do_void() { do { - _gch->oop_since_save_marks_iterate(_level, _scan_cur_or_nonheap, + _gch->oop_since_save_marks_iterate(Generation::Young, _scan_cur_or_nonheap, _scan_older); - } while (!_gch->no_allocs_since_save_marks(_level)); + } while (!_gch->no_allocs_since_save_marks(Generation::Young)); guarantee(_gen->promo_failure_scan_is_complete(), "Failed to finish scan"); } ScanClosure::ScanClosure(DefNewGeneration* g, bool gc_barrier) : OopsInKlassOrGenClosure(g), _g(g), _gc_barrier(gc_barrier) { - assert(_g->level() == 0, "Optimized for youngest generation"); _boundary = _g->reserved().end(); } @@ -125,7 +120,6 @@ FastScanClosure::FastScanClosure(DefNewGeneration* g, bool gc_barrier) : OopsInKlassOrGenClosure(g), _g(g), _gc_barrier(gc_barrier) { - assert(_g->level() == 0, "Optimized for youngest generation"); _boundary = _g->reserved().end(); } @@ -166,7 +160,6 @@ ScanWeakRefClosure::ScanWeakRefClosure(DefNewGeneration* g) : _g(g) { - assert(_g->level() == 0, "Optimized for youngest generation"); _boundary = _g->reserved().end(); } @@ -184,9 +177,8 @@ DefNewGeneration::DefNewGeneration(ReservedSpace rs, size_t initial_size, - int level, const char* policy) - : Generation(rs, initial_size, level), + : Generation(rs, initial_size), _promo_failure_drain_in_progress(false), _should_allocate_from_space(false) { @@ -382,13 +374,9 @@ return; } - int next_level = level() + 1; GenCollectedHeap* gch = GenCollectedHeap::heap(); - assert(next_level < gch->n_gens(), - "DefNewGeneration cannot be an oldest gen"); - Generation* old_gen = gch->old_gen(); - size_t old_size = old_gen->capacity(); + size_t old_size = gch->old_gen()->capacity(); size_t new_size_before = _virtual_space.committed_size(); size_t min_new_size = spec()->init_size(); size_t max_new_size = reserved().byte_size(); @@ -605,7 +593,7 @@ gch->rem_set()->prepare_for_younger_refs_iterate(false); - assert(gch->no_allocs_since_save_marks(0), + assert(gch->no_allocs_since_save_marks(Generation::Young), "save marks have not been newly set."); // Not very pretty. @@ -621,14 +609,14 @@ false); set_promo_failure_scan_stack_closure(&fsc_with_no_gc_barrier); - FastEvacuateFollowersClosure evacuate_followers(gch, _level, this, + FastEvacuateFollowersClosure evacuate_followers(gch, this, &fsc_with_no_gc_barrier, &fsc_with_gc_barrier); - assert(gch->no_allocs_since_save_marks(0), + assert(gch->no_allocs_since_save_marks(Generation::Young), "save marks have not been newly set."); - gch->gen_process_roots(_level, + gch->gen_process_roots(Generation::Young, true, // Process younger gens, if any, // as strong roots. true, // activate StrongRootsScope @@ -867,7 +855,7 @@ void DefNewGeneration::contribute_scratch(ScratchBlock*& list, Generation* requestor, size_t max_alloc_words) { if (requestor == this || _promotion_failed) return; - assert(requestor->level() > level(), "DefNewGeneration must be youngest"); + assert(requestor == GenCollectedHeap::heap()->old_gen(), "We should not call our own generation"); /* $$$ Assert this? "trace" is a "MarkSweep" function so that's not appropriate. if (to_space->top() > to_space->bottom()) { --- old/src/share/vm/memory/defNewGeneration.hpp 2014-10-17 16:10:01.000000000 +0200 +++ new/src/share/vm/memory/defNewGeneration.hpp 2014-10-17 16:10:01.000000000 +0200 @@ -182,23 +182,21 @@ class EvacuateFollowersClosure: public VoidClosure { GenCollectedHeap* _gch; - int _level; ScanClosure* _scan_cur_or_nonheap; ScanClosure* _scan_older; public: - EvacuateFollowersClosure(GenCollectedHeap* gch, int level, + EvacuateFollowersClosure(GenCollectedHeap* gch, ScanClosure* cur, ScanClosure* older); void do_void(); }; class FastEvacuateFollowersClosure: public VoidClosure { GenCollectedHeap* _gch; - int _level; DefNewGeneration* _gen; FastScanClosure* _scan_cur_or_nonheap; FastScanClosure* _scan_older; public: - FastEvacuateFollowersClosure(GenCollectedHeap* gch, int level, + FastEvacuateFollowersClosure(GenCollectedHeap* gch, DefNewGeneration* gen, FastScanClosure* cur, FastScanClosure* older); @@ -206,7 +204,7 @@ }; public: - DefNewGeneration(ReservedSpace rs, size_t initial_byte_size, int level, + DefNewGeneration(ReservedSpace rs, size_t initial_byte_size, const char* policy="Copy"); virtual void ref_processor_init(); --- old/src/share/vm/memory/genCollectedHeap.cpp 2014-10-17 16:10:02.000000000 +0200 +++ new/src/share/vm/memory/genCollectedHeap.cpp 2014-10-17 16:10:02.000000000 +0200 @@ -118,11 +118,11 @@ _gch = this; ReservedSpace young_rs = heap_rs.first_part(gen_policy()->young_gen_spec()->max_size(), false, false); - _young_gen = gen_policy()->young_gen_spec()->init(young_rs, 0, rem_set()); + _young_gen = gen_policy()->young_gen_spec()->init(young_rs, rem_set()); heap_rs = heap_rs.last_part(gen_policy()->young_gen_spec()->max_size()); ReservedSpace old_rs = heap_rs.first_part(gen_policy()->old_gen_spec()->max_size(), false, false); - _old_gen = gen_policy()->old_gen_spec()->init(old_rs, 1, rem_set()); + _old_gen = gen_policy()->old_gen_spec()->init(old_rs, rem_set()); heap_rs = heap_rs.last_part(gen_policy()->old_gen_spec()->max_size()); clear_incremental_collection_failed(); @@ -206,12 +206,8 @@ return _young_gen->used() + _old_gen->used(); } -// Save the "used_region" for generations level and lower. -void GenCollectedHeap::save_used_regions(int level) { - assert(level < _gen_policy->number_of_generations(), "Illegal level parameter"); - if (level == 1) { - _old_gen->save_used_region(); - } +void GenCollectedHeap::save_used_regions() { + _old_gen->save_used_region(); _young_gen->save_used_region(); } @@ -333,8 +329,16 @@ record_gen_tops_before_GC(); if (PrintGC && Verbose) { + // I didn't want to change the logging when removing the level concept, + // but I guess this logging could say young/old or something instead of 0/1. + int level; + if (gen == GenCollectedHeap::heap()->young_gen()) { + level = 0; + } else { + level = 1; + } gclog_or_tty->print("level=%d invoke=%d size=" SIZE_FORMAT, - gen->level(), + level, gen->stat_record()->invocations, size * HeapWordSize); } @@ -396,7 +400,7 @@ gen->stat_record()->accumulated_time.stop(); - update_gc_stats(gen->level(), full); + update_gc_stats(gen, full); if (run_verification && VerifyAfterGC) { HandleMark hm; // Discard invalid handles created during verification @@ -409,11 +413,11 @@ } } -void GenCollectedHeap::do_collection(bool full, - bool clear_all_soft_refs, - size_t size, - bool is_tlab, - int max_level) { +void GenCollectedHeap::do_collection(bool full, + bool clear_all_soft_refs, + size_t size, + bool is_tlab, + Generation::Type max_generation) { ResourceMark rm; DEBUG_ONLY(Thread* my_thread = Thread::current();) @@ -424,7 +428,6 @@ assert(Heap_lock->is_locked(), "the requesting thread should have the Heap_lock"); guarantee(!is_gc_active(), "collection is not reentrant"); - assert(max_level < n_gens(), "sanity check"); if (GC_locker::check_active_before_gc()) { return; // GC is disabled (e.g. JNI GetXXXCritical operation) @@ -442,7 +445,7 @@ { FlagSetting fl(_is_gc_active, true); - bool complete = full && (max_level == (n_gens()-1)); + bool complete = full && (max_generation == Generation::Old); const char* gc_cause_prefix = complete ? "Full GC" : "GC"; gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); @@ -455,6 +458,7 @@ size_t gch_prev_used = used(); bool must_restore_marks_for_biased_locking = false; + bool old_collected = false; bool run_verification = total_collections() >= VerifyGCStartAt; if (_young_gen->performs_in_place_marking() || @@ -466,7 +470,6 @@ } bool prepared_for_verification = false; - int max_level_collected = 0; if (!(full && _old_gen->full_collects_younger_generations()) && _young_gen->should_collect(full, size, is_tlab)) { if (run_verification && VerifyGCLevel <= 0 && VerifyBeforeGC) { @@ -475,7 +478,7 @@ } collect_generation(_young_gen, full, size, is_tlab, run_verification && VerifyGCLevel <= 0, do_clear_all_soft_refs); } - if (max_level == 1 && _old_gen->should_collect(full, size, is_tlab)) { + if (max_generation == Generation::Old && _old_gen->should_collect(full, size, is_tlab)) { if (!complete) { // The full_collections increment was missed above. increment_total_full_collections(); @@ -487,13 +490,13 @@ } } collect_generation(_old_gen, full, size, is_tlab, run_verification && VerifyGCLevel <= 1, do_clear_all_soft_refs); - max_level_collected = 1; + old_collected = true; } // Update "complete" boolean wrt what actually transpired -- // for instance, a promotion failure could have led to // a whole heap collection. - complete = complete || (max_level_collected == n_gens() - 1); + complete = complete || old_collected; if (complete) { // We did a "major" collection // FIXME: See comment at pre_full_gc_dump call @@ -510,7 +513,7 @@ } // Adjust generation sizes. - if (max_level_collected == 1) { + if (old_collected) { _old_gen->compute_new_size(); } _young_gen->compute_new_size(); @@ -551,7 +554,7 @@ } void GenCollectedHeap:: -gen_process_roots(int level, +gen_process_roots(Generation::Type type, bool younger_gens_as_roots, bool activate_scope, SharedHeap::ScanningOption so, @@ -570,7 +573,7 @@ if (younger_gens_as_roots) { if (!_gen_process_roots_tasks->is_task_claimed(GCH_PS_younger_gens)) { - if (level == 1) { + if (type == Generation::Old) { not_older_gens->set_generation(_young_gen); _young_gen->oop_iterate(not_older_gens); } @@ -578,8 +581,8 @@ } } // When collection is parallel, all threads get to cooperate to do - // older-gen scanning. - if (level == 0) { + // old generation scanning. + if (type == Generation::Young) { older_gens->set_generation(_old_gen); rem_set()->younger_refs_iterate(_old_gen, older_gens); older_gens->reset_generation(); @@ -589,7 +592,7 @@ } void GenCollectedHeap:: -gen_process_roots(int level, +gen_process_roots(Generation::Type type, bool younger_gens_as_roots, bool activate_scope, SharedHeap::ScanningOption so, @@ -601,7 +604,7 @@ const bool is_adjust_phase = !only_strong_roots && !younger_gens_as_roots; bool is_moving_collection = false; - if (level == 0 || is_adjust_phase) { + if (type == Generation::Young || is_adjust_phase) { // young collections are always moving is_moving_collection = true; } @@ -609,7 +612,7 @@ MarkingCodeBlobClosure mark_code_closure(not_older_gens, is_moving_collection); CodeBlobClosure* code_closure = &mark_code_closure; - gen_process_roots(level, + gen_process_roots(type, younger_gens_as_roots, activate_scope, so, not_older_gens, only_strong_roots ? NULL : not_older_gens, @@ -628,10 +631,10 @@ #define GCH_SINCE_SAVE_MARKS_ITERATE_DEFN(OopClosureType, nv_suffix) \ void GenCollectedHeap:: \ -oop_since_save_marks_iterate(int level, \ +oop_since_save_marks_iterate(Generation::Type gen, \ OopClosureType* cur, \ OopClosureType* older) { \ - if (level == 0) { \ + if (gen == Generation::Young) { \ _young_gen->oop_since_save_marks_iterate##nv_suffix(cur); \ _old_gen->oop_since_save_marks_iterate##nv_suffix(older); \ } else { \ @@ -643,12 +646,9 @@ #undef GCH_SINCE_SAVE_MARKS_ITERATE_DEFN -bool GenCollectedHeap::no_allocs_since_save_marks(int level) { - if (level == 0) { - if (!_young_gen->no_allocs_since_save_marks()) return false; - } - if (!_old_gen->no_allocs_since_save_marks()) return false; - return true; +bool GenCollectedHeap::no_allocs_since_save_marks(bool include_young) { + return include_young && _young_gen->no_allocs_since_save_marks() || + _old_gen->no_allocs_since_save_marks(); } bool GenCollectedHeap::supports_inline_contig_alloc() const { @@ -675,47 +675,47 @@ #endif // INCLUDE_ALL_GCS } else if (cause == GCCause::_wb_young_gc) { // minor collection for WhiteBox API - collect(cause, 0); + collect(cause, Generation::Young); } else { #ifdef ASSERT - if (cause == GCCause::_scavenge_alot) { - // minor collection only - collect(cause, 0); - } else { - // Stop-the-world full collection - collect(cause, n_gens() - 1); - } + if (cause == GCCause::_scavenge_alot) { + // minor collection only + collect(cause, Generation::Young); + } else { + // Stop-the-world full collection + collect(cause, Generation::Old); + } #else // Stop-the-world full collection - collect(cause, n_gens() - 1); + collect(cause, Generation::Old); #endif } } -void GenCollectedHeap::collect(GCCause::Cause cause, int max_level) { +void GenCollectedHeap::collect(GCCause::Cause cause, Generation::Type max_gen) { // The caller doesn't have the Heap_lock assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock"); MutexLocker ml(Heap_lock); - collect_locked(cause, max_level); + collect_locked(cause, max_gen); } void GenCollectedHeap::collect_locked(GCCause::Cause cause) { // The caller has the Heap_lock assert(Heap_lock->owned_by_self(), "this thread should own the Heap_lock"); - collect_locked(cause, n_gens() - 1); + collect_locked(cause, Generation::Old); } // this is the private collection interface // The Heap_lock is expected to be held on entry. -void GenCollectedHeap::collect_locked(GCCause::Cause cause, int max_level) { +void GenCollectedHeap::collect_locked(GCCause::Cause cause, Generation::Type max_generation) { // Read the GC count while holding the Heap_lock unsigned int gc_count_before = total_collections(); unsigned int full_gc_count_before = total_full_collections(); { MutexUnlocker mu(Heap_lock); // give up heap lock, execute gets it back VM_GenCollectFull op(gc_count_before, full_gc_count_before, - cause, max_level); + cause, max_generation); VMThread::execute(&op); } } @@ -758,28 +758,28 @@ #endif // INCLUDE_ALL_GCS void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs) { - do_full_collection(clear_all_soft_refs, _gen_policy->number_of_generations() - 1); + do_full_collection(clear_all_soft_refs, Generation::Old); } void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs, - int max_level) { - int local_max_level; + Generation::Type max_gen) { + Generation::Type local_max_gen; if (!incremental_collection_will_fail(false /* don't consult_young */) && gc_cause() == GCCause::_gc_locker) { - local_max_level = 0; + local_max_gen = Generation::Young; } else { - local_max_level = max_level; + local_max_gen = max_gen; } do_collection(true /* full */, clear_all_soft_refs /* clear_all_soft_refs */, 0 /* size */, false /* is_tlab */, - local_max_level /* max_level */); + local_max_gen /* max_gen */); // Hack XXX FIX ME !!! // A scavenge may not have been attempted, or may have // been attempted and failed, because the old gen was too full - if (local_max_level == 0 && gc_cause() == GCCause::_gc_locker && + if (local_max_gen == Generation::Young && gc_cause() == GCCause::_gc_locker && incremental_collection_will_fail(false /* don't consult_young */)) { if (PrintGCDetails) { gclog_or_tty->print_cr("GC locker: Trying a full collection " @@ -790,7 +790,7 @@ clear_all_soft_refs /* clear_all_soft_refs */, 0 /* size */, false /* is_tlab */, - n_gens() - 1 /* max_level */); + Generation::Old /* max_gen */); } } @@ -1198,7 +1198,7 @@ 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"); + guarantee(old_gen == _old_gen, "We only get here with an old generation"); assert(obj_size == (size_t)obj->size(), "bad obj_size passed in"); HeapWord* result = NULL; --- old/src/share/vm/memory/genCollectedHeap.hpp 2014-10-17 16:10:03.000000000 +0200 +++ new/src/share/vm/memory/genCollectedHeap.hpp 2014-10-17 16:10:03.000000000 +0200 @@ -91,11 +91,11 @@ // Helper function for two callbacks below. // Considers collection of the first max_level+1 generations. - void do_collection(bool full, - bool clear_all_soft_refs, - size_t size, - bool is_tlab, - int max_level); + void do_collection(bool full, + bool clear_all_soft_refs, + size_t size, + bool is_tlab, + Generation::Type max_generation); // Callback from VM_GenCollectForAllocation operation. // This function does everything necessary/possible to satisfy an @@ -106,7 +106,7 @@ // Callback from VM_GenCollectFull operation. // Perform a full collection of the first max_level+1 generations. virtual void do_full_collection(bool clear_all_soft_refs); - void do_full_collection(bool clear_all_soft_refs, int max_level); + void do_full_collection(bool clear_all_soft_refs, Generation::Type max_gen); // Does the "cause" of GC indicate that // we absolutely __must__ clear soft refs? @@ -115,7 +115,7 @@ public: GenCollectedHeap(GenCollectorPolicy *policy); - GCStats* gc_stats(int level) const; + GCStats* gc_stats(Generation* gen) const; // Returns JNI_OK on success virtual jint initialize(); @@ -155,8 +155,8 @@ size_t capacity() const; size_t used() const; - // Save the "used_region" for generations level and lower. - void save_used_regions(int level); + // Save the "used_region" for both generations. + void save_used_regions(); size_t max_capacity() const; @@ -180,9 +180,9 @@ // The same as above but assume that the caller holds the Heap_lock. void collect_locked(GCCause::Cause cause); - // Perform a full collection of the first max_level+1 generations. + // Perform a full collection of generations up to and including max_gen. // Mostly used for testing purposes. Caller does not hold the Heap_lock on entry. - void collect(GCCause::Cause cause, int max_level); + void collect(GCCause::Cause cause, Generation::Type max_gen); // Returns "TRUE" iff "p" points into the committed areas of the heap. // The methods is_in(), is_in_closed_subset() and is_in_youngest() may @@ -316,10 +316,8 @@ } // Update the gc statistics for each generation. - // "level" is the level of the latest collection. - void update_gc_stats(int current_level, bool full) { - _young_gen->update_gc_stats(current_level, full); - _old_gen->update_gc_stats(current_level, full); + void update_gc_stats(Generation* current_generation, bool full) { + _old_gen->update_gc_stats(current_generation, full); } // Override. @@ -368,8 +366,8 @@ void set_par_threads(uint t); // Invoke the "do_oop" method of one of the closures "not_older_gens" - // or "older_gens" on root locations for the generation at - // "level". (The "older_gens" closure is used for scanning references + // or "older_gens" on root locations for the generations depending on + // the type. (The "older_gens" closure is used for scanning references // from older generations; "not_older_gens" is used everywhere else.) // If "younger_gens_as_roots" is false, younger generations are // not scanned as roots; in this case, the caller must be arranging to @@ -380,7 +378,7 @@ // the closure is applied to: // "SO_None" does none; private: - void gen_process_roots(int level, + void gen_process_roots(Generation::Type type, bool younger_gens_as_roots, bool activate_scope, SharedHeap::ScanningOption so, @@ -395,7 +393,7 @@ static const bool StrongAndWeakRoots = false; static const bool StrongRootsOnly = true; - void gen_process_roots(int level, + void gen_process_roots(Generation::Type type, bool younger_gens_as_roots, bool activate_scope, SharedHeap::ScanningOption so, @@ -420,7 +418,7 @@ // applied to references in the generation at "level", and the "older" // closure to older generations. #define GCH_SINCE_SAVE_MARKS_ITERATE_DECL(OopClosureType, nv_suffix) \ - void oop_since_save_marks_iterate(int level, \ + void oop_since_save_marks_iterate(Generation::Type start_gen, \ OopClosureType* cur, \ OopClosureType* older); @@ -428,21 +426,17 @@ #undef GCH_SINCE_SAVE_MARKS_ITERATE_DECL - // Returns "true" iff no allocations have occurred in any generation at - // "level" or above since the last + // Returns "true" iff no allocations have occurred since the last // call to "save_marks". - bool no_allocs_since_save_marks(int level); + bool no_allocs_since_save_marks(bool include_young); // Returns true if an incremental collection is likely to fail. // We optionally consult the young gen, if asked to do so; // otherwise we base our answer on whether the previous incremental // collection attempt failed with no corrective action as of yet. bool incremental_collection_will_fail(bool consult_young) { - // Assumes a 2-generation system; the first disjunct remembers if an - // incremental collection failed, even when we thought (second disjunct) - // that it would not. - assert(heap()->collector_policy()->is_generation_policy(), - "the following definition may not be suitable for an n(>2)-generation system"); + // The first disjunct remembers if an incremental collection failed, even + // when we thought (second disjunct) that it would not. return incremental_collection_failed() || (consult_young && !_young_gen->collection_attempt_is_safe()); } @@ -482,10 +476,10 @@ // iterating over spaces. void prepare_for_compaction(); - // Perform a full collection of the first max_level+1 generations. + // Perform a full collection of the generations up to and including max_gen. // This is the low level interface used by the public versions of // collect() and collect_locked(). Caller holds the Heap_lock on entry. - void collect_locked(GCCause::Cause cause, int max_level); + void collect_locked(GCCause::Cause cause, Generation::Type max_gen); // Returns success or failure. bool create_cms_collector(); --- old/src/share/vm/memory/genMarkSweep.cpp 2014-10-17 16:10:03.000000000 +0200 +++ new/src/share/vm/memory/genMarkSweep.cpp 2014-10-17 16:10:03.000000000 +0200 @@ -37,6 +37,7 @@ #include "memory/genCollectedHeap.hpp" #include "memory/genMarkSweep.hpp" #include "memory/genOopClosures.inline.hpp" +#include "memory/generation.hpp" #include "memory/generation.inline.hpp" #include "memory/modRefBarrierSet.hpp" #include "memory/referencePolicy.hpp" @@ -52,8 +53,7 @@ #include "utilities/copy.hpp" #include "utilities/events.hpp" -void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, bool clear_all_softrefs) { - guarantee(level == 1, "We always collect both old and young."); +void GenMarkSweep::invoke_at_safepoint(ReferenceProcessor* rp, bool clear_all_softrefs) { assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); GenCollectedHeap* gch = GenCollectedHeap::heap(); @@ -86,11 +86,11 @@ // 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). - gch->save_used_regions(level); + gch->save_used_regions(); allocate_stacks(); - mark_sweep_phase1(level, clear_all_softrefs); + mark_sweep_phase1(clear_all_softrefs); mark_sweep_phase2(); @@ -98,7 +98,7 @@ COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity")); COMPILER2_PRESENT(DerivedPointerTable::set_active(false)); - mark_sweep_phase3(level); + mark_sweep_phase3(); mark_sweep_phase4(); @@ -110,20 +110,14 @@ deallocate_stacks(); - // If compaction completely evacuated all generations younger than this - // one, then we can clear the card table. Otherwise, we must invalidate - // it (consider all cards dirty). In the future, we might consider doing - // compaction within generations only, and doing card-table sliding. - bool all_empty = true; - if (level == 1) { - all_empty = gch->young_gen()->used() == 0; - } - + // If compaction completely evacuated the young generation we can clear + // the card table. Otherwise, we must invalidate it (consider all cards dirty). + // In the future, we might consider doing compaction within generations only, + // and doing card-table sliding. GenRemSet* rs = gch->rem_set(); - assert(level == 1, "Code will break if this isn't true."); Generation* old_gen = gch->old_gen(); // Clear/invalidate below make use of the "prev_used_regions" saved earlier. - if (all_empty) { + if (gch->young_gen()->used() == 0) { // We've evacuated all generations below us. rs->clear_into_younger(old_gen); } else { @@ -189,8 +183,7 @@ _objarray_stack.clear(true); } -void GenMarkSweep::mark_sweep_phase1(int level, - bool clear_all_softrefs) { +void GenMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) { // Recursively traverse all live objects and mark them GCTraceTime tm("phase 1", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id()); trace(" 1"); @@ -201,13 +194,12 @@ // use OopsInGenClosure constructor which takes a generation, // as the Universe has not been created when the static constructors // are run. - assert(level == 1, "We don't use mark-sweep on young generations"); follow_root_closure.set_orig_generation(gch->old_gen()); // Need new claim bits before marking starts. ClassLoaderDataGraph::clear_claimed_marks(); - gch->gen_process_roots(level, + gch->gen_process_roots(Generation::Old, false, // Younger gens are not roots. true, // activate StrongRootsScope SharedHeap::SO_None, @@ -276,7 +268,7 @@ } }; -void GenMarkSweep::mark_sweep_phase3(int level) { +void GenMarkSweep::mark_sweep_phase3() { GenCollectedHeap* gch = GenCollectedHeap::heap(); // Adjust the pointers to reflect the new locations @@ -290,10 +282,9 @@ // use OopsInGenClosure constructor which takes a generation, // as the Universe has not been created when the static constructors // are run. - assert(level == 1, "We don't use mark-sweep on young generations."); adjust_pointer_closure.set_orig_generation(gch->old_gen()); - gch->gen_process_roots(level, + gch->gen_process_roots(Generation::Old, false, // Younger gens are not roots. true, // activate StrongRootsScope SharedHeap::SO_AllCodeCache, --- old/src/share/vm/memory/genMarkSweep.hpp 2014-10-17 16:10:04.000000000 +0200 +++ new/src/share/vm/memory/genMarkSweep.hpp 2014-10-17 16:10:04.000000000 +0200 @@ -31,17 +31,16 @@ friend class VM_MarkSweep; friend class G1MarkSweep; public: - static void invoke_at_safepoint(int level, ReferenceProcessor* rp, - bool clear_all_softrefs); + static void invoke_at_safepoint(ReferenceProcessor* rp, bool clear_all_softrefs); private: // Mark live objects - static void mark_sweep_phase1(int level, bool clear_all_softrefs); + static void mark_sweep_phase1(bool clear_all_softrefs); // Calculate new addresses static void mark_sweep_phase2(); // Update pointers - static void mark_sweep_phase3(int level); + static void mark_sweep_phase3(); // Move objects to new positions static void mark_sweep_phase4(); --- old/src/share/vm/memory/generation.cpp 2014-10-17 16:10:05.000000000 +0200 +++ new/src/share/vm/memory/generation.cpp 2014-10-17 16:10:05.000000000 +0200 @@ -45,8 +45,7 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC -Generation::Generation(ReservedSpace rs, size_t initial_size, int level) : - _level(level), +Generation::Generation(ReservedSpace rs, size_t initial_size) : _ref_processor(NULL) { if (!_virtual_space.initialize(rs, initial_size)) { vm_exit_during_initialization("Could not reserve enough space for " @@ -63,9 +62,11 @@ } GenerationSpec* Generation::spec() { - GenCollectorPolicy* gcp = GenCollectedHeap::heap()->gen_policy(); - assert(0 <= level() && level() < gcp->number_of_generations(), "Bad gen level"); - return level() == 0 ? gcp->young_gen_spec() : gcp->old_gen_spec(); + GenCollectedHeap* gch = GenCollectedHeap::heap(); + if (this == gch->young_gen()) { + return gch->gen_policy()->young_gen_spec(); + } + return gch->gen_policy()->old_gen_spec(); } size_t Generation::max_capacity() const { @@ -114,9 +115,17 @@ void Generation::print_summary_info_on(outputStream* st) { StatRecord* sr = stat_record(); double time = sr->accumulated_time.seconds(); + // I didn't want to change the logging when removing the level concept, + // but I guess this logging could say young/old or something instead of 0/1. + int level; + if (this == GenCollectedHeap::heap()->young_gen()) { + level = 0; + } else { + level = 1; + } st->print_cr("[Accumulated GC generation %d time %3.7f secs, " "%d GC's, avg GC time %3.7f]", - level(), time, sr->invocations, + level, time, sr->invocations, sr->invocations > 0 ? time / sr->invocations : 0.0); } @@ -159,25 +168,14 @@ return (DefNewGeneration*) this; } -Generation* Generation::next_gen() const { - GenCollectedHeap* gch = GenCollectedHeap::heap(); - if (level() == 0) { - return gch->old_gen(); - } else { - return NULL; - } -} - size_t Generation::max_contiguous_available() const { // The largest number of contiguous free words in this or any higher generation. - size_t max = 0; - for (const Generation* gen = this; gen != NULL; gen = gen->next_gen()) { - size_t avail = gen->contiguous_available(); - if (avail > max) { - max = avail; - } + size_t avail = contiguous_available(); + size_t old_avail = 0; + if (this == GenCollectedHeap::heap()->young_gen()) { + old_avail = GenCollectedHeap::heap()->old_gen()->contiguous_available(); } - return max; + return MAX2(avail, old_avail); } bool Generation::promotion_attempt_is_safe(size_t max_promotion_in_bytes) const { @@ -376,9 +374,8 @@ } CardGeneration::CardGeneration(ReservedSpace rs, size_t initial_byte_size, - int level, GenRemSet* remset) : - Generation(rs, initial_byte_size, level), _rs(remset), + Generation(rs, initial_byte_size), _rs(remset), _shrink_factor(0), _min_heap_delta_bytes(), _capacity_at_prologue(), _used_at_prologue() { @@ -634,7 +631,7 @@ SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer(); gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start()); - GenMarkSweep::invoke_at_safepoint(_level, ref_processor(), clear_all_soft_refs); + GenMarkSweep::invoke_at_safepoint(ref_processor(), clear_all_soft_refs); gc_timer->register_gc_end(); --- old/src/share/vm/memory/generation.hpp 2014-10-17 16:10:05.000000000 +0200 +++ new/src/share/vm/memory/generation.hpp 2014-10-17 16:10:05.000000000 +0200 @@ -102,9 +102,6 @@ // Memory area reserved for generation VirtualSpace _virtual_space; - // Level in the generation hierarchy. - int _level; - // ("Weak") Reference processing support ReferenceProcessor* _ref_processor; @@ -114,12 +111,8 @@ // Statistics for garbage collection GCStats* _gc_stats; - // Returns the next generation in the configuration, or else NULL if this - // is the highest generation. - Generation* next_gen() const; - // Initialize the generation. - Generation(ReservedSpace rs, size_t initial_byte_size, int level); + Generation(ReservedSpace rs, size_t initial_byte_size); // Apply "cl->do_oop" to (the address of) (exactly) all the ref fields in // "sp" that point into younger generations. @@ -138,6 +131,11 @@ Other }; + enum Type { + Young, + Old + }; + enum SomePublicConstants { // Generations are GenGrain-aligned and have size that are multiples of // GenGrain. @@ -438,7 +436,7 @@ // generation can decide to gather the amount of promoted data // if the collection of the younger generations has completed. GCStats* gc_stats() const { return _gc_stats; } - virtual void update_gc_stats(int current_level, bool full) {} + virtual void update_gc_stats(Generation* current_generation, bool full) {} // Mark sweep support phase2 virtual void prepare_for_compaction(CompactPoint* cp); @@ -523,8 +521,6 @@ virtual const char* name() const = 0; virtual const char* short_name() const = 0; - int level() const { return _level; } - // Attributes // True iff the given generation may only be the youngest generation. @@ -638,8 +634,7 @@ size_t _capacity_at_prologue; size_t _used_at_prologue; - CardGeneration(ReservedSpace rs, size_t initial_byte_size, int level, - GenRemSet* remset); + CardGeneration(ReservedSpace rs, size_t initial_byte_size, GenRemSet* remset); public: @@ -696,9 +691,8 @@ public: OneContigSpaceCardGeneration(ReservedSpace rs, size_t initial_byte_size, - int level, GenRemSet* remset, - ContiguousSpace* space) : - CardGeneration(rs, initial_byte_size, level, remset), + GenRemSet* remset, ContiguousSpace* space) : + CardGeneration(rs, initial_byte_size, remset), _the_space(space) {} --- old/src/share/vm/memory/generationSpec.cpp 2014-10-17 16:10:06.000000000 +0200 +++ new/src/share/vm/memory/generationSpec.cpp 2014-10-17 16:10:06.000000000 +0200 @@ -36,18 +36,17 @@ #include "gc_implementation/parNew/parNewGeneration.hpp" #endif // INCLUDE_ALL_GCS -Generation* GenerationSpec::init(ReservedSpace rs, int level, - GenRemSet* remset) { +Generation* GenerationSpec::init(ReservedSpace rs, GenRemSet* remset) { switch (name()) { case Generation::DefNew: - return new DefNewGeneration(rs, init_size(), level); + return new DefNewGeneration(rs, init_size()); case Generation::MarkSweepCompact: - return new TenuredGeneration(rs, init_size(), level, remset); + return new TenuredGeneration(rs, init_size(), remset); #if INCLUDE_ALL_GCS case Generation::ParNew: - return new ParNewGeneration(rs, init_size(), level); + return new ParNewGeneration(rs, init_size()); case Generation::ConcurrentMarkSweep: { assert(UseConcMarkSweepGC, "UseConcMarkSweepGC should be set"); @@ -61,7 +60,7 @@ ConcurrentMarkSweepGeneration* g = NULL; g = new ConcurrentMarkSweepGeneration(rs, - init_size(), level, ctrs, UseCMSAdaptiveFreeLists, + init_size(), ctrs, UseCMSAdaptiveFreeLists, (FreeBlockDictionary::DictionaryChoice)CMSDictionaryChoice); g->initialize_performance_counters(); --- old/src/share/vm/memory/generationSpec.hpp 2014-10-17 16:10:07.000000000 +0200 +++ new/src/share/vm/memory/generationSpec.hpp 2014-10-17 16:10:07.000000000 +0200 @@ -45,7 +45,7 @@ _max_size = align_size_up(max_size, alignment); } - Generation* init(ReservedSpace rs, int level, GenRemSet* remset); + Generation* init(ReservedSpace rs, GenRemSet* remset); // Accessors Generation::Name name() const { return _name; } --- old/src/share/vm/memory/tenuredGeneration.cpp 2014-10-17 16:10:07.000000000 +0200 +++ new/src/share/vm/memory/tenuredGeneration.cpp 2014-10-17 16:10:07.000000000 +0200 @@ -36,10 +36,9 @@ #include "utilities/macros.hpp" TenuredGeneration::TenuredGeneration(ReservedSpace rs, - size_t initial_byte_size, int level, + size_t initial_byte_size, GenRemSet* remset) : - OneContigSpaceCardGeneration(rs, initial_byte_size, - level, remset, NULL) + OneContigSpaceCardGeneration(rs, initial_byte_size, remset, NULL) { HeapWord* bottom = (HeapWord*) _virtual_space.low(); HeapWord* end = (HeapWord*) _virtual_space.high(); @@ -171,11 +170,13 @@ err_msg("used: " SIZE_FORMAT " used_after_gc: " SIZE_FORMAT " capacity: " SIZE_FORMAT, used(), used_after_gc, capacity())); } -void TenuredGeneration::update_gc_stats(int current_level, + +void TenuredGeneration::update_gc_stats(Generation* current_generation, bool full) { - // If the next lower level(s) has been collected, gather any statistics + // If the young generation has been collected, gather any statistics // that are of interest at this point. - if (!full && (current_level + 1) == level()) { + bool current_is_young = (current_generation == GenCollectedHeap::heap()->young_gen()); + if (!full && current_is_young) { // Calculate size of data promoted from the younger generations // before doing the collection. size_t used_before_gc = used(); --- old/src/share/vm/memory/tenuredGeneration.hpp 2014-10-17 16:10:08.000000000 +0200 +++ new/src/share/vm/memory/tenuredGeneration.hpp 2014-10-17 16:10:08.000000000 +0200 @@ -53,7 +53,7 @@ CSpaceCounters* _space_counters; public: - TenuredGeneration(ReservedSpace rs, size_t initial_byte_size, int level, + TenuredGeneration(ReservedSpace rs, size_t initial_byte_size, GenRemSet* remset); Generation::Name kind() { return Generation::MarkSweepCompact; } @@ -98,7 +98,7 @@ // Statistics - virtual void update_gc_stats(int level, bool full); + virtual void update_gc_stats(Generation* current_generation, bool full); virtual bool promotion_attempt_is_safe(size_t max_promoted_in_bytes) const; --- old/src/share/vm/runtime/vmStructs.cpp 2014-10-17 16:10:09.000000000 +0200 +++ new/src/share/vm/runtime/vmStructs.cpp 2014-10-17 16:10:09.000000000 +0200 @@ -534,7 +534,6 @@ \ nonstatic_field(Generation, _reserved, MemRegion) \ nonstatic_field(Generation, _virtual_space, VirtualSpace) \ - nonstatic_field(Generation, _level, int) \ nonstatic_field(Generation, _stat_record, Generation::StatRecord) \ \ nonstatic_field(Generation::StatRecord, invocations, int) \