# HG changeset patch # User rkennke # Date 1444246529 -7200 # Node ID 41ee7801dbc147cf3c5bb374830a8b05822cf4d6 # Parent 3abcb0c82f674f2cc87759a30dd1e4dae8006bcb Added more timing points to init-mark pause. diff -r 3abcb0c82f67 -r 41ee7801dbc1 src/share/vm/gc/shenandoah/shenandoahCollectorPolicy.cpp --- a/src/share/vm/gc/shenandoah/shenandoahCollectorPolicy.cpp Wed Oct 07 18:06:30 2015 +0200 +++ b/src/share/vm/gc/shenandoah/shenandoahCollectorPolicy.cpp Wed Oct 07 21:35:29 2015 +0200 @@ -47,8 +47,8 @@ virtual bool should_start_concurrent_mark(size_t used, size_t capacity) const=0; virtual bool update_refs_early(); - virtual void choose_collection_and_free_sets(ShenandoahHeapRegionSet* region_set, - ShenandoahHeapRegionSet* collection_set, + virtual void choose_collection_and_free_sets(ShenandoahHeapRegionSet* region_set, + ShenandoahHeapRegionSet* collection_set, ShenandoahHeapRegionSet* free_set) =0; void print_tracing_info(); }; @@ -69,14 +69,14 @@ if (PrintGCTimeStamps) { if (phase == init_mark) _tracer->report_gc_start(GCCause::_shenandoah_init_mark, _conc_timer->gc_start()); - else if (phase == full_gc) + else if (phase == full_gc) _tracer->report_gc_start(GCCause::_last_ditch_collection, _stw_timer->gc_start()); gclog_or_tty->gclog_stamp(_tracer->gc_id()); gclog_or_tty->print("[GC %s start", _phase_names[phase]); ShenandoahHeap* heap = (ShenandoahHeap*) Universe::heap(); - gclog_or_tty->print(" total = " SIZE_FORMAT " K, used = " SIZE_FORMAT " K free = " SIZE_FORMAT " K", heap->capacity()/ K, heap->used() /K, + gclog_or_tty->print(" total = " SIZE_FORMAT " K, used = " SIZE_FORMAT " K free = " SIZE_FORMAT " K", heap->capacity()/ K, heap->used() /K, ((heap->capacity() - heap->used())/K) ); if (heap->calculateUsed() != heap->used()) { @@ -580,6 +580,10 @@ _phase_names[init_mark] = "InitMark"; _phase_names[final_mark] = "FinalMark"; + _phase_names[accumulate_stats] = "AccumulateStats"; + _phase_names[make_parsable] = "MakeParsable"; + _phase_names[clear_liveness] = "ClearLiveness"; + _phase_names[scan_roots] = "ScanRoots"; _phase_names[rescan_roots] = "RescanRoots"; _phase_names[drain_satb] = "DrainSATB"; _phase_names[drain_queues] = "DrainQueues"; @@ -668,7 +672,7 @@ } void ShenandoahCollectorPolicy::initialize_alignments() { - + // This is expected by our algorithm for ShenandoahHeap::heap_region_containing(). _space_alignment = ShenandoahHeapRegion::RegionSizeBytes; _heap_alignment = ShenandoahHeapRegion::RegionSizeBytes; @@ -713,7 +717,7 @@ } void ShenandoahCollectorPolicy::choose_collection_and_free_sets( - ShenandoahHeapRegionSet* region_set, + ShenandoahHeapRegionSet* region_set, ShenandoahHeapRegionSet* collection_set, ShenandoahHeapRegionSet* free_set) { _heuristics->choose_collection_and_free_sets(region_set, collection_set, free_set); @@ -721,6 +725,10 @@ void ShenandoahCollectorPolicy::print_tracing_info() { print_summary_sd("Initial Mark Pauses", 0, &(_timing_data[init_mark]._ms)); + print_summary_sd("Accumulate Stats", 2, &(_timing_data[accumulate_stats]._ms)); + print_summary_sd("Make Parsable", 2, &(_timing_data[make_parsable]._ms)); + print_summary_sd("Clear Liveness", 2, &(_timing_data[clear_liveness]._ms)); + print_summary_sd("Scan Roots", 2, &(_timing_data[scan_roots]._ms)); print_summary_sd("Final Mark Pauses", 0, &(_timing_data[final_mark]._ms)); print_summary_sd("Rescan Roots", 2, &(_timing_data[rescan_roots]._ms)); @@ -777,4 +785,3 @@ gclog_or_tty->print_cr("%s = "INT32_FORMAT_W(5)", std dev = %8.2lf ms, max = %8.2lf ms)", "(num", seq->num(), seq->sd(), seq->maximum()); } - diff -r 3abcb0c82f67 -r 41ee7801dbc1 src/share/vm/gc/shenandoah/shenandoahCollectorPolicy.hpp --- a/src/share/vm/gc/shenandoah/shenandoahCollectorPolicy.hpp Wed Oct 07 18:06:30 2015 +0200 +++ b/src/share/vm/gc/shenandoah/shenandoahCollectorPolicy.hpp Wed Oct 07 21:35:29 2015 +0200 @@ -42,6 +42,10 @@ enum TimingPhase { init_mark, final_mark, + accumulate_stats, + make_parsable, + clear_liveness, + scan_roots, rescan_roots, drain_satb, drain_queues, @@ -82,7 +86,7 @@ ShenandoahTracer* _tracer; STWGCTimer* _stw_timer; ConcurrentGCTimer* _conc_timer; - + bool _conc_gc_aborted; public: @@ -114,7 +118,7 @@ void record_bytes_start_CM(size_t bytes); void record_bytes_end_CM(size_t bytes); bool should_start_concurrent_mark(size_t used, size_t capacity); - void choose_collection_and_free_sets(ShenandoahHeapRegionSet* region_set, + void choose_collection_and_free_sets(ShenandoahHeapRegionSet* region_set, ShenandoahHeapRegionSet* collection_set, ShenandoahHeapRegionSet* free_set); diff -r 3abcb0c82f67 -r 41ee7801dbc1 src/share/vm/gc/shenandoah/shenandoahHeap.cpp --- a/src/share/vm/gc/shenandoah/shenandoahHeap.cpp Wed Oct 07 18:06:30 2015 +0200 +++ b/src/share/vm/gc/shenandoah/shenandoahHeap.cpp Wed Oct 07 21:35:29 2015 +0200 @@ -96,9 +96,9 @@ class PrintHeapObjectsClosure : public ShenandoahHeapRegionClosure { public: bool doHeapRegion(ShenandoahHeapRegion* r) { - tty->print_cr("Region "INT32_FORMAT" top = "PTR_FORMAT" used = "SIZE_FORMAT_HEX" free = "SIZE_FORMAT_HEX, + tty->print_cr("Region "INT32_FORMAT" top = "PTR_FORMAT" used = "SIZE_FORMAT_HEX" free = "SIZE_FORMAT_HEX, r->region_number(), p2i(r->top()), r->used(), r->free()); - + ShenandoahHeap::heap()->print_heap_objects(r->bottom(), r->top()); return false; } @@ -109,15 +109,15 @@ size_t init_byte_size = collector_policy()->initial_heap_byte_size(); size_t max_byte_size = collector_policy()->max_heap_byte_size(); - if (ShenandoahGCVerbose) - tty->print_cr("init_byte_size = "SIZE_FORMAT","SIZE_FORMAT_HEX" max_byte_size = "INT64_FORMAT","SIZE_FORMAT_HEX, + if (ShenandoahGCVerbose) + tty->print_cr("init_byte_size = "SIZE_FORMAT","SIZE_FORMAT_HEX" max_byte_size = "INT64_FORMAT","SIZE_FORMAT_HEX, init_byte_size, init_byte_size, max_byte_size, max_byte_size); - Universe::check_alignment(max_byte_size, - ShenandoahHeapRegion::RegionSizeBytes, + Universe::check_alignment(max_byte_size, + ShenandoahHeapRegion::RegionSizeBytes, "shenandoah heap"); - Universe::check_alignment(init_byte_size, - ShenandoahHeapRegion::RegionSizeBytes, + Universe::check_alignment(init_byte_size, + ShenandoahHeapRegion::RegionSizeBytes, "shenandoah heap"); ReservedSpace heap_rs = Universe::reserve_heap(max_byte_size, @@ -128,13 +128,13 @@ ReservedSpace pgc_rs = heap_rs.first_part(max_byte_size); _storage.initialize(pgc_rs, init_byte_size); if (ShenandoahGCVerbose) { - tty->print_cr("Calling initialize on reserved space base = "PTR_FORMAT" end = "PTR_FORMAT, + tty->print_cr("Calling initialize on reserved space base = "PTR_FORMAT" end = "PTR_FORMAT, p2i(pgc_rs.base()), p2i(pgc_rs.base() + pgc_rs.size())); } _num_regions = init_byte_size / ShenandoahHeapRegion::RegionSizeBytes; _max_regions = max_byte_size / ShenandoahHeapRegion::RegionSizeBytes; - _ordered_regions = NEW_C_HEAP_ARRAY(ShenandoahHeapRegion*, _max_regions, mtGC); + _ordered_regions = NEW_C_HEAP_ARRAY(ShenandoahHeapRegion*, _max_regions, mtGC); for (size_t i = 0; i < _max_regions; i++) { _ordered_regions[i] = NULL; } @@ -147,7 +147,7 @@ for (size_t i = 0; i < _num_regions; i++) { ShenandoahHeapRegion* current = new ShenandoahHeapRegion(); - current->initialize_heap_region((HeapWord*) pgc_rs.base() + + current->initialize_heap_region((HeapWord*) pgc_rs.base() + regionSizeWords * i, regionSizeWords, i); _free_regions->append(current); _ordered_regions[i] = current; @@ -196,9 +196,9 @@ return JNI_OK; } -ShenandoahHeap::ShenandoahHeap(ShenandoahCollectorPolicy* policy) : +ShenandoahHeap::ShenandoahHeap(ShenandoahCollectorPolicy* policy) : CollectedHeap(), - _shenandoah_policy(policy), + _shenandoah_policy(policy), _concurrent_mark_in_progress(false), _evacuation_in_progress(false), _update_references_in_progress(false), @@ -229,7 +229,7 @@ _pgc = this; _scm = new ShenandoahConcurrentMark(); _used = 0; - // This is odd. They are concurrent gc threads, but they are also task threads. + // This is odd. They are concurrent gc threads, but they are also task threads. // Framework doesn't allow both. _workers = new WorkGang("Concurrent GC Threads", ParallelGCThreads, /* are_GC_task_threads */true, @@ -251,7 +251,7 @@ public: ResetBitmapTask(ShenandoahHeapRegionSet* regions) : - AbstractGangTask("Parallel Reset Bitmap Task"), + AbstractGangTask("Parallel Reset Bitmap Task"), _regions(regions) { } @@ -362,7 +362,7 @@ } void ShenandoahHeap::verify_heap_size_consistency() { - + assert(calculateUsed() == used(), err_msg("heap used size must be consistent heap-used: "SIZE_FORMAT" regions-used: "SIZE_FORMAT, used(), calculateUsed())); } @@ -383,7 +383,7 @@ void ShenandoahHeap::decrease_used(size_t bytes) { assert(_used >= bytes, "never decrease heap size by more than we've left"); _used -= bytes; - + // Atomic::add_ptr(-bytes, &_used); } @@ -410,7 +410,7 @@ _p = p; _result = false; } - + bool doHeapRegion(ShenandoahHeapRegion* r) { if (r->is_in(_p)) { _result = true; @@ -426,7 +426,7 @@ // IsInRegionClosure isIn(p); // heap_region_iterate(&isIn); // bool result = isIn.result(); - + // return isIn.result(); HeapWord* first_region_bottom = _first_region->bottom(); HeapWord* last_region_end = first_region_bottom + (ShenandoahHeapRegion::RegionSizeBytes / HeapWordSize) * _num_regions; @@ -436,7 +436,7 @@ bool ShenandoahHeap::is_in_partial_collection(const void* p ) { Unimplemented(); return false; -} +} bool ShenandoahHeap::is_scavengable(const void* p) { // nyi(); @@ -857,7 +857,7 @@ } }; -HeapWord* ShenandoahHeap::mem_allocate(size_t size, +HeapWord* ShenandoahHeap::mem_allocate(size_t size, bool* gc_overhead_limit_was_exceeded) { #ifdef ASSERT @@ -885,7 +885,7 @@ Thread* _thread; public: ParallelEvacuateRegionObjectClosure(ShenandoahHeap* heap) : - _heap(heap), _thread(Thread::current()) { + _heap(heap), _thread(Thread::current()) { } void do_object(oop p) { @@ -901,7 +901,7 @@ } } }; - + //fixme void ShenandoahHeap::initialize_brooks_ptr(HeapWord* filler, HeapWord* obj, bool new_obj) { BrooksPointer brooks_ptr = BrooksPointer::get(oop(obj)); @@ -916,7 +916,7 @@ class VerifyEvacuatedObjectClosure : public ObjectClosure { public: - + void do_object(oop p) { if (ShenandoahHeap::heap()->is_marked_current(p)) { oop p_prime = oopDesc::bs()->resolve_oop(p); @@ -951,7 +951,7 @@ assert(from_region->getLiveData() > 0, "all-garbage regions are reclaimed earlier"); ParallelEvacuateRegionObjectClosure evacuate_region(this); - + #ifdef ASSERT if (ShenandoahGCVerbose) { tty->print_cr("parallel_evacuate_region starting from_region "INT32_FORMAT": free_regions = "SIZE_FORMAT, from_region->region_number(), _free_regions->available_regions()); @@ -974,14 +974,14 @@ private: ShenandoahHeap* _sh; ShenandoahHeapRegionSet* _cs; - -public: - ParallelEvacuationTask(ShenandoahHeap* sh, + +public: + ParallelEvacuationTask(ShenandoahHeap* sh, ShenandoahHeapRegionSet* cs) : - AbstractGangTask("Parallel Evacuation Task"), + AbstractGangTask("Parallel Evacuation Task"), _cs(cs), _sh(sh) {} - + void work(uint worker_id) { ShenandoahHeapRegion* from_hr = _cs->claim_next(); @@ -1133,7 +1133,7 @@ if (! _heap->is_marked_current(o)) { _heap->print_heap_regions(); _heap->print_all_refs("post-mark"); - tty->print_cr("oop not marked, although referrer is marked: "PTR_FORMAT": in_heap: %s, is_marked: %s", + tty->print_cr("oop not marked, although referrer is marked: "PTR_FORMAT": in_heap: %s, is_marked: %s", p2i((HeapWord*) o), BOOL_TO_STR(_heap->is_in(o)), BOOL_TO_STR(_heap->is_marked_current(o))); _heap->print_heap_locations((HeapWord*) o, (HeapWord*) o + o->size()); @@ -1244,13 +1244,13 @@ if (_collection_set->length() == 0) cancel_concgc(); - + _bytesAllocSinceCM = 0; Universe::update_heap_info_at_gc(); } } - + class ShenandoahUpdateRootsClosure: public ExtendedOopClosure { @@ -1310,7 +1310,7 @@ public: ParallelUpdateRefsTask(ShenandoahHeapRegionSet* regions) : - AbstractGangTask("Parallel Update References Task"), + AbstractGangTask("Parallel Update References Task"), _regions(regions) { } @@ -1488,7 +1488,7 @@ void ShenandoahHeap::evacuate_and_update_roots() { COMPILER2_PRESENT(DerivedPointerTable::clear()); - + if (ShenandoahVerifyReadsToFromSpace) { set_from_region_protection(false); } @@ -1577,12 +1577,12 @@ if (ShenandoahPrintCollectionSet) { tty->print("Printing collection set which contains "SIZE_FORMAT" regions:\n", _collection_set->length()); _collection_set->print(); - + tty->print("Printing free set which contains "SIZE_FORMAT" regions:\n", _free_regions->length()); _free_regions->print(); // if (_collection_set->length() == 0) - // print_heap_regions(); + // print_heap_regions(); } ParallelEvacuationTask evacuationTask = ParallelEvacuationTask(this, _collection_set); @@ -1667,7 +1667,7 @@ size_t ShenandoahHeap::unsafe_max_tlab_alloc(Thread *thread) const { ShenandoahHeapRegion* current = get_current_region_skip_humongous(); - if (current == NULL) + if (current == NULL) return 0; else if (current->free() > MinTLABSize) { return current->free(); @@ -1782,7 +1782,7 @@ AdaptiveSizePolicy* ShenandoahHeap::size_policy() { Unimplemented(); return NULL; - + } ShenandoahCollectorPolicy* ShenandoahHeap::collector_policy() const { @@ -1946,7 +1946,7 @@ void ShenandoahHeap::cleanup_after_cancelconcgc() { if (need_update_refs()) { - ShenandoahUpdateObjectsClosure update_refs_cl; + ShenandoahUpdateObjectsClosure update_refs_cl; ShenandoahIterateUpdateClosure blk(&update_refs_cl); heap_region_iterate(&blk, false, false); } @@ -2011,7 +2011,7 @@ public: ShenandoahIterateOopClosureRegionClosure(ExtendedOopClosure* cl, bool skip_unreachable_objects) : _cl(cl), _skip_unreachable_objects(skip_unreachable_objects) {} - ShenandoahIterateOopClosureRegionClosure(MemRegion mr, ExtendedOopClosure* cl) + ShenandoahIterateOopClosureRegionClosure(MemRegion mr, ExtendedOopClosure* cl) :_mr(mr), _cl(cl) {} bool doHeapRegion(ShenandoahHeapRegion* r) { r->oop_iterate_skip_unreachable(_cl, _skip_unreachable_objects); @@ -2024,7 +2024,7 @@ heap_region_iterate(&blk, skip_dirty_regions, true); } -void ShenandoahHeap::oop_iterate(MemRegion mr, +void ShenandoahHeap::oop_iterate(MemRegion mr, ExtendedOopClosure* cl) { ShenandoahIterateOopClosureRegionClosure blk(mr, cl); heap_region_iterate(&blk, false, true); @@ -2086,7 +2086,7 @@ if (skip_dirty_regions && current->is_in_collection_set()) { continue; } - if (blk->doHeapRegion(current)) { + if (blk->doHeapRegion(current)) { return; } } @@ -2132,7 +2132,7 @@ ShenandoahHeap* sh; public: ClearLivenessClosure(ShenandoahHeap* heap) : sh(heap) { } - + bool doHeapRegion(ShenandoahHeapRegion* r) { r->clearLiveData(); return false; @@ -2142,12 +2142,16 @@ void ShenandoahHeap::start_concurrent_marking() { + shenandoahPolicy()->record_phase_start(ShenandoahCollectorPolicy::accumulate_stats); accumulate_statistics_all_tlabs(); + shenandoahPolicy()->record_phase_end(ShenandoahCollectorPolicy::accumulate_stats); set_concurrent_mark_in_progress(true); // We need to reset all TLABs because we'd lose marks on all objects allocated in them. if (UseTLAB) { + shenandoahPolicy()->record_phase_start(ShenandoahCollectorPolicy::make_parsable); ensure_parsability(true); + shenandoahPolicy()->record_phase_end(ShenandoahCollectorPolicy::make_parsable); } _shenandoah_policy->record_bytes_allocated(_bytesAllocSinceCM); @@ -2159,15 +2163,19 @@ print_all_refs("pre-mark"); } #endif - + + shenandoahPolicy()->record_phase_start(ShenandoahCollectorPolicy::clear_liveness); ClearLivenessClosure clc(this); heap_region_iterate(&clc); + shenandoahPolicy()->record_phase_end(ShenandoahCollectorPolicy::clear_liveness); // print_all_refs("pre -mark"); // oopDesc::_debug = true; + shenandoahPolicy()->record_phase_start(ShenandoahCollectorPolicy::scan_roots); concurrentMark()->prepare_unmarked_root_objs(); + shenandoahPolicy()->record_phase_end(ShenandoahCollectorPolicy::scan_roots); // print_all_refs("pre-mark2"); } @@ -2196,7 +2204,7 @@ if (! sh->is_marked_current(obj)) { sh->print_on(tty); } - assert(sh->is_marked_current(obj), err_msg("Referenced Objects should be marked obj: "PTR_FORMAT", marked: %s, is_in_heap: %s", + assert(sh->is_marked_current(obj), err_msg("Referenced Objects should be marked obj: "PTR_FORMAT", marked: %s, is_in_heap: %s", p2i((HeapWord*) obj), BOOL_TO_STR(sh->is_marked_current(obj)), BOOL_TO_STR(sh->is_in(obj)))); } } @@ -2453,9 +2461,9 @@ if (ShenandoahVerifyReadsToFromSpace) { hr = heap_region_containing(p); { - hr->memProtectionOff(); + hr->memProtectionOff(); required = BrooksPointer::BROOKS_POINTER_OBJ_SIZE + p->size(); - hr->memProtectionOn(); + hr->memProtectionOn(); } } else { required = BrooksPointer::BROOKS_POINTER_OBJ_SIZE + p->size(); @@ -2490,17 +2498,17 @@ } HeapWord* copy = filler + BrooksPointer::BROOKS_POINTER_OBJ_SIZE; - + #ifdef ASSERT if (ShenandoahVerifyReadsToFromSpace) { hr->memProtectionOff(); copy_object(p, filler); hr->memProtectionOn(); } else { - copy_object(p, filler); + copy_object(p, filler); } -#else - copy_object(p, filler); +#else + copy_object(p, filler); #endif HeapWord* result = BrooksPointer::get(p).cas_forwardee((HeapWord*) p, copy); @@ -2585,7 +2593,7 @@ } -bool ShenandoahIsAliveClosure:: do_object_b(oop obj) { +bool ShenandoahIsAliveClosure:: do_object_b(oop obj) { ShenandoahHeap* sh = ShenandoahHeap::heap(); if (sh->need_update_refs()) { @@ -2610,7 +2618,7 @@ tty->print_cr("ShenandoahIsAliveClosure Found an ill object "PTR_FORMAT, p2i((HeapWord*) obj)); obj->print(); } - else + else tty->print_cr("found a healthy object "PTR_FORMAT, p2i((HeapWord*) obj)); } else { @@ -2716,7 +2724,7 @@ OrderAccess::fence(); _shenandoah_policy->report_concgc_cancelled(); } - + if ((! Thread::current()->is_GC_task_thread()) && (! Thread::current()->is_ConcurrentGC_thread())) { while (_evacuation_in_progress) { // wait. Thread::current()->_ParkEvent->park(1) ;