--- old/agent/src/share/classes/sun/jvm/hotspot/gc/shared/Generation.java 2015-06-02 19:27:59.000000000 +0200 +++ new/agent/src/share/classes/sun/jvm/hotspot/gc/shared/Generation.java 2015-06-02 19:27:59.000000000 +0200 @@ -49,7 +49,6 @@ public abstract class Generation extends VMObject { private static long reservedFieldOffset; private static long virtualSpaceFieldOffset; - private static CIntegerField levelField; protected static final int K = 1024; // Fields for class StatRecord private static Field statRecordField; @@ -75,7 +74,6 @@ reservedFieldOffset = type.getField("_reserved").getOffset(); virtualSpaceFieldOffset = type.getField("_virtual_space").getOffset(); - levelField = type.getCIntegerField("_level"); // StatRecord statRecordField = type.getField("_stat_record"); type = db.lookupType("Generation::StatRecord"); @@ -130,14 +128,6 @@ } } - public GenerationSpec spec() { - return ((GenCollectedHeap) VM.getVM().getUniverse().heap()).spec(level()); - } - - public int level() { - return (int) levelField.getValue(addr); - } - public int invocations() { return getStatRecord().getInvocations(); } --- old/agent/src/share/classes/sun/jvm/hotspot/utilities/PointerLocation.java 2015-06-02 19:28:00.000000000 +0200 +++ new/agent/src/share/classes/sun/jvm/hotspot/utilities/PointerLocation.java 2015-06-02 19:28:00.000000000 +0200 @@ -84,11 +84,11 @@ } public boolean isInNewGen() { - return ((gen != null) && (gen.level() == 0)); + return ((gen != null) && (gen == ((GenCollectedHeap)heap).getGen(0))); } public boolean isInOldGen() { - return ((gen != null) && (gen.level() == 1)); + return ((gen != null) && (gen == ((GenCollectedHeap)heap).getGen(1))); } public boolean inOtherGen() { @@ -207,8 +207,6 @@ tty.print("In new generation "); } else if (isInOldGen()) { tty.print("In old generation "); - } else if (gen != null) { - tty.print("In Generation " + getGeneration().level()); } else { tty.print("In unknown section of Java heap"); } --- old/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp 2015-06-02 19:28:01.000000000 +0200 +++ new/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp 2015-06-02 19:28:01.000000000 +0200 @@ -190,10 +190,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()))), _did_compact(false) { @@ -682,12 +682,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(gch->is_old_gen(this), + "The CMS generation should be the old generation"); + uint level = 1; if (Verbose) { - gclog_or_tty->print("[%d %s-%s: "SIZE_FORMAT"("SIZE_FORMAT")]", - level(), short_name(), s, used(), capacity()); + gclog_or_tty->print("[%u %s-%s: "SIZE_FORMAT"("SIZE_FORMAT")]", + 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); + gclog_or_tty->print("[%u %s-%s: "SIZE_FORMAT"K("SIZE_FORMAT"K)]", + level, short_name(), s, used() / K, capacity() / K); } } if (Verbose) { @@ -797,27 +802,22 @@ 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); + 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(gch->is_old_gen(this), "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_for_gc_cause(expand_bytes, 0, CMSExpansionCause::_satisfy_free_ratio); @@ -1650,8 +1650,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(); @@ -2432,7 +2431,7 @@ StrongRootsScope srs(1); gch->gen_process_roots(&srs, - _cmsGen->level(), + Generation::Old, true, // younger gens are roots GenCollectedHeap::ScanningOption(roots_scanning_options()), should_unload_classes(), @@ -2504,7 +2503,7 @@ StrongRootsScope srs(1); gch->gen_process_roots(&srs, - _cmsGen->level(), + Generation::Old, true, // younger gens are roots GenCollectedHeap::ScanningOption(roots_scanning_options()), should_unload_classes(), @@ -3031,7 +3030,7 @@ StrongRootsScope srs(1); gch->gen_process_roots(&srs, - _cmsGen->level(), + Generation::Old, true, // younger gens are roots GenCollectedHeap::ScanningOption(roots_scanning_options()), should_unload_classes(), @@ -4282,15 +4281,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(), @@ -4464,7 +4460,7 @@ CLDToOopClosure cld_closure(&par_mri_cl, true); gch->gen_process_roots(_strong_roots_scope, - _collector->_cmsGen->level(), + Generation::Old, false, // yg was scanned above GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()), _collector->should_unload_classes(), @@ -4603,7 +4599,7 @@ _timer.reset(); _timer.start(); gch->gen_process_roots(_strong_roots_scope, - _collector->_cmsGen->level(), + Generation::Old, false, // yg was scanned above GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()), _collector->should_unload_classes(), @@ -5184,7 +5180,7 @@ StrongRootsScope srs(1); gch->gen_process_roots(&srs, - _cmsGen->level(), + Generation::Old, true, // younger gens as roots GenCollectedHeap::ScanningOption(roots_scanning_options()), should_unload_classes(), @@ -5648,11 +5644,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 = GenCollectedHeap::heap()->is_young_gen(current_generation); + if (!full && current_is_young) { // Gather statistics on the young generation collection. collector()->stats().record_gc0_end(used()); } --- old/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp 2015-06-02 19:28:02.000000000 +0200 +++ new/src/share/vm/gc/cms/concurrentMarkSweepGeneration.hpp 2015-06-02 19:28:02.000000000 +0200 @@ -1063,7 +1063,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. @@ -1079,7 +1079,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/cms/parNewGeneration.cpp 2015-06-02 19:28:03.000000000 +0200 +++ new/src/share/vm/gc/cms/parNewGeneration.cpp 2015-06-02 19:28:03.000000000 +0200 @@ -62,25 +62,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) { @@ -481,7 +481,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(); } @@ -566,11 +565,11 @@ 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, StrongRootsScope* strong_roots_scope) : 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), _strong_roots_scope(strong_roots_scope) @@ -596,7 +595,7 @@ par_scan_state.start_strong_roots(); gch->gen_process_roots(_strong_roots_scope, - _gen->level(), + Generation::Young, true, // Process younger gens, if any, // as strong roots. GenCollectedHeap::SO_ScavengeCodeCache, @@ -616,8 +615,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) @@ -752,7 +751,7 @@ private: virtual void work(uint worker_id); private: - ParNewGeneration& _gen; + ParNewGeneration& _young_gen; ProcessTask& _task; Generation& _old_gen; HeapWord* _young_old_boundary; @@ -760,12 +759,12 @@ }; ParNewRefProcTaskProxy::ParNewRefProcTaskProxy(ProcessTask& task, - ParNewGeneration& gen, + 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), @@ -806,12 +805,12 @@ GenCollectedHeap* gch = GenCollectedHeap::heap(); 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(), - _generation.reserved().end(), _state_set); + _state_set.reset(workers->active_workers(), _young_gen.promotion_failed()); + ParNewRefProcTaskProxy rp_task(task, _young_gen, _old_gen, + _young_gen.reserved().end(), _state_set); workers->run_task(&rp_task); _state_set.reset(0 /* bad value in debug if not reset */, - _generation.promotion_failed()); + _young_gen.promotion_failed()); } void ParNewRefProcTaskExecutor::execute(EnqueueTask& task) @@ -835,10 +834,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) {} @@ -846,10 +845,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 */)); } @@ -972,14 +971,14 @@ 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)? rp->set_active_mt_degree(active_workers); ReferenceProcessorStats stats; if (rp->processing_is_mt()) { - ParNewRefProcTaskExecutor task_executor(*this, thread_state_set); + ParNewRefProcTaskExecutor task_executor(*this, *_old_gen, thread_state_set); stats = rp->process_discovered_references(&is_alive, &keep_alive, &evacuate_followers, &task_executor, _gc_timer, _gc_tracer.gc_id()); @@ -1045,7 +1044,7 @@ rp->set_enqueuing_is_done(true); if (rp->processing_is_mt()) { - ParNewRefProcTaskExecutor task_executor(*this, thread_state_set); + ParNewRefProcTaskExecutor task_executor(*this, *_old_gen, thread_state_set); rp->enqueue_discovered_references(&task_executor); } else { rp->enqueue_discovered_references(NULL); --- old/src/share/vm/gc/cms/parNewGeneration.hpp 2015-06-02 19:28:03.000000000 +0200 +++ new/src/share/vm/gc/cms/parNewGeneration.hpp 2015-06-02 19:28:03.000000000 +0200 @@ -234,14 +234,14 @@ class ParNewGenTask: public AbstractGangTask { private: - ParNewGeneration* _gen; + ParNewGeneration* _young_gen; Generation* _old_gen; HeapWord* _young_old_boundary; class ParScanThreadStateSet* _state_set; StrongRootsScope* _strong_roots_scope; 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(); @@ -288,12 +287,14 @@ // Implements AbstractRefProcTaskExecutor for ParNew. class ParNewRefProcTaskExecutor: public AbstractRefProcTaskExecutor { private: - ParNewGeneration& _generation; + ParNewGeneration& _young_gen; + Generation& _old_gen; ParScanThreadStateSet& _state_set; public: - ParNewRefProcTaskExecutor(ParNewGeneration& generation, + ParNewRefProcTaskExecutor(ParNewGeneration& young_gen, + Generation& old_gen, ParScanThreadStateSet& state_set) - : _generation(generation), _state_set(state_set) + : _young_gen(young_gen), _old_gen(old_gen), _state_set(state_set) { } // Executes a task using worker threads. @@ -353,7 +354,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/cms/parOopClosures.inline.hpp 2015-06-02 19:28:04.000000000 +0200 +++ new/src/share/vm/gc/cms/parOopClosures.inline.hpp 2015-06-02 19:28:04.000000000 +0200 @@ -72,7 +72,7 @@ bool root_scan) { assert((!GenCollectedHeap::heap()->is_in_reserved(p) || generation()->is_in_reserved(p)) - && (generation()->level() == 0 || gc_barrier), + && (GenCollectedHeap::heap()->is_young_gen(generation()) || 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/cms/vmCMSOperations.cpp 2015-06-02 19:28:05.000000000 +0200 +++ new/src/share/vm/gc/cms/vmCMSOperations.cpp 2015-06-02 19:28:05.000000000 +0200 @@ -198,8 +198,7 @@ assert(SafepointSynchronize::is_at_safepoint(), "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 */); + gch->do_full_collection(gch->must_clear_all_soft_refs(), Generation::Young); } // 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/serial/defNewGeneration.cpp 2015-06-02 19:28:06.000000000 +0200 +++ new/src/share/vm/gc/serial/defNewGeneration.cpp 2015-06-02 19:28:05.000000000 +0200 @@ -58,11 +58,13 @@ // Methods of protected closure types. -DefNewGeneration::IsAliveClosure::IsAliveClosure(Generation* g) : _g(g) { - assert(g->level() == 0, "Optimized for youngest gen."); +DefNewGeneration::IsAliveClosure::IsAliveClosure(Generation* young_gen) : _young_gen(young_gen) { + assert(_young_gen->kind() == Generation::ParNew || + _young_gen->kind() == Generation::DefNew, "Expected the young generation here"); } + bool DefNewGeneration::IsAliveClosure::do_object_b(oop p) { - return (HeapWord*)p >= _g->reserved().end() || p->is_forwarded(); + return (HeapWord*)p >= _young_gen->reserved().end() || p->is_forwarded(); } DefNewGeneration::KeepAliveClosure:: @@ -85,39 +87,39 @@ void DefNewGeneration::FastKeepAliveClosure::do_oop(narrowOop* p) { DefNewGeneration::FastKeepAliveClosure::do_oop_work(p); } DefNewGeneration::EvacuateFollowersClosure:: -EvacuateFollowersClosure(GenCollectedHeap* gch, int level, - ScanClosure* cur, ScanClosure* older) : - _gch(gch), _level(level), - _scan_cur_or_nonheap(cur), _scan_older(older) +EvacuateFollowersClosure(GenCollectedHeap* gch, + ScanClosure* cur, + ScanClosure* 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, - DefNewGeneration* gen, - FastScanClosure* cur, FastScanClosure* older) : - _gch(gch), _level(level), _gen(gen), - _scan_cur_or_nonheap(cur), _scan_older(older) -{} +FastEvacuateFollowersClosure(GenCollectedHeap* gch, + FastScanClosure* cur, + FastScanClosure* older) : + _gch(gch), _scan_cur_or_nonheap(cur), _scan_older(older) +{ + assert(_gch->young_gen()->kind() == Generation::DefNew, "Generation should be DefNew"); + _gen = (DefNewGeneration*)_gch->young_gen(); +} void DefNewGeneration::FastEvacuateFollowersClosure::do_void() { do { - _gch->oop_since_save_marks_iterate(_level, _scan_cur_or_nonheap, - _scan_older); - } while (!_gch->no_allocs_since_save_marks(_level)); + _gch->oop_since_save_marks_iterate(Generation::Young, _scan_cur_or_nonheap, _scan_older); + } 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(); } @@ -127,7 +129,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(); } @@ -168,7 +169,6 @@ ScanWeakRefClosure::ScanWeakRefClosure(DefNewGeneration* g) : _g(g) { - assert(_g->level() == 0, "Optimized for youngest generation"); _boundary = _g->reserved().end(); } @@ -186,9 +186,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) { @@ -372,22 +371,18 @@ return success; } - void DefNewGeneration::compute_new_size() { - // This is called after a gc that includes the following generation - // (which is required to exist.) So from-space will normally be empty. + // This is called after a GC that includes the old generation, so from-space + // will normally be empty. // Note that we check both spaces, since if scavenge failed they revert roles. - // If not we bail out (otherwise we would have to relocate the objects) + // If not we bail out (otherwise we would have to relocate the objects). if (!from()->is_empty() || !to()->is_empty()) { return; } - int next_level = level() + 1; GenCollectedHeap* gch = GenCollectedHeap::heap(); - assert(next_level == 1, "DefNewGeneration must be a young 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(); @@ -603,7 +598,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. @@ -619,11 +614,11 @@ false); set_promo_failure_scan_stack_closure(&fsc_with_no_gc_barrier); - FastEvacuateFollowersClosure evacuate_followers(gch, _level, this, + FastEvacuateFollowersClosure evacuate_followers(gch, &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."); { @@ -633,7 +628,7 @@ StrongRootsScope srs(0); gch->gen_process_roots(&srs, - _level, + Generation::Young, true, // Process younger gens, if any, // as strong roots. GenCollectedHeap::SO_ScavengeCodeCache, @@ -870,8 +865,10 @@ 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"); + if (requestor == this || _promotion_failed) { + return; + } + assert(GenCollectedHeap::heap()->is_old_gen(requestor), "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/gc/serial/defNewGeneration.hpp 2015-06-02 19:28:07.000000000 +0200 +++ new/src/share/vm/gc/serial/defNewGeneration.hpp 2015-06-02 19:28:06.000000000 +0200 @@ -154,9 +154,9 @@ public: // was "protected" but caused compile error on win32 class IsAliveClosure: public BoolObjectClosure { - Generation* _g; + Generation* _young_gen; public: - IsAliveClosure(Generation* g); + IsAliveClosure(Generation* young_gen); bool do_object_b(oop p); }; @@ -183,31 +183,28 @@ 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, - DefNewGeneration* gen, + FastEvacuateFollowersClosure(GenCollectedHeap* gch, FastScanClosure* cur, FastScanClosure* older); void do_void(); }; 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/gc/serial/genMarkSweep.cpp 2015-06-02 19:28:07.000000000 +0200 +++ new/src/share/vm/gc/serial/genMarkSweep.cpp 2015-06-02 19:28:07.000000000 +0200 @@ -36,6 +36,7 @@ #include "gc/shared/gcTrace.hpp" #include "gc/shared/gcTraceTime.hpp" #include "gc/shared/genCollectedHeap.hpp" +#include "gc/shared/generation.hpp" #include "gc/shared/genOopClosures.inline.hpp" #include "gc/shared/modRefBarrierSet.hpp" #include "gc/shared/referencePolicy.hpp" @@ -53,8 +54,7 @@ #include "utilities/events.hpp" #include "utilities/stack.inline.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(); @@ -87,11 +87,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(); @@ -99,7 +99,7 @@ COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity")); COMPILER2_PRESENT(DerivedPointerTable::set_active(false)); - mark_sweep_phase3(level); + mark_sweep_phase3(); mark_sweep_phase4(); @@ -184,8 +184,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()); @@ -195,7 +194,6 @@ // 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. @@ -205,7 +203,7 @@ StrongRootsScope srs(1); gch->gen_process_roots(&srs, - level, + Generation::Old, false, // Younger gens are not roots. GenCollectedHeap::SO_None, GenCollectedHeap::StrongRootsOnly, @@ -273,7 +271,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 @@ -286,14 +284,13 @@ // 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()); { StrongRootsScope srs(1); gch->gen_process_roots(&srs, - level, + Generation::Old, false, // Younger gens are not roots. GenCollectedHeap::SO_AllCodeCache, GenCollectedHeap::StrongAndWeakRoots, --- old/src/share/vm/gc/serial/genMarkSweep.hpp 2015-06-02 19:28:08.000000000 +0200 +++ new/src/share/vm/gc/serial/genMarkSweep.hpp 2015-06-02 19:28:08.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/gc/serial/tenuredGeneration.cpp 2015-06-02 19:28:09.000000000 +0200 +++ new/src/share/vm/gc/serial/tenuredGeneration.cpp 2015-06-02 19:28:09.000000000 +0200 @@ -41,9 +41,9 @@ #endif TenuredGeneration::TenuredGeneration(ReservedSpace rs, - size_t initial_byte_size, int level, + size_t initial_byte_size, GenRemSet* remset) : - CardGeneration(rs, initial_byte_size, level, remset) + CardGeneration(rs, initial_byte_size, remset) { HeapWord* bottom = (HeapWord*) _virtual_space.low(); HeapWord* end = (HeapWord*) _virtual_space.high(); @@ -134,11 +134,12 @@ " 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 = GenCollectedHeap::heap()->is_young_gen(current_generation); + if (!full && current_is_young) { // Calculate size of data promoted from the younger generations // before doing the collection. size_t used_before_gc = used(); @@ -192,7 +193,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/gc/serial/tenuredGeneration.hpp 2015-06-02 19:28:09.000000000 +0200 +++ new/src/share/vm/gc/serial/tenuredGeneration.hpp 2015-06-02 19:28:09.000000000 +0200 @@ -55,8 +55,9 @@ void assert_correct_size_change_locking(); public: - TenuredGeneration(ReservedSpace rs, size_t initial_byte_size, - int level, GenRemSet* remset); + TenuredGeneration(ReservedSpace rs, + size_t initial_byte_size, + GenRemSet* remset); Generation::Name kind() { return Generation::MarkSweepCompact; } @@ -120,7 +121,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/gc/shared/cardGeneration.cpp 2015-06-02 19:28:10.000000000 +0200 +++ new/src/share/vm/gc/shared/cardGeneration.cpp 2015-06-02 19:28:10.000000000 +0200 @@ -35,10 +35,10 @@ #include "memory/memRegion.hpp" #include "runtime/java.hpp" -CardGeneration::CardGeneration(ReservedSpace rs, size_t initial_byte_size, - int level, +CardGeneration::CardGeneration(ReservedSpace rs, + size_t initial_byte_size, 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() { --- old/src/share/vm/gc/shared/cardGeneration.hpp 2015-06-02 19:28:11.000000000 +0200 +++ new/src/share/vm/gc/shared/cardGeneration.hpp 2015-06-02 19:28:11.000000000 +0200 @@ -52,8 +52,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); virtual void assert_correct_size_change_locking() = 0; --- old/src/share/vm/gc/shared/cardTableRS.cpp 2015-06-02 19:28:12.000000000 +0200 +++ new/src/share/vm/gc/shared/cardTableRS.cpp 2015-06-02 19:28:11.000000000 +0200 @@ -104,7 +104,9 @@ void CardTableRS::younger_refs_iterate(Generation* g, OopsInGenClosure* blk, uint n_threads) { - _last_cur_val_in_gen[g->level()+1] = cur_youngergen_card_val(); + // The indexing in this array is slightly odd. We want to access + // the old generation record here, which is at index 2. + _last_cur_val_in_gen[2] = cur_youngergen_card_val(); g->younger_refs_iterate(blk, n_threads); } @@ -300,7 +302,8 @@ } void CardTableRS::clear_into_younger(Generation* old_gen) { - assert(old_gen->level() == 1, "Should only be called for the old generation"); + assert(GenCollectedHeap::heap()->is_old_gen(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() @@ -311,7 +314,8 @@ } void CardTableRS::invalidate_or_clear(Generation* old_gen) { - assert(old_gen->level() == 1, "Should only be called for the old generation"); + assert(GenCollectedHeap::heap()->is_old_gen(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 @@ -377,7 +381,9 @@ VerifyCTGenClosure(CardTableRS* ct) : _ct(ct) {} void do_generation(Generation* gen) { // Skip the youngest generation. - if (gen->level() == 0) return; + if (GenCollectedHeap::heap()->is_young_gen(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/gc/shared/cardTableRS.hpp 2015-06-02 19:28:12.000000000 +0200 +++ new/src/share/vm/gc/shared/cardTableRS.hpp 2015-06-02 19:28:12.000000000 +0200 @@ -76,9 +76,8 @@ // An array that contains, for each generation, the card table value last // used as the current value for a younger_refs_do iteration of that - // portion of the table. (The perm gen is index 0; other gens are at - // their level plus 1. They youngest gen is in the table, but will - // always have the value "clean_card".) + // portion of the table. The perm gen is index 0. The young gen is index 1, + // but will always have the value "clean_card". The old gen is index 2. jbyte* _last_cur_val_in_gen; jbyte _cur_youngergen_card_val; --- old/src/share/vm/gc/shared/collectorPolicy.cpp 2015-06-02 19:28:13.000000000 +0200 +++ new/src/share/vm/gc/shared/collectorPolicy.cpp 2015-06-02 19:28:13.000000000 +0200 @@ -750,7 +750,7 @@ false /* clear_all_soft_refs */, size /* size */, is_tlab /* is_tlab */, - number_of_generations() - 1 /* max_level */); + Generation::Old /* max_generation */); } else { if (Verbose && PrintGCDetails) { gclog_or_tty->print(" :: Trying full because partial may fail :: "); @@ -763,7 +763,7 @@ false /* clear_all_soft_refs */, size /* size */, is_tlab /* is_tlab */, - number_of_generations() - 1 /* max_level */); + Generation::Old /* max_generation */); } result = gch->attempt_allocation(size, is_tlab, false /*first_only*/); @@ -791,7 +791,7 @@ true /* clear_all_soft_refs */, size /* size */, is_tlab /* is_tlab */, - number_of_generations() - 1 /* max_level */); + Generation::Old /* max_generation */); } result = gch->attempt_allocation(size, is_tlab, false /* first_only */); --- old/src/share/vm/gc/shared/collectorPolicy.hpp 2015-06-02 19:28:14.000000000 +0200 +++ new/src/share/vm/gc/shared/collectorPolicy.hpp 2015-06-02 19:28:14.000000000 +0200 @@ -261,8 +261,6 @@ size_t initial_old_size() { return _initial_old_size; } size_t max_old_size() { return _max_old_size; } - int number_of_generations() { return 2; } - GenerationSpec* young_gen_spec() const { assert(_young_gen_spec != NULL, "_young_gen_spec should have been initialized"); return _young_gen_spec; --- old/src/share/vm/gc/shared/genCollectedHeap.cpp 2015-06-02 19:28:14.000000000 +0200 +++ new/src/share/vm/gc/shared/genCollectedHeap.cpp 2015-06-02 19:28:14.000000000 +0200 @@ -127,11 +127,11 @@ set_barrier_set(rem_set()->bs()); 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()); clear_incremental_collection_failed(); #if INCLUDE_ALL_GCS @@ -202,12 +202,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 == 0 || level == 1, "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(); } @@ -330,8 +326,16 @@ record_gen_tops_before_GC(); if (PrintGC && Verbose) { - gclog_or_tty->print("level=%d invoke=%d size=" SIZE_FORMAT, - gen->level(), + // 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. + uint level; + if (GenCollectedHeap::heap()->is_young_gen(gen)) { + level = 0; + } else { + level = 1; + } + gclog_or_tty->print("level=%u invoke=%d size=" SIZE_FORMAT, + level, gen->stat_record()->invocations, size * HeapWordSize); } @@ -392,7 +396,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 @@ -405,11 +409,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();) @@ -437,7 +441,7 @@ { FlagSetting fl(_is_gc_active, true); - bool complete = full && (max_level == 1 /* old */); + bool complete = full && (max_generation == Generation::Old); const char* gc_cause_prefix = complete ? "Full GC" : "GC"; TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); // The PrintGCDetails logging starts before we have incremented the GC id. We will do that later @@ -451,9 +455,8 @@ bool run_verification = total_collections() >= VerifyGCStartAt; bool prepared_for_verification = false; - int max_level_collected = 0; - bool old_collects_young = (max_level == 1) && - full && + bool collected_old = false; + bool old_collects_young = complete && _old_gen->full_collects_younger_generations(); if (!old_collects_young && _young_gen->should_collect(full, size, is_tlab)) { @@ -480,7 +483,7 @@ bool must_restore_marks_for_biased_locking = false; - 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(); @@ -503,13 +506,13 @@ true); must_restore_marks_for_biased_locking = true; - max_level_collected = 1; + collected_old = 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 == 1 /* old */); + complete = complete || collected_old; if (complete) { // We did a "major" collection // FIXME: See comment at pre_full_gc_dump call @@ -526,7 +529,7 @@ } // Adjust generation sizes. - if (max_level_collected == 1 /* old */) { + if (collected_old) { _old_gen->compute_new_size(); } _young_gen->compute_new_size(); @@ -654,11 +657,10 @@ DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, !CodeBlobToOopClosure::FixRelocations)); DEBUG_ONLY(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable)); } - } void GenCollectedHeap::gen_process_roots(StrongRootsScope* scope, - int level, + Generation::Type type, bool younger_gens_as_roots, ScanningOption so, bool only_strong_roots, @@ -668,7 +670,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; } @@ -684,7 +686,7 @@ if (younger_gens_as_roots) { if (!_process_strong_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); } @@ -692,8 +694,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, scope->n_threads()); older_gens->reset_generation(); @@ -717,10 +719,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 { \ @@ -732,8 +734,8 @@ #undef GCH_SINCE_SAVE_MARKS_ITERATE_DEFN -bool GenCollectedHeap::no_allocs_since_save_marks(int level) { - if (level == 0 && !_young_gen->no_allocs_since_save_marks()) { +bool GenCollectedHeap::no_allocs_since_save_marks(bool include_young) { + if (include_young && !_young_gen->no_allocs_since_save_marks()) { return false; } return _old_gen->no_allocs_since_save_marks(); @@ -763,47 +765,47 @@ #endif // INCLUDE_ALL_GCS } else if (cause == GCCause::_wb_young_gc) { // minor collection for WhiteBox API - collect(cause, 0 /* young */); + collect(cause, Generation::Young); } else { #ifdef ASSERT if (cause == GCCause::_scavenge_alot) { // minor collection only - collect(cause, 0 /* young */); + collect(cause, Generation::Young); } else { // Stop-the-world full collection - collect(cause, 1 /* old */); + collect(cause, Generation::Old); } #else // Stop-the-world full collection - collect(cause, 1 /* old */); + collect(cause, Generation::Old); #endif } } -void GenCollectedHeap::collect(GCCause::Cause cause, int max_level) { +void GenCollectedHeap::collect(GCCause::Cause cause, Generation::Type max_generation) { // 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_generation); } 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, 1 /* old */); + 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); } } @@ -846,28 +848,28 @@ #endif // INCLUDE_ALL_GCS void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs) { - do_full_collection(clear_all_soft_refs, 1 /* old */); + 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 last_generation) { + Generation::Type local_last_generation; if (!incremental_collection_will_fail(false /* don't consult_young */) && gc_cause() == GCCause::_gc_locker) { - local_max_level = 0; + local_last_generation = Generation::Young; } else { - local_max_level = max_level; + local_last_generation = last_generation; } - do_collection(true /* full */, - clear_all_soft_refs /* clear_all_soft_refs */, - 0 /* size */, - false /* is_tlab */, - local_max_level /* max_level */); + do_collection(true /* full */, + clear_all_soft_refs /* clear_all_soft_refs */, + 0 /* size */, + false /* is_tlab */, + local_last_generation /* last_generation */); // 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_last_generation == 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 " @@ -878,7 +880,7 @@ clear_all_soft_refs /* clear_all_soft_refs */, 0 /* size */, false /* is_tlab */, - 1 /* old */ /* max_level */); + Generation::Old /* last_generation */); } } @@ -1101,12 +1103,8 @@ _young_gen->prepare_for_compaction(&cp); } -GCStats* GenCollectedHeap::gc_stats(int level) const { - if (level == 0) { - return _young_gen->gc_stats(); - } else { - return _old_gen->gc_stats(); - } +GCStats* GenCollectedHeap::gc_stats(Generation* gen) const { + return gen->gc_stats(); } void GenCollectedHeap::verify(bool silent, VerifyOption option /* ignored */) { @@ -1276,7 +1274,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/gc/shared/genCollectedHeap.hpp 2015-06-02 19:28:15.000000000 +0200 +++ new/src/share/vm/gc/shared/genCollectedHeap.hpp 2015-06-02 19:28:15.000000000 +0200 @@ -95,11 +95,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 @@ -110,7 +110,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_generation); // Does the "cause" of GC indicate that // we absolutely __must__ clear soft refs? @@ -121,7 +121,7 @@ FlexibleWorkGang* workers() const { return _workers; } - GCStats* gc_stats(int level) const; + GCStats* gc_stats(Generation* generation) const; // Returns JNI_OK on success virtual jint initialize(); @@ -142,6 +142,9 @@ Generation* young_gen() const { return _young_gen; } Generation* old_gen() const { return _old_gen; } + bool is_young_gen(const Generation* gen) const { return gen == _young_gen; } + bool is_old_gen(const Generation* gen) const { return gen == _old_gen; } + // The generational collector policy. GenCollectorPolicy* gen_policy() const { return _gen_policy; } @@ -160,8 +163,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; @@ -182,9 +185,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_generation. // 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_generation); // 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 @@ -314,10 +317,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); } bool no_gc_in_progress() { return !is_gc_active(); } @@ -365,8 +366,8 @@ static GenCollectedHeap* heap(); // 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 @@ -396,7 +397,7 @@ static const bool StrongRootsOnly = true; void gen_process_roots(StrongRootsScope* scope, - int level, + Generation::Type type, bool younger_gens_as_roots, ScanningOption so, bool only_strong_roots, @@ -420,7 +421,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 +429,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 +479,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_generation. // 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_generation); // Returns success or failure. bool create_cms_collector(); --- old/src/share/vm/gc/shared/generation.cpp 2015-06-02 19:28:16.000000000 +0200 +++ new/src/share/vm/gc/shared/generation.cpp 2015-06-02 19:28:16.000000000 +0200 @@ -42,8 +42,7 @@ #include "utilities/copy.hpp" #include "utilities/events.hpp" -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 " @@ -61,8 +60,10 @@ GenerationSpec* Generation::spec() { GenCollectedHeap* gch = GenCollectedHeap::heap(); - assert(level() == 0 || level() == 1, "Bad gen level"); - return level() == 0 ? gch->gen_policy()->young_gen_spec() : gch->gen_policy()->old_gen_spec(); + if (gch->is_young_gen(this)) { + return gch->gen_policy()->young_gen_spec(); + } + return gch->gen_policy()->old_gen_spec(); } size_t Generation::max_capacity() const { @@ -111,9 +112,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. + uint level; + if (GenCollectedHeap::heap()->is_young_gen(this)) { + 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, + "%u GC's, avg GC time %3.7f]", + level, time, sr->invocations, sr->invocations > 0 ? time / sr->invocations : 0.0); } @@ -149,25 +158,14 @@ return blk.sp != NULL; } -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 (GenCollectedHeap::heap()->is_young_gen(this)) { + 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 { --- old/src/share/vm/gc/shared/generation.hpp 2015-06-02 19:28:17.000000000 +0200 +++ new/src/share/vm/gc/shared/generation.hpp 2015-06-02 19:28:16.000000000 +0200 @@ -98,9 +98,6 @@ // Memory area reserved for generation VirtualSpace _virtual_space; - // Level in the generation hierarchy. - int _level; - // ("Weak") Reference processing support ReferenceProcessor* _ref_processor; @@ -110,12 +107,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. @@ -134,6 +127,11 @@ Other }; + enum Type { + Young, + Old + }; + enum SomePublicConstants { // Generations are GenGrain-aligned and have size that are multiples of // GenGrain. @@ -409,15 +407,14 @@ _time_of_last_gc = now; } - // Generations may keep statistics about collection. This - // method updates those statistics. current_level is - // the level of the collection that has most recently - // occurred. This allows the generation to decide what - // statistics are valid to collect. For example, the - // generation can decide to gather the amount of promoted data - // if the collection of the younger generations has completed. + // Generations may keep statistics about collection. This method + // updates those statistics. current_generation is the generation + // that was most recently collected. This allows the generation to + // decide what statistics are valid to collect. For example, the + // 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); @@ -502,8 +499,6 @@ virtual const char* name() const = 0; virtual const char* short_name() const = 0; - int level() const { return _level; } - // Reference Processing accessor ReferenceProcessor* const ref_processor() { return _ref_processor; } --- old/src/share/vm/gc/shared/generationSpec.cpp 2015-06-02 19:28:17.000000000 +0200 +++ new/src/share/vm/gc/shared/generationSpec.cpp 2015-06-02 19:28:17.000000000 +0200 @@ -36,18 +36,17 @@ #include "gc/cms/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/gc/shared/generationSpec.hpp 2015-06-02 19:28:18.000000000 +0200 +++ new/src/share/vm/gc/shared/generationSpec.hpp 2015-06-02 19:28:18.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/gc/shared/vmGCOperations.cpp 2015-06-02 19:28:19.000000000 +0200 +++ new/src/share/vm/gc/shared/vmGCOperations.cpp 2015-06-02 19:28:19.000000000 +0200 @@ -184,7 +184,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/shared/vmGCOperations.hpp 2015-06-02 19:28:20.000000000 +0200 +++ new/src/share/vm/gc/shared/vmGCOperations.hpp 2015-06-02 19:28:19.000000000 +0200 @@ -26,6 +26,7 @@ #define SHARE_VM_GC_SHARED_VMGCOPERATIONS_HPP #include "gc/shared/collectedHeap.hpp" +#include "gc/shared/generation.hpp" #include "memory/heapInspection.hpp" #include "prims/jvmtiExport.hpp" #include "runtime/handles.hpp" @@ -193,14 +194,14 @@ // GenCollectedHeap heap. class VM_GenCollectFull: public VM_GC_Operation { private: - int _max_level; + Generation::Type _max_generation; public: VM_GenCollectFull(uint gc_count_before, uint 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/runtime/vmStructs.cpp 2015-06-02 19:28:20.000000000 +0200 +++ new/src/share/vm/runtime/vmStructs.cpp 2015-06-02 19:28:20.000000000 +0200 @@ -545,7 +545,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) \ --- old/src/share/vm/services/memoryService.cpp 2015-06-02 19:28:21.000000000 +0200 +++ new/src/share/vm/services/memoryService.cpp 2015-06-02 19:28:21.000000000 +0200 @@ -127,7 +127,6 @@ assert(policy->is_generation_policy(), "Only support two generations"); GenCollectorPolicy* gen_policy = policy->as_generation_policy(); - guarantee(gen_policy->number_of_generations() == 2, "Only support two-generation heap"); if (gen_policy != NULL) { Generation::Name kind = gen_policy->young_gen_spec()->name(); switch (kind) {